diff --git a/runtime/class_linker/panda_file_translator.cpp b/runtime/class_linker/panda_file_translator.cpp index def03eb75a5187891698ef0ef384da71023adfb8..d5b8862f8754caca442893e7b5cdf8951d33f78d 100644 --- a/runtime/class_linker/panda_file_translator.cpp +++ b/runtime/class_linker/panda_file_translator.cpp @@ -494,8 +494,6 @@ void PandaFileTranslator::UpdateICOffset(JSMethod *method, const BytecodeInstruc case BytecodeInstruction::Opcode::ECMA_TRYSTGLOBALBYNAME_PREF_ID32: case BytecodeInstruction::Opcode::ECMA_LDGLOBALVAR_PREF_ID32: case BytecodeInstruction::Opcode::ECMA_STGLOBALVAR_PREF_ID32: - method->SetSlotSize(bc_offset + 1); - break; case BytecodeInstruction::Opcode::ECMA_LDOBJBYVALUE_PREF_V8_V8: case BytecodeInstruction::Opcode::ECMA_STOBJBYVALUE_PREF_V8_V8: case BytecodeInstruction::Opcode::ECMA_STOWNBYVALUE_PREF_V8_V8: @@ -508,7 +506,7 @@ void PandaFileTranslator::UpdateICOffset(JSMethod *method, const BytecodeInstruc case BytecodeInstruction::Opcode::ECMA_STSUPERBYNAME_PREF_ID32_V8: case BytecodeInstruction::Opcode::ECMA_LDMODVARBYNAME_PREF_ID32_V8: case BytecodeInstruction::Opcode::ECMA_STMODULEVAR_PREF_ID32: - method->SetSlotSize(bc_offset + 2); + method->SetSlotSize(bc_offset + inst.GetSize()); break; default: return; diff --git a/runtime/ecma_vm.cpp b/runtime/ecma_vm.cpp index 8a75438821be73a1938d0bde8bbf4e6a78185a0f..96fb16d525c052c8f61f66aaeaa906f5bd8454ae 100644 --- a/runtime/ecma_vm.cpp +++ b/runtime/ecma_vm.cpp @@ -282,6 +282,7 @@ bool EcmaVM::Initialize() factory_->ObtainRootClass(GetGlobalEnv()); globalConst->InitGlobalConstant(thread_); globalEnvHandle->SetEmptyArray(thread_, factory_->NewEmptyArray()); + globalEnvHandle->SetEmptyWeakArray(thread_, factory_->NewEmptyArray(true)); globalEnvHandle->SetEmptyLayoutInfo(thread_, factory_->CreateLayoutInfo(0)); globalEnvHandle->SetRegisterSymbols(thread_, SymbolTable::Create(thread_)); globalEnvHandle->SetGlobalRecord(thread_, GlobalDictionary::Create(thread_)); diff --git a/runtime/global_env.h b/runtime/global_env.h index 24725689a9c9e8786b6009ccd9583748f781f8db..67c101ada691edd494c2ff5af9500f1da3e5050d 100644 --- a/runtime/global_env.h +++ b/runtime/global_env.h @@ -92,6 +92,7 @@ class JSThread; V(JSTaggedValue, AsyncFromSyncIteratorPrototype, ASYNC_FROM_SYNC_ITERATOR_PROTOTYPE_OFFSET) \ V(JSTaggedValue, JSGlobalObject, JS_GLOBAL_OBJECT_INDEX) \ V(JSTaggedValue, EmptyArray, EMPTY_ARRAY_OBJECT_INDEX) \ + V(JSTaggedValue, EmptyWeakArray, EMPTY_WEAK_ARRAY_OBJECT_INDEX) \ V(JSTaggedValue, EmptyLayoutInfo, EMPTY_LAYOUT_INFO_OBJECT_INDEX) \ V(JSTaggedValue, EmptyTaggedQueue, EMPTY_TAGGED_QUEUE_OBJECT_INDEX) \ V(JSTaggedValue, HasInstanceSymbol, HASINSTANCE_SYMBOL_INDEX) \ diff --git a/runtime/global_env_constants.cpp b/runtime/global_env_constants.cpp index bda7c1b003186e014077d1b27579a0e341a7f766..8c333a714024c72fe03ca2d1fc057cd55700a0bf 100644 --- a/runtime/global_env_constants.cpp +++ b/runtime/global_env_constants.cpp @@ -65,6 +65,9 @@ void GlobalEnvConstants::InitRootsClass([[maybe_unused]] JSThread *thread, JSHCl factory->NewEcmaDynClass(dynClassClass, 0, JSType::STRING, HClass::STRING).GetTaggedValue()); SetConstant(ConstantIndex::ARRAY_CLASS_INDEX, factory->NewEcmaDynClass(dynClassClass, 0, JSType::TAGGED_ARRAY, HClass::ARRAY).GetTaggedValue()); + JSHClass *weak_array_class = *factory->NewEcmaDynClass(dynClassClass, 0, JSType::TAGGED_ARRAY, HClass::ARRAY); + weak_array_class->SetWeakContainer(true); + SetConstant(ConstantIndex::WEAK_ARRAY_CLASS_INDEX, JSTaggedValue(weak_array_class)); SetConstant( ConstantIndex::DICTIONARY_CLASS_INDEX, factory diff --git a/runtime/global_env_constants.h b/runtime/global_env_constants.h index f06d29abab8bb80a564b0f08de32dd0cba2d0b42..4440db66639aafd3316e2011eb39ff08df8472b2 100644 --- a/runtime/global_env_constants.h +++ b/runtime/global_env_constants.h @@ -35,6 +35,7 @@ class JSThread; V(JSTaggedValue, HClassClass, HCLASS_CLASS_INDEX, ecma_roots_class) \ V(JSTaggedValue, StringClass, STRING_CLASS_INDEX, ecma_roots_class) \ V(JSTaggedValue, ArrayClass, ARRAY_CLASS_INDEX, ecma_roots_class) \ + V(JSTaggedValue, WeakArrayClass, WEAK_ARRAY_CLASS_INDEX, ecma_roots_class) \ V(JSTaggedValue, DictionaryClass, DICTIONARY_CLASS_INDEX, ecma_roots_class) \ V(JSTaggedValue, JSNativePointerClass, JS_NATIVE_POINTER_CLASS_INDEX, ecma_roots_class) \ V(JSTaggedValue, EnvClass, ENV_CLASS_INDEX, ecma_roots_class) \ diff --git a/runtime/ic/ic_runtime.cpp b/runtime/ic/ic_runtime.cpp index 90e857ef162e4559c9a431157aa3beaa4ef21068..34f007aa26699ce03d3104636f01a3cd5877579c 100644 --- a/runtime/ic/ic_runtime.cpp +++ b/runtime/ic/ic_runtime.cpp @@ -33,9 +33,6 @@ namespace panda::ecmascript { void ICRuntime::UpdateLoadHandler(const ObjectOperator &op, JSHandle key, JSHandle receiver) { - if (icAccessor_.GetICState() == ProfileTypeAccessor::ICState::MEGA) { - return; - } if (IsNamedIC(GetICKind())) { key = JSHandle(); } @@ -76,9 +73,6 @@ void ICRuntime::UpdateLoadHandler(const ObjectOperator &op, JSHandle key, JSHandle receiver) { - if (icAccessor_.GetICState() == ProfileTypeAccessor::ICState::MEGA) { - return; - } if (IsNamedIC(GetICKind())) { key = JSHandle(); } diff --git a/runtime/ic/ic_runtime_stub-inl.h b/runtime/ic/ic_runtime_stub-inl.h index ef77544f4e269071f9e623a19e983f70186f2b57..ce4114ea4cf6f5be27c429e804758091b7cb9e44 100644 --- a/runtime/ic/ic_runtime_stub-inl.h +++ b/runtime/ic/ic_runtime_stub-inl.h @@ -36,11 +36,25 @@ #include "plugins/ecmascript/runtime/runtime_call_id.h" namespace panda::ecmascript { -JSTaggedValue ICRuntimeStub::LoadGlobalICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, - JSTaggedValue globalValue, JSTaggedValue key, uint32_t slotId, - bool isTryLoad) +bool ICRuntimeStub::HaveICForFunction(JSThread *thread) +{ + auto *func = JSFunction::Cast(GetThisFunc(thread).GetHeapObject()); + return !func->GetProfileTypeInfo().IsUndefined(); +} + +ProfileTypeInfo *ICRuntimeStub::GetRuntimeProfileTypeInfo(JSThread *thread) +{ + auto *func = JSFunction::Cast(GetThisFunc(thread).GetHeapObject()); + JSTaggedValue profileTypeInfo = func->GetProfileTypeInfo(); + return ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()); +} + +JSTaggedValue ICRuntimeStub::LoadGlobalICByName(JSThread *thread, JSTaggedValue globalValue, JSTaggedValue key, + uint32_t slotId, bool isTryLoad) { INTERPRETER_TRACE(thread, LoadGlobalICByName); + ASSERT(HaveICForFunction(thread)); + ProfileTypeInfo *profileTypeInfo = GetRuntimeProfileTypeInfo(thread); JSTaggedValue handler = profileTypeInfo->Get(slotId); if (handler.IsHeapObject()) { auto result = LoadGlobal(handler); @@ -58,11 +72,12 @@ JSTaggedValue ICRuntimeStub::LoadGlobalICByName(JSThread *thread, ProfileTypeInf return icRuntime.LoadMiss(receiverHandle, keyHandle); } -JSTaggedValue ICRuntimeStub::StoreGlobalICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, - JSTaggedValue globalValue, JSTaggedValue key, JSTaggedValue value, - uint32_t slotId, bool isTryStore) +JSTaggedValue ICRuntimeStub::StoreGlobalICByName(JSThread *thread, JSTaggedValue globalValue, JSTaggedValue key, + JSTaggedValue value, uint32_t slotId, bool isTryStore) { INTERPRETER_TRACE(thread, StoreGlobalICByName); + ASSERT(HaveICForFunction(thread)); + ProfileTypeInfo *profileTypeInfo = GetRuntimeProfileTypeInfo(thread); JSTaggedValue handler = profileTypeInfo->Get(slotId); if (handler.IsHeapObject()) { auto result = StoreGlobal(thread, value, handler); @@ -97,81 +112,122 @@ JSTaggedValue ICRuntimeStub::CheckPolyHClass(JSTaggedValue cachedValue, JSHClass return JSTaggedValue::Hole(); } -JSTaggedValue ICRuntimeStub::TryLoadICByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue firstValue, - JSTaggedValue secondValue) +JSTaggedValue ICRuntimeStub::LoadICByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId) { - INTERPRETER_TRACE(thread, TryLoadICByName); + INTERPRETER_TRACE(thread, LoadICByName); + ASSERT(HaveICForFunction(thread)); + ProfileTypeInfo *profileTypeInfo = GetRuntimeProfileTypeInfo(thread); + JSTaggedValue hclassValue = profileTypeInfo->Get(slotId); + if (hclassValue.IsHole()) { + return JSTaggedValue::Hole(); + } if (LIKELY(receiver.IsHeapObject())) { auto hclass = receiver.GetTaggedObject()->GetClass(); - if (LIKELY(firstValue.GetWeakReferentUnChecked() == hclass)) { - return LoadICWithHandler(thread, receiver, receiver, secondValue); - } - JSTaggedValue cachedHandler = CheckPolyHClass(firstValue, hclass); - if (!cachedHandler.IsHole()) { - return LoadICWithHandler(thread, receiver, receiver, cachedHandler); - } + size_t index = slotId; + do { + if (!hclassValue.IsHeapObject()) { + break; + } + if (LIKELY(hclassValue.GetTaggedObject() == hclass)) { + JSTaggedValue handler = profileTypeInfo->Get(index + 1); + if (handler.IsUndefined()) { + break; + } + return LoadICWithHandler(thread, receiver, receiver, handler); + } + index += 2U; + hclassValue = profileTypeInfo->Get(index); + } while (index < slotId + 4U); } - return JSTaggedValue::Hole(); + return LoadMissedICByName(thread, profileTypeInfo, receiver, key, slotId); } -JSTaggedValue ICRuntimeStub::TryLoadICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue firstValue, JSTaggedValue secondValue) +JSTaggedValue ICRuntimeStub::LoadICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId) { - INTERPRETER_TRACE(thread, TryLoadICByValue); - if (receiver.IsHeapObject()) { + INTERPRETER_TRACE(thread, LoadICByValue); + ASSERT(HaveICForFunction(thread)); + ProfileTypeInfo *profileTypeInfo = GetRuntimeProfileTypeInfo(thread); + JSTaggedValue firstValue = profileTypeInfo->Get(slotId); + if (firstValue.IsHole()) { + return JSTaggedValue::Hole(); + } + if (receiver.IsHeapObject() && firstValue.IsHeapObject()) { auto hclass = receiver.GetTaggedObject()->GetClass(); - if (firstValue.GetWeakReferentUnChecked() == hclass) { - ASSERT(HandlerBase::IsElement(secondValue.GetInt())); + if (firstValue.GetTaggedObject() == hclass) { + ASSERT(HandlerBase::IsElement(profileTypeInfo->Get(slotId + 1).GetInt())); return LoadElement(JSObject::Cast(receiver.GetHeapObject()), key); } // Check key if (firstValue == key) { - JSTaggedValue cachedHandler = CheckPolyHClass(secondValue, hclass); - if (!cachedHandler.IsHole()) { - return LoadICWithHandler(thread, receiver, receiver, cachedHandler); + JSTaggedValue hclassValue = profileTypeInfo->Get(slotId + 1); + if (hclassValue.GetTaggedObject() == hclass) { + JSTaggedValue handler = profileTypeInfo->Get(slotId + 2); + return LoadICWithHandler(thread, receiver, receiver, handler); } } } - return JSTaggedValue::Hole(); + return LoadMissedICByValue(thread, profileTypeInfo, receiver, key, slotId); } -JSTaggedValue ICRuntimeStub::TryStoreICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue firstValue, JSTaggedValue secondValue, JSTaggedValue value) +JSTaggedValue ICRuntimeStub::StoreICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, + JSTaggedValue value, uint32_t slotId) { - INTERPRETER_TRACE(thread, TryStoreICByValue); - if (receiver.IsHeapObject()) { + INTERPRETER_TRACE(thread, StoreICByValue); + ASSERT(HaveICForFunction(thread)); + ProfileTypeInfo *profileTypeInfo = GetRuntimeProfileTypeInfo(thread); + JSTaggedValue firstValue = profileTypeInfo->Get(slotId); + if (firstValue.IsHole()) { + return JSTaggedValue::Hole(); + } + if (receiver.IsHeapObject() && firstValue.IsHeapObject()) { auto hclass = receiver.GetTaggedObject()->GetClass(); - if (firstValue.GetWeakReferentUnChecked() == hclass) { - auto handlerInfo = static_cast(secondValue.GetInt()); + if (firstValue.GetTaggedObject() == hclass) { + JSTaggedValue handler = profileTypeInfo->Get(slotId + 1); + auto handlerInfo = static_cast(handler.GetInt()); return StoreElement(thread, JSObject::Cast(receiver.GetHeapObject()), key, value, handlerInfo); } // Check key if (firstValue == key) { - JSTaggedValue cachedHandler = CheckPolyHClass(secondValue, hclass); - if (!cachedHandler.IsHole()) { - return StoreICWithHandler(thread, receiver, receiver, value, cachedHandler); + JSTaggedValue hclassValue = profileTypeInfo->Get(slotId + 1); + if (hclassValue.GetTaggedObject() == hclass) { + JSTaggedValue handler = profileTypeInfo->Get(slotId + 2); + return StoreICWithHandler(thread, receiver, receiver, value, handler); } } } - return JSTaggedValue::Hole(); + return StoreMissedICByValue(thread, profileTypeInfo, receiver, key, value, slotId); } -JSTaggedValue ICRuntimeStub::TryStoreICByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue firstValue, - JSTaggedValue secondValue, JSTaggedValue value) +JSTaggedValue ICRuntimeStub::StoreICByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, + JSTaggedValue value, uint32_t slotId) { - INTERPRETER_TRACE(thread, TryStoreICByName); + INTERPRETER_TRACE(thread, StoreICByName); + ASSERT(HaveICForFunction(thread)); + ProfileTypeInfo *profileTypeInfo = GetRuntimeProfileTypeInfo(thread); + JSTaggedValue hclassValue = profileTypeInfo->Get(slotId); + if (hclassValue.IsHole()) { + return JSTaggedValue::Hole(); + } if (receiver.IsHeapObject()) { auto hclass = receiver.GetTaggedObject()->GetClass(); - if (firstValue.GetWeakReferentUnChecked() == hclass) { - return StoreICWithHandler(thread, receiver, receiver, value, secondValue); - } - JSTaggedValue cachedHandler = CheckPolyHClass(firstValue, hclass); - if (!cachedHandler.IsHole()) { - return StoreICWithHandler(thread, receiver, receiver, value, cachedHandler); - } + size_t index = slotId; + do { + if (!hclassValue.IsHeapObject()) { + break; + } + if (LIKELY(hclassValue.GetTaggedObject() == hclass)) { + JSTaggedValue handler = profileTypeInfo->Get(index + 1); + if (handler.IsUndefined()) { + break; + } + return StoreICWithHandler(thread, receiver, receiver, value, handler); + } + index += 2U; + hclassValue = profileTypeInfo->Get(index); + } while (index < slotId + 4U); } - return JSTaggedValue::Hole(); + return StoreMissedICByName(thread, profileTypeInfo, receiver, key, value, slotId); } JSTaggedValue ICRuntimeStub::StoreICWithHandler(JSThread *thread, JSTaggedValue receiver, JSTaggedValue holder, diff --git a/runtime/ic/ic_runtime_stub.cpp b/runtime/ic/ic_runtime_stub.cpp index 3f99ce7a47837137f6958c807b93f0b5df6e1d65..ae090c21a7598e6503d810bdc38b61b80cbd2afc 100644 --- a/runtime/ic/ic_runtime_stub.cpp +++ b/runtime/ic/ic_runtime_stub.cpp @@ -34,10 +34,10 @@ #include "plugins/ecmascript/runtime/runtime_call_id.h" namespace panda::ecmascript { -JSTaggedValue ICRuntimeStub::LoadICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, JSTaggedValue receiver, - JSTaggedValue key, uint32_t slotId) +JSTaggedValue ICRuntimeStub::LoadMissedICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, + JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId) { - INTERPRETER_TRACE(thread, LoadICByName); + INTERPRETER_TRACE(thread, LoadMissedICByName); [[maybe_unused]] EcmaHandleScope handleScope(thread); auto keyHandle = JSHandle(thread, key); auto receiverHandle = JSHandle(thread, receiver); @@ -46,10 +46,10 @@ JSTaggedValue ICRuntimeStub::LoadICByName(JSThread *thread, ProfileTypeInfo *pro return icRuntime.LoadMiss(receiverHandle, keyHandle); } -JSTaggedValue ICRuntimeStub::LoadICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, JSTaggedValue receiver, - JSTaggedValue key, uint32_t slotId) +JSTaggedValue ICRuntimeStub::LoadMissedICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, + JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId) { - INTERPRETER_TRACE(thread, LoadICByValue); + INTERPRETER_TRACE(thread, LoadMissedICByValue); [[maybe_unused]] EcmaHandleScope handleScope(thread); auto keyHandle = JSHandle(thread, key); @@ -59,10 +59,11 @@ JSTaggedValue ICRuntimeStub::LoadICByValue(JSThread *thread, ProfileTypeInfo *pr return icRuntime.LoadMiss(receiverHandle, keyHandle); } -JSTaggedValue ICRuntimeStub::StoreICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, JSTaggedValue receiver, - JSTaggedValue key, JSTaggedValue value, uint32_t slotId) +JSTaggedValue ICRuntimeStub::StoreMissedICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, + JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, + uint32_t slotId) { - INTERPRETER_TRACE(thread, StoreICByValue); + INTERPRETER_TRACE(thread, StoreMissedICByValue); [[maybe_unused]] EcmaHandleScope handleScope(thread); auto keyHandle = JSHandle(thread, key); @@ -73,10 +74,11 @@ JSTaggedValue ICRuntimeStub::StoreICByValue(JSThread *thread, ProfileTypeInfo *p return icRuntime.StoreMiss(receiverHandle, keyHandle, valueHandle); } -JSTaggedValue ICRuntimeStub::StoreICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, JSTaggedValue receiver, - JSTaggedValue key, JSTaggedValue value, uint32_t slotId) +JSTaggedValue ICRuntimeStub::StoreMissedICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, + JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, + uint32_t slotId) { - INTERPRETER_TRACE(thread, StoreICByName); + INTERPRETER_TRACE(thread, StoreMissedICByName); [[maybe_unused]] EcmaHandleScope handleScope(thread); auto keyHandle = JSHandle(thread, key); diff --git a/runtime/ic/ic_runtime_stub.h b/runtime/ic/ic_runtime_stub.h index d2740c33133471c139dfb68331bf2fae6c07aa3a..9bb4a1b9e248720cc5079df72bec9ec0ef1be049 100644 --- a/runtime/ic/ic_runtime_stub.h +++ b/runtime/ic/ic_runtime_stub.h @@ -25,23 +25,17 @@ class ProfileTypeInfo; class ICRuntimeStub { public: - ARK_INLINE static inline JSTaggedValue LoadGlobalICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, - JSTaggedValue globalValue, JSTaggedValue key, - uint32_t slotId, bool isTryLoad = false); - ARK_INLINE static inline JSTaggedValue StoreGlobalICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, - JSTaggedValue globalValue, JSTaggedValue key, - JSTaggedValue value, uint32_t slotId, + ARK_INLINE static inline bool HaveICForFunction(JSThread *thread); + ARK_INLINE static inline JSTaggedValue LoadGlobalICByName(JSThread *thread, JSTaggedValue globalValue, + JSTaggedValue key, uint32_t slotId, + bool isTryLoad = false); + ARK_INLINE static inline JSTaggedValue StoreGlobalICByName(JSThread *thread, JSTaggedValue globalValue, + JSTaggedValue key, JSTaggedValue value, uint32_t slotId, bool isTryStore = false); - ARK_NOINLINE static JSTaggedValue LoadICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, - JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId); - ARK_INLINE static inline JSTaggedValue TryLoadICByName(JSThread *thread, JSTaggedValue receiver, - JSTaggedValue firstValue, JSTaggedValue secondValue); - ARK_INLINE static inline JSTaggedValue TryStoreICByName(JSThread *thread, JSTaggedValue receiver, - JSTaggedValue firstValue, JSTaggedValue secondValue, - JSTaggedValue value); - ARK_NOINLINE static JSTaggedValue StoreICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, - JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, - uint32_t slotId); + ARK_INLINE static inline JSTaggedValue LoadICByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, + uint32_t slotId); + ARK_INLINE static inline JSTaggedValue StoreICByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, + JSTaggedValue value, uint32_t slotId); ARK_INLINE static inline JSTaggedValue CheckPolyHClass(JSTaggedValue cachedValue, JSHClass *hclass); static inline JSTaggedValue LoadICWithHandler(JSThread *thread, JSTaggedValue receiver, JSTaggedValue holder, JSTaggedValue handler); @@ -58,20 +52,27 @@ public: ARK_INLINE static inline JSTaggedValue StoreGlobal(JSThread *thread, JSTaggedValue value, JSTaggedValue handler); ARK_INLINE static inline JSTaggedValue LoadPrototype(JSThread *thread, JSTaggedValue receiver, JSTaggedValue handler); - ARK_INLINE static inline JSTaggedValue TryLoadICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue firstValue, JSTaggedValue secondValue); - ARK_NOINLINE static JSTaggedValue LoadICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, - JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId); - ARK_INLINE static inline JSTaggedValue TryStoreICByValue(JSThread *thread, JSTaggedValue receiver, - JSTaggedValue key, JSTaggedValue firstValue, - JSTaggedValue secondValue, JSTaggedValue value); - ARK_NOINLINE static JSTaggedValue StoreICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, - JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, - uint32_t slotId); + ARK_INLINE static inline JSTaggedValue LoadICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, + uint32_t slotId); + ARK_INLINE static inline JSTaggedValue StoreICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, + JSTaggedValue value, uint32_t slotId); ARK_INLINE static inline JSTaggedValue LoadElement(JSObject *receiver, JSTaggedValue key); ARK_INLINE static inline JSTaggedValue StoreElement(JSThread *thread, JSObject *receiver, JSTaggedValue key, JSTaggedValue value, uint32_t handlerInfo); ARK_INLINE static inline uint32_t TryToElementsIndex(JSTaggedValue key); + +private: + static inline ProfileTypeInfo *GetRuntimeProfileTypeInfo(JSThread *thread); + ARK_NOINLINE static JSTaggedValue LoadMissedICByName(JSThread *thread, ProfileTypeInfo *profileTypeArray, + JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId); + ARK_NOINLINE static JSTaggedValue StoreMissedICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, + JSTaggedValue receiver, JSTaggedValue key, + JSTaggedValue value, uint32_t slotId); + ARK_NOINLINE static JSTaggedValue LoadMissedICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, + JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId); + ARK_NOINLINE static JSTaggedValue StoreMissedICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, + JSTaggedValue receiver, JSTaggedValue key, + JSTaggedValue value, uint32_t slotId); }; } // namespace panda::ecmascript diff --git a/runtime/ic/profile_type_info.cpp b/runtime/ic/profile_type_info.cpp index 8176a9b97af00baa5874600e6de66e5db7d1fb6b..306d1aeed291aacda784c30b87a2b778da4ae394 100644 --- a/runtime/ic/profile_type_info.cpp +++ b/runtime/ic/profile_type_info.cpp @@ -22,15 +22,17 @@ namespace panda::ecmascript { void ProfileTypeAccessor::AddElementHandler(JSHandle dynclass, JSHandle handler) const { auto profileData = profileTypeInfo_->Get(slotId_); - ASSERT(!profileData.IsHole()); + if (profileData.IsHole()) { + return; + } auto index = slotId_; if (profileData.IsUndefined()) { - profileTypeInfo_->Set(thread_, index, GetWeakRef(dynclass.GetTaggedValue())); + profileTypeInfo_->Set(thread_, index, dynclass.GetTaggedValue()); profileTypeInfo_->Set(thread_, index + 1, handler.GetTaggedValue()); return; } // clear key ic - if (!profileData.IsWeak() && (profileData.IsString() || profileData.IsSymbol())) { + if (profileData.IsString() || profileData.IsSymbol()) { profileTypeInfo_->Set(thread_, index, GetWeakRef(dynclass.GetTaggedValue())); profileTypeInfo_->Set(thread_, index + 1, handler.GetTaggedValue()); return; @@ -40,52 +42,24 @@ void ProfileTypeAccessor::AddElementHandler(JSHandle dynclass, JS void ProfileTypeAccessor::AddHandlerWithoutKey(JSHandle dynclass, JSHandle handler) const { - auto index = slotId_; if (IsNamedGlobalIC(GetKind())) { - profileTypeInfo_->Set(thread_, index, handler.GetTaggedValue()); + profileTypeInfo_->Set(thread_, slotId_, handler.GetTaggedValue()); return; } - auto profileData = profileTypeInfo_->Get(slotId_); - ASSERT(!profileData.IsHole()); - if (profileData.IsUndefined()) { - profileTypeInfo_->Set(thread_, index, GetWeakRef(dynclass.GetTaggedValue())); - profileTypeInfo_->Set(thread_, index + 1, handler.GetTaggedValue()); + auto index = slotId_; + auto profileData = profileTypeInfo_->Get(index); + if (profileData.IsHole()) { return; } - if (!profileData.IsWeak() && profileData.IsTaggedArray()) { // POLY - ASSERT(profileTypeInfo_->Get(index + 1) == JSTaggedValue::Hole()); - JSHandle arr(thread_, profileData); - const uint32_t step = 2; - uint32_t newLen = arr->GetLength() + step; - if (newLen > CACHE_MAX_LEN) { - profileTypeInfo_->Set(thread_, index, JSTaggedValue::Hole()); - profileTypeInfo_->Set(thread_, index + 1, JSTaggedValue::Hole()); - return; - } - auto factory = thread_->GetEcmaVM()->GetFactory(); - JSHandle newArr = factory->NewTaggedArray(newLen); - uint32_t i = 0; - for (; i < arr->GetLength(); i += step) { - newArr->Set(thread_, i, arr->Get(i)); - newArr->Set(thread_, i + 1, arr->Get(i + 1)); - } - newArr->Set(thread_, i, GetWeakRef(dynclass.GetTaggedValue())); - newArr->Set(thread_, i + 1, handler.GetTaggedValue()); - profileTypeInfo_->Set(thread_, index, newArr.GetTaggedValue()); - profileTypeInfo_->Set(thread_, index + 1, JSTaggedValue::Hole()); + while (!profileData.IsUndefined() && index < slotId_ + 4U) { + index += 2U; + } + if (index == slotId_ + 4U) { + profileTypeInfo_->Set(thread_, slotId_, JSTaggedValue::Hole()); return; } - // MONO to POLY - auto factory = thread_->GetEcmaVM()->GetFactory(); - JSHandle newArr = factory->NewTaggedArray(POLY_CASE_NUM); - uint32_t arrIndex = 0; - newArr->Set(thread_, arrIndex++, profileTypeInfo_->Get(index)); - newArr->Set(thread_, arrIndex++, profileTypeInfo_->Get(index + 1)); - newArr->Set(thread_, arrIndex++, GetWeakRef(dynclass.GetTaggedValue())); - newArr->Set(thread_, arrIndex, handler.GetTaggedValue()); - - profileTypeInfo_->Set(thread_, index, newArr.GetTaggedValue()); - profileTypeInfo_->Set(thread_, index + 1, JSTaggedValue::Hole()); + profileTypeInfo_->Set(thread_, index, dynclass.GetTaggedValue()); + profileTypeInfo_->Set(thread_, index + 1, handler.GetTaggedValue()); } void ProfileTypeAccessor::AddHandlerWithKey(JSHandle key, JSHandle dynclass, @@ -96,87 +70,35 @@ void ProfileTypeAccessor::AddHandlerWithKey(JSHandle key, JSHandl return; } auto profileData = profileTypeInfo_->Get(slotId_); - ASSERT(!profileData.IsHole()); - auto index = slotId_; - if (profileData.IsUndefined() && profileTypeInfo_->Get(index + 1) == JSTaggedValue::Undefined()) { - profileTypeInfo_->Set(thread_, index, key.GetTaggedValue()); - const int arrayLength = 2; - JSHandle newArr = thread_->GetEcmaVM()->GetFactory()->NewTaggedArray(arrayLength); - newArr->Set(thread_, 0, GetWeakRef(dynclass.GetTaggedValue())); - newArr->Set(thread_, 1, handler.GetTaggedValue()); - profileTypeInfo_->Set(thread_, index + 1, newArr.GetTaggedValue()); + if (profileData.IsUndefined() && profileTypeInfo_->Get(slotId_ + 1).IsUndefined()) { + profileTypeInfo_->Set(thread_, slotId_, key.GetTaggedValue()); + profileTypeInfo_->Set(thread_, slotId_ + 1U, dynclass.GetTaggedValue()); + profileTypeInfo_->Set(thread_, slotId_ + 2U, handler.GetTaggedValue()); return; } // for element ic, profileData may dynclass or taggedarray if (key.GetTaggedValue() != profileData) { - profileTypeInfo_->Set(thread_, index, JSTaggedValue::Hole()); - profileTypeInfo_->Set(thread_, index + 1, JSTaggedValue::Hole()); - return; - } - JSTaggedValue patchValue = profileTypeInfo_->Get(index + 1); - ASSERT(patchValue.IsTaggedArray()); - JSHandle arr(thread_, patchValue); - const uint32_t step = 2; - if (arr->GetLength() > step) { // POLY - uint32_t newLen = arr->GetLength() + step; - if (newLen > CACHE_MAX_LEN) { - profileTypeInfo_->Set(thread_, index, JSTaggedValue::Hole()); - profileTypeInfo_->Set(thread_, index + 1, JSTaggedValue::Hole()); - return; - } - auto factory = thread_->GetEcmaVM()->GetFactory(); - JSHandle newArr = factory->NewTaggedArray(newLen); - newArr->Set(thread_, 0, GetWeakRef(dynclass.GetTaggedValue())); - newArr->Set(thread_, 1, handler.GetTaggedValue()); - for (uint32_t i = 0; i < arr->GetLength(); i += step) { - newArr->Set(thread_, i + step, arr->Get(i)); - newArr->Set(thread_, i + step + 1, arr->Get(i + 1)); - } - profileTypeInfo_->Set(thread_, index + 1, newArr.GetTaggedValue()); + profileTypeInfo_->Set(thread_, slotId_, JSTaggedValue::Hole()); return; } - // MONO - auto factory = thread_->GetEcmaVM()->GetFactory(); - JSHandle newArr = factory->NewTaggedArray(POLY_CASE_NUM); - uint32_t arrIndex = 0; - newArr->Set(thread_, arrIndex++, arr->Get(0)); - newArr->Set(thread_, arrIndex++, arr->Get(1)); - newArr->Set(thread_, arrIndex++, GetWeakRef(dynclass.GetTaggedValue())); - newArr->Set(thread_, arrIndex++, handler.GetTaggedValue()); - - profileTypeInfo_->Set(thread_, index + 1, newArr.GetTaggedValue()); } void ProfileTypeAccessor::AddGlobalHandlerKey(JSHandle key, JSHandle handler) const { - auto index = slotId_; - const uint8_t step = 2; // key and value pair + uint32_t index = slotId_; JSTaggedValue indexVal = profileTypeInfo_->Get(index); if (indexVal.IsUndefined()) { - auto factory = thread_->GetEcmaVM()->GetFactory(); - JSHandle newArr = factory->NewTaggedArray(step); - newArr->Set(thread_, 0, GetWeakRef(key.GetTaggedValue())); - newArr->Set(thread_, 1, handler.GetTaggedValue()); - profileTypeInfo_->Set(thread_, index, newArr.GetTaggedValue()); + profileTypeInfo_->Set(thread_, index, key.GetTaggedValue()); + profileTypeInfo_->Set(thread_, index + 1, handler.GetTaggedValue()); return; } - ASSERT(indexVal.IsTaggedArray()); - JSHandle arr(thread_, indexVal); - uint32_t newLen = arr->GetLength() + step; - if (newLen > CACHE_MAX_LEN) { - profileTypeInfo_->Set(thread_, index, JSTaggedValue::Hole()); + index += 2U; + if (indexVal.IsUndefined()) { + profileTypeInfo_->Set(thread_, index, key.GetTaggedValue()); + profileTypeInfo_->Set(thread_, index + 1, handler.GetTaggedValue()); return; } - auto factory = thread_->GetEcmaVM()->GetFactory(); - JSHandle newArr = factory->NewTaggedArray(newLen); - newArr->Set(thread_, 0, GetWeakRef(key.GetTaggedValue())); - newArr->Set(thread_, 1, handler.GetTaggedValue()); - - for (uint32_t i = 0; i < arr->GetLength(); i += step) { - newArr->Set(thread_, i + step, arr->Get(i)); - newArr->Set(thread_, i + step + 1, arr->Get(i + 1)); - } - profileTypeInfo_->Set(thread_, index, newArr.GetTaggedValue()); + profileTypeInfo_->Set(thread_, slotId_, JSTaggedValue::Hole()); } void ProfileTypeAccessor::AddGlobalRecordHandler(JSHandle handler) const diff --git a/runtime/ic/proto_change_details.cpp b/runtime/ic/proto_change_details.cpp index 1fd1b38ef6bdc37481b9e0207bbadebcbb2bcfc1..d4682164a564ef615decd8943a050165a10add92 100644 --- a/runtime/ic/proto_change_details.cpp +++ b/runtime/ic/proto_change_details.cpp @@ -20,10 +20,8 @@ namespace panda::ecmascript { JSHandle ChangeListener::Add(const JSThread *thread, const JSHandle &array, const JSHandle &value, uint32_t *index) { - JSTaggedValue weakValue; if (!array->Full()) { - weakValue = JSTaggedValue(value.GetTaggedValue().CreateAndGetWeakRef()); - uint32_t arrayIndex = array->PushBack(thread, weakValue); + uint32_t arrayIndex = array->PushBack(thread, value.GetTaggedValue()); if (arrayIndex != TaggedArray::MAX_ARRAY_INDEX) { if (index != nullptr) { *index = arrayIndex; @@ -35,8 +33,7 @@ JSHandle ChangeListener::Add(const JSThread *thread, const JSHan // if exist hole, use it. uint32_t holeIndex = CheckHole(array); if (holeIndex != TaggedArray::MAX_ARRAY_INDEX) { - weakValue = JSTaggedValue(value.GetTaggedValue().CreateAndGetWeakRef()); - array->Set(thread, holeIndex, weakValue); + array->Set(thread, holeIndex, value.GetTaggedValue()); if (index != nullptr) { *index = holeIndex; } @@ -44,8 +41,7 @@ JSHandle ChangeListener::Add(const JSThread *thread, const JSHan } // the vector is full and no hole exists. JSHandle newArray = WeakVector::Grow(thread, JSHandle(array), array->GetCapacity() + 1); - weakValue = JSTaggedValue(value.GetTaggedValue().CreateAndGetWeakRef()); - uint32_t arrayIndex = newArray->PushBack(thread, weakValue); + uint32_t arrayIndex = newArray->PushBack(thread, value.GetTaggedValue()); ASSERT(arrayIndex != TaggedArray::MAX_ARRAY_INDEX); if (index != nullptr) { *index = arrayIndex; @@ -70,6 +66,6 @@ JSTaggedValue ChangeListener::Get(uint32_t index) if (!value.IsHeapObject()) { return value; } - return JSTaggedValue(value.GetTaggedWeakRef()); + return value; } } // namespace panda::ecmascript diff --git a/runtime/intrinsics-inl.h b/runtime/intrinsics-inl.h index dd4fd1ecc9b321b2801579221203b67d0b69c64b..5f14e46686d1687b26e8563d643a215c25acdaed 100644 --- a/runtime/intrinsics-inl.h +++ b/runtime/intrinsics-inl.h @@ -415,17 +415,18 @@ INLINE_ECMA_INTRINSICS uint64_t TryLdGlobalByName(JSThread *thread, uint32_t str auto global_obj = GetGlobalObject(thread); auto prop = constpool->GetObjectFromCache(stringId); + JSTaggedValue result = JSTaggedValue::Hole(); #if ECMASCRIPT_ENABLE_IC - auto profileTypeInfo = GetRuntimeProfileTypeInfo(thread); - if (!profileTypeInfo.IsUndefined()) { - JSTaggedValue res = ICRuntimeStub::LoadGlobalICByName( - thread, ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()), global_obj, prop, slotId, true); - return res.GetRawData(); + if (ICRuntimeStub::HaveICForFunction(thread)) { + result = ICRuntimeStub::LoadGlobalICByName(thread, global_obj, prop, slotId, true); + if (!result.IsHole()) { + return result.GetRawData(); + } } #endif bool found = false; - JSTaggedValue result = FastRuntimeStub::GetGlobalOwnProperty(global_obj, prop, &found); + result = FastRuntimeStub::GetGlobalOwnProperty(global_obj, prop, &found); if (found) { return result.GetRawData(); } @@ -755,22 +756,10 @@ INLINE_ECMA_INTRINSICS uint64_t LdObjByValue(JSThread *thread, uint64_t rec, uin auto receiver = JSTaggedValue(rec); auto prop_key = JSTaggedValue(pkey); + JSTaggedValue res = JSTaggedValue::Hole(); #if ECMASCRIPT_ENABLE_IC - auto profileTypeInfo = GetRuntimeProfileTypeInfo(thread); - if (!profileTypeInfo.IsUndefined()) { - auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()); - JSTaggedValue firstValue = profileTypeArray->Get(slotId); - JSTaggedValue res = JSTaggedValue::Hole(); - - if (LIKELY(firstValue.IsHeapObject())) { - JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1); - res = ICRuntimeStub::TryLoadICByValue(thread, receiver, prop_key, firstValue, secondValue); - } - // IC miss and not enter the megamorphic state, store as polymorphic - if (res.IsHole() && !firstValue.IsHole()) { - res = ICRuntimeStub::LoadICByValue(thread, profileTypeArray, receiver, prop_key, slotId); - } - + if (ICRuntimeStub::HaveICForFunction(thread)) { + res = ICRuntimeStub::LoadICByValue(thread, receiver, prop_key, slotId); if (LIKELY(!res.IsHole())) { return res.GetRawData(); } @@ -779,7 +768,7 @@ INLINE_ECMA_INTRINSICS uint64_t LdObjByValue(JSThread *thread, uint64_t rec, uin // fast path if (LIKELY(receiver.IsHeapObject())) { - JSTaggedValue res = FastRuntimeStub::GetPropertyByValue(thread, receiver, prop_key); + res = FastRuntimeStub::GetPropertyByValue(thread, receiver, prop_key); if (!res.IsHole()) { return res.GetRawData(); } @@ -798,22 +787,10 @@ INLINE_ECMA_INTRINSICS uint64_t StObjByValue(JSThread *thread, uint64_t rec, uin auto prop_key = JSTaggedValue(pkey); auto value = JSTaggedValue(val); + JSTaggedValue res = JSTaggedValue::Hole(); #if ECMASCRIPT_ENABLE_IC - auto profileTypeInfo = GetRuntimeProfileTypeInfo(thread); - if (!profileTypeInfo.IsUndefined()) { - auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()); - JSTaggedValue firstValue = profileTypeArray->Get(slotId); - JSTaggedValue res = JSTaggedValue::Hole(); - - if (LIKELY(firstValue.IsHeapObject())) { - JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1); - res = ICRuntimeStub::TryStoreICByValue(thread, receiver, prop_key, firstValue, secondValue, value); - } - // IC miss and not enter the megamorphic state, store as polymorphic - if (res.IsHole() && !firstValue.IsHole()) { - res = ICRuntimeStub::StoreICByValue(thread, profileTypeArray, receiver, prop_key, value, slotId); - } - + if (ICRuntimeStub::HaveICForFunction(thread)) { + res = ICRuntimeStub::StoreICByValue(thread, receiver, prop_key, value, slotId); if (LIKELY(!res.IsHole())) { return res.GetRawData(); } @@ -825,7 +802,7 @@ INLINE_ECMA_INTRINSICS uint64_t StObjByValue(JSThread *thread, uint64_t rec, uin JSHandle valueHandle(thread, value); if (receiver.IsHeapObject()) { - JSTaggedValue res = FastRuntimeStub::SetPropertyByValue(thread, receiver, prop_key, value); + res = FastRuntimeStub::SetPropertyByValue(thread, receiver, prop_key, value); if (!res.IsHole()) { return res.GetRawData(); } @@ -846,13 +823,13 @@ INLINE_ECMA_INTRINSICS uint64_t TryStGlobalByName(JSThread *thread, uint32_t str JSTaggedValue prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id); auto global_obj = GetGlobalObject(thread); + JSTaggedValue result = JSTaggedValue::Hole(); #if ECMASCRIPT_ENABLE_IC - auto profileTypeInfo = GetRuntimeProfileTypeInfo(thread); - if (!profileTypeInfo.IsUndefined()) { - JSTaggedValue res = - ICRuntimeStub::StoreGlobalICByName(thread, ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()), - global_obj, prop_key, JSTaggedValue(value), slotId, true); - return res.GetRawData(); + if (ICRuntimeStub::HaveICForFunction(thread)) { + result = ICRuntimeStub::StoreGlobalICByName(thread, global_obj, prop_key, JSTaggedValue(value), slotId, true); + if (!result.IsHole()) { + return result.GetRawData(); + } } #endif @@ -865,7 +842,7 @@ INLINE_ECMA_INTRINSICS uint64_t TryStGlobalByName(JSThread *thread, uint32_t str // 2. find from global object FastRuntimeStub::GetGlobalOwnProperty(global_obj, prop_key, &found); if (!found) { - auto result = SlowRuntimeStub::ThrowReferenceError(thread, prop_key, " is not defined"); + result = SlowRuntimeStub::ThrowReferenceError(thread, prop_key, " is not defined"); if (result.IsException()) { return result.GetRawData(); } @@ -879,17 +856,18 @@ INLINE_ECMA_INTRINSICS uint64_t LdGlobalVar(JSThread *thread, uint32_t string_id auto global_obj = thread->GetGlobalObject(); auto prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id); + JSTaggedValue result = JSTaggedValue::Hole(); #if ECMASCRIPT_ENABLE_IC - auto profileTypeInfo = GetRuntimeProfileTypeInfo(thread); - if (!profileTypeInfo.IsUndefined()) { - JSTaggedValue res = ICRuntimeStub::LoadGlobalICByName( - thread, ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()), global_obj, prop_key, slotId); - return res.GetRawData(); + if (ICRuntimeStub::HaveICForFunction(thread)) { + result = ICRuntimeStub::LoadGlobalICByName(thread, global_obj, prop_key, slotId); + if (!result.IsHole()) { + return result.GetRawData(); + } } #endif bool found = false; - auto result = FastRuntimeStub::GetGlobalOwnProperty(global_obj, prop_key, &found); + result = FastRuntimeStub::GetGlobalOwnProperty(global_obj, prop_key, &found); if (found) { return result.GetRawData(); } @@ -904,12 +882,12 @@ INLINE_ECMA_INTRINSICS uint64_t StGlobalVar(JSThread *thread, uint32_t string_id JSTaggedValue prop = GetConstantPool(thread)->GetObjectFromCache(string_id); #if ECMASCRIPT_ENABLE_IC - auto profileTypeInfo = GetRuntimeProfileTypeInfo(thread); - if (!profileTypeInfo.IsUndefined()) { - JSTaggedValue res = - ICRuntimeStub::StoreGlobalICByName(thread, ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()), - global_obj, prop, JSTaggedValue(value), slotId); - return res.GetRawData(); + if (ICRuntimeStub::HaveICForFunction(thread)) { + JSTaggedValue result = + ICRuntimeStub::StoreGlobalICByName(thread, global_obj, prop, JSTaggedValue(value), slotId); + if (!result.IsHole()) { + return result.GetRawData(); + } } #endif @@ -930,22 +908,10 @@ INLINE_ECMA_INTRINSICS uint64_t LdObjByName(JSThread *thread, uint32_t stringId, auto obj = JSTaggedValue(object); auto prop_key = GetConstantPool(thread)->GetObjectFromCache(stringId); + JSTaggedValue res = JSTaggedValue::Hole(); #if ECMASCRIPT_ENABLE_IC - auto profileTypeInfo = GetRuntimeProfileTypeInfo(thread); - if (!profileTypeInfo.IsUndefined()) { - auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()); - JSTaggedValue firstValue = profileTypeArray->Get(slotId); - JSTaggedValue res = JSTaggedValue::Hole(); - - if (LIKELY(firstValue.IsHeapObject())) { - JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1); - res = ICRuntimeStub::TryLoadICByName(thread, obj, firstValue, secondValue); - } - // IC miss and not enter the megamorphic state, store as polymorphic - if (res.IsHole() && !firstValue.IsHole()) { - res = ICRuntimeStub::LoadICByName(thread, profileTypeArray, obj, prop_key, slotId); - } - + if (ICRuntimeStub::HaveICForFunction(thread)) { + res = ICRuntimeStub::LoadICByName(thread, obj, prop_key, slotId); if (LIKELY(!res.IsHole())) { return res.GetRawData(); } @@ -953,7 +919,7 @@ INLINE_ECMA_INTRINSICS uint64_t LdObjByName(JSThread *thread, uint32_t stringId, #endif if (LIKELY(obj.IsHeapObject())) { - JSTaggedValue res = FastRuntimeStub::GetPropertyByName(thread, obj, prop_key); + res = FastRuntimeStub::GetPropertyByName(thread, obj, prop_key); if (!res.IsHole()) { return res.GetRawData(); } @@ -970,22 +936,10 @@ INLINE_ECMA_INTRINSICS uint64_t StObjByName(JSThread *thread, uint32_t string_id auto prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id); + JSTaggedValue res = JSTaggedValue::Hole(); #if ECMASCRIPT_ENABLE_IC - auto profileTypeInfo = GetRuntimeProfileTypeInfo(thread); - if (!profileTypeInfo.IsUndefined()) { - auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()); - JSTaggedValue firstValue = profileTypeArray->Get(slotId); - JSTaggedValue res = JSTaggedValue::Hole(); - - if (LIKELY(firstValue.IsHeapObject())) { - JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1); - res = ICRuntimeStub::TryStoreICByName(thread, obj, firstValue, secondValue, value); - } - // IC miss and not enter the megamorphic state, store as polymorphic - if (res.IsHole() && !firstValue.IsHole()) { - res = ICRuntimeStub::StoreICByName(thread, profileTypeArray, obj, prop_key, value, slotId); - } - + if (ICRuntimeStub::HaveICForFunction(thread)) { + res = ICRuntimeStub::StoreICByName(thread, obj, prop_key, value, slotId); if (LIKELY(!res.IsHole())) { return res.GetRawData(); } @@ -993,7 +947,7 @@ INLINE_ECMA_INTRINSICS uint64_t StObjByName(JSThread *thread, uint32_t string_id #endif if (obj.IsHeapObject()) { - JSTaggedValue res = FastRuntimeStub::SetPropertyByName(thread, obj, prop_key, value); + res = FastRuntimeStub::SetPropertyByName(thread, obj, prop_key, value); if (!res.IsHole()) { return res.GetRawData(); } diff --git a/runtime/mem/ecma_reference_processor.cpp b/runtime/mem/ecma_reference_processor.cpp index df0a76bdf88c4d8207ebf2df7ba785d6d87c4a82..44a1d8b2a823f233958250be8ff9ac793bf681b1 100644 --- a/runtime/mem/ecma_reference_processor.cpp +++ b/runtime/mem/ecma_reference_processor.cpp @@ -26,6 +26,21 @@ namespace panda::mem::ecmascript { EcmaReferenceProcessor::EcmaReferenceProcessor(panda::ecmascript::EcmaVM *vm) : vm_(vm), gc_(vm->GetGC()) {} +template +bool EnumerateArrayElements(const panda::ecmascript::TaggedArray *array, const Callback &cb) +{ + for (size_t i = 0; i < array->GetLength(); ++i) { + panda::ecmascript::JSTaggedValue key = array->Get(i); + if (!key.IsHeapObject()) { + continue; + } + if (cb(i, key.GetHeapObject())) { + return true; + } + } + return false; +} + template bool EnumerateKeys(Container *container, const Callback &cb) { @@ -71,6 +86,9 @@ bool EcmaReferenceProcessor::IsReference([[maybe_unused]] const BaseClass *base_ }; auto object_type = hcls->GetObjectType(); switch (object_type) { + case panda::ecmascript::JSType::TAGGED_ARRAY: + return EnumerateArrayElements(static_cast(ref), + is_reference_checker); case panda::ecmascript::JSType::LINKED_HASH_MAP: return EnumerateKeys(static_cast(ref), is_reference_checker); case panda::ecmascript::JSType::LINKED_HASH_SET: @@ -100,7 +118,18 @@ void EcmaReferenceProcessor::ProcessReferences([[maybe_unused]] bool concurrent, auto *hcls = panda::ecmascript::JSHClass::FromHClass(reference->ClassAddr()); ASSERT(hcls->IsWeakContainer()); auto object_type = hcls->GetObjectType(); - if (object_type == panda::ecmascript::JSType::LINKED_HASH_MAP) { + if (object_type == panda::ecmascript::JSType::TAGGED_ARRAY) { + auto *array = static_cast(reference); + auto handler = [this, array](uint32_t index, ObjectHeader *elem) { + if (!gc_->IsMarked(elem)) { + ObjectAccessor::SetDynValueWithoutBarrier( + array, array->GetElementOffset(index), + panda::ecmascript::JSTaggedValue::Undefined().GetRawData()); + } + return false; + }; + EnumerateArrayElements(array, handler); + } else if (object_type == panda::ecmascript::JSType::LINKED_HASH_MAP) { auto *map = static_cast(reference); auto map_handler = [this, map, thread](int index, ObjectHeader *key) { if (!gc_->IsMarked(key)) { diff --git a/runtime/object_factory.cpp b/runtime/object_factory.cpp index dcb831ccfee74f3e999b1c8542a32ed366cabac5..7d0a8eb3177835e66761f4db10d1c34c4e8c9e6c 100644 --- a/runtime/object_factory.cpp +++ b/runtime/object_factory.cpp @@ -127,6 +127,7 @@ void ObjectFactory::ObtainRootClass([[maybe_unused]] const JSHandle & hclassClass_ = JSHClass::Cast(globalConst->GetHClassClass().GetTaggedObject()); stringClass_ = JSHClass::Cast(globalConst->GetStringClass().GetTaggedObject()); arrayClass_ = JSHClass::Cast(globalConst->GetArrayClass().GetTaggedObject()); + weakArrayClass_ = JSHClass::Cast(globalConst->GetWeakArrayClass().GetTaggedObject()); dictionaryClass_ = JSHClass::Cast(globalConst->GetDictionaryClass().GetTaggedObject()); jsNativePointerClass_ = JSHClass::Cast(globalConst->GetJSNativePointerClass().GetTaggedObject()); freeObjectWithNoneFieldClass_ = JSHClass::Cast(globalConst->GetFreeObjectWithNoneFieldClass().GetTaggedObject()); @@ -1567,10 +1568,10 @@ JSHandle ObjectFactory::NewJSRealm() return realm; } -JSHandle ObjectFactory::NewEmptyArray() +JSHandle ObjectFactory::NewEmptyArray(bool weak) { NewObjectHook(); - auto header = heapHelper_.AllocateNonMovableOrHugeObject(arrayClass_, TaggedArray::SIZE); + auto header = heapHelper_.AllocateNonMovableOrHugeObject(weak ? weakArrayClass_ : arrayClass_, TaggedArray::SIZE); JSHandle array(thread_, header); array->SetLength(0); return array; @@ -1613,14 +1614,24 @@ JSHandle ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedVal } JSHandle ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedValue initVal) +{ + return NewTaggedArrayImpl(length, initVal, false); +} + +JSHandle ObjectFactory::NewWeakTaggedArray(uint32_t length, JSTaggedValue initVal) +{ + return NewTaggedArrayImpl(length, initVal, true); +} + +JSHandle ObjectFactory::NewTaggedArrayImpl(uint32_t length, JSTaggedValue initVal, bool weak) { NewObjectHook(); if (length == 0) { - return EmptyArray(); + return weak ? EmptyWeakArray() : EmptyArray(); } size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length); - auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(arrayClass_, size); + auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(weak ? weakArrayClass_ : arrayClass_, size); JSHandle array(thread_, header); array->InitializeWithSpecialValue(initVal, length); return array; @@ -1661,10 +1672,11 @@ JSHandle ObjectFactory::NewLinkedHashTable(array_size_t length, JST JSHandle ObjectFactory::ExtendArray(const JSHandle &old, uint32_t length, JSTaggedValue initVal) { + bool weak = old->GetClass()->IsWeakContainer(); ASSERT(length > old->GetLength()); NewObjectHook(); size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length); - auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(arrayClass_, size); + auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(weak ? weakArrayClass_ : arrayClass_, size); JSHandle newArray(thread_, header); newArray->SetLength(length); @@ -1686,14 +1698,15 @@ JSHandle ObjectFactory::CopyPartArray(const JSHandle & ASSERT(start <= end); ASSERT(end <= old->GetLength()); + bool weak = old->GetClass()->IsWeakContainer(); uint32_t newLength = end - start; if (newLength == 0) { - return EmptyArray(); + return weak ? EmptyWeakArray() : EmptyArray(); } NewObjectHook(); size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength); - auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(arrayClass_, size); + auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(weak ? weakArrayClass_ : arrayClass_, size); JSHandle newArray(thread_, header); newArray->SetLength(newLength); @@ -1710,8 +1723,9 @@ JSHandle ObjectFactory::CopyPartArray(const JSHandle & JSHandle ObjectFactory::CopyArray(const JSHandle &old, [[maybe_unused]] uint32_t oldLength, uint32_t newLength, JSTaggedValue initVal) { + bool weak = old->GetClass()->IsWeakContainer(); if (newLength == 0) { - return EmptyArray(); + return weak ? EmptyWeakArray() : EmptyArray(); } if (newLength > oldLength) { return ExtendArray(old, newLength, initVal); @@ -1719,7 +1733,7 @@ JSHandle ObjectFactory::CopyArray(const JSHandle &old, NewObjectHook(); size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength); - auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(arrayClass_, size); + auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(weak ? weakArrayClass_ : arrayClass_, size); JSHandle newArray(thread_, header); newArray->SetLength(newLength); @@ -1811,6 +1825,12 @@ JSHandle ObjectFactory::EmptyArray() const return JSHandle(env->GetEmptyArray()); } +JSHandle ObjectFactory::EmptyWeakArray() const +{ + JSHandle env = vm_->GetGlobalEnv(); + return JSHandle(env->GetEmptyWeakArray()); +} + JSHandle ObjectFactory::NewObjectWrapper(const JSHandle &value) { NewObjectHook(); @@ -1904,7 +1924,7 @@ JSHandle ObjectFactory::NewProfileTypeInfo(uint32_t length) ASSERT(length > 0); size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length); - auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(arrayClass_, size); + auto header = heapHelper_.AllocateNonMovableOrHugeObject(arrayClass_, size); JSHandle array(thread_, header); array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length); diff --git a/runtime/object_factory.h b/runtime/object_factory.h index d766a832ec4e272a038fe65f397f7666f69fd5be..be2bd732d9f48265982b0c19c4779713c6335d91 100644 --- a/runtime/object_factory.h +++ b/runtime/object_factory.h @@ -236,6 +236,7 @@ public: JSHandle NewTaggedArray(uint32_t length, JSTaggedValue initVal = JSTaggedValue::Hole()); JSHandle NewTaggedArray(uint32_t length, JSTaggedValue initVal, bool nonMovable); JSHandle NewTaggedArray(uint32_t length, JSTaggedValue initVal, MemSpaceType spaceType); + JSHandle NewWeakTaggedArray(uint32_t length, JSTaggedValue initVal = JSTaggedValue::Hole()); JSHandle NewDictionaryArray(uint32_t length); JSHandle NewJSForinIterator(const JSHandle &obj); @@ -268,6 +269,7 @@ public: JSHandle GetEmptyString() const; JSHandle EmptyArray() const; + JSHandle EmptyWeakArray() const; JSHandle NewObjectWrapper(const JSHandle &value); @@ -393,6 +395,8 @@ public: } private: + JSHandle NewTaggedArrayImpl(uint32_t length, JSTaggedValue initVal, bool weak); + friend class GlobalEnv; friend class GlobalEnvConstants; friend class EcmaString; @@ -408,6 +412,7 @@ private: JSHClass *hclassClass_ {nullptr}; JSHClass *stringClass_ {nullptr}; JSHClass *arrayClass_ {nullptr}; + JSHClass *weakArrayClass_ {nullptr}; JSHClass *dictionaryClass_ {nullptr}; JSHClass *freeObjectWithNoneFieldClass_ {nullptr}; JSHClass *freeObjectWithOneFieldClass_ {nullptr}; @@ -485,7 +490,7 @@ private: inline EcmaString *AllocStringObject(size_t size); inline EcmaString *AllocNonMovableStringObject(size_t size); - JSHandle NewEmptyArray(); // only used for EcmaVM. + JSHandle NewEmptyArray(bool weak = false); // only used for EcmaVM. JSHandle CreateJSArguments(); JSHandle CreateJSArrayInstanceClass(JSHandle proto); diff --git a/runtime/runtime_call_id.h b/runtime/runtime_call_id.h index 241354aa91d3b7a426b6b49a93ca77a9512956b5..400b1d8960f8dd7d6f2d381fa63a2689c75f9efc 100644 --- a/runtime/runtime_call_id.h +++ b/runtime/runtime_call_id.h @@ -134,15 +134,15 @@ namespace panda::ecmascript { V(CloseIterator) \ V(StArraySpread) \ V(GetCallSpreadArgs) \ - V(TryLoadICByName) \ V(LoadICByName) \ + V(LoadMissedICByName) \ V(GetPropertyByName) \ - V(TryLoadICByValue) \ V(LoadICByValue) \ - V(TryStoreICByName) \ + V(LoadMissedICByValue) \ V(StoreICByName) \ - V(TryStoreICByValue) \ + V(StoreMissedICByName) \ V(StoreICByValue) \ + V(StoreMissedICByValue) \ V(NotifyInlineCache) \ V(CompressCollector_RunPhases) \ V(MixSpaceCollector_RunPhases) \ diff --git a/runtime/tagged_array.h b/runtime/tagged_array.h index fe6cb89e8aea668075a107b32938db097aaa1dc3..c8bac76aa47bd707fbc74560320f9e2bbbbc93d8 100644 --- a/runtime/tagged_array.h +++ b/runtime/tagged_array.h @@ -82,6 +82,11 @@ public: } inline void Trim(JSThread *thread, uint32_t newLength); + inline size_t GetElementOffset(uint32_t idx) const + { + return DATA_OFFSET + idx * JSTaggedValue::TaggedTypeSize(); + } + static constexpr size_t LENGTH_OFFSET = TaggedObjectSize(); SET_GET_PRIMITIVE_FIELD(Length, uint32_t, LENGTH_OFFSET, DATA_OFFSET); static constexpr size_t SIZE = DATA_OFFSET; // Empty Array size diff --git a/runtime/weak_vector.cpp b/runtime/weak_vector.cpp index 1684cc98df25882b838faa3d30407f183e1edca4..dea11549f9385957234f3ef1c37aaf88dbcd8f89 100644 --- a/runtime/weak_vector.cpp +++ b/runtime/weak_vector.cpp @@ -23,7 +23,7 @@ JSHandle WeakVector::Create(const JSThread *thread, uint32_t capacit ASSERT(capacity < MAX_VECTOR_INDEX); uint32_t length = VectorToArrayIndex(capacity); - JSHandle vector = JSHandle(thread->GetEcmaVM()->GetFactory()->NewTaggedArray(length)); + JSHandle vector = JSHandle(thread->GetEcmaVM()->GetFactory()->NewWeakTaggedArray(length)); vector->SetEnd(thread, 0); return vector;