diff --git a/runtime/base/typed_array_helper.cpp b/runtime/base/typed_array_helper.cpp index bb191f07b2546907e2ce37d1f2b09750abcd10c2..458188ae85bfe12439b6237fb07036e974029f3b 100644 --- a/runtime/base/typed_array_helper.cpp +++ b/runtime/base/typed_array_helper.cpp @@ -233,7 +233,7 @@ JSTaggedValue TypedArrayHelper::CreateFromTypedArray(EcmaRuntimeCallInfo *argv, for (int32_t count = elementLength; count > 0; count--) { // i. Let value be GetValueFromBuffer(srcData, srcByteIndex, srcType, true, Unordered). JSTaggedValue taggedData = - BuiltinsArrayBuffer::GetValueFromBuffer(thread, srcData.GetTaggedValue(), srcByteIndex, srcType, true); + BuiltinsArrayBuffer::GetValueFromBuffer(thread, srcData, srcByteIndex, srcType, true); value.Update(taggedData); // ii. Perform SetValueInBuffer(data, targetByteIndex, elementType, value, true, Unordered). BuiltinsArrayBuffer::SetValueInBuffer(thread, data, targetByteIndex, elementType, value, true); diff --git a/runtime/builtins/builtins_arraybuffer.cpp b/runtime/builtins/builtins_arraybuffer.cpp index b38235ffeb08ae9dd44cf99e7b97c3f1db8cc0d4..dc691d52d86634aff27fb0964f32a072058f1bef 100644 --- a/runtime/builtins/builtins_arraybuffer.cpp +++ b/runtime/builtins/builtins_arraybuffer.cpp @@ -321,10 +321,10 @@ JSTaggedValue BuiltinsArrayBuffer::CloneArrayBuffer(JSThread *thread, const JSHa // 24.1.1.5 // NOLINTNEXTLINE(readability-function-size) -JSTaggedValue BuiltinsArrayBuffer::GetValueFromBuffer(JSThread *thread, JSTaggedValue arrBuf, int32_t byteIndex, - DataViewType type, bool littleEndian) +JSTaggedValue BuiltinsArrayBuffer::GetValueFromBuffer(JSThread *thread, JSHandle arrBuf, + int32_t byteIndex, DataViewType type, bool littleEndian) { - JSArrayBuffer *jsArrayBuffer = JSArrayBuffer::Cast(arrBuf.GetTaggedObject()); + JSArrayBuffer *jsArrayBuffer = JSArrayBuffer::Cast(arrBuf->GetTaggedObject()); JSTaggedValue data = jsArrayBuffer->GetArrayBufferData(); void *pointer = JSNativePointer::Cast(data.GetTaggedObject())->GetExternalPointer(); auto *block = reinterpret_cast(pointer); diff --git a/runtime/builtins/builtins_arraybuffer.h b/runtime/builtins/builtins_arraybuffer.h index dc20d1ae7b2ac4c5a5d1a51ba62a7b2cc64693bb..1e63cf59f62a938699176794c50eb9277fde6d86 100644 --- a/runtime/builtins/builtins_arraybuffer.h +++ b/runtime/builtins/builtins_arraybuffer.h @@ -61,7 +61,7 @@ public: // 24.1.1.2 IsDetachedBuffer(arrayBuffer) static bool IsDetachedBuffer(JSTaggedValue arrayBuffer); // 24.1.1.5 GetValueFromBuffer ( arrayBuffer, byteIndex, type, isLittleEndian ) - static JSTaggedValue GetValueFromBuffer(JSThread *thread, JSTaggedValue arrBuf, int32_t byteIndex, + static JSTaggedValue GetValueFromBuffer(JSThread *thread, JSHandle arrBuf, int32_t byteIndex, DataViewType type, bool littleEndian); // 24.1.1.6 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isLittleEndian ) static JSTaggedValue SetValueInBuffer(JSThread *thread, JSHandle arrBuf, int32_t byteIndex, diff --git a/runtime/builtins/builtins_dataview.cpp b/runtime/builtins/builtins_dataview.cpp index 64925d13d417f326e9c56306e82d2cf86d401ba4..4fc8f10161a5f5aef978bb57fd998cfda8527ab3 100644 --- a/runtime/builtins/builtins_dataview.cpp +++ b/runtime/builtins/builtins_dataview.cpp @@ -386,7 +386,7 @@ JSTaggedValue BuiltinsDataView::GetViewValue(JSThread *thread, const JSHandleGetViewedArrayBuffer(); + JSHandle buffer(thread, dataView->GetViewedArrayBuffer()); return BuiltinsArrayBuffer::GetValueFromBuffer(thread, buffer, bufferIndex, type, isLittleEndian); } } diff --git a/runtime/builtins/builtins_typedarray.cpp b/runtime/builtins/builtins_typedarray.cpp index 7e4835c08fc0aa642b7894b08448ad2dc69d6357..9f4582da987dd49e68a1b93d6bcd5afba133ca4d 100644 --- a/runtime/builtins/builtins_typedarray.cpp +++ b/runtime/builtins/builtins_typedarray.cpp @@ -1049,8 +1049,8 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv) JSHandle typedArray(argArray); // 12. Let srcBuffer be the value of typedArray’s [[ViewedArrayBuffer]] internal slot. // 13. If IsDetachedBuffer(srcBuffer) is true, throw a TypeError exception. - JSTaggedValue srcBuffer = JSTypedArray::Cast(*typedArray)->GetViewedArrayBuffer(); - if (BuiltinsArrayBuffer::IsDetachedBuffer(srcBuffer)) { + JSMutableHandle srcBuffer(thread, JSTypedArray::Cast(*typedArray)->GetViewedArrayBuffer()); + if (BuiltinsArrayBuffer::IsDetachedBuffer(srcBuffer.GetTaggedValue())) { THROW_TYPE_ERROR_AND_RETURN(thread, "The ArrayBuffer of typedArray is detached buffer.", JSTaggedValue::Exception()); } @@ -1077,9 +1077,9 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv) // d. Let srcByteIndex be 0. // 25. Else, let srcByteIndex be srcByteOffset. int32_t srcByteIndex; - if (JSTaggedValue::SameValue(srcBuffer, targetBuffer.GetTaggedValue())) { - srcBuffer = - BuiltinsArrayBuffer::CloneArrayBuffer(thread, targetBuffer, srcByteOffset, env->GetArrayBufferFunction()); + if (JSTaggedValue::SameValue(srcBuffer.GetTaggedValue(), targetBuffer.GetTaggedValue())) { + srcBuffer.Update( + BuiltinsArrayBuffer::CloneArrayBuffer(thread, targetBuffer, srcByteOffset, env->GetArrayBufferFunction())); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); srcByteIndex = 0; } else { @@ -1250,8 +1250,8 @@ JSTaggedValue BuiltinsTypedArray::Slice(EcmaRuntimeCallInfo *argv) // iv. Increase targetByteIndex by 1. JSMutableHandle value(thread, JSTaggedValue::Undefined()); for (int32_t targetByteIndex = 0; targetByteIndex < count * elementSize; srcByteIndex++, targetByteIndex++) { - JSTaggedValue taggedData = BuiltinsArrayBuffer::GetValueFromBuffer(thread, srcBuffer.GetTaggedValue(), - srcByteIndex, DataViewType::UINT8, true); + JSTaggedValue taggedData = + BuiltinsArrayBuffer::GetValueFromBuffer(thread, srcBuffer, srcByteIndex, DataViewType::UINT8, true); value.Update(taggedData); BuiltinsArrayBuffer::SetValueInBuffer(thread, targetBuffer, targetByteIndex, DataViewType::UINT8, value, true); diff --git a/runtime/ic/ic_runtime_stub-inl.h b/runtime/ic/ic_runtime_stub-inl.h index 38c294ed2b47f6840759e5a22831a9d8481ce511..cb9b20c24223dd4e07ca950b145d6898b3ebf783 100644 --- a/runtime/ic/ic_runtime_stub-inl.h +++ b/runtime/ic/ic_runtime_stub-inl.h @@ -36,6 +36,19 @@ #include "plugins/ecmascript/runtime/runtime_call_id.h" namespace panda::ecmascript { + +ICRuntimeStub::ICRuntimeStub(JSThread *thread, uint32_t slot_id) : thread_(thread) +{ + auto *func = JSFunction::Cast(GetThisFunc(thread).GetHeapObject()); + uint8_t *mapping = func->GetMethod()->GetICMapping(); + ASSERT(mapping != nullptr); + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + slot_id_ = mapping[slot_id]; + JSTaggedValue profile_type_info = func->GetProfileTypeInfo(); + ASSERT(!profile_type_info.IsUndefined()); + profile_type_info_ = ProfileTypeInfo::Cast(profile_type_info.GetTaggedObject()); +} + bool ICRuntimeStub::HaveICForFunction(JSThread *thread) { auto *func = JSFunction::Cast(GetThisFunc(thread).GetHeapObject()); @@ -58,53 +71,25 @@ ProfileTypeInfo *ICRuntimeStub::GetRuntimeProfileTypeInfo(JSThread *thread) return ProfileTypeInfo::Cast(profile_type_info.GetTaggedObject()); } -JSTaggedValue ICRuntimeStub::LoadGlobalICByName(JSThread *thread, JSTaggedValue global_value, JSTaggedValue key, - uint32_t slot_id, bool is_try_load) +std::pair ICRuntimeStub::LoadGlobalICByName() { - INTERPRETER_TRACE(thread, LoadGlobalICByName); - ASSERT(HaveICForFunction(thread)); - slot_id = MapSlotId(thread, slot_id); - ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(thread); - JSTaggedValue handler = profile_type_info->Get(slot_id); + INTERPRETER_TRACE(thread_, LoadGlobalICByName); + JSTaggedValue handler = profile_type_info_->Get(slot_id_); + if (handler.IsHeapObject()) { - auto result = LoadGlobal(handler); - if (!result.IsHole()) { - return result; - } + return std::make_pair(LoadGlobal(handler), false); } - - [[maybe_unused]] EcmaHandleScope handle_scope(thread); - auto key_handle = JSHandle(thread, key); - auto receiver_handle = JSHandle(thread, global_value); - auto profile_info_handle = JSHandle(thread, profile_type_info); - LoadICRuntime ic_runtime(thread, JSHandle::Cast(profile_info_handle), slot_id, - is_try_load ? ICKind::TRY_NAMED_GLOBAL_LOAD_IC : ICKind::NAMED_GLOBAL_LOAD_IC); - return ic_runtime.LoadMiss(receiver_handle, key_handle); + return std::make_pair(JSTaggedValue::Hole(), true); } -JSTaggedValue ICRuntimeStub::StoreGlobalICByName(JSThread *thread, JSTaggedValue global_value, JSTaggedValue key, - JSTaggedValue value, uint32_t slot_id, bool is_try_store) +std::pair ICRuntimeStub::StoreGlobalICByName(JSTaggedValue value) { - INTERPRETER_TRACE(thread, StoreGlobalICByName); - ASSERT(HaveICForFunction(thread)); - slot_id = MapSlotId(thread, slot_id); - ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(thread); - JSTaggedValue handler = profile_type_info->Get(slot_id); + INTERPRETER_TRACE(thread_, StoreGlobalICByName); + JSTaggedValue handler = profile_type_info_->Get(slot_id_); if (handler.IsHeapObject()) { - auto result = StoreGlobal(thread, value, handler); - if (!result.IsHole()) { - return result; - } + return std::make_pair(StoreGlobal(thread_, value, handler), false); } - - [[maybe_unused]] EcmaHandleScope handle_scope(thread); - auto key_handle = JSHandle(thread, key); - auto receiver_handle = JSHandle(thread, global_value); - auto value_handle = JSHandle(thread, value); - auto profile_info_handle = JSHandle(thread, profile_type_info); - StoreICRuntime ic_runtime(thread, JSHandle::Cast(profile_info_handle), slot_id, - is_try_store ? ICKind::TRY_NAMED_GLOBAL_STORE_IC : ICKind::NAMED_GLOBAL_STORE_IC); - return ic_runtime.StoreMiss(receiver_handle, key_handle, value_handle); + return std::make_pair(JSTaggedValue::Hole(), true); } JSTaggedValue ICRuntimeStub::CheckPolyHClass(JSTaggedValue cached_value, JSHClass *hclass) @@ -123,127 +108,113 @@ JSTaggedValue ICRuntimeStub::CheckPolyHClass(JSTaggedValue cached_value, JSHClas return JSTaggedValue::Hole(); } -JSTaggedValue ICRuntimeStub::LoadICByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, uint32_t slot_id) +std::pair ICRuntimeStub::LoadICByName(JSTaggedValue receiver) { - INTERPRETER_TRACE(thread, LoadICByName); - ASSERT(HaveICForFunction(thread)); - slot_id = MapSlotId(thread, slot_id); - ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(thread); - JSTaggedValue hclass_value = profile_type_info->Get(slot_id); + INTERPRETER_TRACE(thread_, LoadICByName); + JSTaggedValue hclass_value = profile_type_info_->Get(slot_id_); if (hclass_value.IsHole()) { - return JSTaggedValue::Hole(); + return std::make_pair(JSTaggedValue::Hole(), false); } if (LIKELY(receiver.IsHeapObject())) { auto hclass = receiver.GetTaggedObject()->GetClass(); - size_t index = slot_id; + size_t index = slot_id_; do { if (!hclass_value.IsHeapObject()) { break; } if (LIKELY(hclass_value.GetTaggedObject() == hclass)) { - JSTaggedValue handler = profile_type_info->Get(index + 1); + JSTaggedValue handler = profile_type_info_->Get(index + 1); if (handler.IsUndefined()) { break; } - return LoadICWithHandler(thread, receiver, receiver, handler); + return std::make_pair(LoadICWithHandler(thread_, receiver, receiver, handler), false); } index += 2U; - hclass_value = profile_type_info->Get(index); - } while (index < slot_id + SlotSizeForICByName()); + hclass_value = profile_type_info_->Get(index); + } while (index < slot_id_ + SlotSizeForICByName()); } - return LoadMissedICByName(thread, profile_type_info, receiver, key, slot_id); + return std::make_pair(JSTaggedValue::Hole(), true); } -JSTaggedValue ICRuntimeStub::LoadICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - uint32_t slot_id) +std::pair ICRuntimeStub::LoadICByValue(JSTaggedValue receiver, JSTaggedValue key) { - INTERPRETER_TRACE(thread, LoadICByValue); - ASSERT(HaveICForFunction(thread)); - slot_id = MapSlotId(thread, slot_id); - ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(thread); - JSTaggedValue first_value = profile_type_info->Get(slot_id); + INTERPRETER_TRACE(thread_, LoadICByValue); + JSTaggedValue first_value = profile_type_info_->Get(slot_id_); if (first_value.IsHole()) { - return JSTaggedValue::Hole(); + return std::make_pair(JSTaggedValue::Hole(), false); } if (receiver.IsHeapObject() && first_value.IsHeapObject()) { auto hclass = receiver.GetTaggedObject()->GetClass(); if (first_value.GetTaggedObject() == hclass) { - ASSERT(HandlerBase::IsElement(profile_type_info->Get(slot_id + 1).GetInt())); - return LoadElement(JSObject::Cast(receiver.GetHeapObject()), key); + ASSERT(HandlerBase::IsElement(profile_type_info_->Get(slot_id_ + 1).GetInt())); + return std::make_pair(LoadElement(JSObject::Cast(receiver.GetHeapObject()), key), false); } // Check key if (first_value == key) { - JSTaggedValue hclass_value = profile_type_info->Get(slot_id + 1); + JSTaggedValue hclass_value = profile_type_info_->Get(slot_id_ + 1); if (hclass_value.GetTaggedObject() == hclass) { - JSTaggedValue handler = profile_type_info->Get(slot_id + 2); - return LoadICWithHandler(thread, receiver, receiver, handler); + JSTaggedValue handler = profile_type_info_->Get(slot_id_ + 2); + return std::make_pair(LoadICWithHandler(thread_, receiver, receiver, handler), false); } } } - return LoadMissedICByValue(thread, profile_type_info, receiver, key, slot_id); + return std::make_pair(JSTaggedValue::Hole(), true); } -JSTaggedValue ICRuntimeStub::StoreICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue value, uint32_t slot_id) +std::pair ICRuntimeStub::StoreICByValue(JSTaggedValue receiver, JSTaggedValue key, + JSTaggedValue value) { - INTERPRETER_TRACE(thread, StoreICByValue); - ASSERT(HaveICForFunction(thread)); - slot_id = MapSlotId(thread, slot_id); - ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(thread); - JSTaggedValue first_value = profile_type_info->Get(slot_id); + INTERPRETER_TRACE(thread_, StoreICByValue); + JSTaggedValue first_value = profile_type_info_->Get(slot_id_); if (first_value.IsHole()) { - return JSTaggedValue::Hole(); + return std::make_pair(JSTaggedValue::Hole(), false); } if (receiver.IsHeapObject() && first_value.IsHeapObject()) { auto hclass = receiver.GetTaggedObject()->GetClass(); if (first_value.GetTaggedObject() == hclass) { - JSTaggedValue handler = profile_type_info->Get(slot_id + 1); + JSTaggedValue handler = profile_type_info_->Get(slot_id_ + 1); auto handler_info = static_cast(handler.GetInt()); - return StoreElement(thread, JSObject::Cast(receiver.GetHeapObject()), key, value, handler_info); + return std::make_pair( + StoreElement(thread_, JSObject::Cast(receiver.GetHeapObject()), key, value, handler_info), false); } // Check key if (first_value == key) { - JSTaggedValue hclass_value = profile_type_info->Get(slot_id + 1); + JSTaggedValue hclass_value = profile_type_info_->Get(slot_id_ + 1); if (hclass_value.GetTaggedObject() == hclass) { - JSTaggedValue handler = profile_type_info->Get(slot_id + 2); - return StoreICWithHandler(thread, receiver, receiver, value, handler); + JSTaggedValue handler = profile_type_info_->Get(slot_id_ + 2); + return std::make_pair(StoreICWithHandler(thread_, receiver, receiver, value, handler), false); } } } - - return StoreMissedICByValue(thread, profile_type_info, receiver, key, value, slot_id); + return std::make_pair(JSTaggedValue::Hole(), true); } -JSTaggedValue ICRuntimeStub::StoreICByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue value, uint32_t slot_id) +std::pair ICRuntimeStub::StoreICByName(JSTaggedValue receiver, JSTaggedValue value) { - INTERPRETER_TRACE(thread, StoreICByName); - ASSERT(HaveICForFunction(thread)); - slot_id = MapSlotId(thread, slot_id); - ProfileTypeInfo *profile_type_info = GetRuntimeProfileTypeInfo(thread); - JSTaggedValue hclass_value = profile_type_info->Get(slot_id); + INTERPRETER_TRACE(thread_, StoreICByName); + JSTaggedValue hclass_value = profile_type_info_->Get(slot_id_); if (hclass_value.IsHole()) { - return JSTaggedValue::Hole(); + return std::make_pair(JSTaggedValue::Hole(), false); } if (receiver.IsHeapObject()) { auto hclass = receiver.GetTaggedObject()->GetClass(); - size_t index = slot_id; + size_t index = slot_id_; do { if (!hclass_value.IsHeapObject()) { break; } if (LIKELY(hclass_value.GetTaggedObject() == hclass)) { - JSTaggedValue handler = profile_type_info->Get(index + 1); + JSTaggedValue handler = profile_type_info_->Get(index + 1); if (handler.IsUndefined()) { break; } - return StoreICWithHandler(thread, receiver, receiver, value, handler); + return std::make_pair(StoreICWithHandler(thread_, receiver, receiver, value, handler), false); } index += 2U; - hclass_value = profile_type_info->Get(index); - } while (index < slot_id + SlotSizeForICByName()); + hclass_value = profile_type_info_->Get(index); + } while (index < slot_id_ + SlotSizeForICByName()); } - return StoreMissedICByName(thread, profile_type_info, receiver, key, value, slot_id); + return std::make_pair(JSTaggedValue::Hole(), true); } 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 ae090c21a7598e6503d810bdc38b61b80cbd2afc..6f2f41cf7a6a09a73ace642912f451f6ee3e1b8d 100644 --- a/runtime/ic/ic_runtime_stub.cpp +++ b/runtime/ic/ic_runtime_stub.cpp @@ -34,60 +34,25 @@ #include "plugins/ecmascript/runtime/runtime_call_id.h" namespace panda::ecmascript { -JSTaggedValue ICRuntimeStub::LoadMissedICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, - JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId) -{ - INTERPRETER_TRACE(thread, LoadMissedICByName); - [[maybe_unused]] EcmaHandleScope handleScope(thread); - auto keyHandle = JSHandle(thread, key); - auto receiverHandle = JSHandle(thread, receiver); - auto profileInfoHandle = JSHandle(thread, profileTypeInfo); - LoadICRuntime icRuntime(thread, profileInfoHandle, slotId, ICKind::NAMED_LOAD_IC); - return icRuntime.LoadMiss(receiverHandle, keyHandle); -} -JSTaggedValue ICRuntimeStub::LoadMissedICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, - JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId) +JSTaggedValue ICRuntimeStub::LoadMiss(JSTaggedValue receiver, JSTaggedValue key, ICKind kind) { - INTERPRETER_TRACE(thread, LoadMissedICByValue); - - [[maybe_unused]] EcmaHandleScope handleScope(thread); - auto keyHandle = JSHandle(thread, key); - auto receiverHandle = JSHandle(thread, receiver); - auto profileInfoHandle = JSHandle(thread, profileTypeInfo); - LoadICRuntime icRuntime(thread, JSHandle::Cast(profileInfoHandle), slotId, ICKind::LOAD_IC); - return icRuntime.LoadMiss(receiverHandle, keyHandle); + [[maybe_unused]] EcmaHandleScope handle_scope(thread_); + auto key_handle = JSHandle(thread_, key); + auto receiver_handle = JSHandle(thread_, receiver); + auto profile_info_handle = JSHandle(thread_, profile_type_info_); + LoadICRuntime ic_runtime(thread_, profile_info_handle, slot_id_, kind); + return ic_runtime.LoadMiss(receiver_handle, key_handle); } -JSTaggedValue ICRuntimeStub::StoreMissedICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, - JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, - uint32_t slotId) +JSTaggedValue ICRuntimeStub::StoreMiss(JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, ICKind kind) { - INTERPRETER_TRACE(thread, StoreMissedICByValue); - - [[maybe_unused]] EcmaHandleScope handleScope(thread); - auto keyHandle = JSHandle(thread, key); - auto receiverHandle = JSHandle(thread, receiver); - auto valueHandle = JSHandle(thread, value); - auto profileInfoHandle = JSHandle(thread, profileTypeInfo); - StoreICRuntime icRuntime(thread, JSHandle::Cast(profileInfoHandle), slotId, ICKind::STORE_IC); - return icRuntime.StoreMiss(receiverHandle, keyHandle, valueHandle); + [[maybe_unused]] EcmaHandleScope handle_scope(thread_); + auto key_handle = JSHandle(thread_, key); + auto receiver_handle = JSHandle(thread_, receiver); + auto value_handle = JSHandle(thread_, value); + auto profile_info_handle = JSHandle(thread_, profile_type_info_); + StoreICRuntime ic_runtime(thread_, profile_info_handle, slot_id_, kind); + return ic_runtime.StoreMiss(receiver_handle, key_handle, value_handle); } - -JSTaggedValue ICRuntimeStub::StoreMissedICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, - JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, - uint32_t slotId) -{ - INTERPRETER_TRACE(thread, StoreMissedICByName); - - [[maybe_unused]] EcmaHandleScope handleScope(thread); - auto keyHandle = JSHandle(thread, key); - auto receiverHandle = JSHandle(thread, receiver); - auto valueHandle = JSHandle(thread, value); - auto profileInfoHandle = JSHandle(thread, profileTypeInfo); - StoreICRuntime icRuntime(thread, JSHandle::Cast(profileInfoHandle), slotId, - ICKind::NAMED_STORE_IC); - return icRuntime.StoreMiss(receiverHandle, keyHandle, valueHandle); -} - } // namespace panda::ecmascript diff --git a/runtime/ic/ic_runtime_stub.h b/runtime/ic/ic_runtime_stub.h index bd191a5e1e0527dabb3b7119a99fc906c4c54c6f..09a5ac36d5480181b8ef110c381c239bc695ef52 100644 --- a/runtime/ic/ic_runtime_stub.h +++ b/runtime/ic/ic_runtime_stub.h @@ -19,12 +19,15 @@ #include "plugins/ecmascript/runtime/base/config.h" #include "plugins/ecmascript/runtime/js_tagged_value.h" #include "plugins/ecmascript/runtime/property_attributes.h" +#include "plugins/ecmascript/runtime/ic/profile_type_info.h" namespace panda::ecmascript { class ProfileTypeInfo; class ICRuntimeStub { public: + inline ICRuntimeStub(JSThread *thread, uint32_t slot_id); + static inline constexpr uint32_t SlotSizeForGlobalICByName() { return 1U; @@ -41,16 +44,10 @@ public: } ARK_INLINE static inline bool HaveICForFunction(JSThread *thread); - ARK_INLINE static inline JSTaggedValue LoadGlobalICByName(JSThread *thread, JSTaggedValue global_value, - JSTaggedValue key, uint32_t slot_id, - bool is_try_load = false); - ARK_INLINE static inline JSTaggedValue StoreGlobalICByName(JSThread *thread, JSTaggedValue global_value, - JSTaggedValue key, JSTaggedValue value, uint32_t slot_id, - bool is_try_store = false); - ARK_INLINE static inline JSTaggedValue LoadICByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - uint32_t slot_id); - ARK_INLINE static inline JSTaggedValue StoreICByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue value, uint32_t slot_id); + ARK_INLINE inline std::pair LoadGlobalICByName(); + ARK_INLINE inline std::pair StoreGlobalICByName(JSTaggedValue value); + ARK_INLINE inline std::pair LoadICByName(JSTaggedValue receiver); + ARK_INLINE inline std::pair StoreICByName(JSTaggedValue receiver, JSTaggedValue value); ARK_INLINE static inline JSTaggedValue CheckPolyHClass(JSTaggedValue cached_value, JSHClass *hclass); static inline JSTaggedValue LoadICWithHandler(JSThread *thread, JSTaggedValue receiver, JSTaggedValue holder, JSTaggedValue handler); @@ -67,28 +64,24 @@ 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 LoadICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - uint32_t slot_id); - ARK_INLINE static inline JSTaggedValue StoreICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue value, uint32_t slot_id); + ARK_INLINE inline std::pair LoadICByValue(JSTaggedValue receiver, JSTaggedValue key); + ARK_INLINE inline std::pair StoreICByValue(JSTaggedValue receiver, JSTaggedValue key, + JSTaggedValue value); 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 handler_info); ARK_INLINE static inline uint32_t TryToElementsIndex(JSTaggedValue key); + ARK_NOINLINE JSTaggedValue LoadMiss(JSTaggedValue receiver, JSTaggedValue key, ICKind kind); + ARK_NOINLINE JSTaggedValue StoreMiss(JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, ICKind kind); + private: static inline uint32_t MapSlotId(JSThread *thread, uint32_t slot_id); static inline ProfileTypeInfo *GetRuntimeProfileTypeInfo(JSThread *thread); - ARK_NOINLINE static JSTaggedValue LoadMissedICByName(JSThread *thread, ProfileTypeInfo *profile_type_array, - JSTaggedValue receiver, JSTaggedValue key, uint32_t slot_id); - ARK_NOINLINE static JSTaggedValue StoreMissedICByName(JSThread *thread, ProfileTypeInfo *profile_type_info, - JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue value, uint32_t slot_id); - ARK_NOINLINE static JSTaggedValue LoadMissedICByValue(JSThread *thread, ProfileTypeInfo *profile_type_info, - JSTaggedValue receiver, JSTaggedValue key, uint32_t slot_id); - ARK_NOINLINE static JSTaggedValue StoreMissedICByValue(JSThread *thread, ProfileTypeInfo *profile_type_info, - JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue value, uint32_t slot_id); + + JSThread *thread_; + uint32_t slot_id_; + ProfileTypeInfo *profile_type_info_; }; } // namespace panda::ecmascript diff --git a/runtime/intrinsics-inl.h b/runtime/intrinsics-inl.h index 69887e70f395cb9497aecb3ef029ea9f4859bb31..9b8f7e862b84264e1bbc402c0748837af7f4f524 100644 --- a/runtime/intrinsics-inl.h +++ b/runtime/intrinsics-inl.h @@ -421,19 +421,22 @@ INLINE_ECMA_INTRINSICS uint64_t TryLdGlobalByName(JSThread *thread, uint32_t str auto global_obj = GetGlobalObject(thread); auto prop = constpool->GetObjectFromCache(string_id); - JSTaggedValue result = JSTaggedValue::Hole(); #if ECMASCRIPT_ENABLE_IC if (ICRuntimeStub::HaveICForFunction(thread)) { - result = ICRuntimeStub::LoadGlobalICByName(thread, global_obj, prop, slot_id, true); - if (!result.IsHole()) { - return result.GetRawData(); + ICRuntimeStub ic_runtime(thread, slot_id); + auto result = ic_runtime.LoadGlobalICByName(); + if (!result.first.IsHole()) { + return result.first.GetRawData(); + } + if (result.second) { + return ic_runtime.LoadMiss(global_obj, prop, ICKind::TRY_NAMED_GLOBAL_LOAD_IC).GetRawData(); } } #endif bool found = false; - result = FastRuntimeStub::GetGlobalOwnProperty(global_obj, prop, &found); + JSTaggedValue result = FastRuntimeStub::GetGlobalOwnProperty(global_obj, prop, &found); if (found) { return result.GetRawData(); } @@ -905,19 +908,22 @@ 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 if (ICRuntimeStub::HaveICForFunction(thread)) { - res = ICRuntimeStub::LoadICByValue(thread, receiver, prop_key, slot_id); - if (LIKELY(!res.IsHole())) { - return res.GetRawData(); + ICRuntimeStub ic_runtime(thread, slot_id); + auto res = ic_runtime.LoadICByValue(receiver, prop_key); + if (LIKELY(!res.first.IsHole())) { + return res.first.GetRawData(); + } + if (res.second) { + return ic_runtime.LoadMiss(receiver, prop_key, ICKind::LOAD_IC).GetRawData(); } } #endif // fast path if (LIKELY(receiver.IsHeapObject())) { - res = FastRuntimeStub::GetPropertyByValue(thread, &receiver, &prop_key); + JSTaggedValue res = FastRuntimeStub::GetPropertyByValue(thread, &receiver, &prop_key); if (!res.IsHole()) { return res.GetRawData(); } @@ -936,12 +942,15 @@ 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 if (ICRuntimeStub::HaveICForFunction(thread)) { - res = ICRuntimeStub::StoreICByValue(thread, receiver, prop_key, value, slot_id); - if (LIKELY(!res.IsHole())) { - return res.GetRawData(); + ICRuntimeStub ic_runtime(thread, slot_id); + auto res = ic_runtime.StoreICByValue(receiver, prop_key, value); + if (LIKELY(!res.first.IsHole())) { + return res.first.GetRawData(); + } + if (res.second) { + return ic_runtime.StoreMiss(receiver, prop_key, value, ICKind::STORE_IC).GetRawData(); } } #endif @@ -951,7 +960,7 @@ INLINE_ECMA_INTRINSICS uint64_t StObjByValue(JSThread *thread, uint64_t rec, uin JSHandle value_handle(thread, value); if (receiver.IsHeapObject()) { - res = FastRuntimeStub::SetPropertyByValue(thread, receiver, prop_key, value); + JSTaggedValue res = FastRuntimeStub::SetPropertyByValue(thread, receiver, prop_key, value); if (!res.IsHole()) { return res.GetRawData(); } @@ -972,12 +981,16 @@ 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 if (ICRuntimeStub::HaveICForFunction(thread)) { - result = ICRuntimeStub::StoreGlobalICByName(thread, global_obj, prop_key, JSTaggedValue(value), slot_id, true); - if (!result.IsHole()) { - return result.GetRawData(); + ICRuntimeStub ic_runtime(thread, slot_id); + auto result = ic_runtime.StoreGlobalICByName(JSTaggedValue(value)); + if (!result.first.IsHole()) { + return result.first.GetRawData(); + } + if (result.second) { + return ic_runtime.StoreMiss(global_obj, prop_key, JSTaggedValue(value), ICKind::TRY_NAMED_GLOBAL_STORE_IC) + .GetRawData(); } } #endif @@ -986,10 +999,9 @@ 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) { - result = SlowRuntimeStub::ThrowReferenceError(thread, prop_key, " is not defined"); - if (result.IsException()) { - return result.GetRawData(); - } + JSTaggedValue result = SlowRuntimeStub::ThrowReferenceError(thread, prop_key, " is not defined"); + ASSERT(result.IsException()); + return result.GetRawData(); } return SlowRuntimeStub::StGlobalVar(thread, prop_key, JSTaggedValue(value)).GetRawData(); } @@ -1000,18 +1012,21 @@ 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 if (ICRuntimeStub::HaveICForFunction(thread)) { - result = ICRuntimeStub::LoadGlobalICByName(thread, global_obj, prop_key, slot_id); - if (!result.IsHole()) { - return result.GetRawData(); + ICRuntimeStub ic_runtime(thread, slot_id); + auto result = ic_runtime.LoadGlobalICByName(); + if (!result.first.IsHole()) { + return result.first.GetRawData(); + } + if (result.second) { + return ic_runtime.LoadMiss(global_obj, prop_key, ICKind::NAMED_GLOBAL_LOAD_IC).GetRawData(); } } #endif bool found = false; - result = FastRuntimeStub::GetGlobalOwnProperty(global_obj, prop_key, &found); + JSTaggedValue result = FastRuntimeStub::GetGlobalOwnProperty(global_obj, prop_key, &found); if (found) { return result.GetRawData(); } @@ -1027,10 +1042,14 @@ INLINE_ECMA_INTRINSICS uint64_t StGlobalVar(JSThread *thread, uint32_t string_id #if ECMASCRIPT_ENABLE_IC if (ICRuntimeStub::HaveICForFunction(thread)) { - JSTaggedValue result = - ICRuntimeStub::StoreGlobalICByName(thread, global_obj, prop, JSTaggedValue(value), slot_id); - if (!result.IsHole()) { - return result.GetRawData(); + ICRuntimeStub ic_runtime(thread, slot_id); + auto result = ic_runtime.StoreGlobalICByName(JSTaggedValue(value)); + if (!result.first.IsHole()) { + return result.first.GetRawData(); + } + if (result.second) { + return ic_runtime.StoreMiss(global_obj, prop, JSTaggedValue(value), ICKind::NAMED_GLOBAL_STORE_IC) + .GetRawData(); } } #endif @@ -1045,18 +1064,21 @@ INLINE_ECMA_INTRINSICS uint64_t LdObjByName(JSThread *thread, uint32_t string_id auto obj = JSTaggedValue(object); auto prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id); - JSTaggedValue res = JSTaggedValue::Hole(); #if ECMASCRIPT_ENABLE_IC if (ICRuntimeStub::HaveICForFunction(thread)) { - res = ICRuntimeStub::LoadICByName(thread, obj, prop_key, slot_id); - if (LIKELY(!res.IsHole())) { - return res.GetRawData(); + ICRuntimeStub ic_runtime(thread, slot_id); + auto result = ic_runtime.LoadICByName(obj); + if (LIKELY(!result.first.IsHole())) { + return result.first.GetRawData(); + } + if (result.second) { + return ic_runtime.LoadMiss(obj, prop_key, ICKind::NAMED_LOAD_IC).GetRawData(); } } #endif if (LIKELY(obj.IsHeapObject())) { - res = FastRuntimeStub::GetPropertyByName(thread, obj, prop_key); + JSTaggedValue res = FastRuntimeStub::GetPropertyByName(thread, obj, prop_key); if (!res.IsHole()) { return res.GetRawData(); } @@ -1075,18 +1097,21 @@ 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 if (ICRuntimeStub::HaveICForFunction(thread)) { - res = ICRuntimeStub::StoreICByName(thread, obj, prop_key, value, slot_id); - if (LIKELY(!res.IsHole())) { - return res.GetRawData(); + ICRuntimeStub ic_runtime(thread, slot_id); + auto res = ic_runtime.StoreICByName(obj, value); + if (LIKELY(!res.first.IsHole())) { + return res.first.GetRawData(); + } + if (res.second) { + return ic_runtime.StoreMiss(obj, prop_key, value, ICKind::NAMED_STORE_IC).GetRawData(); } } #endif if (obj.IsHeapObject()) { - res = FastRuntimeStub::SetPropertyByName(thread, obj, prop_key, value); + JSTaggedValue res = FastRuntimeStub::SetPropertyByName(thread, obj, prop_key, value); if (!res.IsHole()) { return res.GetRawData(); } diff --git a/runtime/js_typed_array.cpp b/runtime/js_typed_array.cpp index 8029c578f41dbb87b020b28f899b81983067b845..0b96445ebd8073525a42e5ee26b6ef5f8f2371ef 100644 --- a/runtime/js_typed_array.cpp +++ b/runtime/js_typed_array.cpp @@ -360,7 +360,7 @@ OperationResult JSTypedArray::IntegerIndexedElementGet(JSThread *thread, const J { // We use buffer without handle and GC can move it. So we have to get buffer each time. // To make developer get buffer each time use scope and don't populate buffer into function's scope. - JSTaggedValue buffer = JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer(); + JSHandle buffer(thread, JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer()); result = BuiltinsArrayBuffer::GetValueFromBuffer(thread, buffer, byteIndex, elementType, true); } return OperationResult(thread, result, PropertyMetaData(true)); @@ -375,9 +375,9 @@ bool JSTypedArray::FastCopyElementToArray(JSThread *thread, const JSHandleIsTypedArray()); // 3. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. JSHandle typedarrayObj(typed_array); - JSTaggedValue buffer = JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer(); + JSHandle buffer(thread, JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer()); // 4. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. - if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { + if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer.GetTaggedValue())) { THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", false); } @@ -442,7 +442,7 @@ OperationResult JSTypedArray::FastElementGet(JSThread *thread, const JSHandleGetViewedArrayBuffer(); + JSHandle buffer(thread, JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer()); JSTaggedValue result = BuiltinsArrayBuffer::GetValueFromBuffer(thread, buffer, byteIndex, elementType, true); return OperationResult(thread, result, PropertyMetaData(true)); } diff --git a/runtime/runtime_call_id.h b/runtime/runtime_call_id.h index e20e66776d11e887de9d5c522bd67f9b4368638d..184f2606c6f653d76ac0c2eb2a4022683e976c95 100644 --- a/runtime/runtime_call_id.h +++ b/runtime/runtime_call_id.h @@ -137,14 +137,10 @@ namespace panda::ecmascript { V(StArraySpread) \ V(GetCallSpreadArgs) \ V(LoadICByName) \ - V(LoadMissedICByName) \ V(GetPropertyByName) \ V(LoadICByValue) \ - V(LoadMissedICByValue) \ V(StoreICByName) \ - V(StoreMissedICByName) \ V(StoreICByValue) \ - V(StoreMissedICByValue) \ V(NotifyInlineCache) \ V(CompressCollector_RunPhases) \ V(MixSpaceCollector_RunPhases) \