From fe11b7eb931b757fdfee558a82280bb3bf38e548 Mon Sep 17 00:00:00 2001 From: Andrey Efremov Date: Fri, 9 Aug 2024 02:03:20 +0800 Subject: [PATCH] Fix test262 from #18438 - Fix invalid SpillFill reg in LSRA - Fix private get/set in NumberSpeculativeRetype - Fix missing deopt in private get/set lowering - Add more comments for circuit gates Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IAIA95 Change-Id: I5a522457cad3a4ab796ebbb8335d97974e40532b Signed-off-by: Andrey Efremov --- ecmascript/compiler/circuit.cpp | 32 +++++- ecmascript/compiler/circuit.h | 31 +++++- .../maple/maple_be/src/cg/reg_alloc_lsra.cpp | 15 ++- ecmascript/compiler/combined_pass_visitor.cpp | 4 + ecmascript/compiler/combined_pass_visitor.h | 6 +- ecmascript/compiler/gate.cpp | 43 ++++---- ecmascript/compiler/gate.h | 5 +- ecmascript/compiler/gate_accessor.cpp | 14 ++- .../compiler/ntype_bytecode_lowering.cpp | 1 + .../compiler/number_speculative_retype.cpp | 14 +++ ecmascript/compiler/slowpath_lowering.cpp | 1 + .../compiler/typed_bytecode_lowering.cpp | 3 + ecmascript/compiler/typed_hcr_lowering.cpp | 1 + test/aottest/BUILD.gn | 1 + test/aottest/builtin_inlining/number/BUILD.gn | 1 + .../number/ParseFloatNumber/BUILD.gn | 17 +++ .../builtinNumberParseFloatNumber.ts | 101 ++++++++++++++++++ test/aottest/privateproperty/BUILD.gn | 1 + .../aottest/privateproperty/expect_output.txt | 2 + .../privateproperty/pgo_expect_output.txt | 2 + .../privateproperty/privateproperty.ts | 21 ++++ test/aottest/privateproperty_js/BUILD.gn | 20 ++++ .../privateproperty_js/expect_output.txt | 15 +++ .../privateproperty_js/pgo_expect_output.txt | 15 +++ .../privateproperty_js/privateproperty_js.js | 31 ++++++ 25 files changed, 355 insertions(+), 42 deletions(-) create mode 100644 test/aottest/builtin_inlining/number/ParseFloatNumber/BUILD.gn create mode 100644 test/aottest/builtin_inlining/number/ParseFloatNumber/builtinNumberParseFloatNumber.ts create mode 100644 test/aottest/privateproperty_js/BUILD.gn create mode 100644 test/aottest/privateproperty_js/expect_output.txt create mode 100644 test/aottest/privateproperty_js/pgo_expect_output.txt create mode 100644 test/aottest/privateproperty_js/privateproperty_js.js diff --git a/ecmascript/compiler/circuit.cpp b/ecmascript/compiler/circuit.cpp index be31da2c5e..f7d7605287 100644 --- a/ecmascript/compiler/circuit.cpp +++ b/ecmascript/compiler/circuit.cpp @@ -94,7 +94,7 @@ bool Circuit::AddComment(GateRef g, std::string &&str) return true; } -std::string_view Circuit::GetComment(GateRef gate) +std::string_view Circuit::GetComment(GateRef gate) const { if (debugInfo_ == nullptr || !debugInfo_->IsEnable()) { return ""; @@ -143,6 +143,11 @@ GateRef Circuit::NewGate(const GateMetaData *meta, MachineType machineType, size if (comment != nullptr) { AddComment(result, std::string(comment)); } +#ifndef NDEBUG + if (UNLIKELY(debugInfo_ != nullptr && !currentComment_.empty())) { + AddComment(result, std::string(currentComment_)); + } +#endif return result; } @@ -182,7 +187,7 @@ void Circuit::PrintAllGatesWithBytecode() const std::vector gateList; GetAllGates(gateList); for (const auto &gate : gateList) { - LoadGatePtrConst(gate)->PrintWithBytecode(); + LoadGatePtrConst(gate)->PrintWithBytecode(GetComment(gate)); } } @@ -418,6 +423,29 @@ GateId Circuit::GetId(GateRef gate) const return LoadGatePtrConst(gate)->GetId(); } +#ifndef NDEBUG +Circuit::ScopedComment::ScopedComment(std::string &&str, std::string_view *comment) + : old_(*comment), comment_(comment) +{ + if (comment->empty()) { + str_ = std::move(str); + } else { + str_ = std::string{*comment} + " " + std::move(str); + } + *comment_ = {str_}; +} + +Circuit::ScopedComment Circuit::VisitGateBegin(GateRef visitedGate) +{ + return ScopedComment("old " + std::to_string(GetId(visitedGate)), ¤tComment_); +} + +Circuit::ScopedComment Circuit::CommentBegin(std::string &&str) +{ + return ScopedComment(std::move(str), ¤tComment_); +} +#endif + void Circuit::Print(GateRef gate) const { LoadGatePtrConst(gate)->Print(); diff --git a/ecmascript/compiler/circuit.h b/ecmascript/compiler/circuit.h index 6736909dee..e9f55b2991 100644 --- a/ecmascript/compiler/circuit.h +++ b/ecmascript/compiler/circuit.h @@ -236,12 +236,40 @@ public: isOsr_ = true; } +#ifndef NDEBUG + class ScopedComment { + public: + explicit ScopedComment(std::string &&str, std::string_view *comment); + + ~ScopedComment() + { + *comment_ = old_; + } + private: + std::string_view old_; + std::string str_; + std::string_view *comment_; + }; + + ScopedComment VisitGateBegin(GateRef visitedGate); + ScopedComment CommentBegin(std::string &&str); +#else + size_t VisitGateBegin([[maybe_unused]] GateRef visitedGate) + { + return 0; + } + size_t CommentBegin([[maybe_unused]] GateRef visitedGate) + { + return 0; + } +#endif + private: static const size_t CIRCUIT_SPACE = 1U << 30U; // 1GB public: void Print(GateRef gate) const; bool AddComment(GateRef g, std::string &&str); - std::string_view GetComment(GateRef gate); + std::string_view GetComment(GateRef gate) const; private: GateType GetGateType(GateRef gate) const; @@ -312,6 +340,7 @@ private: DebugInfo* debugInfo_ {nullptr}; #ifndef NDEBUG ChunkVector allGates_; + std::string_view currentComment_ {}; #endif friend class GateAccessor; diff --git a/ecmascript/compiler/codegen/maple/maple_be/src/cg/reg_alloc_lsra.cpp b/ecmascript/compiler/codegen/maple/maple_be/src/cg/reg_alloc_lsra.cpp index 47b5f40d2c..663280a4af 100644 --- a/ecmascript/compiler/codegen/maple/maple_be/src/cg/reg_alloc_lsra.cpp +++ b/ecmascript/compiler/codegen/maple/maple_be/src/cg/reg_alloc_lsra.cpp @@ -449,6 +449,7 @@ void LSRALinearScanRegAllocator::InitFreeRegPool() } } } + DEBUG_ASSERT(intSpillRegSet.size() >= 2U, "too few spill regs"); if (needDump) { PrintRegSet(intCallerRegSet, "ALLOCATABLE_INT_CALLER"); @@ -1402,10 +1403,10 @@ void LSRALinearScanRegAllocator::InsertCallerSave(Insn &insn, Operand &opnd, boo phyOpnd = regInfo->GetOrCreatePhyRegOperand(static_cast(rli->GetAssignedReg()), regSize, regType); std::string comment; bool isOutOfRange = false; + auto tmpReg = static_cast(intSpillRegSet[spillIdx] + firstIntReg); if (isDef) { Insn *nextInsn = insn.GetNext(); - memOpnd = GetSpillMem(vRegNO, true, insn, static_cast(intSpillRegSet[spillIdx + 1] + firstIntReg), - isOutOfRange, regSize); + memOpnd = GetSpillMem(vRegNO, true, insn, tmpReg, isOutOfRange, regSize); Insn *stInsn = regInfo->BuildStrInsn(regSize, spType, *phyOpnd, *memOpnd); comment = " SPILL for caller_save " + std::to_string(vRegNO); ++callerSaveSpillCount; @@ -1422,8 +1423,7 @@ void LSRALinearScanRegAllocator::InsertCallerSave(Insn &insn, Operand &opnd, boo insn.GetBB()->InsertInsnAfter(insn, *stInsn); } } else { - memOpnd = GetSpillMem(vRegNO, false, insn, static_cast(intSpillRegSet[spillIdx] + firstIntReg), - isOutOfRange, regSize); + memOpnd = GetSpillMem(vRegNO, false, insn, tmpReg, isOutOfRange, regSize); Insn *ldInsn = regInfo->BuildLdrInsn(regSize, spType, *phyOpnd, *memOpnd); comment = " RELOAD for caller_save " + std::to_string(vRegNO); ++callerSaveReloadCount; @@ -1514,6 +1514,7 @@ void LSRALinearScanRegAllocator::SpillOperand(Insn &insn, Operand &opnd, bool is } else { CHECK_FATAL(false, "SpillOperand: Should be int or float type"); } + auto tmpReg = static_cast(intSpillRegSet[spillIdx] + firstIntReg); bool isOutOfRange = false; auto *phyOpnd = regInfo->GetOrCreatePhyRegOperand(static_cast(spReg), regSize, regType); @@ -1532,8 +1533,7 @@ void LSRALinearScanRegAllocator::SpillOperand(Insn &insn, Operand &opnd, bool is ++spillCount; Insn *nextInsn = insn.GetNext(); - memOpnd = GetSpillMem(regNO, true, insn, static_cast(intSpillRegSet[spillIdx + 1] + firstIntReg), - isOutOfRange, regSize); + memOpnd = GetSpillMem(regNO, true, insn, tmpReg, isOutOfRange, regSize); Insn *stInsn = regInfo->BuildStrInsn(regSize, spType, *phyOpnd, *memOpnd); if (li->GetLastUse() == insn.GetId()) { regInfo->FreeSpillRegMem(regNO); @@ -1558,8 +1558,7 @@ void LSRALinearScanRegAllocator::SpillOperand(Insn &insn, Operand &opnd, bool is << cgFunc->GetName() << "\n"; } ++reloadCount; - memOpnd = GetSpillMem(regNO, false, insn, static_cast(intSpillRegSet[spillIdx] + firstIntReg), - isOutOfRange, regSize); + memOpnd = GetSpillMem(regNO, false, insn, tmpReg, isOutOfRange, regSize); Insn *ldInsn = regInfo->BuildLdrInsn(regSize, spType, *phyOpnd, *memOpnd); if (li->GetLastUse() == insn.GetId()) { regInfo->FreeSpillRegMem(regNO); diff --git a/ecmascript/compiler/combined_pass_visitor.cpp b/ecmascript/compiler/combined_pass_visitor.cpp index cb00ad7cc3..aa4191d1be 100644 --- a/ecmascript/compiler/combined_pass_visitor.cpp +++ b/ecmascript/compiler/combined_pass_visitor.cpp @@ -97,6 +97,9 @@ void CombinedPassVisitor::ReplaceGate(GateRef gate, StateDepend stateDepend, Gat it = acc_.ReplaceIn(it, replacement); } } +#ifndef NDEBUG + acc_.GetCircuit()->AddComment(replacement, "old V " + std::to_string(acc_.GetId(gate))); +#endif } void CombinedPassVisitor::VistDependSelectorForLoop(GateRef gate) @@ -161,6 +164,7 @@ void CombinedPassVisitor::ReVisitGate(GateRef gate) GateRef CombinedPassVisitor::VisitGate(GateRef gate) { + [[maybe_unused]] auto scopedGate = circuit_->VisitGateBegin(gate); auto skip = passList_.end(); for (auto i = passList_.begin(); i != passList_.end();) { if (i == skip) { diff --git a/ecmascript/compiler/combined_pass_visitor.h b/ecmascript/compiler/combined_pass_visitor.h index 15b1a939b4..dff5e22957 100644 --- a/ecmascript/compiler/combined_pass_visitor.h +++ b/ecmascript/compiler/combined_pass_visitor.h @@ -66,11 +66,11 @@ public: chunk_(chunk), workList_(chunk), changedList_(chunk), orderList_(chunk), passList_(chunk) {} virtual ~CombinedPassVisitor() = default; void AddPass(PassVisitor* pass); - + int32_t GetGateOrder(GateRef gate) override; void SetGateOrder(GateRef gate, int32_t orderId) override; void Resize(int32_t size, int32_t num) override; - + void VisitGraph(); GateRef VisitGate(GateRef gate); void ReVisitGate(GateRef gate) override; @@ -82,7 +82,7 @@ public: void VistDependSelectorForLoop(GateRef gate); protected: - + void VisitTopGate(Edge& current); void PushGate(GateRef gate, size_t index) diff --git a/ecmascript/compiler/gate.cpp b/ecmascript/compiler/gate.cpp index cffa1452f4..b3286398f7 100644 --- a/ecmascript/compiler/gate.cpp +++ b/ecmascript/compiler/gate.cpp @@ -964,62 +964,57 @@ size_t Gate::PrintInGate(size_t numIns, size_t idx, size_t size, bool inListPrev return idx; } -void Gate::PrintWithBytecode() const +std::string Gate::GetBytecodeStr() const { - auto opcode = GetOpCode(); - std::string bytecodeStr = ""; - switch (opcode) { + switch (GetOpCode()) { case OpCode::JS_BYTECODE: { - bytecodeStr = GetJSBytecodeMetaData()->Str(); - break; + return GetJSBytecodeMetaData()->Str(); } case OpCode::TYPED_BINARY_OP: { auto typedOp = TypedBinaryAccessor(GetOneParameterMetaData()->GetValue()).GetTypedBinOp(); - bytecodeStr = GateMetaData::Str(typedOp); - break; + return GateMetaData::Str(typedOp); } case OpCode::TYPED_UNARY_OP: { auto typedOp = TypedUnaryAccessor(GetOneParameterMetaData()->GetValue()).GetTypedUnOp(); - bytecodeStr = GateMetaData::Str(typedOp); - break; + return GateMetaData::Str(typedOp); } case OpCode::TYPED_CONDITION_JUMP: { auto typedOp = TypedJumpAccessor(GetOneParameterMetaData()->GetValue()).GetTypedJumpOp(); - bytecodeStr = GateMetaData::Str(typedOp); - break; + return GateMetaData::Str(typedOp); } case OpCode::LOAD_ELEMENT: { auto typedOp = static_cast(GetOneParameterMetaData()->GetValue()); - bytecodeStr = GateMetaData::Str(typedOp); - break; + return GateMetaData::Str(typedOp); } case OpCode::STORE_ELEMENT: { auto typedOp = static_cast(GetOneParameterMetaData()->GetValue()); - bytecodeStr = GateMetaData::Str(typedOp); - break; + return GateMetaData::Str(typedOp); } case OpCode::TYPED_CALLTARGETCHECK_OP: { TypedCallTargetCheckAccessor accessor(GetOneParameterMetaData()->GetValue()); auto typedOp = accessor.GetCallTargetCheckOp(); - bytecodeStr = GateMetaData::Str(typedOp); - break; + return GateMetaData::Str(typedOp); } case OpCode::CONVERT: case OpCode::CHECK_AND_CONVERT: { ValuePairTypeAccessor accessor(GetOneParameterMetaData()->GetValue()); - bytecodeStr = GateMetaData::Str(accessor.GetSrcType()) + "_TO_" + + return GateMetaData::Str(accessor.GetSrcType()) + "_TO_" + GateMetaData::Str(accessor.GetDstType()); - break; } default: - break; + return ""; } - PrintGateWithAdditionOp(bytecodeStr); + return ""; } -void Gate::PrintGateWithAdditionOp(std::string additionOp) const +void Gate::PrintWithBytecode(std::string_view comment) const { - Print(additionOp); + PrintGateWithAdditionOp(GetBytecodeStr(), comment); +} + +void Gate::PrintGateWithAdditionOp(std::string additionOp, std::string_view comment) const +{ + Print(additionOp, false, -1, comment); } MarkCode Gate::GetMark(TimeStamp stamp) const diff --git a/ecmascript/compiler/gate.h b/ecmascript/compiler/gate.h index 5e080b7b45..e1f47a4070 100644 --- a/ecmascript/compiler/gate.h +++ b/ecmascript/compiler/gate.h @@ -186,8 +186,8 @@ public: void ShortPrint(std::string bytecode = "", bool inListPreview = false, size_t highlightIdx = -1) const; size_t PrintInGate(size_t numIns, size_t idx, size_t size, bool inListPreview, size_t highlightIdx, std::ostringstream &log, bool isEnd = false) const; - void PrintGateWithAdditionOp(std::string additionOp) const; - void PrintWithBytecode() const; + void PrintGateWithAdditionOp(std::string additionOp, std::string_view comment) const; + void PrintWithBytecode(std::string_view comment) const; void CheckNullInput() const; void CheckStateInput() const; void CheckValueInput(bool isArch64) const; @@ -284,6 +284,7 @@ private: void DumpInputs(std::ostringstream &oss, bool inListPreview, size_t highlightIdx) const; void DumpOutputs(std::ostringstream &oss, bool inListPreview) const; + std::string GetBytecodeStr() const; // ... // out(2) diff --git a/ecmascript/compiler/gate_accessor.cpp b/ecmascript/compiler/gate_accessor.cpp index fe61808e32..e823dabe57 100644 --- a/ecmascript/compiler/gate_accessor.cpp +++ b/ecmascript/compiler/gate_accessor.cpp @@ -773,7 +773,7 @@ void GateAccessor::PrintById(size_t id) const GateRef gate = circuit_->GetGateRefById(id); if (gate != Circuit::NullGate()) { Gate *gatePtr = circuit_->LoadGatePtr(gate); - gatePtr->PrintWithBytecode(); + gatePtr->PrintWithBytecode(circuit_->GetComment(gate)); } else { LOG_COMPILER(INFO) << "id overflow!"; } @@ -783,7 +783,7 @@ void GateAccessor::PrintById(size_t id) const void GateAccessor::PrintWithBytecode(GateRef gate) const { Gate *gatePtr = circuit_->LoadGatePtr(gate); - gatePtr->PrintWithBytecode(); + gatePtr->PrintWithBytecode(circuit_->GetComment(gate)); } void GateAccessor::ShortPrint(GateRef gate) const @@ -1307,6 +1307,10 @@ void GateAccessor::ReplaceHirAndDeleteIfException(GateRef hirGate, if (ifException != Circuit::NullGate()) { ReplaceGate(ifException, circuit_->DeadGate()); } + #ifndef NDEBUG + GetCircuit()->AddComment(value, "old V " + std::to_string(GetId(hirGate))); + GetCircuit()->AddComment(replacement.Depend(), "old D " + std::to_string(GetId(hirGate))); + #endif } UseIterator GateAccessor::DeleteGate(const UseIterator &useIt) @@ -1550,6 +1554,9 @@ void GateAccessor::ReplaceGate(GateRef gate, GateRef state, GateRef depend, Gate UNREACHABLE(); } } +#ifndef NDEBUG + GetCircuit()->AddComment(value, "old V " + std::to_string(GetId(gate))); +#endif DeleteGate(gate); } @@ -1585,6 +1592,9 @@ void GateAccessor::ReplaceGate(GateRef gate, StateDepend stateDepend, GateRef re it = ReplaceIn(it, replacement); } } +#ifndef NDEBUG + GetCircuit()->AddComment(replacement, "old V " + std::to_string(GetId(gate))); +#endif DeleteGate(gate); } diff --git a/ecmascript/compiler/ntype_bytecode_lowering.cpp b/ecmascript/compiler/ntype_bytecode_lowering.cpp index b88919373d..94eea5442a 100644 --- a/ecmascript/compiler/ntype_bytecode_lowering.cpp +++ b/ecmascript/compiler/ntype_bytecode_lowering.cpp @@ -51,6 +51,7 @@ void NTypeBytecodeLowering::RunNTypeBytecodeLowering() void NTypeBytecodeLowering::Lower(GateRef gate) { + [[maybe_unused]] auto scopedGate = circuit_->VisitGateBegin(gate); EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate); // initialize label manager Environment env(gate, circuit_, &builder_); diff --git a/ecmascript/compiler/number_speculative_retype.cpp b/ecmascript/compiler/number_speculative_retype.cpp index ed4f99590c..05dacc5a57 100644 --- a/ecmascript/compiler/number_speculative_retype.cpp +++ b/ecmascript/compiler/number_speculative_retype.cpp @@ -300,6 +300,8 @@ GateRef NumberSpeculativeRetype::VisitGate(GateRef gate) case OpCode::TAGGED_TO_INT64: case OpCode::TYPED_CALL_BUILTIN: case OpCode::TYPED_CALL_BUILTIN_SIDE_EFFECT: + case OpCode::CALL_PRIVATE_GETTER: + case OpCode::CALL_PRIVATE_SETTER: case OpCode::MAP_GET: case OpCode::NEW_NUMBER: case OpCode::TYPED_ARRAY_ENTRIES: @@ -1717,6 +1719,18 @@ GateRef NumberSpeculativeRetype::VisitNumberParseFloat(GateRef gate) return SetOutputType(gate, GateType::DoubleType()); } ASSERT(IsConvert()); + Environment env(gate, circuit_, &builder_); + GateRef input = acc_.GetValueIn(gate, 0); + TypeInfo type = GetNumberTypeInfo(input); + if (type == TypeInfo::INT32) { + // replace parseFloat with cast + input = CheckAndConvertToFloat64(input, GateType::NumberType(), ConvertToNumber::DISABLE); + acc_.ReplaceGate(gate, builder_.GetStateDepend(), input); + } else { + acc_.ReplaceValueIn(gate, ConvertToTagged(input), 0); + acc_.ReplaceStateIn(gate, builder_.GetState()); + acc_.ReplaceDependIn(gate, builder_.GetDepend()); + } return Circuit::NullGate(); } diff --git a/ecmascript/compiler/slowpath_lowering.cpp b/ecmascript/compiler/slowpath_lowering.cpp index d806e378a0..ab277d7789 100644 --- a/ecmascript/compiler/slowpath_lowering.cpp +++ b/ecmascript/compiler/slowpath_lowering.cpp @@ -51,6 +51,7 @@ void SlowPathLowering::CallRuntimeLowering() for (const auto &gate : gateList) { auto op = acc_.GetOpCode(gate); + [[maybe_unused]] auto scopedGate = circuit_->VisitGateBegin(gate); switch (op) { case OpCode::JS_BYTECODE: Lower(gate); diff --git a/ecmascript/compiler/typed_bytecode_lowering.cpp b/ecmascript/compiler/typed_bytecode_lowering.cpp index f4877e9ff4..773610fdd5 100644 --- a/ecmascript/compiler/typed_bytecode_lowering.cpp +++ b/ecmascript/compiler/typed_bytecode_lowering.cpp @@ -111,6 +111,7 @@ bool TypedBytecodeLowering::CheckIsInOptBCIgnoreRange(int32_t index, EcmaOpcode void TypedBytecodeLowering::Lower(GateRef gate) { + [[maybe_unused]] auto scopedGate = circuit_->VisitGateBegin(gate); // not all opcode will visit heap, but now jit lock all opcode Jit::JitLockHolder lock(compilationEnv_, "TypedBytecodeLowering::Lower"); @@ -655,6 +656,7 @@ void TypedBytecodeLowering::LowerTypedLdPrivateProperty(GateRef gate) GateRef key = builder_.GetKeyFromLexivalEnv( tacc.GetLexicalEnv(), builder_.TaggedGetInt(levelIndex), builder_.TaggedGetInt(slotIndex)); + builder_.HeapObjectCheck(key, frameState); if (tacc.IsAccessor()) { builder_.DeoptCheck(builder_.IsJSFunction(key), frameState, DeoptType::NOTJSFUNCTION); result = builder_.CallPrivateGetter(gate, receiver, key); @@ -692,6 +694,7 @@ void TypedBytecodeLowering::LowerTypedStPrivateProperty(GateRef gate) GateRef key = builder_.GetKeyFromLexivalEnv( tacc.GetLexicalEnv(), builder_.TaggedGetInt(levelIndex), builder_.TaggedGetInt(slotIndex)); + builder_.HeapObjectCheck(key, frameState); if (tacc.IsAccessor()) { builder_.DeoptCheck(builder_.IsJSFunction(key), frameState, DeoptType::NOTJSFUNCTION); builder_.CallPrivateSetter(gate, receiver, key, value); diff --git a/ecmascript/compiler/typed_hcr_lowering.cpp b/ecmascript/compiler/typed_hcr_lowering.cpp index 3ce8593a9d..849ee9eba7 100644 --- a/ecmascript/compiler/typed_hcr_lowering.cpp +++ b/ecmascript/compiler/typed_hcr_lowering.cpp @@ -40,6 +40,7 @@ GateRef TypedHCRLowering::VisitGate(GateRef gate) { GateRef glue = acc_.GetGlueFromArgList(); auto op = acc_.GetOpCode(gate); + [[maybe_unused]] auto scopedGate = circuit_->VisitGateBegin(gate); switch (op) { case OpCode::PRIMITIVE_TYPE_CHECK: LowerPrimitiveTypeCheck(gate); diff --git a/test/aottest/BUILD.gn b/test/aottest/BUILD.gn index 51b5062063..0d9b48ab55 100644 --- a/test/aottest/BUILD.gn +++ b/test/aottest/BUILD.gn @@ -249,6 +249,7 @@ group("ark_aot_ts_test") { "poplexenv", "proxy", "privateproperty", + "privateproperty_js", "resumegenerator", "rodata", "setobjectwithproto", diff --git a/test/aottest/builtin_inlining/number/BUILD.gn b/test/aottest/builtin_inlining/number/BUILD.gn index 7e6dd05f96..d73c800eef 100644 --- a/test/aottest/builtin_inlining/number/BUILD.gn +++ b/test/aottest/builtin_inlining/number/BUILD.gn @@ -16,6 +16,7 @@ group("ark_aot_builtin_inlining_number_test") { test_list = [ "Constructor", "ParseFloat", + "ParseFloatNumber", ] deps = [] diff --git a/test/aottest/builtin_inlining/number/ParseFloatNumber/BUILD.gn b/test/aottest/builtin_inlining/number/ParseFloatNumber/BUILD.gn new file mode 100644 index 0000000000..f847ee97ec --- /dev/null +++ b/test/aottest/builtin_inlining/number/ParseFloatNumber/BUILD.gn @@ -0,0 +1,17 @@ +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//arkcompiler/ets_runtime/test/test_helper.gni") + +host_aot_builtin_inlining_test_action("builtinNumberParseFloatNumber") { +} diff --git a/test/aottest/builtin_inlining/number/ParseFloatNumber/builtinNumberParseFloatNumber.ts b/test/aottest/builtin_inlining/number/ParseFloatNumber/builtinNumberParseFloatNumber.ts new file mode 100644 index 0000000000..7464470808 --- /dev/null +++ b/test/aottest/builtin_inlining/number/ParseFloatNumber/builtinNumberParseFloatNumber.ts @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +declare function print(arg:any):string; + +function testNumberParseFloat(a : any, shouldThrow = 0): any +{ + try { + if (shouldThrow == 1) { + throw Error("thr 1"); + } + let x = Number.parseFloat(a); + if (shouldThrow == 2) { + throw Error("thr 2"); + } + return x; + } catch (e) { + print("catch", "'" + e + "'", "in testNumberParseFloat"); + throw (e) + } finally { + print("exit testNumberParseFloat"); + } +} + +function testParseFloat(a : any, shouldThrow = 0): any +{ + try { + if (shouldThrow == 1) { + throw Error("thr 1"); + } + let x = parseFloat(a); + if (shouldThrow == 2) { + throw Error("thr 2"); + } + return x; + } catch (e) { + print("catch", "'" + e + "'", "in testParseFloat"); + throw (e) + } finally { + print("exit testParseFloat"); + } +} + +print(Number.parseFloat === parseFloat); +//: true + +function test(a : any) +{ + let checks = [typeof a, a]; + print(checks) +} + +function testParseFloatInt(a: number) { + try { + return parseFloat((a | 0) as any); + } catch (e) { + print("catch", "'" + e + "'", "in testParseFloat"); + throw (e) + } +} +test(testParseFloatInt(-2)); +//aot: [trace] aot inline builtin: Number.parseFloat, caller function name:#*#testParseFloatInt@builtinNumberParseFloatNumber +//aot: [trace] aot inline function name: #*#test@builtinNumberParseFloatNumber caller function name: func_main_0@builtinNumberParseFloatNumber +//: number,-2 + +let negZero = testParseFloat(-0.0 as any); +//aot: [trace] aot inline builtin: Number.parseFloat, caller function name:#*#testParseFloat@builtinNumberParseFloatNumber +//aot: [trace] Check Type: NotString1 +//: exit testParseFloat +print(Object.is(negZero, -0)) +//aot: [trace] aot inline builtin: Object.is, caller function name:func_main_0@builtinNumberParseFloatNumber +//: false +print(Object.is(negZero, 0)) +//aot: [trace] aot inline builtin: Object.is, caller function name:func_main_0@builtinNumberParseFloatNumber +//: true + +test(testParseFloat(-2.01)); +//aot: [trace] aot inline builtin: Number.parseFloat, caller function name:#*#testParseFloat@builtinNumberParseFloatNumber +//aot: [trace] Check Type: NotString1 +//: exit testParseFloat +//aot: [trace] aot inline function name: #*#test@builtinNumberParseFloatNumber caller function name: func_main_0@builtinNumberParseFloatNumber +//: number,-2.01 + +test(testNumberParseFloat(-2.01)); +//aot: [trace] aot inline builtin: Number.parseFloat, caller function name:#*#testNumberParseFloat@builtinNumberParseFloatNumber +//aot: [trace] Check Type: NotString1 +//: exit testNumberParseFloat +//aot: [trace] aot inline function name: #*#test@builtinNumberParseFloatNumber caller function name: func_main_0@builtinNumberParseFloatNumber +//: number,-2.01 diff --git a/test/aottest/privateproperty/BUILD.gn b/test/aottest/privateproperty/BUILD.gn index bdf6588403..14804918c1 100644 --- a/test/aottest/privateproperty/BUILD.gn +++ b/test/aottest/privateproperty/BUILD.gn @@ -16,4 +16,5 @@ import("//arkcompiler/ets_runtime/test/test_helper.gni") host_aot_test_action("privateproperty") { deps = [] is_enable_pgo = true + is_enable_opt_inlining = true } diff --git a/test/aottest/privateproperty/expect_output.txt b/test/aottest/privateproperty/expect_output.txt index 93fa4d345d..0d221254b0 100644 --- a/test/aottest/privateproperty/expect_output.txt +++ b/test/aottest/privateproperty/expect_output.txt @@ -23,5 +23,7 @@ 1 Symbol() Symbol(symbol) +3 +3 testReadIcSlotInPrivatePropertyIns success TypeError : invalid or cannot find private key diff --git a/test/aottest/privateproperty/pgo_expect_output.txt b/test/aottest/privateproperty/pgo_expect_output.txt index 5b2dd8f201..0c78280ce7 100644 --- a/test/aottest/privateproperty/pgo_expect_output.txt +++ b/test/aottest/privateproperty/pgo_expect_output.txt @@ -23,5 +23,7 @@ 1 Symbol() Symbol(symbol) +3 +3 testReadIcSlotInPrivatePropertyIns success TypeError : invalid or cannot find private key diff --git a/test/aottest/privateproperty/privateproperty.ts b/test/aottest/privateproperty/privateproperty.ts index cefd248ee7..a0ba3abc27 100644 --- a/test/aottest/privateproperty/privateproperty.ts +++ b/test/aottest/privateproperty/privateproperty.ts @@ -53,6 +53,27 @@ const namedSymbol = Symbol("symbol"); print(symbol.toString()); print(namedSymbol.toString()); +class BitwiseAnd { + #setterCalledWith: number = 0; + get #field() { + return 0b010111; + } + set #field(value) { + this.#setterCalledWith = value; + } + compoundAssignment() { + return this.#field &= 0b101011; + } + setterCalledWithValue() { + return this.#setterCalledWith; + } +} + +const o = new BitwiseAnd(); +// Check that CALL_PRIVATE_GETTER/CALL_PRIVATE_SETTER are processed correctly in NumberSpeculativeRetype +print(o.compoundAssignment()); +print(o.setterCalledWithValue()); + // Test if the `slotid` is read correctly in the `ldprivateproperty`/`stprivateproperty` function testReadIcSlotInPrivatePropertyIns() { let a; diff --git a/test/aottest/privateproperty_js/BUILD.gn b/test/aottest/privateproperty_js/BUILD.gn new file mode 100644 index 0000000000..3b7920b7b2 --- /dev/null +++ b/test/aottest/privateproperty_js/BUILD.gn @@ -0,0 +1,20 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//arkcompiler/ets_runtime/test/test_helper.gni") + +host_aot_js_test_action("privateproperty_js") { + deps = [] + is_enable_pgo = true + is_enable_opt_inlining = true +} diff --git a/test/aottest/privateproperty_js/expect_output.txt b/test/aottest/privateproperty_js/expect_output.txt new file mode 100644 index 0000000000..6e01715be7 --- /dev/null +++ b/test/aottest/privateproperty_js/expect_output.txt @@ -0,0 +1,15 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +TypeError : invalid or cannot find private key +undefined diff --git a/test/aottest/privateproperty_js/pgo_expect_output.txt b/test/aottest/privateproperty_js/pgo_expect_output.txt new file mode 100644 index 0000000000..b484f10a2b --- /dev/null +++ b/test/aottest/privateproperty_js/pgo_expect_output.txt @@ -0,0 +1,15 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +TypeError : Cannot read property of undefined +undefined diff --git a/test/aottest/privateproperty_js/privateproperty_js.js b/test/aottest/privateproperty_js/privateproperty_js.js new file mode 100644 index 0000000000..eb4184bf94 --- /dev/null +++ b/test/aottest/privateproperty_js/privateproperty_js.js @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var a; +try { + class ComputedProperty { + #m() { + return 0; + } + [this.#m] = 'a'; + } + + a = new ComputedProperty(); + print('passed??'); +} catch (e) { + print(e.name + ' : ' + e.message); +} finally { + print(a); +}