!7479 五大项整改::HeapSnapshot::GenerateNode();Elements::MigrateArrayWithKind();StoreICRuntime::StoreMiss();JITProfiler::ConvertICByNameWithHandler()

Merge pull request !7479 from 杨云飞/master
This commit is contained in:
openharmony_ci 2024-05-25 15:53:14 +00:00 committed by Gitee
commit cd4448e45b
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
8 changed files with 395 additions and 220 deletions

View File

@ -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);

View File

@ -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);

View File

@ -153,47 +153,73 @@ ElementsKind Elements::ToElementsKind(JSTaggedValue value, ElementsKind kind)
return MergeElementsKind(valueKind, kind);
}
void Elements::HandleIntKindMigration(const JSThread *thread, const JSHandle<JSObject> &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<uint32_t>(kind) >= static_cast<uint32_t>(ElementsKind::NUMBER) &&
static_cast<uint32_t>(kind) <= static_cast<uint32_t>(ElementsKind::HOLE_NUMBER);
}
bool Elements::IsStringOrNoneOrHole(const ElementsKind kind)
{
return static_cast<uint32_t>(kind) >= static_cast<uint32_t>(ElementsKind::STRING) ||
kind == ElementsKind::NONE || kind == ElementsKind::HOLE;
}
void Elements::HandleNumberKindMigration(const JSThread *thread, const JSHandle<JSObject> &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<JSObject> &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<JSObject> &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<uint32_t>(newKind) >= static_cast<uint32_t>(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<uint32_t>(oldKind) >= static_cast<uint32_t>(ElementsKind::NUMBER) &&
static_cast<uint32_t>(oldKind) <= static_cast<uint32_t>(ElementsKind::HOLE_NUMBER)) {
if (static_cast<uint32_t>(newKind) >= static_cast<uint32_t>(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<uint32_t>(newKind) >= static_cast<uint32_t>(ElementsKind::NUMBER) &&
static_cast<uint32_t>(newKind) <= static_cast<uint32_t>(ElementsKind::HOLE_NUMBER)) {
JSTaggedValue newElements = MigrateFromHeapValueToRawValue(thread, object, needCOW, false);
object->SetElements(thread, newElements);
}
HandleOtherKindMigration(thread, object, newKind, needCOW);
}
}

View File

@ -88,6 +88,15 @@ public:
private:
static JSTaggedValue MigrateFromRawValueToHeapValue(const JSThread *thread, const JSHandle<JSObject> object,
bool needCOW, bool isIntKind);
static void HandleIntKindMigration(const JSThread *thread, const JSHandle<JSObject> &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<JSObject> &object,
const ElementsKind newKind, bool needCOW);
static void HandleOtherKindMigration(const JSThread *thread, const JSHandle<JSObject> &object,
const ElementsKind newKind, bool needCOW);
static JSTaggedValue MigrateFromHeapValueToRawValue(const JSThread *thread, const JSHandle<JSObject> object,
bool needCOW, bool isIntKind);
static void MigrateFromHoleIntToHoleNumber(const JSThread *thread, const JSHandle<JSObject> object);

View File

@ -333,59 +333,55 @@ JSTaggedValue LoadICRuntime::LoadTypedArrayValueMiss(JSHandle<JSTaggedValue> rec
}
}
JSTaggedValue StoreICRuntime::StoreMiss(JSHandle<JSTaggedValue> receiver, JSHandle<JSTaggedValue> key,
JSHandle<JSTaggedValue> value, bool isOwn)
JSTaggedValue StoreICRuntime::HandleOrdinarySet(JSHandle<JSTaggedValue> &receiver,
JSHandle<JSTaggedValue> &key,
JSHandle<JSTaggedValue> &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<JSTaggedValue>(thread_, box));
}
return JSTaggedValue::Undefined();
}
}
UpdateReceiverHClass(JSHandle<JSTaggedValue>(GetThread(), JSHandle<JSObject>::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<JSTaggedValue> &key,
JSHandle<JSTaggedValue> &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<JSTaggedValue>(thread_, box));
}
return JSTaggedValue::Undefined();
}
if (key->IsJSFunction()) { // key is a private setter
JSHandle<JSTaggedValue> 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<JSTaggedValue> &receiver,
JSHandle<JSTaggedValue> &key,
JSHandle<JSTaggedValue> &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<JSTaggedValue> &receiver,
JSHandle<JSTaggedValue> &key,
JSHandle<JSTaggedValue> &value)
{
JSHandle<JSTaggedValue> 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<JSTaggedValue> receiver,
JSHandle<JSTaggedValue> key,
JSHandle<JSTaggedValue> 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<JSTaggedValue> 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<JSTaggedValue> receiver, JSHand
return JSTaggedValue::Exception();
}
JSTaggedValue StoreICRuntime::StoreMiss(JSHandle<JSTaggedValue> receiver, JSHandle<JSTaggedValue> key,
JSHandle<JSTaggedValue> 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<JSTaggedValue>(GetThread(), JSHandle<JSObject>::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<JSTaggedValue> receiver, JSHandle<JSTaggedValue> key,
JSHandle<JSTaggedValue> value)
{

View File

@ -106,6 +106,21 @@ public:
JSTaggedValue StoreTypedArrayValueMiss(JSHandle<JSTaggedValue> receiver, JSHandle<JSTaggedValue> key,
JSHandle<JSTaggedValue> value);
private:
JSTaggedValue HandleOrdinarySet(JSHandle<JSTaggedValue> &receiver,
JSHandle<JSTaggedValue> &key,
JSHandle<JSTaggedValue> &value);
JSTaggedValue HandleGlobalStoreIC(JSTaggedValue &box, JSHandle<JSTaggedValue> &key,
JSHandle<JSTaggedValue> &value);
JSTaggedValue HandleSharedArraySet(JSHandle<JSTaggedValue> &receiver,
JSHandle<JSTaggedValue> &key,
JSHandle<JSTaggedValue> &value);
JSTaggedValue HandlePrivateSetter(JSHandle<JSTaggedValue> &receiver,
JSHandle<JSTaggedValue> &key,
JSHandle<JSTaggedValue> &value);
JSTaggedValue HandlePropertySet(JSHandle<JSTaggedValue> receiver,
JSHandle<JSTaggedValue> key,
JSHandle<JSTaggedValue> value, bool isOwn, ICKind kind);
};
} // namespace panda::ecmascript

View File

@ -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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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()) {

View File

@ -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,