diff --git a/ecmascript/builtin_entries.h b/ecmascript/builtin_entries.h index ea4e4f1840ebe59803e2b6ca9190685da3ea8176..c64fbf57f1495b59fe8cd50d25d9e7c53852caba 100644 --- a/ecmascript/builtin_entries.h +++ b/ecmascript/builtin_entries.h @@ -111,7 +111,7 @@ public: BuiltinIndex(const BuiltinIndex&) = delete; BuiltinIndex& operator=(const BuiltinIndex&) = delete; - static const int32_t NOT_FOUND = -1; + static const size_t NOT_FOUND = -1; static BuiltinIndex& GetInstance() { @@ -126,20 +126,25 @@ public: return sizeof(JSTaggedValue) * (index * 2); // 2 is size of BuiltinEntries } - int32_t GetBuiltinIndex(JSTaggedValue key) const + size_t GetBuiltinBoxOffset(size_t index) + { + return sizeof(JSTaggedValue) * (index * 2); // 2 is size of BuiltinEntries + } + + size_t GetBuiltinIndex(JSTaggedValue key) const { auto ecmaString = EcmaString::Cast(key.GetTaggedObject()); auto str = std::string(ConvertToString(ecmaString)); return GetBuiltinIndex(str); } - int32_t GetBuiltinIndex(const std::string& key) const + size_t GetBuiltinIndex(const std::string& key) const { auto it = builtinIndex_.find(key); if (it == builtinIndex_.end()) { return NOT_FOUND; } else { - return static_cast(it->second); + return static_cast(it->second); } } @@ -216,4 +221,4 @@ private: BuiltinIndex() {} }; // class BuiltinIndex } // namespace panda::ecmascript -#endif // ECMASCRIPT_BUILTIN_ENTRIES_H \ No newline at end of file +#endif // ECMASCRIPT_BUILTIN_ENTRIES_H diff --git a/ecmascript/compiler/early_elimination.cpp b/ecmascript/compiler/early_elimination.cpp index ab14504617b17dc754840c1998b7c37f83ec7cee..ca009595169002d113a565dfed780286c7bd8daf 100644 --- a/ecmascript/compiler/early_elimination.cpp +++ b/ecmascript/compiler/early_elimination.cpp @@ -89,6 +89,7 @@ GateRef EarlyElimination::VisitGate(GateRef gate) case OpCode::TYPE_OF_CHECK: case OpCode::ARRAY_CONSTRUCTOR_CHECK: case OpCode::OBJECT_CONSTRUCTOR_CHECK: + case OpCode::LOAD_BUILTIN_OBJECT: return TryEliminateGate(gate); case OpCode::STATE_SPLIT: return TryEliminateFrameState(gate); @@ -378,6 +379,11 @@ bool EarlyElimination::CheckReplacement(GateRef lhs, GateRef rhs) } break; } + case OpCode::LOAD_BUILTIN_OBJECT: { + if (acc_.GetIndex(lhs) != acc_.GetIndex(rhs)) { + return false; + } + } default: break; } diff --git a/ecmascript/compiler/tests/meta_data_equal_test.cpp b/ecmascript/compiler/tests/meta_data_equal_test.cpp index a6978b9a1964f3e962296556138c15a9c979b1d8..ab3b873c25e06e3c0d5626d06ac59bf2d9ff385e 100644 --- a/ecmascript/compiler/tests/meta_data_equal_test.cpp +++ b/ecmascript/compiler/tests/meta_data_equal_test.cpp @@ -136,10 +136,10 @@ HWTEST_F_L0(MetaDataEqualTests, HCRMetaDataEqualTest) builder.SetEnvironment(&env); // JSBytecodeMetaData - auto meta = circuit.JSBytecode(0, EcmaOpcode::JEQZ_IMM8, 0, true, false); + auto meta = circuit.JSBytecode(0, EcmaOpcode::JEQZ_IMM8, 0, 0, true, false); auto gate = circuit.NewGate(meta, MachineType::I64, {Circuit::NullGate(), Circuit::NullGate()}, GateType::AnyType()); - auto meta2 = circuit.JSBytecode(0, EcmaOpcode::JEQZ_IMM8, 0, true, false); + auto meta2 = circuit.JSBytecode(0, EcmaOpcode::JEQZ_IMM8, 0, 0, true, false); auto gate2 = circuit.NewGate(meta2, MachineType::I64, {Circuit::NullGate(), Circuit::NullGate()}, GateType::AnyType()); diff --git a/ecmascript/compiler/type_bytecode_lowering.cpp b/ecmascript/compiler/type_bytecode_lowering.cpp index b8b213525b20accffa97ef5793c9bc5e1da9d1db..c209fdfa5fae77fb051fe90a9238e8cc98dbc3bc 100644 --- a/ecmascript/compiler/type_bytecode_lowering.cpp +++ b/ecmascript/compiler/type_bytecode_lowering.cpp @@ -450,6 +450,9 @@ void TypeBytecodeLowering::LowerTypedLdObjByName(GateRef gate) DISALLOW_GARBAGE_COLLECTION; LoadObjByNameTypeInfoAccessor tacc(thread_, circuit_, gate, chunk_); + if (TryLowerTypedLdobjBynameFromGloablBuiltin(gate)) { + return; + } if (TryLowerTypedLdObjByNameForBuiltin(gate)) { return; } @@ -721,6 +724,34 @@ bool TypeBytecodeLowering::TryLowerTypedLdObjByNameForBuiltin(const LoadBulitinO return false; } +bool TypeBytecodeLowering::TryLowerTypedLdobjBynameFromGloablBuiltin(GateRef gate) +{ + LoadBulitinObjTypeInfoAccessor tacc(thread_, circuit_, gate, chunk_); + GateRef receiver = tacc.GetReceiver(); + if (acc_.GetOpCode(receiver) != OpCode::LOAD_BUILTIN_OBJECT) { + return false; + } + JSHandle globalEnv = thread_->GetEcmaVM()->GetGlobalEnv(); + uint64_t index = acc_.TryGetValue(receiver); + BuiltinType type = static_cast(index); + if (type == BuiltinType::BT_MATH) { + auto math = globalEnv->GetMathFunction(); + JSHClass *hclass = math.GetTaggedValue().GetTaggedObject()->GetClass(); + JSTaggedValue key = tacc.GetKeyTaggedValue(); + PropertyLookupResult plr = JSHClass::LookupPropertyInBuiltinHClass(thread_, hclass, key); + if (!plr.IsFound() || plr.IsAccessor()) { + return false; + } + AddProfiling(gate); + GateRef plrGate = builder_.Int32(plr.GetData()); + GateRef result = builder_.LoadProperty(receiver, plrGate, plr.IsFunction()); + acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), result); + DeleteConstDataIfNoUser(tacc.GetKey()); + return true; + } + return false; +} + void TypeBytecodeLowering::LowerTypedLdArrayLength(const LoadBulitinObjTypeInfoAccessor &tacc) { GateRef gate = tacc.GetGate(); @@ -1690,7 +1721,7 @@ void TypeBytecodeLowering::LowerTypedTryLdGlobalByName(GateRef gate) return; } AddProfiling(gate); - GateRef result = builder_.LoadBuiltinObject(static_cast(builtin.GetBuiltinBoxOffset(key))); + GateRef result = builder_.LoadBuiltinObject(index); acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), result); DeleteConstDataIfNoUser(tacc.GetKey()); } diff --git a/ecmascript/compiler/type_bytecode_lowering.h b/ecmascript/compiler/type_bytecode_lowering.h index 9b6217fdd9dcd8c7ee22a5aad940b86dcbe4a708..f4df547283142dd601d351f53c1952c987ab52c7 100644 --- a/ecmascript/compiler/type_bytecode_lowering.h +++ b/ecmascript/compiler/type_bytecode_lowering.h @@ -203,6 +203,7 @@ private: BuiltinsStubCSigns::ID id, bool isThrow); void DeleteConstDataIfNoUser(GateRef gate); bool TryLowerNewBuiltinConstructor(GateRef gate); + bool TryLowerTypedLdobjBynameFromGloablBuiltin(GateRef gate); void AddProfiling(GateRef gate); diff --git a/ecmascript/compiler/type_hcr_lowering.cpp b/ecmascript/compiler/type_hcr_lowering.cpp index 5c95c9ae67f6c5acd714f99585d48459b909f29b..ed634f22f58d8383987c98aa8bb7e74f70028f49 100644 --- a/ecmascript/compiler/type_hcr_lowering.cpp +++ b/ecmascript/compiler/type_hcr_lowering.cpp @@ -2201,7 +2201,8 @@ void TypeHCRLowering::LowerLoadBuiltinObject(GateRef gate) Environment env(gate, circuit_, &builder_); GateRef glue = acc_.GetGlueFromArgList(); auto builtinEntriesOffset = JSThread::GlueData::GetBuiltinEntriesOffset(false); - auto boxOffset = builtinEntriesOffset + acc_.GetIndex(gate); + size_t index = acc_.GetIndex(gate); + auto boxOffset = builtinEntriesOffset + BuiltinIndex::GetInstance().GetBuiltinBoxOffset(index); GateRef box = builder_.LoadConstOffset(VariableType::JS_POINTER(), glue, boxOffset); GateRef builtin = builder_.LoadConstOffset(VariableType::JS_POINTER(), box, PropertyBox::VALUE_OFFSET); auto frameState = GetFrameState(gate); diff --git a/ecmascript/js_hclass.cpp b/ecmascript/js_hclass.cpp index bb01fb81cf91809e55c89f9f9048525a4d4c4375..55fb356fa7691a119090540f6a6ee64db8fc6b58 100644 --- a/ecmascript/js_hclass.cpp +++ b/ecmascript/js_hclass.cpp @@ -1164,4 +1164,45 @@ CString JSHClass::DumpToString(JSTaggedType hclassVal) } return result; } + +PropertyLookupResult JSHClass::LookupPropertyInBuiltinHClass(const JSThread *thread, JSHClass *hclass, + JSTaggedValue key) +{ + DISALLOW_GARBAGE_COLLECTION; + + PropertyLookupResult result; + if (hclass->IsDictionaryMode()) { + result.SetIsFound(false); + return result; + } + + int entry = JSHClass::FindPropertyEntry(thread, hclass, key); + // found in local + if (entry != -1) { + result.SetIsFound(true); + result.SetIsLocal(true); + PropertyAttributes attr = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject())->GetAttr(entry); + if (attr.IsInlinedProps()) { + result.SetIsInlinedProps(true); + result.SetOffset(hclass->GetInlinedPropertiesOffset(entry)); + } else { + result.SetIsInlinedProps(false); + result.SetOffset(attr.GetOffset() - hclass->GetInlinedProperties()); + } + + if (attr.IsNotHole()) { + result.SetIsNotHole(true); + } + if (attr.IsAccessor()) { + result.SetIsAccessor(true); + } + result.SetRepresentation(attr.GetRepresentation()); + result.SetIsWritable(attr.IsWritable()); + return result; + } + + // not fuond + result.SetIsFound(false); + return result; +} } // namespace panda::ecmascript diff --git a/ecmascript/js_hclass.h b/ecmascript/js_hclass.h index e14e4d37bf171e516eccde5b727d7ae67137bc45..f53d4cc25e7dc54966aa3ab4b8a2b7e7f56d425b 100644 --- a/ecmascript/js_hclass.h +++ b/ecmascript/js_hclass.h @@ -1722,6 +1722,8 @@ public: static PropertyLookupResult LookupPropertyInPGOHClass(const JSThread *thread, JSHClass *hclass, JSTaggedValue key); static PropertyLookupResult LookupPropertyInBuiltinPrototypeHClass(const JSThread *thread, JSHClass *hclass, JSTaggedValue key); + static PropertyLookupResult LookupPropertyInBuiltinHClass(const JSThread *thread, JSHClass *hclass, + JSTaggedValue key); static constexpr size_t PROTOTYPE_OFFSET = TaggedObjectSize(); ACCESSORS(Proto, PROTOTYPE_OFFSET, LAYOUT_OFFSET);