diff --git a/BUILD.gn b/BUILD.gn index 0f8e7fe84d7bd8d9216411a4bd284f2846d65196..e333df1748f6f2539f90a08dbd6d1d66c23345c3 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -232,6 +232,7 @@ ecma_source = [ "ecmascript/base/typed_array_helper.cpp", "ecmascript/base/utf_helper.cpp", "ecmascript/builtins.cpp", + "ecmascript/builtins/builtins_ark_tools.cpp", "ecmascript/builtins/builtins_array.cpp", "ecmascript/builtins/builtins_arraybuffer.cpp", "ecmascript/builtins/builtins_async_function.cpp", diff --git a/ecmascript/base/config.h b/ecmascript/base/config.h index c8d03a02be511fc80c8ed3205f0a7e6c6e297a14..b114c552263e46b7bc41823207ef2da6afdab5e2 100644 --- a/ecmascript/base/config.h +++ b/ecmascript/base/config.h @@ -22,6 +22,7 @@ namespace panda::ecmascript { #define ECMASCRIPT_ENABLE_RUNTIME_STAT 0 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define ECMASCRIPT_ENABLE_IC 1 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define ECMASCRIPT_OBJECT_DUMP 1 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) } // namespace panda::ecmascript #endif // ECMASCRIPT_BASE_CONFIG_H diff --git a/ecmascript/builtins.cpp b/ecmascript/builtins.cpp index 239543543a0bf7c584273e21edc2885e306bd130..7a1516f448949ed22280370b0163e0eae1ff28b2 100644 --- a/ecmascript/builtins.cpp +++ b/ecmascript/builtins.cpp @@ -17,6 +17,7 @@ #include "ecmascript/base/error_type.h" #include "ecmascript/base/number_helper.h" +#include "ecmascript/builtins/builtins_ark_tools.h" #include "ecmascript/builtins/builtins_array.h" #include "ecmascript/builtins/builtins_arraybuffer.h" #include "ecmascript/builtins/builtins_async_function.h" @@ -302,6 +303,10 @@ void Builtins::InitializeGlobalObject(const JSHandle &env, const JSHa SetFunction(env, globalObject, "stopRuntimeStat", Global::StopRuntimeStat, 0); #endif +#if ECMASCRIPT_OBJECT_DUMP + SetConstant(globalObject, "arkTools", InitializeArkTools(env).GetTaggedValue()); +#endif + // Global object function SetFunction(env, globalObject, "eval", Global::NotSupportEval, FunctionLength::ONE); SetFunction(env, globalObject, "isFinite", Global::IsFinite, FunctionLength::ONE); @@ -2733,4 +2738,13 @@ void Builtins::InitializeJSNativeObject(const JSHandle &env) const env->SetJSNativeObjectClass(thread_, dynclass); } + +JSHandle Builtins::InitializeArkTools(const JSHandle &env) const +{ + [[maybe_unused]] EcmaHandleScope scope(thread_); + + JSHandle tools = factory_->NewEmptyJSObject(); + SetFunction(env, tools, "print", builtins::BuiltinsArkTools::ObjectDump, FunctionLength::ZERO); + return tools; +} } // namespace panda::ecmascript diff --git a/ecmascript/builtins.h b/ecmascript/builtins.h index 7a7753ea9633b6ddcde42fc5ab3ad3e546c9c7bc..1ae4d9c22f3cccb68c459a6afe662e74f74703ba 100644 --- a/ecmascript/builtins.h +++ b/ecmascript/builtins.h @@ -209,6 +209,7 @@ private: void SetGetter(const JSHandle &obj, const JSHandle &key, const JSHandle &getter) const; void InitializeJSNativeObject(const JSHandle &env) const; + JSHandle InitializeArkTools(const JSHandle &env) const; }; } // namespace panda::ecmascript #endif // ECMASCRIPT_BUILTINS_H diff --git a/ecmascript/builtins/builtins_ark_tools.cpp b/ecmascript/builtins/builtins_ark_tools.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0104b8986346bb019c4da9fe29842df201b9a839 --- /dev/null +++ b/ecmascript/builtins/builtins_ark_tools.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ecmascript/builtins/builtins_ark_tools.h" +#include +#include +#include "ecmascript/base/string_helper.h" + +namespace panda::ecmascript::builtins { +using StringHelper = base::StringHelper; + +JSTaggedValue BuiltinsArkTools::ObjectDump(EcmaRuntimeCallInfo *msg) +{ + if (msg == nullptr) { + return JSTaggedValue::Undefined(); + } + JSThread *thread = msg->GetThread(); + [[maybe_unused]] EcmaHandleScope handleScope(thread); + + JSHandle str = JSTaggedValue::ToString(thread, GetCallArg(msg, 0)); + // The default log level of ace_engine and js_runtime is error + LOG(ERROR, RUNTIME) << ": " << base::StringHelper::ToStdString(*str); + + uint32_t numArgs = msg->GetArgsNumber(); + for (uint32_t i = 1; i < numArgs; i++) { + JSHandle obj = GetCallArg(msg, i); + std::ostringstream oss; + obj->Dump(thread, oss); + + // The default log level of ace_engine and js_runtime is error + LOG(ERROR, RUNTIME) << ": " << oss.str(); + } + + return JSTaggedValue::Undefined(); +} +} // namespace panda::ecmascript::builtins diff --git a/ecmascript/builtins/builtins_ark_tools.h b/ecmascript/builtins/builtins_ark_tools.h new file mode 100644 index 0000000000000000000000000000000000000000..f5256bb6d9a4230d10eb2a2732d3dea5345ebbb8 --- /dev/null +++ b/ecmascript/builtins/builtins_ark_tools.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_ARK_TOOLS_H +#define ECMASCRIPT_BUILTINS_BUILTINS_ARK_TOOLS_H + +#include "ecmascript/base/builtins_base.h" +#include "ecmascript/js_thread.h" + +namespace panda::ecmascript::builtins { +class BuiltinsArkTools : public base::BuiltinsBase { +public: + // Make sure the ECMASCRIPT_OBJECT_DUMP in config.h has been opened before use it + // Use through arkTools.print(msg, [obj1, obj2, ... objn]) in js + static JSTaggedValue ObjectDump(EcmaRuntimeCallInfo *msg); +}; +} // namespace panda::ecmascript::builtins + +#endif // ECMASCRIPT_BUILTINS_BUILTINS_ARK_TOOLS_H diff --git a/ecmascript/dump.cpp b/ecmascript/dump.cpp index 92f46420e8fd8f5b2b11a8e2479dbbe7c2363004..b2f3bbaa6ca40f001a1588a8df810e1e5f294559 100644 --- a/ecmascript/dump.cpp +++ b/ecmascript/dump.cpp @@ -1348,13 +1348,10 @@ static void DumpArrayClass([[maybe_unused]] JSThread *thread, const TaggedArray { DISALLOW_GARBAGE_COLLECTION; array_size_t len = arr->GetLength(); - for (array_size_t i = 0; i < len; i++) { JSTaggedValue val(arr->Get(i)); - if (!val.IsHole()) { - CString str = ToCString(i); - vec.push_back(std::make_pair(str, val)); - } + CString str = ToCString(i); + vec.push_back(std::make_pair(str, val)); } } @@ -1376,6 +1373,7 @@ static void DumpObject(JSThread *thread, TaggedObject *obj, std::vectorGetDescription().GetTaggedObject())); - } else { - UNREACHABLE(); + if (key.IsInt()) { + res = std::to_string(key.GetInt()); + } else if (key.IsDouble()) { + res = std::to_string(key.GetDouble()); + } else if (key.IsBoolean()) { + res = key.IsTrue() ? "true" : "false"; + } else if (key.IsHeapObject()) { + if (key.IsWeak()) { + key.RemoveWeakTag(); + } + if (key.IsString()) { + EcmaStringToStd(res, EcmaString::Cast(key.GetTaggedObject())); + } else if (key.IsSymbol()) { + JSSymbol *sym = JSSymbol::Cast(key.GetTaggedObject()); + EcmaStringToStd(res, EcmaString::Cast(sym->GetDescription().GetTaggedObject())); + } } } @@ -1557,7 +1564,7 @@ void NumberDictionary::DumpForSnapshot([[maybe_unused]] JSThread *thread, int size = Size(); for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); - if (!key.IsUndefined() && !key.IsHole()) { + if (!key.IsUndefined() && !key.IsHole() && !key.IsNull()) { JSTaggedValue val(GetValue(hashIndex)); CString str = ToCString(static_cast(JSTaggedNumber(key).GetNumber())); vec.push_back(std::make_pair(str, val)); @@ -1572,9 +1579,8 @@ void NameDictionary::DumpForSnapshot([[maybe_unused]] JSThread *thread, int size = Size(); for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); - if (!key.IsUndefined() && !key.IsHole()) { + if (!key.IsUndefined() && !key.IsHole() && !key.IsNull()) { JSTaggedValue val(GetValue(hashIndex)); - CString str; KeyToStd(str, key); vec.push_back(std::make_pair(str, val)); @@ -1589,12 +1595,10 @@ void GlobalDictionary::DumpForSnapshot([[maybe_unused]] JSThread *thread, int size = Size(); for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); - if (!key.IsUndefined() && !key.IsHole()) { - PropertyBox *box = PropertyBox::Cast(key.GetTaggedObject()); - + if (!key.IsUndefined() && !key.IsHole() && !key.IsNull()) { CString str; KeyToStd(str, key); - JSTaggedValue val = box->GetValue(); + JSTaggedValue val = GetValue(hashIndex); vec.push_back(std::make_pair(str, val)); } } @@ -1607,7 +1611,7 @@ void LinkedHashSet::DumpForSnapshot([[maybe_unused]] JSThread *thread, int capacity = NumberOfElements() + NumberOfDeletedElements(); for (int hashIndex = 0; hashIndex < capacity; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); - if (!key.IsUndefined() && !key.IsHole()) { + if (!key.IsUndefined() && !key.IsHole() && !key.IsNull()) { CString str; KeyToStd(str, key); vec.push_back(std::make_pair(str, JSTaggedValue::Hole())); @@ -1622,8 +1626,8 @@ void LinkedHashMap::DumpForSnapshot([[maybe_unused]] JSThread *thread, int capacity = NumberOfElements() + NumberOfDeletedElements(); for (int hashIndex = 0; hashIndex < capacity; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); - if (!key.IsUndefined() && !key.IsHole()) { - JSTaggedValue val(GetValue(hashIndex)); + if (!key.IsUndefined() && !key.IsHole() && !key.IsNull()) { + JSTaggedValue val = GetValue(hashIndex); CString str; KeyToStd(str, key); vec.push_back(std::make_pair(str, val)); diff --git a/ecmascript/ecma_isa.yaml b/ecmascript/ecma_isa.yaml index 3a59436ab3b7b3ce20cf8fa6358a7efb6f6fb073..26a06b0b2fc03230b739a2ec86ffa15d701d3960 100644 --- a/ecmascript/ecma_isa.yaml +++ b/ecmascript/ecma_isa.yaml @@ -577,3 +577,12 @@ groups: prefix: ecma format: [pref_op_id_32] properties: [string_id] + - sig: ecma.stownbyvaluewithnameset v1:in:top, v2:in:top + acc: in:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.stownbynamewithnameset string_id, v:in:top + acc: in:top + prefix: ecma + format: [pref_op_id_32_v_8] + properties: [string_id] diff --git a/ecmascript/hprof/heap_profiler.cpp b/ecmascript/hprof/heap_profiler.cpp index 6a2d640af63acfd297553abf9a7a21393cf67a2b..42a38012445c67c29ee2e0992bae98375ab68f65 100644 --- a/ecmascript/hprof/heap_profiler.cpp +++ b/ecmascript/hprof/heap_profiler.cpp @@ -37,6 +37,10 @@ bool HeapProfiler::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, con { [[maybe_unused]] bool heapClean = ForceFullGC(thread); ASSERT(heapClean); + auto heap = thread->GetEcmaVM()->GetHeap(); + size_t heapSize = heap->GetNewSpace()->GetHeapObjectSize() + heap->GetOldSpace()->GetHeapObjectSize() + + heap->GetNonMovableSpace()->GetHeapObjectSize(); + LOG(ERROR, RUNTIME) << "HeapProfiler DumpSnapshot heap size " << heapSize; HeapSnapShot *snapShot = MakeHeapSnapShot(thread, SampleType::ONE_SHOT); ASSERT(snapShot != nullptr); std::pair realPath = FilePathValid(filePath); @@ -148,7 +152,6 @@ bool HeapProfiler::ForceFullGC(JSThread *thread) if (vm->IsInitialized()) { const_cast(vm->GetHeap())->CollectGarbage(TriggerGCType::SEMI_GC); const_cast(vm->GetHeap())->CollectGarbage(TriggerGCType::OLD_GC); - const_cast(vm->GetHeap())->CollectGarbage(TriggerGCType::NON_MOVE_GC); return true; } return false; @@ -156,6 +159,7 @@ bool HeapProfiler::ForceFullGC(JSThread *thread) HeapSnapShot *HeapProfiler::MakeHeapSnapShot(JSThread *thread, SampleType sampleType) { + LOG(ERROR, RUNTIME) << "HeapProfiler::MakeHeapSnapShot"; DISALLOW_GARBAGE_COLLECTION; switch (sampleType) { case SampleType::ONE_SHOT: { diff --git a/ecmascript/hprof/heap_profiler_interface.cpp b/ecmascript/hprof/heap_profiler_interface.cpp index 93ae61bbe70ea75d72c8ac6c875006927466a7df..0292c07942560ee71e3e6cf3a98e7f4f27a8add4 100644 --- a/ecmascript/hprof/heap_profiler_interface.cpp +++ b/ecmascript/hprof/heap_profiler_interface.cpp @@ -20,6 +20,7 @@ namespace panda::ecmascript { void HeapProfilerInterface::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &filePath) { + LOG(ERROR, RUNTIME) << "HeapProfilerInterface::DumpHeapSnapshot"; const Heap *heap = thread->GetEcmaVM()->GetHeap(); auto *hprof = const_cast(heap->GetRegionFactory())->New(heap); if (UNLIKELY(hprof == nullptr)) { diff --git a/ecmascript/hprof/heap_snapshot.cpp b/ecmascript/hprof/heap_snapshot.cpp index 32512f9f6b8c1e55df4ff1edcc07edae77c4e0f3..04006470cf6de84da83b463ff14617d9f8afec82 100644 --- a/ecmascript/hprof/heap_snapshot.cpp +++ b/ecmascript/hprof/heap_snapshot.cpp @@ -22,6 +22,7 @@ #include "ecmascript/global_env.h" #include "ecmascript/hprof/heap_root_visitor.h" #include "ecmascript/ic/property_box.h" +#include "ecmascript/js_array.h" #include "ecmascript/js_handle.h" #include "ecmascript/js_hclass-inl.h" #include "ecmascript/js_object-inl.h" @@ -144,10 +145,17 @@ CString *HeapSnapShot::GenerateNodeName(JSThread *thread, TaggedObject *entry) CString *name = GetString("UnKnownType"); auto *hCls = entry->GetClass(); if (hCls->IsTaggedArray()) { + CString arrayName; TaggedArray *array = TaggedArray::Cast(entry); - CString arrayName("Array["); - arrayName.append(ToCString(array->GetLength())); - arrayName.append("]"); + if (hCls->IsDictionary()) { + arrayName = "TaggedDict["; + arrayName.append(ToCString(array->GetLength())); + arrayName.append("]"); + } else { + arrayName = "TaggedArray["; + arrayName.append(ToCString(array->GetLength())); + arrayName.append("]"); + } name = GetString(arrayName); // String type was handled singly, see#GenerateStringNode } else if (hCls->IsHClass()) { name = GetString("HiddenClass"); @@ -161,7 +169,11 @@ CString *HeapSnapShot::GenerateNodeName(JSThread *thread, TaggedObject *entry) } else if (hCls->IsJSSymbol()) { name = GetString("JSSymbol"); } else if (hCls->IsJSArray()) { - name = GetString("JSArray"); + JSArray *jsArray = JSArray::Cast(entry); + CString arrayName("JSArray["); + arrayName.append(ToCString(jsArray->GetLength().GetInt())); + arrayName.append("]"); + name = GetString(arrayName); } else if (hCls->IsTypedArray()) { name = GetString("TypedArray"); } else if (hCls->IsJSTypedArray()) { @@ -352,7 +364,7 @@ CString *HeapSnapShot::GenerateNodeName(JSThread *thread, TaggedObject *entry) NodeType HeapSnapShot::GenerateNodeType(TaggedObject *entry) { - NodeType nodeType; + NodeType nodeType = NodeType::INVALID; auto *hCls = entry->GetClass(); if (hCls->IsTaggedArray()) { nodeType = NodeType::JS_ARRAY; @@ -381,8 +393,14 @@ Node *HeapSnapShot::GenerateNode(JSThread *thread, JSTaggedValue entry, int sequ sequenceId = sequenceId_ + SEQ_STEP; } if (entry.IsHeapObject()) { + if (entry.IsWeak()) { + entry.RemoveWeakTag(); + } if (entry.IsString()) { - return GenerateStringNode(entry, sequenceId); + node = GenerateStringNode(entry, sequenceId); + if (node == nullptr) { + LOG(ERROR, RUNTIME) << "string node nullptr"; + } } TaggedObject *obj = entry.GetTaggedObject(); auto *baseClass = obj->GetClass(); @@ -404,44 +422,36 @@ Node *HeapSnapShot::GenerateNode(JSThread *thread, JSTaggedValue entry, int sequ } } } else { - auto *obj = reinterpret_cast(entry.GetRawData()); CString primitiveName; - JSTaggedValue primitiveObj(obj); - if (primitiveObj.IsInt()) { - primitiveName.append("Int:"); - } else if (primitiveObj.IsDouble()) { + // A primitive value with tag will be regarded as a pointer + auto *obj = reinterpret_cast(entry.GetRawData()); + if (entry.IsInt()) { + primitiveName.append("Int:" + ToCString(entry.GetInt())); + } else if (entry.IsDouble()) { primitiveName.append("Double:"); - } else if (primitiveObj.IsSpecial()) { - if (primitiveObj.IsHole()) { - primitiveName.append("Hole"); - } else if (primitiveObj.IsNull()) { - primitiveName.append("Null"); - } else if (primitiveObj.IsTrue()) { - primitiveName.append("Boolean:true"); - } else if (primitiveObj.IsFalse()) { - primitiveName.append("Boolean:false"); - } else if (primitiveObj.IsException()) { - primitiveName.append("Exception"); - } else if (primitiveObj.IsUndefined()) { - primitiveName.append("Undefined"); - } + } 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"); } node = Node::NewNode(heap_, sequenceId, nodeCount_, GetString(primitiveName), NodeType::JS_PRIMITIVE_REF, 0, obj); - Node *existNode = entryMap_.FindOrInsertNode(node); // Fast Index - if (existNode == node) { - if (sequenceId == sequenceId_ + SEQ_STEP) { - sequenceId_ = sequenceId; // Odd Digit - } - InsertNodeUnique(node); - } else { - const_cast(heap_->GetRegionFactory())->Delete(node); - node = nullptr; - existNode->SetLive(true); + entryMap_.InsertEntry(node); // Fast Index + if (sequenceId == sequenceId_ + SEQ_STEP) { + sequenceId_ = sequenceId; // Odd Digit } + InsertNodeUnique(node); } return node; } @@ -482,11 +492,16 @@ void HeapSnapShot::FillEdges(JSThread *thread) auto *objFrom = reinterpret_cast((*iter)->GetAddress()); std::vector> nameResources; JSTaggedValue(objFrom).DumpForSnapshot(thread, nameResources); + JSTaggedValue objValue(objFrom); for (auto const &it : nameResources) { - auto *to = reinterpret_cast(it.second.GetRawData()); - Node *entryTo = entryMap_.FindEntry(Node::NewAddress(to)); + JSTaggedValue toValue = it.second; + Node *entryTo = nullptr; + if (toValue.IsHeapObject()) { + auto *to = reinterpret_cast(toValue.GetHeapObject()); + entryTo = entryMap_.FindEntry(Node::NewAddress(to)); + } if (entryTo == nullptr) { - entryTo = GenerateNode(thread, it.second); + entryTo = GenerateNode(thread, toValue); } if (entryTo != nullptr) { Edge *edge = Edge::NewEdge(heap_, edgeCount_, EdgeType::DEFAULT, *iter, entryTo, GetString(it.first)); @@ -565,8 +580,8 @@ Edge *HeapSnapShot::InsertEdgeUnique(Edge *edge) void HeapSnapShot::AddSyntheticRoot(JSThread *thread) { - Node *syntheticRoot = Node::NewNode(heap_, 1, nodeCount_, GetString("SyntheticRoot"), NodeType::SYNTHETIC, 0, - nullptr); + Node *syntheticRoot = Node::NewNode(heap_, 1, nodeCount_, GetString("SyntheticRoot"), + NodeType::SYNTHETIC, 0, nullptr); InsertNodeAt(0, syntheticRoot); int edgeOffset = 0; @@ -632,7 +647,7 @@ CString EntryVisitor::ConvertKey(JSTaggedValue key) keyString = EcmaString::Cast(symbol->GetDescription().GetTaggedObject()); } // convert, expensive but safe - int length; + int length = 0; if (keyString->IsUtf8()) { length = keyString->GetUtf8Length(); std::vector buffer(length); @@ -687,7 +702,7 @@ void HeapEntryMap::InsertEntry(Node *node) FrontType NodeTypeConverter::Convert(NodeType type) { - FrontType fType; + FrontType fType = FrontType::DEFAULT; if (type == NodeType::PROPERTY_BOX) { fType = FrontType::HIDDEN; } else if (type == NodeType::JS_ARRAY || type == NodeType::JS_TYPED_ARRAY) { diff --git a/ecmascript/hprof/heap_snapshot.h b/ecmascript/hprof/heap_snapshot.h index be10d01f51b8ddaa092ad154a92742628d6ef18a..f2ad5fb7d12a33f1d9c760815a88f24de9131645 100644 --- a/ecmascript/hprof/heap_snapshot.h +++ b/ecmascript/hprof/heap_snapshot.h @@ -224,9 +224,9 @@ public: { return nodeEntryCount_; } + void InsertEntry(Node *node); private: - void InsertEntry(Node *node); size_t nodeEntryCount_{0}; CUnorderedMap nodesMap_{}; }; diff --git a/ecmascript/hprof/heap_snapshot_json_serializer.cpp b/ecmascript/hprof/heap_snapshot_json_serializer.cpp index 1946fdb7dd94a734c698e33c885b69bfb46f719d..5cbed3f0f5bd1b87d4e42314ac8f1e2eededf793 100644 --- a/ecmascript/hprof/heap_snapshot_json_serializer.cpp +++ b/ecmascript/hprof/heap_snapshot_json_serializer.cpp @@ -22,6 +22,7 @@ namespace panda::ecmascript { bool HeapSnapShotJSONSerializer::Serialize(HeapSnapShot *snapShot, const CString &fileName) { // Serialize Node/Edge/String-Table + LOG(ERROR, RUNTIME) << "HeapSnapShotJSONSerializer::Serialize begin"; snapShot_ = snapShot; ASSERT(snapShot_->GetNodes() != nullptr && snapShot_->GetEdges() != nullptr && snapShot_->GetEcmaStringTable() != nullptr); @@ -38,6 +39,7 @@ bool HeapSnapShotJSONSerializer::Serialize(HeapSnapShot *snapShot, const CString SerializerSnapShotClosure(); // 9. WriteJSON(fileName); // 10. + LOG(ERROR, RUNTIME) << "HeapSnapShotJSONSerializer::Serialize exit"; return true; } @@ -191,6 +193,7 @@ void HeapSnapShotJSONSerializer::SerializerSnapShotClosure() void HeapSnapShotJSONSerializer::WriteJSON(const CString &fileName) { std::string fName(fileName); + LOG(ERROR, RUNTIME) << "HeapSnapShotJSONSerializer::WriteJSON" << fName; outputStream_.open(fName, std::ios::out); if (!outputStream_.good()) { LOG_ECMA(ERROR) << "open file failed"; diff --git a/ecmascript/ic/ic_runtime_stub-inl.h b/ecmascript/ic/ic_runtime_stub-inl.h index ea51670b40064d3d9b5b1e0bb4315343d622bcc2..c1610b181cd4c3f9815738ff3653440132e4f7e9 100644 --- a/ecmascript/ic/ic_runtime_stub-inl.h +++ b/ecmascript/ic/ic_runtime_stub-inl.h @@ -40,6 +40,7 @@ namespace panda::ecmascript { JSTaggedValue ICRuntimeStub::LoadGlobalICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, JSTaggedValue globalValue, JSTaggedValue key, uint32_t slotId) { + INTERPRETER_TRACE(thread, LoadGlobalICByName); JSTaggedValue handler = profileTypeInfo->Get(slotId); if (handler.IsHeapObject()) { auto result = LoadGlobal(handler); @@ -61,6 +62,7 @@ JSTaggedValue ICRuntimeStub::StoreGlobalICByName(JSThread *thread, ProfileTypeIn JSTaggedValue globalValue, JSTaggedValue key, JSTaggedValue value, uint32_t slotId) { + INTERPRETER_TRACE(thread, StoreGlobalICByName); JSTaggedValue handler = profileTypeInfo->Get(slotId); if (handler.IsHeapObject()) { auto result = StoreGlobal(thread, value, handler); @@ -232,6 +234,7 @@ ARK_INLINE JSTaggedValue ICRuntimeStub::StoreICWithHandler(JSThread *thread, JST JSTaggedValue holder, JSTaggedValue value, JSTaggedValue handler) { + INTERPRETER_TRACE(thread, StoreICWithHandler); if (handler.IsInt()) { auto handlerInfo = static_cast(handler.GetInt()); if (HandlerBase::IsField(handlerInfo)) { @@ -258,6 +261,7 @@ ARK_INLINE JSTaggedValue ICRuntimeStub::StoreICWithHandler(JSThread *thread, JST JSTaggedValue ICRuntimeStub::StorePrototype(JSThread *thread, JSTaggedValue receiver, JSTaggedValue value, JSTaggedValue handler) { + INTERPRETER_TRACE(thread, StorePrototype); ASSERT(handler.IsPrototypeHandler()); PrototypeHandler *prototypeHandler = PrototypeHandler::Cast(handler.GetTaggedObject()); auto cellValue = prototypeHandler->GetProtoCell(); @@ -274,6 +278,7 @@ JSTaggedValue ICRuntimeStub::StorePrototype(JSThread *thread, JSTaggedValue rece void ICRuntimeStub::StoreWithTransition(JSThread *thread, JSObject *receiver, JSTaggedValue value, JSTaggedValue handler) { + INTERPRETER_TRACE(thread, StoreWithTransition); TransitionHandler *transitionHandler = TransitionHandler::Cast(handler.GetTaggedObject()); JSHClass *newHClass = JSHClass::Cast(transitionHandler->GetTransitionHClass().GetTaggedObject()); receiver->SetClass(newHClass); @@ -309,6 +314,7 @@ void ICRuntimeStub::StoreWithTransition(JSThread *thread, JSObject *receiver, JS ARK_INLINE void ICRuntimeStub::StoreField(JSThread *thread, JSObject *receiver, JSTaggedValue value, uint32_t handler) { + INTERPRETER_TRACE(thread, StoreField); int index = HandlerBase::GetOffset(handler); if (HandlerBase::IsInlinedProps(handler)) { SET_VALUE_WITH_BARRIER(thread, receiver, index * JSTaggedValue::TaggedTypeSize(), value); @@ -342,6 +348,7 @@ ARK_INLINE JSTaggedValue ICRuntimeStub::LoadGlobal(JSTaggedValue handler) ARK_INLINE JSTaggedValue ICRuntimeStub::StoreGlobal(JSThread *thread, JSTaggedValue value, JSTaggedValue handler) { + INTERPRETER_TRACE(thread, StoreGlobal); ASSERT(handler.IsPropertyBox()); PropertyBox *cell = PropertyBox::Cast(handler.GetHeapObject()); if (cell->IsInvalid()) { @@ -354,6 +361,7 @@ ARK_INLINE JSTaggedValue ICRuntimeStub::StoreGlobal(JSThread *thread, JSTaggedVa JSTaggedValue ICRuntimeStub::LoadPrototype(JSThread *thread, JSTaggedValue receiver, JSTaggedValue handler) { + INTERPRETER_TRACE(thread, LoadPrototype); ASSERT(handler.IsPrototypeHandler()); PrototypeHandler *prototypeHandler = PrototypeHandler::Cast(handler.GetTaggedObject()); auto cellValue = prototypeHandler->GetProtoCell(); @@ -370,6 +378,7 @@ JSTaggedValue ICRuntimeStub::LoadPrototype(JSThread *thread, JSTaggedValue recei ARK_INLINE JSTaggedValue ICRuntimeStub::LoadICWithHandler(JSThread *thread, JSTaggedValue receiver, JSTaggedValue holder, JSTaggedValue handler) { + INTERPRETER_TRACE(thread, LoadICWithHandler); if (LIKELY(handler.IsInt())) { auto handlerInfo = static_cast(handler.GetInt()); if (LIKELY(HandlerBase::IsField(handlerInfo))) { @@ -410,6 +419,7 @@ ARK_INLINE JSTaggedValue ICRuntimeStub::LoadElement(JSObject *receiver, JSTagged JSTaggedValue ICRuntimeStub::StoreElement(JSThread *thread, JSObject *receiver, JSTaggedValue key, JSTaggedValue value, uint32_t handlerInfo) { + INTERPRETER_TRACE(thread, StoreElement); ASSERT(HandlerBase::IsElement(handlerInfo)); auto index = TryToElementsIndex(key); if (index < 0) { diff --git a/ecmascript/interpreter/fast_runtime_stub-inl.h b/ecmascript/interpreter/fast_runtime_stub-inl.h index a6276a00fffb3cc09808f10e39077083795bdbb8..f5ec11414d2ce4cdb8eae9570a076457ca17930c 100644 --- a/ecmascript/interpreter/fast_runtime_stub-inl.h +++ b/ecmascript/interpreter/fast_runtime_stub-inl.h @@ -184,6 +184,7 @@ int32_t FastRuntimeStub::TryToElementsIndex(JSTaggedValue key) JSTaggedValue FastRuntimeStub::CallGetter(JSThread *thread, JSTaggedValue receiver, JSTaggedValue holder, JSTaggedValue value) { + INTERPRETER_TRACE(thread, CallGetter); // Accessor [[maybe_unused]] EcmaHandleScope handleScope(thread); AccessorData *accessor = AccessorData::Cast(value.GetTaggedObject()); @@ -198,6 +199,7 @@ JSTaggedValue FastRuntimeStub::CallGetter(JSThread *thread, JSTaggedValue receiv JSTaggedValue FastRuntimeStub::CallSetter(JSThread *thread, JSTaggedValue receiver, JSTaggedValue value, JSTaggedValue accessorValue) { + INTERPRETER_TRACE(thread, CallSetter); // Accessor [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle objHandle(thread, receiver); @@ -223,6 +225,7 @@ bool FastRuntimeStub::ShouldCallSetter(JSTaggedValue receiver, JSTaggedValue hol JSTaggedValue FastRuntimeStub::AddPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value) { + INTERPRETER_TRACE(thread, AddPropertyByName); [[maybe_unused]] EcmaHandleScope handleScope(thread); if (UNLIKELY(!JSObject::Cast(receiver)->IsExtensible())) { THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot add property in prevent extensions ", JSTaggedValue::Exception()); @@ -292,6 +295,7 @@ JSTaggedValue FastRuntimeStub::AddPropertyByName(JSThread *thread, JSTaggedValue JSTaggedValue FastRuntimeStub::AddPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index, JSTaggedValue value) { + INTERPRETER_TRACE(thread, AddPropertyByIndex); [[maybe_unused]] EcmaHandleScope handleScope(thread); if (UNLIKELY(!JSObject::Cast(receiver)->IsExtensible())) { THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot add property in prevent extensions ", JSTaggedValue::Exception()); @@ -305,6 +309,7 @@ JSTaggedValue FastRuntimeStub::AddPropertyByIndex(JSThread *thread, JSTaggedValu template JSTaggedValue FastRuntimeStub::GetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index) { + INTERPRETER_TRACE(thread, GetPropertyByIndex); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSTaggedValue holder = receiver; do { @@ -351,6 +356,7 @@ JSTaggedValue FastRuntimeStub::GetPropertyByIndex(JSThread *thread, JSTaggedValu template JSTaggedValue FastRuntimeStub::GetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key) { + INTERPRETER_TRACE(thread, GetPropertyByValue); if (UNLIKELY(!key.IsNumber() && !key.IsStringOrSymbol())) { return JSTaggedValue::Hole(); } @@ -432,6 +438,7 @@ template JSTaggedValue FastRuntimeStub::SetPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value) { + INTERPRETER_TRACE(thread, SetPropertyByName); // property JSTaggedValue holder = receiver; do { @@ -504,6 +511,7 @@ template JSTaggedValue FastRuntimeStub::SetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index, JSTaggedValue value) { + INTERPRETER_TRACE(thread, SetPropertyByIndex); JSTaggedValue holder = receiver; do { auto *hclass = holder.GetTaggedObject()->GetClass(); @@ -539,6 +547,7 @@ template JSTaggedValue FastRuntimeStub::SetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value) { + INTERPRETER_TRACE(thread, SetPropertyByValue); if (UNLIKELY(!key.IsNumber() && !key.IsStringOrSymbol())) { return JSTaggedValue::Hole(); } @@ -579,6 +588,7 @@ JSTaggedValue FastRuntimeStub::GetGlobalOwnProperty(JSTaggedValue receiver, JSTa JSTaggedValue FastRuntimeStub::FastTypeOf(JSThread *thread, JSTaggedValue obj) { + INTERPRETER_TRACE(thread, FastTypeOf); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); switch (obj.GetRawData()) { case JSTaggedValue::VALUE_TRUE: @@ -611,6 +621,7 @@ JSTaggedValue FastRuntimeStub::FastTypeOf(JSThread *thread, JSTaggedValue obj) bool FastRuntimeStub::FastSetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index, JSTaggedValue value) { + INTERPRETER_TRACE(thread, FastSetPropertyByIndex); JSTaggedValue result = FastRuntimeStub::SetPropertyByIndex(thread, receiver, index, value); if (!result.IsHole()) { return result != JSTaggedValue::Exception(); @@ -622,6 +633,7 @@ bool FastRuntimeStub::FastSetPropertyByIndex(JSThread *thread, JSTaggedValue rec bool FastRuntimeStub::FastSetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value) { + INTERPRETER_TRACE(thread, FastSetPropertyByValue); JSTaggedValue result = FastRuntimeStub::SetPropertyByValue(thread, receiver, key, value); if (!result.IsHole()) { return result != JSTaggedValue::Exception(); @@ -634,6 +646,7 @@ bool FastRuntimeStub::FastSetPropertyByValue(JSThread *thread, JSTaggedValue rec // must not use for interpreter JSTaggedValue FastRuntimeStub::FastGetPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key) { + INTERPRETER_TRACE(thread, FastGetPropertyByName); ASSERT(key.IsStringOrSymbol()); if (key.IsString() && !EcmaString::Cast(key.GetTaggedObject())->IsInternString()) { JSHandle receiverHandler(thread, receiver); @@ -653,6 +666,7 @@ JSTaggedValue FastRuntimeStub::FastGetPropertyByName(JSThread *thread, JSTaggedV JSTaggedValue FastRuntimeStub::FastGetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key) { + INTERPRETER_TRACE(thread, FastGetPropertyByValue); JSTaggedValue result = FastRuntimeStub::GetPropertyByValue(thread, receiver, key); if (result.IsHole()) { return JSTaggedValue::GetProperty(thread, JSHandle(thread, receiver), @@ -666,6 +680,7 @@ JSTaggedValue FastRuntimeStub::FastGetPropertyByValue(JSThread *thread, JSTagged template // UseHole is only for Array::Sort() which requires Hole order JSTaggedValue FastRuntimeStub::FastGetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index) { + INTERPRETER_TRACE(thread, FastGetPropertyByIndex); JSTaggedValue result = GetPropertyByIndex(thread, receiver, index); if (result.IsHole() && !UseHole) { return JSTaggedValue::GetProperty(thread, JSHandle(thread, receiver), index) @@ -677,6 +692,7 @@ JSTaggedValue FastRuntimeStub::FastGetPropertyByIndex(JSThread *thread, JSTagged JSTaggedValue FastRuntimeStub::NewLexicalEnvDyn(JSThread *thread, ObjectFactory *factory, uint16_t numVars) { + INTERPRETER_TRACE(thread, NewLexicalEnvDyn); [[maybe_unused]] EcmaHandleScope handleScope(thread); LexicalEnv *newEnv = factory->InlineNewLexicalEnv(numVars); if (UNLIKELY(newEnv == nullptr)) { @@ -736,6 +752,7 @@ JSTaggedValue FastRuntimeStub::GetElementWithArray(JSTaggedValue receiver, uint3 bool FastRuntimeStub::SetElement(JSThread *thread, JSTaggedValue receiver, uint32_t index, JSTaggedValue value, bool mayThrow) { + INTERPRETER_TRACE(thread, SetElement); JSTaggedValue holder = receiver; bool onPrototype = false; @@ -808,6 +825,7 @@ bool FastRuntimeStub::SetElement(JSThread *thread, JSTaggedValue receiver, uint3 bool FastRuntimeStub::SetPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, bool mayThrow) { + INTERPRETER_TRACE(thread, SetPropertyByName); // property JSTaggedValue holder = receiver; bool onPrototype = false; @@ -930,6 +948,7 @@ bool FastRuntimeStub::SetPropertyByName(JSThread *thread, JSTaggedValue receiver bool FastRuntimeStub::SetGlobalOwnProperty(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, bool mayThrow) { + INTERPRETER_TRACE(thread, SetGlobalOwnProperty); uint32_t index = 0; if (JSTaggedValue::ToElementIndex(key, &index)) { return SetElement(thread, receiver, index, value, mayThrow); @@ -1011,6 +1030,7 @@ bool FastRuntimeStub::SetGlobalOwnProperty(JSThread *thread, JSTaggedValue recei void FastRuntimeStub::SetOwnPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value) { + INTERPRETER_TRACE(thread, SetOwnPropertyByName); TaggedArray *properties = TaggedArray::Cast(JSObject::Cast(receiver)->GetProperties().GetHeapObject()); PropertyAttributes attr; uint32_t indexOrEntry; @@ -1045,6 +1065,7 @@ void FastRuntimeStub::SetOwnPropertyByName(JSThread *thread, JSTaggedValue recei // set element that is not accessor and is writable bool FastRuntimeStub::SetOwnElement(JSThread *thread, JSTaggedValue receiver, uint32_t index, JSTaggedValue value) { + INTERPRETER_TRACE(thread, SetOwnElement); PropertyAttributes attr; uint32_t indexOrEntry; TaggedArray *elements = TaggedArray::Cast(JSObject::Cast(receiver)->GetElements().GetHeapObject()); @@ -1068,6 +1089,7 @@ bool FastRuntimeStub::SetOwnElement(JSThread *thread, JSTaggedValue receiver, ui bool FastRuntimeStub::FastSetProperty(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, bool mayThrow) { + INTERPRETER_TRACE(thread, FastSetProperty); if (receiver.IsJSObject() && !receiver.IsTypedArray() && (key.IsStringOrSymbol())) { uint32_t index = 0; if (UNLIKELY(JSTaggedValue::ToElementIndex(key, &index))) { @@ -1090,6 +1112,7 @@ bool FastRuntimeStub::FastSetProperty(JSThread *thread, JSTaggedValue receiver, JSTaggedValue FastRuntimeStub::FastGetProperty(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key) { + INTERPRETER_TRACE(thread, FastGetProperty); JSTaggedValue result; if (receiver.IsJSObject() && !receiver.IsTypedArray() && (key.IsStringOrSymbol())) { uint32_t index = 0; @@ -1123,6 +1146,7 @@ JSTaggedValue FastRuntimeStub::FastGetProperty(JSThread *thread, JSTaggedValue r JSTaggedValue FastRuntimeStub::FindOwnProperty(JSThread *thread, JSObject *obj, TaggedArray *properties, JSTaggedValue key, PropertyAttributes *attr, uint32_t *indexOrEntry) { + INTERPRETER_TRACE(thread, FindOwnProperty); if (!properties->IsDictionaryMode()) { JSHClass *cls = obj->GetJSHClass(); JSTaggedValue attrs = cls->GetAttributes(); @@ -1194,6 +1218,7 @@ JSTaggedValue FastRuntimeStub::FindOwnElement(TaggedArray *elements, uint32_t in JSTaggedValue FastRuntimeStub::FindOwnProperty(JSThread *thread, JSObject *obj, JSTaggedValue key) { + INTERPRETER_TRACE(thread, FindOwnProperty); TaggedArray *array = TaggedArray::Cast(obj->GetProperties().GetHeapObject()); if (!array->IsDictionaryMode()) { JSHClass *cls = obj->GetJSHClass(); @@ -1255,6 +1280,7 @@ JSTaggedValue FastRuntimeStub::FindOwnElement(JSObject *obj, uint32_t index) JSTaggedValue FastRuntimeStub::HasOwnProperty(JSThread *thread, JSObject *obj, JSTaggedValue key) { + INTERPRETER_TRACE(thread, HasOwnProperty); uint32_t index = 0; if (UNLIKELY(JSTaggedValue::ToElementIndex(key, &index))) { return FastRuntimeStub::FindOwnElement(obj, index); diff --git a/ecmascript/interpreter/interpreter-inl.h b/ecmascript/interpreter/interpreter-inl.h index 99efe62c898a8b9f80112c357b8041fd98da66a2..70225021df91fb60713ebf6180278a0b31b60494 100644 --- a/ecmascript/interpreter/interpreter-inl.h +++ b/ecmascript/interpreter/interpreter-inl.h @@ -205,6 +205,7 @@ namespace panda::ecmascript { JSTaggedValue EcmaInterpreter::ExecuteNative(JSThread *thread, const CallParams& params) { + INTERPRETER_TRACE(thread, ExecuteNative); JSTaggedType *sp = const_cast(thread->GetCurrentSPFrame()); JSMethod *methodToCall = params.callTarget->GetCallTarget(); ASSERT(methodToCall->GetNumVregs() == 0); @@ -242,6 +243,7 @@ JSTaggedValue EcmaInterpreter::ExecuteNative(JSThread *thread, const CallParams& JSTaggedValue EcmaInterpreter::Execute(JSThread *thread, const CallParams& params) { + INTERPRETER_TRACE(thread, Execute); JSMethod *method = params.callTarget->GetCallTarget(); ASSERT(thread->IsEcmaInterpreter()); if (method->IsNative()) { @@ -2303,9 +2305,6 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool value = GET_ACC(); if (!res.IsHole()) { INTERPRETER_RETURN_IF_ABRUPT(res); - if (value.IsJSFunction()) { - JSFunction::SetFunctionNameNoPrefix(thread, JSFunction::Cast(value.GetTaggedObject()), propKey); - } RESTORE_ACC(); DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } @@ -2745,6 +2744,73 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool DISPATCH(BytecodeInstruction::Format::PREF_ID32); } + HANDLE_OPCODE(HANDLE_STOWNBYVALUEWITHNAMESET_PREF_V8_V8) { + uint32_t v0 = READ_INST_8_1(); + uint32_t v1 = READ_INST_8_2(); + LOG_INST() << "intrinsics::stownbyvaluewithnameset" + << " v" << v0 << " v" << v1; + JSTaggedValue receiver = GET_VREG_VALUE(v0); + if (receiver.IsHeapObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) { + SAVE_ACC(); + JSTaggedValue propKey = GET_VREG_VALUE(v1); + JSTaggedValue value = GET_ACC(); + // fast path + JSTaggedValue res = FastRuntimeStub::SetPropertyByValue(thread, receiver, propKey, value); + + // SetPropertyByValue maybe gc need update the value + RESTORE_ACC(); + propKey = GET_VREG_VALUE(v1); + value = GET_ACC(); + if (!res.IsHole()) { + INTERPRETER_RETURN_IF_ABRUPT(res); + JSFunction::SetFunctionNameNoPrefix(thread, JSFunction::Cast(value.GetTaggedObject()), propKey); + RESTORE_ACC(); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); + } + } + + // slow path + SAVE_ACC(); + receiver = GET_VREG_VALUE(v0); // Maybe moved by GC + auto propKey = GET_VREG_VALUE(v1); // Maybe moved by GC + auto value = GET_ACC(); // Maybe moved by GC + JSTaggedValue res = SlowRuntimeStub::StOwnByValueWithNameSet(thread, receiver, propKey, value); + RESTORE_ACC(); + INTERPRETER_RETURN_IF_ABRUPT(res); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); + } + HANDLE_OPCODE(HANDLE_STOWNBYNAMEWITHNAMESET_PREF_ID32_V8) { + uint32_t stringId = READ_INST_32_1(); + uint32_t v0 = READ_INST_8_5(); + LOG_INST() << "intrinsics::stownbynamewithnameset " + << "v" << v0 << " stringId:" << stringId; + + JSTaggedValue receiver = GET_VREG_VALUE(v0); + if (receiver.IsJSObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) { + JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); + JSTaggedValue value = GET_ACC(); + // fast path + SAVE_ACC(); + JSTaggedValue res = FastRuntimeStub::SetPropertyByName(thread, receiver, propKey, value); + if (!res.IsHole()) { + INTERPRETER_RETURN_IF_ABRUPT(res); + JSFunction::SetFunctionNameNoPrefix(thread, JSFunction::Cast(value.GetTaggedObject()), propKey); + RESTORE_ACC(); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8); + } + RESTORE_ACC(); + } + + SAVE_ACC(); + receiver = GET_VREG_VALUE(v0); // Maybe moved by GC + auto propKey = constpool->GetObjectFromCache(stringId); // Maybe moved by GC + auto value = GET_ACC(); // Maybe moved by GC + JSTaggedValue res = SlowRuntimeStub::StOwnByNameWithNameSet(thread, receiver, propKey, value); + RESTORE_ACC(); + INTERPRETER_RETURN_IF_ABRUPT(res); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8); + } + HANDLE_OPCODE(HANDLE_LDGLOBALVAR_PREF_ID32) { uint32_t stringId = READ_INST_32_1(); JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); diff --git a/ecmascript/interpreter/interpreter.h b/ecmascript/interpreter/interpreter.h index 62964b5a7da72604bcc56228f5b9b2e7ada53de2..cb988f370138aae771da0c4d057671abfa2a8989 100644 --- a/ecmascript/interpreter/interpreter.h +++ b/ecmascript/interpreter/interpreter.h @@ -214,6 +214,8 @@ enum EcmaOpcode { STCONSTTOGLOBALRECORD_PREF_ID32, STLETTOGLOBALRECORD_PREF_ID32, STCLASSTOGLOBALRECORD_PREF_ID32, + STOWNBYVALUEWITHNAMESET_PREF_V8_V8, + STOWNBYNAMEWITHNAMESET_PREF_ID32_V8, MOV_DYN_V8_V8, MOV_DYN_V16_V16, LDA_STR_ID32, diff --git a/ecmascript/interpreter/slow_runtime_stub.cpp b/ecmascript/interpreter/slow_runtime_stub.cpp index 5874bcd6cb94543c838b29b4afb366a02a4967a6..8d5738619f34ec70e511eb1e6a9c8496913164bf 100644 --- a/ecmascript/interpreter/slow_runtime_stub.cpp +++ b/ecmascript/interpreter/slow_runtime_stub.cpp @@ -67,6 +67,7 @@ JSTaggedValue SlowRuntimeStub::CallSpreadDyn(JSThread *thread, JSTaggedValue fun JSTaggedValue SlowRuntimeStub::NegDyn(JSThread *thread, JSTaggedValue value) { + INTERPRETER_TRACE(thread, NegDyn); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle input(thread, value); @@ -89,6 +90,7 @@ JSTaggedValue SlowRuntimeStub::NegDyn(JSThread *thread, JSTaggedValue value) JSTaggedValue SlowRuntimeStub::AsyncFunctionEnter(JSThread *thread) { + INTERPRETER_TRACE(thread, AsyncFunctionEnter); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); [[maybe_unused]] EcmaHandleScope handleScope(thread); // 1. create promise @@ -126,6 +128,7 @@ JSTaggedValue SlowRuntimeStub::ToNumber(JSThread *thread, JSTaggedValue value) JSTaggedValue SlowRuntimeStub::NotDyn(JSThread *thread, JSTaggedValue value) { + INTERPRETER_TRACE(thread, NotDyn); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle valueHandle(thread, value); int32_t number = JSTaggedValue::ToInt32(thread, valueHandle); @@ -135,6 +138,7 @@ JSTaggedValue SlowRuntimeStub::NotDyn(JSThread *thread, JSTaggedValue value) JSTaggedValue SlowRuntimeStub::IncDyn(JSThread *thread, JSTaggedValue value) { + INTERPRETER_TRACE(thread, IncDyn); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle valueHandle(thread, value); @@ -145,6 +149,7 @@ JSTaggedValue SlowRuntimeStub::IncDyn(JSThread *thread, JSTaggedValue value) JSTaggedValue SlowRuntimeStub::DecDyn(JSThread *thread, JSTaggedValue value) { + INTERPRETER_TRACE(thread, DecDyn); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle valueHandle(thread, value); @@ -155,6 +160,7 @@ JSTaggedValue SlowRuntimeStub::DecDyn(JSThread *thread, JSTaggedValue value) void SlowRuntimeStub::ThrowDyn(JSThread *thread, JSTaggedValue value) { + INTERPRETER_TRACE(thread, ThrowDyn); [[maybe_unused]] EcmaHandleScope handleScope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); @@ -165,6 +171,7 @@ void SlowRuntimeStub::ThrowDyn(JSThread *thread, JSTaggedValue value) JSTaggedValue SlowRuntimeStub::GetPropIterator(JSThread *thread, JSTaggedValue value) { + INTERPRETER_TRACE(thread, GetPropIterator); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle objHandle(thread, value); @@ -175,6 +182,7 @@ JSTaggedValue SlowRuntimeStub::GetPropIterator(JSThread *thread, JSTaggedValue v void SlowRuntimeStub::ThrowConstAssignment(JSThread *thread, JSTaggedValue value) { + INTERPRETER_TRACE(thread, ThrowConstAssignment); [[maybe_unused]] EcmaHandleScope handleScope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); @@ -194,11 +202,8 @@ JSTaggedValue SlowRuntimeStub::Add2Dyn(JSThread *thread, EcmaVM *ecma_vm, JSTagg JSHandle leftValue(thread, left); JSHandle rightValue(thread, right); if (leftValue->IsString() && rightValue->IsString()) { - JSHandle stringA0 = JSTaggedValue::ToString(thread, leftValue); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - JSHandle stringA1 = JSTaggedValue::ToString(thread, rightValue); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - EcmaString *newString = EcmaString::Concat(stringA0, stringA1, ecma_vm); + EcmaString *newString = EcmaString::Concat(JSHandle(leftValue), + JSHandle(rightValue), ecma_vm); return JSTaggedValue(newString); } JSHandle primitiveA0(thread, JSTaggedValue::ToPrimitive(thread, leftValue)); @@ -378,6 +383,7 @@ JSTaggedValue SlowRuntimeStub::GreaterEqDyn(JSThread *thread, JSTaggedValue left JSTaggedValue SlowRuntimeStub::ToJSTaggedValueWithInt32(JSThread *thread, JSTaggedValue value) { + INTERPRETER_TRACE(thread, ToJSTaggedValueWithInt32); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle valueHandle(thread, value); int32_t res = JSTaggedValue::ToInt32(thread, valueHandle); @@ -387,6 +393,7 @@ JSTaggedValue SlowRuntimeStub::ToJSTaggedValueWithInt32(JSThread *thread, JSTagg JSTaggedValue SlowRuntimeStub::ToJSTaggedValueWithUint32(JSThread *thread, JSTaggedValue value) { + INTERPRETER_TRACE(thread, ToJSTaggedValueWithUint32); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle valueHandle(thread, value); int32_t res = JSTaggedValue::ToUint32(thread, valueHandle); @@ -508,6 +515,7 @@ JSTaggedValue SlowRuntimeStub::ExpDyn(JSThread *thread, JSTaggedValue base, JSTa JSTaggedValue SlowRuntimeStub::IsInDyn(JSThread *thread, JSTaggedValue prop, JSTaggedValue obj) { + INTERPRETER_TRACE(thread, IsInDyn); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle propHandle(thread, prop); @@ -524,6 +532,7 @@ JSTaggedValue SlowRuntimeStub::IsInDyn(JSThread *thread, JSTaggedValue prop, JST JSTaggedValue SlowRuntimeStub::InstanceofDyn(JSThread *thread, JSTaggedValue obj, JSTaggedValue target) { + INTERPRETER_TRACE(thread, InstanceofDyn); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle objHandle(thread, obj); @@ -673,6 +682,7 @@ JSTaggedValue SlowRuntimeStub::NewObjSpreadDyn(JSThread *thread, JSTaggedValue f void SlowRuntimeStub::ThrowUndefinedIfHole(JSThread *thread, JSTaggedValue obj) { + INTERPRETER_TRACE(thread, ThrowUndefinedIfHole); [[maybe_unused]] EcmaHandleScope handleScope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); @@ -685,6 +695,7 @@ void SlowRuntimeStub::ThrowUndefinedIfHole(JSThread *thread, JSTaggedValue obj) JSTaggedValue SlowRuntimeStub::ThrowIfSuperNotCorrectCall(JSThread *thread, uint16_t index, JSTaggedValue thisValue) { + INTERPRETER_TRACE(thread, ThrowIfSuperNotCorrectCall); [[maybe_unused]] EcmaHandleScope handleScope(thread); if (index == 0 && (thisValue.IsUndefined() || thisValue.IsHole())) { @@ -698,6 +709,7 @@ JSTaggedValue SlowRuntimeStub::ThrowIfSuperNotCorrectCall(JSThread *thread, uint void SlowRuntimeStub::ThrowIfNotObject(JSThread *thread) { + INTERPRETER_TRACE(thread, ThrowIfNotObject); [[maybe_unused]] EcmaHandleScope handleScope(thread); THROW_TYPE_ERROR(thread, "Inner return result is not object"); @@ -705,6 +717,7 @@ void SlowRuntimeStub::ThrowIfNotObject(JSThread *thread) void SlowRuntimeStub::ThrowThrowNotExists(JSThread *thread) { + INTERPRETER_TRACE(thread, ThrowThrowNotExists); [[maybe_unused]] EcmaHandleScope handleScope(thread); THROW_TYPE_ERROR(thread, "Throw method is not defined"); @@ -712,6 +725,7 @@ void SlowRuntimeStub::ThrowThrowNotExists(JSThread *thread) void SlowRuntimeStub::ThrowPatternNonCoercible(JSThread *thread) { + INTERPRETER_TRACE(thread, ThrowPatternNonCoercible); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle msg(thread->GlobalConstants()->GetHandledObjNotCoercibleString()); @@ -740,6 +754,32 @@ JSTaggedValue SlowRuntimeStub::StOwnByName(JSThread *thread, JSTaggedValue obj, return JSTaggedValue::True(); } +JSTaggedValue SlowRuntimeStub::StOwnByNameWithNameSet(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, + JSTaggedValue value) +{ + INTERPRETER_TRACE(thread, StOwnByNameDyn); + [[maybe_unused]] EcmaHandleScope handleScope(thread); + + JSHandle objHandle(thread, obj); + JSHandle propHandle(thread, prop); + JSHandle valueHandle(thread, value); + ASSERT(propHandle->IsStringOrSymbol()); + + JSHandle propKey = JSTaggedValue::ToPropertyKey(thread, propHandle); + + // property in class is non-enumerable + bool enumerable = !(objHandle->IsClassPrototype() || objHandle->IsClassConstructor()); + + PropertyDescriptor desc(thread, valueHandle, true, enumerable, true); + bool ret = JSTaggedValue::DefineOwnProperty(thread, objHandle, propHandle, desc); + if (!ret) { + return ThrowTypeError(thread, "SetOwnByNameWithNameSet failed"); + } + JSFunctionBase::SetFunctionName(thread, JSHandle::Cast(valueHandle), propKey, + JSHandle(thread, JSTaggedValue::Undefined())); + return JSTaggedValue::True(); +} + JSTaggedValue SlowRuntimeStub::StOwnByIndex(JSThread *thread, JSTaggedValue obj, uint32_t idx, JSTaggedValue value) { INTERPRETER_TRACE(thread, StOwnByIdDyn); @@ -763,6 +803,7 @@ JSTaggedValue SlowRuntimeStub::StOwnByIndex(JSThread *thread, JSTaggedValue obj, JSTaggedValue SlowRuntimeStub::StOwnByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, JSTaggedValue value) { [[maybe_unused]] EcmaHandleScope handleScope(thread); + INTERPRETER_TRACE(thread, StOwnByValueDyn); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); JSHandle objHandle(thread, obj); @@ -783,6 +824,33 @@ JSTaggedValue SlowRuntimeStub::StOwnByValue(JSThread *thread, JSTaggedValue obj, if (!ret) { return ThrowTypeError(thread, "StOwnByValue failed"); } + return JSTaggedValue::True(); +} + +JSTaggedValue SlowRuntimeStub::StOwnByValueWithNameSet(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, + JSTaggedValue value) +{ + [[maybe_unused]] EcmaHandleScope handleScope(thread); + INTERPRETER_TRACE(thread, StOwnByValueDyn); + const GlobalEnvConstants *globalConst = thread->GlobalConstants(); + JSHandle objHandle(thread, obj); + JSHandle keyHandle(thread, key); + JSHandle valueHandle(thread, value); + + if (objHandle->IsClassConstructor() && + JSTaggedValue::SameValue(keyHandle, globalConst->GetHandledPrototypeString())) { + return ThrowTypeError(thread, "In a class, static property named 'prototype' throw a TypeError"); + } + + // property in class is non-enumerable + bool enumerable = !(objHandle->IsClassPrototype() || objHandle->IsClassConstructor()); + + PropertyDescriptor desc(thread, valueHandle, true, enumerable, true); + JSMutableHandle propKey(JSTaggedValue::ToPropertyKey(thread, keyHandle)); + bool ret = JSTaggedValue::DefineOwnProperty(thread, objHandle, propKey, desc); + if (!ret) { + return ThrowTypeError(thread, "StOwnByValueWithNameSet failed"); + } if (valueHandle->IsJSFunction()) { if (propKey->IsNumber()) { propKey.Update(base::NumberHelper::NumberToString(thread, propKey.GetTaggedValue()).GetTaggedValue()); @@ -795,6 +863,7 @@ JSTaggedValue SlowRuntimeStub::StOwnByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue SlowRuntimeStub::CreateEmptyArray(JSThread *thread, ObjectFactory *factory, JSHandle globalEnv) { + INTERPRETER_TRACE(thread, CreateEmptyArray); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle builtinObj(globalEnv->GetArrayFunction()); @@ -805,6 +874,7 @@ JSTaggedValue SlowRuntimeStub::CreateEmptyArray(JSThread *thread, ObjectFactory JSTaggedValue SlowRuntimeStub::CreateEmptyObject(JSThread *thread, ObjectFactory *factory, JSHandle globalEnv) { + INTERPRETER_TRACE(thread, CreateEmptyObject); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle builtinObj(globalEnv->GetObjectFunction()); @@ -814,6 +884,7 @@ JSTaggedValue SlowRuntimeStub::CreateEmptyObject(JSThread *thread, ObjectFactory JSTaggedValue SlowRuntimeStub::CreateObjectWithBuffer(JSThread *thread, ObjectFactory *factory, JSObject *literal) { + INTERPRETER_TRACE(thread, CreateObjectWithBuffer); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle obj(thread, literal); @@ -826,6 +897,7 @@ JSTaggedValue SlowRuntimeStub::CreateObjectWithBuffer(JSThread *thread, ObjectFa JSTaggedValue SlowRuntimeStub::CreateObjectHavingMethod(JSThread *thread, ObjectFactory *factory, JSObject *literal, JSTaggedValue env, ConstantPool *constpool) { + INTERPRETER_TRACE(thread, CreateObjectHavingMethod); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle obj(thread, literal); @@ -838,6 +910,7 @@ JSTaggedValue SlowRuntimeStub::CreateObjectHavingMethod(JSThread *thread, Object JSTaggedValue SlowRuntimeStub::SetObjectWithProto(JSThread *thread, JSTaggedValue proto, JSTaggedValue obj) { + INTERPRETER_TRACE(thread, SetObjectWithProto); [[maybe_unused]] EcmaHandleScope handleScope(thread); if (!proto.IsECMAObject() && !proto.IsNull()) { @@ -852,6 +925,7 @@ JSTaggedValue SlowRuntimeStub::SetObjectWithProto(JSThread *thread, JSTaggedValu JSTaggedValue SlowRuntimeStub::IterNext(JSThread *thread, JSTaggedValue iter) { + INTERPRETER_TRACE(thread, IterNext); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle iterHandle(thread, iter); @@ -862,6 +936,7 @@ JSTaggedValue SlowRuntimeStub::IterNext(JSThread *thread, JSTaggedValue iter) JSTaggedValue SlowRuntimeStub::CloseIterator(JSThread *thread, JSTaggedValue iter) { + INTERPRETER_TRACE(thread, CloseIterator); [[maybe_unused]] EcmaHandleScope handleScope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); @@ -888,6 +963,7 @@ JSTaggedValue SlowRuntimeStub::CloseIterator(JSThread *thread, JSTaggedValue ite JSTaggedValue SlowRuntimeStub::ImportModule([[maybe_unused]] JSThread *thread, [[maybe_unused]] JSTaggedValue moduleName) { + INTERPRETER_TRACE(thread, ImportModule); [[maybe_unused]] EcmaHandleScope scope(thread); JSHandle name(thread, moduleName); JSHandle module = thread->GetEcmaVM()->GetModuleByName(name); @@ -897,6 +973,7 @@ JSTaggedValue SlowRuntimeStub::ImportModule([[maybe_unused]] JSThread *thread, void SlowRuntimeStub::StModuleVar([[maybe_unused]] JSThread *thread, [[maybe_unused]] JSTaggedValue exportName, [[maybe_unused]] JSTaggedValue exportObj) { + INTERPRETER_TRACE(thread, StModuleVar); [[maybe_unused]] EcmaHandleScope scope(thread); JSHandle name(thread, exportName); JSHandle value(thread, exportObj); @@ -905,6 +982,7 @@ void SlowRuntimeStub::StModuleVar([[maybe_unused]] JSThread *thread, [[maybe_unu void SlowRuntimeStub::CopyModule(JSThread *thread, JSTaggedValue srcModule) { + INTERPRETER_TRACE(thread, CopyModule); [[maybe_unused]] EcmaHandleScope scope(thread); JSHandle srcModuleObj(thread, srcModule); thread->GetEcmaVM()->GetModuleManager()->CopyModule(thread, srcModuleObj); @@ -914,6 +992,7 @@ JSTaggedValue SlowRuntimeStub::LdModvarByName([[maybe_unused]] JSThread *thread, [[maybe_unused]] JSTaggedValue moduleObj, [[maybe_unused]] JSTaggedValue itemName) { + INTERPRETER_TRACE(thread, LdModvarByName); [[maybe_unused]] EcmaHandleScope scope(thread); JSHandle module(thread, moduleObj); JSHandle item(thread, itemName); @@ -923,6 +1002,7 @@ JSTaggedValue SlowRuntimeStub::LdModvarByName([[maybe_unused]] JSThread *thread, JSTaggedValue SlowRuntimeStub::CreateRegExpWithLiteral(JSThread *thread, JSTaggedValue pattern, uint8_t flags) { + INTERPRETER_TRACE(thread, CreateRegExpWithLiteral); [[maybe_unused]] EcmaHandleScope handleScope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); @@ -962,6 +1042,7 @@ JSTaggedValue SlowRuntimeStub::CreateRegExpWithLiteral(JSThread *thread, JSTagge JSTaggedValue SlowRuntimeStub::CreateArrayWithBuffer(JSThread *thread, ObjectFactory *factory, JSArray *literal) { + INTERPRETER_TRACE(thread, CreateArrayWithBuffer); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle array(thread, literal); @@ -973,6 +1054,7 @@ JSTaggedValue SlowRuntimeStub::CreateArrayWithBuffer(JSThread *thread, ObjectFac JSTaggedValue SlowRuntimeStub::GetTemplateObject(JSThread *thread, JSTaggedValue literal) { + INTERPRETER_TRACE(thread, GetTemplateObject); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle templateLiteral(thread, literal); @@ -983,6 +1065,7 @@ JSTaggedValue SlowRuntimeStub::GetTemplateObject(JSThread *thread, JSTaggedValue JSTaggedValue SlowRuntimeStub::GetNextPropName(JSThread *thread, JSTaggedValue iter) { + INTERPRETER_TRACE(thread, GetNextPropName); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle iterator(thread, iter); @@ -995,6 +1078,7 @@ JSTaggedValue SlowRuntimeStub::GetNextPropName(JSThread *thread, JSTaggedValue i JSTaggedValue SlowRuntimeStub::CopyDataProperties(JSThread *thread, JSTaggedValue dst, JSTaggedValue src) { + INTERPRETER_TRACE(thread, CopyDataProperties); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle dstHandle(thread, dst); @@ -1022,6 +1106,7 @@ JSTaggedValue SlowRuntimeStub::CopyDataProperties(JSThread *thread, JSTaggedValu JSTaggedValue SlowRuntimeStub::GetIteratorNext(JSThread *thread, JSTaggedValue obj, JSTaggedValue method) { + INTERPRETER_TRACE(thread, GetIteratorNext); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle iter(thread, obj); @@ -1039,7 +1124,7 @@ JSTaggedValue SlowRuntimeStub::GetIteratorNext(JSThread *thread, JSTaggedValue o JSTaggedValue SlowRuntimeStub::GetUnmapedArgs(JSThread *thread, JSTaggedType *sp, uint32_t actualNumArgs, uint32_t startIdx) { - INTERPRETER_TRACE(thread, GetUnmappedArgs); + INTERPRETER_TRACE(thread, GetUnmapedArgs); [[maybe_unused]] EcmaHandleScope handleScope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); @@ -1292,12 +1377,14 @@ JSTaggedValue SlowRuntimeStub::TryLdGlobalByName(JSThread *thread, JSTaggedValue JSTaggedValue SlowRuntimeStub::TryStGlobalByName(JSThread *thread, JSTaggedValue prop) { + INTERPRETER_TRACE(thread, TryStGlobalByName); // If fast path is fail, not need slow path, just throw error. return ThrowReferenceError(thread, prop, " is not defined"); } JSTaggedValue SlowRuntimeStub::LdGlobalVar(JSThread *thread, JSTaggedValue global, JSTaggedValue prop) { + INTERPRETER_TRACE(thread, LdGlobalVar); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle objHandle(thread, global.GetTaggedObject()->GetClass()->GetPrototype()); @@ -1309,6 +1396,7 @@ JSTaggedValue SlowRuntimeStub::LdGlobalVar(JSThread *thread, JSTaggedValue globa JSTaggedValue SlowRuntimeStub::StGlobalVar(JSThread *thread, JSTaggedValue prop, JSTaggedValue value) { + INTERPRETER_TRACE(thread, StGlobalVar); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle global(thread, thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalObject()); @@ -1322,6 +1410,7 @@ JSTaggedValue SlowRuntimeStub::StGlobalVar(JSThread *thread, JSTaggedValue prop, JSTaggedValue SlowRuntimeStub::TryUpdateGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value) { + INTERPRETER_TRACE(thread, TryUpdateGlobalRecord); [[maybe_unused]] EcmaHandleScope handleScope(thread); EcmaVM *vm = thread->GetEcmaVM(); @@ -1338,6 +1427,7 @@ JSTaggedValue SlowRuntimeStub::TryUpdateGlobalRecord(JSThread *thread, JSTaggedV JSTaggedValue SlowRuntimeStub::LdGlobalRecord(JSThread *thread, JSTaggedValue key, bool *found) { + INTERPRETER_TRACE(thread, LdGlobalRecord); [[maybe_unused]] EcmaHandleScope handleScope(thread); EcmaVM *vm = thread->GetEcmaVM(); @@ -1353,6 +1443,7 @@ JSTaggedValue SlowRuntimeStub::LdGlobalRecord(JSThread *thread, JSTaggedValue ke JSTaggedValue SlowRuntimeStub::StGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value, bool isConst) { + INTERPRETER_TRACE(thread, StGlobalRecord); [[maybe_unused]] EcmaHandleScope handleScope(thread); EcmaVM *vm = thread->GetEcmaVM(); @@ -1375,6 +1466,7 @@ JSTaggedValue SlowRuntimeStub::StGlobalRecord(JSThread *thread, JSTaggedValue pr JSTaggedValue SlowRuntimeStub::ThrowReferenceError(JSThread *thread, JSTaggedValue prop, const char *desc) { + INTERPRETER_TRACE(thread, ThrowReferenceError); [[maybe_unused]] EcmaHandleScope handleScope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle propName = JSTaggedValue::ToString(thread, JSHandle(thread, prop)); @@ -1388,6 +1480,7 @@ JSTaggedValue SlowRuntimeStub::ThrowReferenceError(JSThread *thread, JSTaggedVal JSTaggedValue SlowRuntimeStub::ThrowTypeError(JSThread *thread, const char *message) { + INTERPRETER_TRACE(thread, ThrowTypeError); [[maybe_unused]] EcmaHandleScope handleScope(thread); ASSERT_NO_ABRUPT_COMPLETION(thread); THROW_TYPE_ERROR_AND_RETURN(thread, message, JSTaggedValue::Exception()); @@ -1395,6 +1488,7 @@ JSTaggedValue SlowRuntimeStub::ThrowTypeError(JSThread *thread, const char *mess JSTaggedValue SlowRuntimeStub::ThrowSyntaxError(JSThread *thread, const char *message) { + INTERPRETER_TRACE(thread, ThrowSyntaxError); [[maybe_unused]] EcmaHandleScope handleScope(thread); ASSERT_NO_ABRUPT_COMPLETION(thread); THROW_SYNTAX_ERROR_AND_RETURN(thread, message, JSTaggedValue::Exception()); @@ -1514,6 +1608,7 @@ JSTaggedValue SlowRuntimeStub::DefinefuncDyn(JSThread *thread, JSFunction *func) JSTaggedValue SlowRuntimeStub::NewClassFunc(JSThread *thread, JSFunction *func) { + INTERPRETER_TRACE(thread, NewClassFunc); [[maybe_unused]] EcmaHandleScope handleScope(thread); auto method = func->GetCallTarget(); @@ -1528,6 +1623,7 @@ JSTaggedValue SlowRuntimeStub::NewClassFunc(JSThread *thread, JSFunction *func) JSTaggedValue SlowRuntimeStub::DefineClass(JSThread *thread, JSFunction *func, TaggedArray *literal, JSTaggedValue proto, JSTaggedValue lexenv, ConstantPool *constpool) { + INTERPRETER_TRACE(thread, DefineClass); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); @@ -1652,6 +1748,7 @@ JSTaggedValue SlowRuntimeStub::DefineClass(JSThread *thread, JSFunction *func, T JSTaggedValue SlowRuntimeStub::SuperCall(JSThread *thread, JSTaggedValue func, JSTaggedValue newTarget, uint16_t firstVRegIdx, uint16_t length) { + INTERPRETER_TRACE(thread, SuperCall); [[maybe_unused]] EcmaHandleScope handleScope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); EcmaFrameHandler frameHandler(thread); @@ -1677,6 +1774,7 @@ JSTaggedValue SlowRuntimeStub::SuperCall(JSThread *thread, JSTaggedValue func, J JSTaggedValue SlowRuntimeStub::SuperCallSpread(JSThread *thread, JSTaggedValue func, JSTaggedValue newTarget, JSTaggedValue array) { + INTERPRETER_TRACE(thread, SuperCallSpread); [[maybe_unused]] EcmaHandleScope handleScope(thread); EcmaFrameHandler frameHandler(thread); @@ -1699,6 +1797,7 @@ JSTaggedValue SlowRuntimeStub::SuperCallSpread(JSThread *thread, JSTaggedValue f JSTaggedValue SlowRuntimeStub::DefineMethod(JSThread *thread, JSFunction *func, JSTaggedValue homeObject) { + INTERPRETER_TRACE(thread, DefineMethod); [[maybe_unused]] EcmaHandleScope handleScope(thread); ASSERT(homeObject.IsECMAObject()); JSHandle homeObjectHandle(thread, homeObject); @@ -1716,6 +1815,7 @@ JSTaggedValue SlowRuntimeStub::DefineMethod(JSThread *thread, JSFunction *func, JSTaggedValue SlowRuntimeStub::LdSuperByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, JSTaggedValue thisFunc) { + INTERPRETER_TRACE(thread, LdSuperByValue); [[maybe_unused]] EcmaHandleScope handleScope(thread); ASSERT(thisFunc.IsJSFunction()); // get Homeobject form function @@ -1740,6 +1840,7 @@ JSTaggedValue SlowRuntimeStub::LdSuperByValue(JSThread *thread, JSTaggedValue ob JSTaggedValue SlowRuntimeStub::StSuperByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, JSTaggedValue value, JSTaggedValue thisFunc) { + INTERPRETER_TRACE(thread, StSuperByValue); [[maybe_unused]] EcmaHandleScope handleScope(thread); ASSERT(thisFunc.IsJSFunction()); // get Homeobject form function @@ -1794,6 +1895,7 @@ JSTaggedValue SlowRuntimeStub::GetCallSpreadArgs(JSThread *thread, JSTaggedValue void SlowRuntimeStub::ThrowDeleteSuperProperty(JSThread *thread) { + INTERPRETER_TRACE(thread, ThrowDeleteSuperProperty); [[maybe_unused]] EcmaHandleScope handleScope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); @@ -1804,6 +1906,7 @@ void SlowRuntimeStub::ThrowDeleteSuperProperty(JSThread *thread) JSTaggedValue SlowRuntimeStub::NotifyInlineCache(JSThread *thread, JSFunction *func, JSMethod *method) { + INTERPRETER_TRACE(thread, NotifyInlineCache); uint32_t icSlotSize = method->GetSlotSize(); if (icSlotSize > 0 && icSlotSize < ProfileTypeInfo::INVALID_SLOT_INDEX) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); diff --git a/ecmascript/interpreter/slow_runtime_stub.h b/ecmascript/interpreter/slow_runtime_stub.h index 5523c60564e922c08ed50a2d90c3bb170215671e..afa120f0ce5363cf0377931671767a785f508afd 100644 --- a/ecmascript/interpreter/slow_runtime_stub.h +++ b/ecmascript/interpreter/slow_runtime_stub.h @@ -79,8 +79,12 @@ public: static void ThrowDeleteSuperProperty(JSThread *thread); static JSTaggedValue StOwnByName(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, JSTaggedValue value); + static JSTaggedValue StOwnByNameWithNameSet(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, + JSTaggedValue value); static JSTaggedValue StOwnByIndex(JSThread *thread, JSTaggedValue obj, uint32_t idx, JSTaggedValue value); static JSTaggedValue StOwnByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, JSTaggedValue value); + static JSTaggedValue StOwnByValueWithNameSet(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, + JSTaggedValue value); static JSTaggedValue CreateEmptyArray(JSThread *thread, ObjectFactory *factory, JSHandle globalEnv); static JSTaggedValue CreateEmptyObject(JSThread *thread, ObjectFactory *factory, JSHandle globalEnv); static JSTaggedValue CreateObjectWithBuffer(JSThread *thread, ObjectFactory *factory, JSObject *literal); diff --git a/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl b/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl index bb5386e842a7b1828d9389d546d363f3dfcfdbdd..5aaacdc93266af639b912df0b1ad5162fc3a554f 100644 --- a/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl +++ b/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl @@ -144,6 +144,8 @@ &&DEBUG_HANDLE_STCONSTTOGLOBALRECORD_PREF_ID32, &&DEBUG_HANDLE_STLETTOGLOBALRECORD_PREF_ID32, &&DEBUG_HANDLE_STCLASSTOGLOBALRECORD_PREF_ID32, + &&DEBUG_HANDLE_STOWNBYVALUEWITHNAMESET_PREF_V8_V8, + &&DEBUG_HANDLE_STOWNBYNAMEWITHNAMESET_PREF_ID32_V8, &&DEBUG_HANDLE_MOV_DYN_V8_V8, &&DEBUG_HANDLE_MOV_DYN_V16_V16, &&DEBUG_HANDLE_LDA_STR_ID32, @@ -266,6 +268,4 @@ &&DEBUG_HANDLE_OVERFLOW, &&DEBUG_HANDLE_OVERFLOW, &&DEBUG_HANDLE_OVERFLOW, - &&DEBUG_HANDLE_OVERFLOW, - &&DEBUG_HANDLE_OVERFLOW, - &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, \ No newline at end of file diff --git a/ecmascript/interpreter/templates/debugger_instruction_handler.inl b/ecmascript/interpreter/templates/debugger_instruction_handler.inl index 60d3cac4a82b366bd14e74e1ef0b85a7bf6e0a19..e578e5cfebc0112b1cc23d32b2a883ac7b3c05a8 100644 --- a/ecmascript/interpreter/templates/debugger_instruction_handler.inl +++ b/ecmascript/interpreter/templates/debugger_instruction_handler.inl @@ -668,6 +668,16 @@ NOTIFY_DEBUGGER_EVENT(); REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STCLASSTOGLOBALRECORD_PREF_ID32); } + HANDLE_OPCODE(DEBUG_HANDLE_STOWNBYVALUEWITHNAMESET_PREF_V8_V8) + { + NOTIFY_DEBUGGER_EVENT(); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOWNBYVALUEWITHNAMESET_PREF_V8_V8); + } + HANDLE_OPCODE(DEBUG_HANDLE_STOWNBYNAMEWITHNAMESET_PREF_ID32_V8) + { + NOTIFY_DEBUGGER_EVENT(); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOWNBYNAMEWITHNAMESET_PREF_ID32_V8); + } HANDLE_OPCODE(DEBUG_HANDLE_MOV_DYN_V8_V8) { NOTIFY_DEBUGGER_EVENT(); diff --git a/ecmascript/interpreter/templates/instruction_dispatch.inl b/ecmascript/interpreter/templates/instruction_dispatch.inl index a9599b0c7a085d7ba8a7a26e8808d2bf800d9b1a..2462b523597738826ddbf06720d5c4543b814e4c 100644 --- a/ecmascript/interpreter/templates/instruction_dispatch.inl +++ b/ecmascript/interpreter/templates/instruction_dispatch.inl @@ -144,6 +144,8 @@ &&HANDLE_STCONSTTOGLOBALRECORD_PREF_ID32, &&HANDLE_STLETTOGLOBALRECORD_PREF_ID32, &&HANDLE_STCLASSTOGLOBALRECORD_PREF_ID32, + &&HANDLE_STOWNBYVALUEWITHNAMESET_PREF_V8_V8, + &&HANDLE_STOWNBYNAMEWITHNAMESET_PREF_ID32_V8, &&HANDLE_MOV_DYN_V8_V8, &&HANDLE_MOV_DYN_V16_V16, &&HANDLE_LDA_STR_ID32, @@ -267,5 +269,4 @@ &&HANDLE_OVERFLOW, &&HANDLE_OVERFLOW, &&HANDLE_OVERFLOW, - &&HANDLE_OVERFLOW, - &&HANDLE_OVERFLOW, + diff --git a/ecmascript/js_object.h b/ecmascript/js_object.h index 127658b16b22c08e96218626b778c752bbb04b9f..d0e6be3516cf7785f17b7a6918ecc73e70bcd0c3 100644 --- a/ecmascript/js_object.h +++ b/ecmascript/js_object.h @@ -359,7 +359,7 @@ public: class JSObject : public ECMAObject { public: - static constexpr int MIN_ELEMENTS_LENGTH = 16; + static constexpr int MIN_ELEMENTS_LENGTH = 3; static constexpr int MIN_PROPERTIES_LENGTH = JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS; static constexpr int PROPERTIES_GROW_SIZE = 4; static constexpr int FAST_ELEMENTS_FACTOR = 3; diff --git a/ecmascript/runtime_call_id.h b/ecmascript/runtime_call_id.h index 2539364caafd5e36ff7d2adbc43b353080e26dc7..a98164358f7ee318ea5ba2bfa3f223d7d01d4cc2 100644 --- a/ecmascript/runtime_call_id.h +++ b/ecmascript/runtime_call_id.h @@ -83,7 +83,7 @@ namespace panda::ecmascript { V(RefeqDyn) \ V(TypeofDyn) \ V(LdnewobjrangeDyn) \ - V(IsinDyn) \ + V(IsInDyn) \ V(InstanceofDyn) \ V(NewobjspreadDyn) \ V(CallArg0Dyn) \ @@ -97,7 +97,6 @@ namespace panda::ecmascript { V(StlexvarDyn) \ V(LdlexvarDyn) \ V(LdlexenvDyn) \ - V(GetUnmappedArgs) \ V(GetPropIterator) \ V(CreateIterResultObj) \ V(DefineGeneratorFunc) \ @@ -138,6 +137,76 @@ namespace panda::ecmascript { V(CompressCollector_RunPhases) \ V(OldSpaceCollector_RunPhases) \ V(SemiSpaceCollector_RunPhases) \ + V(LoadGlobalICByName) \ + V(StoreGlobalICByName) \ + V(StoreICWithHandler) \ + V(StorePrototype) \ + V(StoreWithTransition) \ + V(StoreField) \ + V(StoreGlobal) \ + V(LoadPrototype) \ + V(LoadICWithHandler) \ + V(StoreElement) \ + V(CallGetter) \ + V(CallSetter) \ + V(AddPropertyByName) \ + V(AddPropertyByIndex) \ + V(GetPropertyByIndex) \ + V(GetPropertyByValue) \ + V(SetPropertyByName) \ + V(SetPropertyByIndex) \ + V(SetPropertyByValue) \ + V(FastTypeOf) \ + V(FastSetPropertyByIndex) \ + V(FastSetPropertyByValue) \ + V(FastGetPropertyByName) \ + V(FastGetPropertyByValue) \ + V(FastGetPropertyByIndex) \ + V(NewLexicalEnvDyn) \ + V(SetElement) \ + V(SetGlobalOwnProperty) \ + V(SetOwnPropertyByName) \ + V(SetOwnElement) \ + V(FastSetProperty) \ + V(FastGetProperty) \ + V(FindOwnProperty) \ + V(HasOwnProperty) \ + V(ExecuteNative) \ + V(Execute) \ + V(ToJSTaggedValueWithInt32) \ + V(ToJSTaggedValueWithUint32) \ + V(ThrowIfSuperNotCorrectCall) \ + V(CreateEmptyArray) \ + V(CreateEmptyObject) \ + V(CreateObjectWithBuffer) \ + V(CreateObjectHavingMethod) \ + V(SetObjectWithProto) \ + V(ImportModule) \ + V(StModuleVar) \ + V(CopyModule) \ + V(LdModvarByName) \ + V(CreateRegExpWithLiteral) \ + V(CreateArrayWithBuffer) \ + V(GetNextPropName) \ + V(CopyDataProperties) \ + V(GetUnmapedArgs) \ + V(TryStGlobalByName) \ + V(LdGlobalVar) \ + V(StGlobalVar) \ + V(TryUpdateGlobalRecord) \ + V(LdGlobalRecord) \ + V(StGlobalRecord) \ + V(ThrowReferenceError) \ + V(ThrowTypeError) \ + V(ThrowSyntaxError) \ + V(NewClassFunc) \ + V(DefineClass) \ + V(SuperCall) \ + V(SuperCallSpread) \ + V(DefineMethod) \ + V(LdSuperByValue) \ + V(StSuperByValue) \ + V(ThrowDeleteSuperProperty) \ V(GetIteratorNext) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)