From 0c80f8f1a4062f6f635b679d2d7b89a74a5365e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E4=BA=91=E9=A3=9E?= Date: Wed, 22 May 2024 11:11:31 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=94=E5=A4=A7=E9=A1=B9=E6=95=B4=E6=94=B9?= =?UTF-8?q?=EF=BC=9AHeapSnapshot::GenerateNode()=EF=BC=9BElements::Migrate?= =?UTF-8?q?ArrayWithKind()=EF=BC=9BStoreICRuntime::StoreMiss()=EF=BC=9BJIT?= =?UTF-8?q?Profiler::ConvertICByNameWithHandler()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 杨云飞 --- ecmascript/dfx/hprof/heap_snapshot.cpp | 152 +++++++++++-------- ecmascript/dfx/hprof/heap_snapshot.h | 6 + ecmascript/elements.cpp | 90 +++++++---- ecmascript/elements.h | 9 ++ ecmascript/ic/ic_runtime.cpp | 126 ++++++++++------ ecmascript/ic/ic_runtime.h | 15 ++ ecmascript/jit/jit_profiler.cpp | 201 +++++++++++++++---------- ecmascript/jit/jit_profiler.h | 16 ++ 8 files changed, 395 insertions(+), 220 deletions(-) diff --git a/ecmascript/dfx/hprof/heap_snapshot.cpp b/ecmascript/dfx/hprof/heap_snapshot.cpp index e4e45fc007..f2e4d509f1 100644 --- a/ecmascript/dfx/hprof/heap_snapshot.cpp +++ b/ecmascript/dfx/hprof/heap_snapshot.cpp @@ -658,6 +658,88 @@ void HeapSnapshot::FillNodes(bool isInFinish, bool isSimplify) } } +Node *HeapSnapshot::HandleStringNode(JSTaggedValue &entry, size_t &size, bool &isInFinish) +{ + Node* node = nullptr; + if (isPrivate_) { + node = GeneratePrivateStringNode(size); + } else { + node = GenerateStringNode(entry, size, isInFinish); + } + if (node == nullptr) { + LOG_ECMA(ERROR) << "string node nullptr"; + } + return node; +} + +Node *HeapSnapshot::HandleFunctionNode(JSTaggedValue &entry, size_t &size, bool &isInFinish) +{ + Node* node = GenerateFunctionNode(entry, size, isInFinish); + if (node == nullptr) { + LOG_ECMA(ERROR) << "function node nullptr"; + } + return node; +} + +Node *HeapSnapshot::HandleObjectNode(JSTaggedValue &entry, size_t &size, bool &isInFinish) +{ + Node* node = GenerateObjectNode(entry, size, isInFinish); + if (node == nullptr) { + LOG_ECMA(ERROR) << "object node nullptr"; + } + return node; +} + +Node *HeapSnapshot::HandleBaseClassNode(size_t size, bool idExist, unsigned int &sequenceId, + TaggedObject* obj, JSTaggedType &addr) +{ + size_t selfSize = (size != 0) ? size : obj->GetClass()->SizeFromJSHClass(obj); + size_t nativeSize = 0; + if (obj->GetClass()->IsJSNativePointer()) { + nativeSize = JSNativePointer::Cast(obj)->GetBindingSize(); + } + Node* node = Node::NewNode(chunk_, sequenceId, nodeCount_, GenerateNodeName(obj), GenerateNodeType(obj), + selfSize, nativeSize, addr); + entryMap_.InsertEntry(node); + if (!idExist) { + entryIdMap_->InsertId(addr, sequenceId); + } + InsertNodeUnique(node); + ASSERT(entryMap_.FindEntry(node->GetAddress())->GetAddress() == node->GetAddress()); + return node; +} + +CString HeapSnapshot::GeneratePrimitiveNameString(JSTaggedValue &entry) +{ + CString primitiveName; + if (entry.IsInt()) { + primitiveName.append("Int:"); + if (!isPrivate_) { + primitiveName.append(ToCString(entry.GetInt())); + } + } else if (entry.IsDouble()) { + primitiveName.append("Double:"); + if (!isPrivate_) { + primitiveName.append(FloatToCString(entry.GetDouble())); + } + } else if (entry.IsHole()) { + primitiveName.append("Hole"); + } else if (entry.IsNull()) { + primitiveName.append("Null"); + } else if (entry.IsTrue()) { + primitiveName.append("Boolean:true"); + } else if (entry.IsFalse()) { + primitiveName.append("Boolean:false"); + } else if (entry.IsException()) { + primitiveName.append("Exception"); + } else if (entry.IsUndefined()) { + primitiveName.append("Undefined"); + } else { + primitiveName.append("Illegal_Primitive"); + } + return primitiveName; +} + Node *HeapSnapshot::GenerateNode(JSTaggedValue entry, size_t size, bool isInFinish, bool isSimplify) { Node *node = nullptr; @@ -666,29 +748,13 @@ Node *HeapSnapshot::GenerateNode(JSTaggedValue entry, size_t size, bool isInFini entry.RemoveWeakTag(); } if (entry.IsString()) { - if (isPrivate_) { - node = GeneratePrivateStringNode(size); - } else { - node = GenerateStringNode(entry, size, isInFinish); - } - if (node == nullptr) { - LOG_ECMA(ERROR) << "string node nullptr"; - } - return node; + return HandleStringNode(entry, size, isInFinish); } if (entry.IsJSFunction()) { - node = GenerateFunctionNode(entry, size, isInFinish); - if (node == nullptr) { - LOG_ECMA(ERROR) << "function node nullptr"; - } - return node; + return HandleFunctionNode(entry, size, isInFinish); } if (entry.IsOnlyJSObject()) { - node = GenerateObjectNode(entry, size, isInFinish); - if (node == nullptr) { - LOG_ECMA(ERROR) << "function node nullptr"; - } - return node; + return HandleObjectNode(entry, size, isInFinish); } TaggedObject *obj = entry.GetTaggedObject(); auto *baseClass = obj->GetClass(); @@ -697,59 +763,17 @@ Node *HeapSnapshot::GenerateNode(JSTaggedValue entry, size_t size, bool isInFini Node *existNode = entryMap_.FindEntry(addr); // Fast Index auto [idExist, sequenceId] = entryIdMap_->FindId(addr); if (existNode == nullptr) { - size_t selfSize = (size != 0) ? size : obj->GetClass()->SizeFromJSHClass(obj); - size_t nativeSize = 0; - if (obj->GetClass()->IsJSNativePointer()) { - nativeSize = JSNativePointer::Cast(obj)->GetBindingSize(); - } - node = Node::NewNode(chunk_, sequenceId, nodeCount_, GenerateNodeName(obj), GenerateNodeType(obj), - selfSize, nativeSize, addr); - entryMap_.InsertEntry(node); - if (!idExist) { - entryIdMap_->InsertId(addr, sequenceId); - } - InsertNodeUnique(node); - ASSERT(entryMap_.FindEntry(node->GetAddress())->GetAddress() == node->GetAddress()); - return node; + return HandleBaseClassNode(size, idExist, sequenceId, obj, addr); } else { existNode->SetLive(true); return existNode; } } } else if (!isSimplify) { - CString primitiveName; - if (entry.IsInt()) { - if (!captureNumericValue_) { + if ((entry.IsInt() || entry.IsDouble()) && !captureNumericValue_) { return nullptr; - } - primitiveName.append("Int:"); - if (!isPrivate_) { - primitiveName.append(ToCString(entry.GetInt())); - } - } else if (entry.IsDouble()) { - if (!captureNumericValue_) { - return nullptr; - } - primitiveName.append("Double:"); - if (!isPrivate_) { - primitiveName.append(FloatToCString(entry.GetDouble())); - } - } else if (entry.IsHole()) { - primitiveName.append("Hole"); - } else if (entry.IsNull()) { - primitiveName.append("Null"); - } else if (entry.IsTrue()) { - primitiveName.append("Boolean:true"); - } else if (entry.IsFalse()) { - primitiveName.append("Boolean:false"); - } else if (entry.IsException()) { - primitiveName.append("Exception"); - } else if (entry.IsUndefined()) { - primitiveName.append("Undefined"); - } else { - primitiveName.append("Illegal_Primitive"); } - + CString primitiveName = GeneratePrimitiveNameString(entry); // A primitive value with tag will be regarded as a pointer JSTaggedType addr = entry.GetRawData(); Node *existNode = entryMap_.FindEntry(addr); diff --git a/ecmascript/dfx/hprof/heap_snapshot.h b/ecmascript/dfx/hprof/heap_snapshot.h index c105608e15..9f6208df87 100644 --- a/ecmascript/dfx/hprof/heap_snapshot.h +++ b/ecmascript/dfx/hprof/heap_snapshot.h @@ -500,6 +500,12 @@ private: void FillNodes(bool isInFinish = false, bool isSimplify = false); Node *GenerateNode(JSTaggedValue entry, size_t size = 0, bool isInFinish = false, bool isSimplify = false); + Node *HandleStringNode(JSTaggedValue &entry, size_t &size, bool &isInFinish); + Node *HandleFunctionNode(JSTaggedValue &entry, size_t &size, bool &isInFinish); + Node *HandleObjectNode(JSTaggedValue &entry, size_t &size, bool &isInFinish); + Node *HandleBaseClassNode(size_t size, bool idExist, unsigned int &sequenceId, + TaggedObject* obj, JSTaggedType &addr); + CString GeneratePrimitiveNameString(JSTaggedValue &entry); Node *GeneratePrivateStringNode(size_t size); Node *GenerateStringNode(JSTaggedValue entry, size_t size, bool isInFinish = false); Node *GenerateFunctionNode(JSTaggedValue entry, size_t size, bool isInFinish = false); diff --git a/ecmascript/elements.cpp b/ecmascript/elements.cpp index 13b6765fec..f2c4e6095b 100644 --- a/ecmascript/elements.cpp +++ b/ecmascript/elements.cpp @@ -153,47 +153,73 @@ ElementsKind Elements::ToElementsKind(JSTaggedValue value, ElementsKind kind) return MergeElementsKind(valueKind, kind); } +void Elements::HandleIntKindMigration(const JSThread *thread, const JSHandle &object, + const ElementsKind newKind, bool needCOW) +{ + if (IsStringOrNoneOrHole(newKind)) { + JSTaggedValue newElements = MigrateFromRawValueToHeapValue(thread, object, needCOW, true); + object->SetElements(thread, newElements); + } else if (newKind == ElementsKind::NUMBER || newKind == ElementsKind::HOLE_NUMBER) { + MigrateFromHoleIntToHoleNumber(thread, object); + } +} + +bool Elements::IsNumberKind(const ElementsKind kind) +{ + return static_cast(kind) >= static_cast(ElementsKind::NUMBER) && + static_cast(kind) <= static_cast(ElementsKind::HOLE_NUMBER); +} + +bool Elements::IsStringOrNoneOrHole(const ElementsKind kind) +{ + return static_cast(kind) >= static_cast(ElementsKind::STRING) || + kind == ElementsKind::NONE || kind == ElementsKind::HOLE; +} + +void Elements::HandleNumberKindMigration(const JSThread *thread, const JSHandle &object, + const ElementsKind newKind, bool needCOW) +{ + if (IsStringOrNoneOrHole(newKind)) { + JSTaggedValue newElements = MigrateFromRawValueToHeapValue(thread, object, needCOW, false); + object->SetElements(thread, newElements); + } else if (newKind == ElementsKind::INT || newKind == ElementsKind::HOLE_INT) { + MigrateFromHoleNumberToHoleInt(thread, object); + } +} + +void Elements::HandleOtherKindMigration(const JSThread *thread, const JSHandle &object, + const ElementsKind newKind, bool needCOW) +{ + if (newKind == ElementsKind::INT || newKind == ElementsKind::HOLE_INT) { + JSTaggedValue newElements = MigrateFromHeapValueToRawValue(thread, object, needCOW, true); + object->SetElements(thread, newElements); + } else if (IsNumberKind(newKind)) { + JSTaggedValue newElements = MigrateFromHeapValueToRawValue(thread, object, needCOW, false); + object->SetElements(thread, newElements); + } +} + void Elements::MigrateArrayWithKind(const JSThread *thread, const JSHandle &object, const ElementsKind oldKind, const ElementsKind newKind) { if (!thread->GetEcmaVM()->IsEnableElementsKind()) { return; } - if (oldKind == newKind) { - return; - } - // When create ArrayLiteral from constantPool, we need to preserve the COW property if necessary. - // When transition happens to Array, e.g. arr.x = 1, we need to preserve the COW property if necessary. - bool needCOW = object->GetElements().IsCOWArray(); - if ((oldKind == ElementsKind::INT && newKind == ElementsKind::HOLE_INT) || + + if (oldKind == newKind || + (oldKind == ElementsKind::INT && newKind == ElementsKind::HOLE_INT) || (oldKind == ElementsKind::NUMBER && newKind == ElementsKind::HOLE_NUMBER)) { return; - } else if (oldKind == ElementsKind::INT || oldKind == ElementsKind::HOLE_INT) { - if (static_cast(newKind) >= static_cast(ElementsKind::STRING) || - newKind == ElementsKind::NONE || newKind == ElementsKind::HOLE) { - JSTaggedValue newElements = MigrateFromRawValueToHeapValue(thread, object, needCOW, true); - object->SetElements(thread, newElements); - } else if (newKind == ElementsKind::NUMBER || newKind == ElementsKind::HOLE_NUMBER) { - MigrateFromHoleIntToHoleNumber(thread, object); - } - } else if (static_cast(oldKind) >= static_cast(ElementsKind::NUMBER) && - static_cast(oldKind) <= static_cast(ElementsKind::HOLE_NUMBER)) { - if (static_cast(newKind) >= static_cast(ElementsKind::STRING) || - newKind == ElementsKind::NONE || newKind == ElementsKind::HOLE) { - JSTaggedValue newElements = MigrateFromRawValueToHeapValue(thread, object, needCOW, false); - object->SetElements(thread, newElements); - } else if (newKind == ElementsKind::INT || newKind == ElementsKind::HOLE_INT) { - MigrateFromHoleNumberToHoleInt(thread, object); - } + } + + bool needCOW = object->GetElements().IsCOWArray(); + + if (oldKind == ElementsKind::INT || oldKind == ElementsKind::HOLE_INT) { + HandleIntKindMigration(thread, object, newKind, needCOW); + } else if ((IsNumberKind(oldKind))) { + HandleNumberKindMigration(thread, object, newKind, needCOW); } else { - if (newKind == ElementsKind::INT || newKind == ElementsKind::HOLE_INT) { - JSTaggedValue newElements = MigrateFromHeapValueToRawValue(thread, object, needCOW, true); - object->SetElements(thread, newElements); - } else if (static_cast(newKind) >= static_cast(ElementsKind::NUMBER) && - static_cast(newKind) <= static_cast(ElementsKind::HOLE_NUMBER)) { - JSTaggedValue newElements = MigrateFromHeapValueToRawValue(thread, object, needCOW, false); - object->SetElements(thread, newElements); - } + HandleOtherKindMigration(thread, object, newKind, needCOW); } } diff --git a/ecmascript/elements.h b/ecmascript/elements.h index a71eee9470..b10c272796 100644 --- a/ecmascript/elements.h +++ b/ecmascript/elements.h @@ -88,6 +88,15 @@ public: private: static JSTaggedValue MigrateFromRawValueToHeapValue(const JSThread *thread, const JSHandle object, bool needCOW, bool isIntKind); + static void HandleIntKindMigration(const JSThread *thread, const JSHandle &object, + const ElementsKind newKind, bool needCOW); + static bool IsNumberKind(const ElementsKind kind); + static bool IsStringOrNoneOrHole(const ElementsKind kind); + static void HandleNumberKindMigration(const JSThread *thread, + const JSHandle &object, + const ElementsKind newKind, bool needCOW); + static void HandleOtherKindMigration(const JSThread *thread, const JSHandle &object, + const ElementsKind newKind, bool needCOW); static JSTaggedValue MigrateFromHeapValueToRawValue(const JSThread *thread, const JSHandle object, bool needCOW, bool isIntKind); static void MigrateFromHoleIntToHoleNumber(const JSThread *thread, const JSHandle object); diff --git a/ecmascript/ic/ic_runtime.cpp b/ecmascript/ic/ic_runtime.cpp index 83e1f8cbc5..51a585e00c 100644 --- a/ecmascript/ic/ic_runtime.cpp +++ b/ecmascript/ic/ic_runtime.cpp @@ -333,59 +333,55 @@ JSTaggedValue LoadICRuntime::LoadTypedArrayValueMiss(JSHandle rec } } -JSTaggedValue StoreICRuntime::StoreMiss(JSHandle receiver, JSHandle key, - JSHandle value, bool isOwn) +JSTaggedValue StoreICRuntime::HandleOrdinarySet(JSHandle &receiver, + JSHandle &key, + JSHandle &value) { - ICKind kind = GetICKind(); - if (IsValueIC(kind)) { - key = JSTaggedValue::ToPropertyKey(GetThread(), key); - } - if (!receiver->IsJSObject() || receiver->HasOrdinaryGet()) { - icAccessor_.SetAsMega(); - bool success = JSTaggedValue::SetProperty(GetThread(), receiver, key, value, true); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); - return success ? JSTaggedValue::Undefined() : JSTaggedValue::Exception(); - } - if (receiver->IsTypedArray() || receiver->IsSharedTypedArray()) { - return StoreTypedArrayValueMiss(receiver, key, value); - } - - // global variable find from global record firstly - if (kind == ICKind::NamedGlobalStoreIC || kind == ICKind::NamedGlobalTryStoreIC) { - JSTaggedValue box = SlowRuntimeStub::LdGlobalRecord(thread_, key.GetTaggedValue()); - if (!box.IsUndefined()) { - ASSERT(box.IsPropertyBox()); - SlowRuntimeStub::TryUpdateGlobalRecord(thread_, key.GetTaggedValue(), value.GetTaggedValue()); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); - if (icAccessor_.GetICState() != ProfileTypeAccessor::ICState::MEGA) { - icAccessor_.AddGlobalRecordHandler(JSHandle(thread_, box)); - } - return JSTaggedValue::Undefined(); - } - } - UpdateReceiverHClass(JSHandle(GetThread(), JSHandle::Cast(receiver)->GetClass())); + icAccessor_.SetAsMega(); + bool success = JSTaggedValue::SetProperty(GetThread(), receiver, key, value, true); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); + return success ? JSTaggedValue::Undefined() : JSTaggedValue::Exception(); +} - // fixme(hzzhouzebin) Open IC for SharedArray later. - if (receiver->IsJSSharedArray()) { - bool success = JSSharedArray::SetProperty(thread_, receiver, key, value, true, SCheckMode::CHECK); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); - if (success) { - return JSTaggedValue::Undefined(); - } - return JSTaggedValue::Exception(); +JSTaggedValue StoreICRuntime::HandleGlobalStoreIC(JSTaggedValue &box, JSHandle &key, + JSHandle &value) +{ + ASSERT(box.IsPropertyBox()); + SlowRuntimeStub::TryUpdateGlobalRecord(thread_, key.GetTaggedValue(), value.GetTaggedValue()); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); + if (icAccessor_.GetICState() != ProfileTypeAccessor::ICState::MEGA) { + icAccessor_.AddGlobalRecordHandler(JSHandle(thread_, box)); } + return JSTaggedValue::Undefined(); +} - if (key->IsJSFunction()) { // key is a private setter - JSHandle undefined = thread_->GlobalConstants()->GetHandledUndefined(); - EcmaRuntimeCallInfo* info = - EcmaInterpreter::NewRuntimeCallInfo(thread_, key, receiver, undefined, 1); // 1: setter has 1 argument - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); - info->SetCallArg(value.GetTaggedValue()); - JSTaggedValue resSetter = JSFunction::Call(info); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); - return resSetter; - } +JSTaggedValue StoreICRuntime::HandleSharedArraySet(JSHandle &receiver, + JSHandle &key, + JSHandle &value) +{ + bool success = JSSharedArray::SetProperty(thread_, receiver, key, value, true, SCheckMode::CHECK); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); + return success ? JSTaggedValue::Undefined() : JSTaggedValue::Exception(); +} +JSTaggedValue StoreICRuntime::HandlePrivateSetter(JSHandle &receiver, + JSHandle &key, + JSHandle &value) +{ + JSHandle undefined = thread_->GlobalConstants()->GetHandledUndefined(); + EcmaRuntimeCallInfo* info = + EcmaInterpreter::NewRuntimeCallInfo(thread_, key, receiver, undefined, 1); // 1: setter has 1 argument + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); + info->SetCallArg(value.GetTaggedValue()); + JSTaggedValue resSetter = JSFunction::Call(info); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); + return resSetter; +} + +JSTaggedValue StoreICRuntime::HandlePropertySet(JSHandle receiver, + JSHandle key, + JSHandle value, bool isOwn, ICKind kind) +{ ObjectOperator op = ConstructOp(receiver, key, value, isOwn); if (!op.IsFound()) { if (kind == ICKind::NamedGlobalStoreIC) { @@ -395,6 +391,7 @@ JSTaggedValue StoreICRuntime::StoreMiss(JSHandle receiver, JSHand return SlowRuntimeStub::ThrowReferenceError(GetThread(), key.GetTaggedValue(), " is not defined"); } } + bool success = JSObject::SetProperty(&op, value, true); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); // ic-switch @@ -418,6 +415,39 @@ JSTaggedValue StoreICRuntime::StoreMiss(JSHandle receiver, JSHand return JSTaggedValue::Exception(); } +JSTaggedValue StoreICRuntime::StoreMiss(JSHandle receiver, JSHandle key, + JSHandle value, bool isOwn) +{ + ICKind kind = GetICKind(); + if (IsValueIC(kind)) { + key = JSTaggedValue::ToPropertyKey(GetThread(), key); + } + if (!receiver->IsJSObject() || receiver->HasOrdinaryGet()) { + return HandleOrdinarySet(receiver, key, value); + } + if (receiver->IsTypedArray() || receiver->IsSharedTypedArray()) { + return StoreTypedArrayValueMiss(receiver, key, value); + } + + // global variable find from global record firstly + if (kind == ICKind::NamedGlobalStoreIC || kind == ICKind::NamedGlobalTryStoreIC) { + JSTaggedValue box = SlowRuntimeStub::LdGlobalRecord(thread_, key.GetTaggedValue()); + if (!box.IsUndefined()) { + return HandleGlobalStoreIC(box, key, value); + } + } + UpdateReceiverHClass(JSHandle(GetThread(), JSHandle::Cast(receiver)->GetClass())); + + // fixme(hzzhouzebin) Open IC for SharedArray later. + if (receiver->IsJSSharedArray()) { + return HandleSharedArraySet(receiver, key, value); + } + if (key->IsJSFunction()) { // key is a private setter + return HandlePrivateSetter(receiver, key, value); + } + return HandlePropertySet(receiver, key, value, isOwn, kind); +} + JSTaggedValue StoreICRuntime::StoreTypedArrayValueMiss(JSHandle receiver, JSHandle key, JSHandle value) { diff --git a/ecmascript/ic/ic_runtime.h b/ecmascript/ic/ic_runtime.h index 38ef5c067a..861391ddc8 100644 --- a/ecmascript/ic/ic_runtime.h +++ b/ecmascript/ic/ic_runtime.h @@ -106,6 +106,21 @@ public: JSTaggedValue StoreTypedArrayValueMiss(JSHandle receiver, JSHandle key, JSHandle value); +private: + JSTaggedValue HandleOrdinarySet(JSHandle &receiver, + JSHandle &key, + JSHandle &value); + JSTaggedValue HandleGlobalStoreIC(JSTaggedValue &box, JSHandle &key, + JSHandle &value); + JSTaggedValue HandleSharedArraySet(JSHandle &receiver, + JSHandle &key, + JSHandle &value); + JSTaggedValue HandlePrivateSetter(JSHandle &receiver, + JSHandle &key, + JSHandle &value); + JSTaggedValue HandlePropertySet(JSHandle receiver, + JSHandle key, + JSHandle value, bool isOwn, ICKind kind); }; } // namespace panda::ecmascript diff --git a/ecmascript/jit/jit_profiler.cpp b/ecmascript/jit/jit_profiler.cpp index 696654798f..24db58cc54 100644 --- a/ecmascript/jit/jit_profiler.cpp +++ b/ecmascript/jit/jit_profiler.cpp @@ -375,98 +375,147 @@ void JITProfiler::ConvertICByName(int32_t bcOffset, uint32_t slotId, BCType type } void JITProfiler::ConvertICByNameWithHandler(ApEntityId abcId, int32_t bcOffset, - JSHClass *hclass, JSTaggedValue secondValue, BCType type) + JSHClass *hclass, + JSTaggedValue secondValue, BCType type) { if (type == BCType::LOAD) { - if (secondValue.IsInt()) { - auto handlerInfo = static_cast(secondValue.GetInt()); - if (HandlerBase::IsNonExist(handlerInfo)) { - return; - } - if (HandlerBase::IsField(handlerInfo) || HandlerBase::IsAccessor(handlerInfo)) { - AddObjectInfo(abcId, bcOffset, hclass, hclass, hclass); - } - AddBuiltinsInfoByNameInInstance(abcId, bcOffset, hclass); - } else if (secondValue.IsPrototypeHandler()) { - auto prototypeHandler = PrototypeHandler::Cast(secondValue.GetTaggedObject()); - auto cellValue = prototypeHandler->GetProtoCell(); - if (cellValue.IsUndefined()) { - return; - } - ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetTaggedObject()); - if (cell->GetHasChanged()) { - return; - } - auto holder = prototypeHandler->GetHolder(); - auto holderHClass = holder.GetTaggedObject()->GetClass(); - JSTaggedValue handlerInfoVal = prototypeHandler->GetHandlerInfo(); - if (!handlerInfoVal.IsInt()) { - return; - } - auto handlerInfo = static_cast(handlerInfoVal.GetInt()); - if (HandlerBase::IsNonExist(handlerInfo)) { - return; - } - auto accessorMethodId = prototypeHandler->GetAccessorMethodId(); - if (!AddObjectInfo(abcId, bcOffset, hclass, holderHClass, holderHClass, accessorMethodId)) { - return AddBuiltinsInfoByNameInProt(abcId, bcOffset, hclass, holderHClass); - } - } + HandleLoadType(abcId, bcOffset, hclass, secondValue); // LoadGlobal return; } + HandleOtherTypes(abcId, bcOffset, hclass, secondValue); +} + +void JITProfiler::HandleLoadType(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue) +{ + if (secondValue.IsInt()) { + HandleLoadTypeInt(abcId, bcOffset, hclass, secondValue); + } else if (secondValue.IsPrototypeHandler()) { + HandleLoadTypePrototypeHandler(abcId, bcOffset, hclass, secondValue); + } +} + +void JITProfiler::HandleLoadTypeInt(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue) +{ + auto handlerInfo = static_cast(secondValue.GetInt()); + if (HandlerBase::IsNonExist(handlerInfo)) { + return; + } + if (HandlerBase::IsField(handlerInfo) || HandlerBase::IsAccessor(handlerInfo)) { + AddObjectInfo(abcId, bcOffset, hclass, hclass, hclass); + } + AddBuiltinsInfoByNameInInstance(abcId, bcOffset, hclass); +} + +void JITProfiler::HandleLoadTypePrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue) +{ + auto prototypeHandler = PrototypeHandler::Cast(secondValue.GetTaggedObject()); + auto cellValue = prototypeHandler->GetProtoCell(); + if (cellValue.IsUndefined()) { + return; + } + ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetTaggedObject()); + if (cell->GetHasChanged()) { + return; + } + auto holder = prototypeHandler->GetHolder(); + auto holderHClass = holder.GetTaggedObject()->GetClass(); + JSTaggedValue handlerInfoVal = prototypeHandler->GetHandlerInfo(); + if (!handlerInfoVal.IsInt()) { + return; + } + auto handlerInfo = static_cast(handlerInfoVal.GetInt()); + if (HandlerBase::IsNonExist(handlerInfo)) { + return; + } + auto accessorMethodId = prototypeHandler->GetAccessorMethodId(); + if (!AddObjectInfo(abcId, bcOffset, hclass, holderHClass, holderHClass, accessorMethodId)) { + return AddBuiltinsInfoByNameInProt(abcId, bcOffset, hclass, holderHClass); + } +} + +void JITProfiler::HandleOtherTypes(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue) +{ if (secondValue.IsInt()) { AddObjectInfo(abcId, bcOffset, hclass, hclass, hclass); } else if (secondValue.IsTransitionHandler()) { - auto transitionHandler = TransitionHandler::Cast(secondValue.GetTaggedObject()); - auto transitionHClassVal = transitionHandler->GetTransitionHClass(); - if (transitionHClassVal.IsJSHClass()) { - auto transitionHClass = JSHClass::Cast(transitionHClassVal.GetTaggedObject()); - AddObjectInfo(abcId, bcOffset, hclass, hclass, transitionHClass); - } + HandleTransitionHandler(abcId, bcOffset, hclass, secondValue); } else if (secondValue.IsTransWithProtoHandler()) { - auto transWithProtoHandler = TransWithProtoHandler::Cast(secondValue.GetTaggedObject()); - auto cellValue = transWithProtoHandler->GetProtoCell(); - ASSERT(cellValue.IsProtoChangeMarker()); - ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetTaggedObject()); - if (cell->GetHasChanged()) { - return; - } - auto transitionHClassVal = transWithProtoHandler->GetTransitionHClass(); - if (transitionHClassVal.IsJSHClass()) { - auto transitionHClass = JSHClass::Cast(transitionHClassVal.GetTaggedObject()); - AddObjectInfo(abcId, bcOffset, hclass, hclass, transitionHClass); - } + HandleTransWithProtoHandler(abcId, bcOffset, hclass, secondValue); } else if (secondValue.IsPrototypeHandler()) { - auto prototypeHandler = PrototypeHandler::Cast(secondValue.GetTaggedObject()); - auto cellValue = prototypeHandler->GetProtoCell(); - if (cellValue.IsUndefined()) { - return; - } - ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetTaggedObject()); - if (cell->GetHasChanged()) { - return; - } - auto holder = prototypeHandler->GetHolder(); - auto holderHClass = holder.GetTaggedObject()->GetClass(); - auto accessorMethodId = prototypeHandler->GetAccessorMethodId(); - AddObjectInfo(abcId, bcOffset, hclass, holderHClass, holderHClass, accessorMethodId); + HandleOtherTypesPrototypeHandler(abcId, bcOffset, hclass, secondValue); } else if (secondValue.IsPropertyBox()) { // StoreGlobal } else if (secondValue.IsStoreTSHandler()) { - StoreTSHandler *storeTSHandler = StoreTSHandler::Cast(secondValue.GetTaggedObject()); - auto cellValue = storeTSHandler->GetProtoCell(); - ASSERT(cellValue.IsProtoChangeMarker()); - ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetTaggedObject()); - if (cell->GetHasChanged()) { - return; - } - auto holder = storeTSHandler->GetHolder(); - auto holderHClass = holder.GetTaggedObject()->GetClass(); - AddObjectInfo(abcId, bcOffset, hclass, holderHClass, holderHClass); + HandleStoreTSHandler(abcId, bcOffset, hclass, secondValue); } } +void JITProfiler::HandleTransitionHandler(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue) +{ + auto transitionHandler = TransitionHandler::Cast(secondValue.GetTaggedObject()); + auto transitionHClassVal = transitionHandler->GetTransitionHClass(); + if (transitionHClassVal.IsJSHClass()) { + auto transitionHClass = JSHClass::Cast(transitionHClassVal.GetTaggedObject()); + AddObjectInfo(abcId, bcOffset, hclass, hclass, transitionHClass); + } +} + +void JITProfiler::HandleTransWithProtoHandler(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue) +{ + auto transWithProtoHandler = TransWithProtoHandler::Cast(secondValue.GetTaggedObject()); + auto cellValue = transWithProtoHandler->GetProtoCell(); + ASSERT(cellValue.IsProtoChangeMarker()); + ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetTaggedObject()); + if (cell->GetHasChanged()) { + return; + } + auto transitionHClassVal = transWithProtoHandler->GetTransitionHClass(); + if (transitionHClassVal.IsJSHClass()) { + auto transitionHClass = JSHClass::Cast(transitionHClassVal.GetTaggedObject()); + AddObjectInfo(abcId, bcOffset, hclass, hclass, transitionHClass); + } +} + +void JITProfiler::HandleOtherTypesPrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue) +{ + auto prototypeHandler = PrototypeHandler::Cast(secondValue.GetTaggedObject()); + auto cellValue = prototypeHandler->GetProtoCell(); + if (cellValue.IsUndefined()) { + return; + } + ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetTaggedObject()); + if (cell->GetHasChanged()) { + return; + } + auto holder = prototypeHandler->GetHolder(); + auto holderHClass = holder.GetTaggedObject()->GetClass(); + auto accessorMethodId = prototypeHandler->GetAccessorMethodId(); + AddObjectInfo(abcId, bcOffset, hclass, holderHClass, holderHClass, accessorMethodId); +} + +void JITProfiler::HandleStoreTSHandler(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue) +{ + StoreTSHandler *storeTSHandler = StoreTSHandler::Cast(secondValue.GetTaggedObject()); + auto cellValue = storeTSHandler->GetProtoCell(); + ASSERT(cellValue.IsProtoChangeMarker()); + ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetTaggedObject()); + if (cell->GetHasChanged()) { + return; + } + auto holder = storeTSHandler->GetHolder(); + auto holderHClass = holder.GetTaggedObject()->GetClass(); + AddObjectInfo(abcId, bcOffset, hclass, holderHClass, holderHClass); +} + void JITProfiler::ConvertICByNameWithPoly(ApEntityId abcId, int32_t bcOffset, JSTaggedValue cacheValue, BCType type) { if (cacheValue.IsWeak()) { diff --git a/ecmascript/jit/jit_profiler.h b/ecmascript/jit/jit_profiler.h index 7b3c58aaaa..96a78243d5 100644 --- a/ecmascript/jit/jit_profiler.h +++ b/ecmascript/jit/jit_profiler.h @@ -88,6 +88,22 @@ private: void ConvertICByName(int32_t bcOffset, uint32_t slotId, BCType type); void ConvertICByNameWithHandler(ApEntityId abcId, int32_t bcOffset, JSHClass *hclass, JSTaggedValue secondValue, BCType type); + void HandleLoadType(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue); + void HandleLoadTypeInt(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue); + void HandleLoadTypePrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue); + void HandleOtherTypes(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue); + void HandleTransitionHandler(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue); + void HandleTransWithProtoHandler(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue); + void HandleOtherTypesPrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue); + void HandleStoreTSHandler(ApEntityId &abcId, int32_t &bcOffset, + JSHClass *hclass, JSTaggedValue &secondValue); void ConvertICByNameWithPoly(ApEntityId abcId, int32_t bcOffset, JSTaggedValue cacheValue, BCType type); void ConvertICByValue(int32_t bcOffset, uint32_t slotId, BCType type); void ConvertICByValueWithHandler(ApEntityId abcId, int32_t bcOffset, JSHClass *hclass,