mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 16:13:49 +00:00
Merge remote-tracking branch 'open/master'
Change-Id: Idf4c31507cf0d772e81d39bb6b9ab17436076aeb Signed-off-by: wanyanglan <wanyanglan1@huawei.com>
This commit is contained in:
commit
7fd302d7a4
17
BUILD.gn
17
BUILD.gn
@ -123,11 +123,11 @@ source_set("libark_js_intl_static") {
|
||||
deps = [
|
||||
"$ark_root/libpandabase:libarkbase",
|
||||
"$ark_root/libpandafile:libarkfile",
|
||||
"$ark_root/runtime:arkruntime_header_deps",
|
||||
"//third_party/icu/icu4c:shared_icui18n",
|
||||
"//third_party/icu/icu4c:shared_icuuc",
|
||||
sdk_libc_secshared_dep,
|
||||
]
|
||||
deps += arkruntime_header_gen_deps
|
||||
}
|
||||
|
||||
config("ark_jsruntime_common_config") {
|
||||
@ -436,14 +436,14 @@ source_set("libark_jsruntime_test_static") {
|
||||
sources += intl_sources
|
||||
|
||||
deps = [
|
||||
":copy_resource_xml",
|
||||
":copy_ark_resource",
|
||||
"$ark_root/libpandabase:libarkbase",
|
||||
"$ark_root/libpandafile:libarkfile",
|
||||
"$ark_root/runtime:arkruntime_header_deps",
|
||||
"//third_party/icu/icu4c:shared_icui18n",
|
||||
"//third_party/icu/icu4c:shared_icuuc",
|
||||
sdk_libc_secshared_dep,
|
||||
]
|
||||
deps += arkruntime_header_gen_deps
|
||||
|
||||
if (is_debug && is_linux && (current_cpu == "x86" || current_cpu == "x64") &&
|
||||
run_with_asan) {
|
||||
@ -478,25 +478,28 @@ ohos_shared_library("libark_jsruntime_test") {
|
||||
subsystem_name = "test"
|
||||
}
|
||||
|
||||
action("copy_resource_xml") {
|
||||
action("copy_ark_resource") {
|
||||
deps = []
|
||||
|
||||
script = "//ark/js_runtime/test/copy_resource.py"
|
||||
|
||||
src_path = "//ark/js_runtime/test/resource/js_runtime/"
|
||||
src_path = "//ark/js_runtime/test/resource/js_runtime"
|
||||
src_xml = "ohos_test.xml"
|
||||
dst_path = "//ark/test/resource/js_runtime/"
|
||||
|
||||
args = [
|
||||
"--src-path",
|
||||
rebase_path(src_path),
|
||||
rebase_path("${src_path}/"),
|
||||
"--src-xml",
|
||||
src_xml,
|
||||
"--dst-path",
|
||||
rebase_path(dst_path),
|
||||
]
|
||||
|
||||
inputs = [ src_path + src_xml ]
|
||||
inputs = [
|
||||
src_path,
|
||||
"${src_path}/${src_xml}",
|
||||
]
|
||||
outputs = [ "$target_out_dir" ]
|
||||
}
|
||||
|
||||
|
@ -399,14 +399,13 @@ JSTaggedValue BuiltinsPromise::PerformPromiseThen(JSThread *thread, const JSHand
|
||||
if (JSTaggedValue::SameValue(promise->GetPromiseState(),
|
||||
JSTaggedValue(static_cast<int32_t>(PromiseStatus::PENDING)))) {
|
||||
JSHandle<TaggedQueue> fulfillReactions(thread, promise->GetPromiseFulfillReactions());
|
||||
auto result =
|
||||
JSTaggedValue(TaggedQueue::Push(thread, fulfillReactions, JSHandle<JSTaggedValue>::Cast(fulfillReaction)));
|
||||
promise->SetPromiseFulfillReactions(thread, result);
|
||||
TaggedQueue *newQueue =
|
||||
TaggedQueue::Push(thread, fulfillReactions, JSHandle<JSTaggedValue>::Cast(fulfillReaction));
|
||||
promise->SetPromiseFulfillReactions(thread, JSTaggedValue(newQueue));
|
||||
|
||||
JSHandle<TaggedQueue> rejectReactions(thread, promise->GetPromiseRejectReactions());
|
||||
result =
|
||||
JSTaggedValue(TaggedQueue::Push(thread, rejectReactions, JSHandle<JSTaggedValue>::Cast(rejectReaction)));
|
||||
promise->SetPromiseRejectReactions(thread, result);
|
||||
newQueue = TaggedQueue::Push(thread, rejectReactions, JSHandle<JSTaggedValue>::Cast(rejectReaction));
|
||||
promise->SetPromiseRejectReactions(thread, JSTaggedValue(newQueue));
|
||||
} else if (JSTaggedValue::SameValue(promise->GetPromiseState(),
|
||||
JSTaggedValue(static_cast<int32_t>(PromiseStatus::FULFILLED)))) {
|
||||
JSHandle<TaggedArray> argv = factory->NewTaggedArray(2); // 2: 2 means two args stored in array
|
||||
@ -414,7 +413,7 @@ JSTaggedValue BuiltinsPromise::PerformPromiseThen(JSThread *thread, const JSHand
|
||||
argv->Set(thread, 1, promise->GetPromiseResult());
|
||||
|
||||
JSHandle<JSFunction> promiseReactionsJob(env->GetPromiseReactionJob());
|
||||
job->EnqueueJob(thread, job::QueueType::QUEUE_PROMISE, promiseReactionsJob, argv);
|
||||
job::MicroJobQueue::EnqueueJob(thread, job, job::QueueType::QUEUE_PROMISE, promiseReactionsJob, argv);
|
||||
} else if (JSTaggedValue::SameValue(promise->GetPromiseState(),
|
||||
JSTaggedValue(static_cast<int32_t>(PromiseStatus::REJECTED)))) {
|
||||
JSHandle<TaggedArray> argv = factory->NewTaggedArray(2); // 2: 2 means two args stored in array
|
||||
@ -422,7 +421,7 @@ JSTaggedValue BuiltinsPromise::PerformPromiseThen(JSThread *thread, const JSHand
|
||||
argv->Set(thread, 1, promise->GetPromiseResult());
|
||||
|
||||
JSHandle<JSFunction> promiseReactionsJob(env->GetPromiseReactionJob());
|
||||
job->EnqueueJob(thread, job::QueueType::QUEUE_PROMISE, promiseReactionsJob, argv);
|
||||
job::MicroJobQueue::EnqueueJob(thread, job, job::QueueType::QUEUE_PROMISE, promiseReactionsJob, argv);
|
||||
}
|
||||
return capability->GetPromise();
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ JSTaggedValue BuiltinsPromiseHandler::Resolve(EcmaRuntimeCallInfo *argv)
|
||||
|
||||
JSHandle<JSFunction> promiseResolveThenableJob(env->GetPromiseResolveThenableJob());
|
||||
JSHandle<job::MicroJobQueue> job = thread->GetEcmaVM()->GetMicroJobQueue();
|
||||
job->EnqueueJob(thread, job::QueueType::QUEUE_PROMISE, promiseResolveThenableJob, arguments);
|
||||
job::MicroJobQueue::EnqueueJob(thread, job, job::QueueType::QUEUE_PROMISE, promiseResolveThenableJob, arguments);
|
||||
|
||||
// 13. Return undefined.
|
||||
return JSTaggedValue::Undefined();
|
||||
|
@ -449,7 +449,7 @@ HWTEST_F_L0(BuiltinsPromiseTest, Race2)
|
||||
*/
|
||||
auto microJobQueue = EcmaVM::Cast(instance)->GetMicroJobQueue();
|
||||
if (!thread->HasPendingException()) {
|
||||
microJobQueue->ExecutePendingJob(thread);
|
||||
job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
|
||||
}
|
||||
}
|
||||
|
||||
@ -550,7 +550,7 @@ HWTEST_F_L0(BuiltinsPromiseTest, All)
|
||||
*/
|
||||
auto microJobQueue = EcmaVM::Cast(instance)->GetMicroJobQueue();
|
||||
if (!thread->HasPendingException()) {
|
||||
microJobQueue->ExecutePendingJob(thread);
|
||||
job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
|
||||
}
|
||||
}
|
||||
|
||||
@ -606,7 +606,7 @@ HWTEST_F_L0(BuiltinsPromiseTest, Catch)
|
||||
*/
|
||||
auto microJobQueue = EcmaVM::Cast(instance)->GetMicroJobQueue();
|
||||
if (!thread->HasPendingException()) {
|
||||
microJobQueue->ExecutePendingJob(thread);
|
||||
job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
|
||||
}
|
||||
}
|
||||
|
||||
@ -664,7 +664,7 @@ HWTEST_F_L0(BuiltinsPromiseTest, ThenResolve)
|
||||
*/
|
||||
auto microJobQueue = EcmaVM::Cast(instance)->GetMicroJobQueue();
|
||||
if (!thread->HasPendingException()) {
|
||||
microJobQueue->ExecutePendingJob(thread);
|
||||
job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
|
||||
}
|
||||
}
|
||||
|
||||
@ -721,7 +721,7 @@ HWTEST_F_L0(BuiltinsPromiseTest, ThenReject)
|
||||
*/
|
||||
auto microJobQueue = EcmaVM::Cast(instance)->GetMicroJobQueue();
|
||||
if (!thread->HasPendingException()) {
|
||||
microJobQueue->ExecutePendingJob(thread);
|
||||
job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
|
||||
}
|
||||
}
|
||||
} // namespace panda::test
|
||||
|
@ -37,8 +37,8 @@ public:
|
||||
|
||||
inline void FreeMethodData(RegionFactory *factory);
|
||||
|
||||
DECL_DUMP()
|
||||
DECL_VISIT_OBJECT(LOCATION_OFFSET, METHODS_DATA_OFFSET)
|
||||
DECL_DUMP()
|
||||
};
|
||||
|
||||
class LexicalFunction : public ECMAObject {
|
||||
@ -65,6 +65,7 @@ public:
|
||||
ACCESSORS(Program, PROGRAM_OFFSET, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT(NAME_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
};
|
||||
|
||||
class ConstantPool : public TaggedArray {
|
||||
|
@ -133,8 +133,8 @@ source_set("libark_jsoptimizer_static") {
|
||||
deps = [
|
||||
"$ark_root/libpandabase:libarkbase",
|
||||
"$ark_root/libpandafile:libarkfile",
|
||||
"$ark_root/runtime:arkruntime_header_deps",
|
||||
]
|
||||
deps += arkruntime_header_gen_deps
|
||||
}
|
||||
|
||||
ohos_shared_library("libark_jsoptimizer") {
|
||||
|
@ -658,7 +658,6 @@ void SetElementStub::GenerateCircuit()
|
||||
void GetPropertyByIndexStub::GenerateCircuit()
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
env->SetFrameType(FrameType::OPTIMIZED_ENTRY_FRAME);
|
||||
AddrShift thread = PtrArgument(0);
|
||||
AddrShift receiver = PtrArgument(1);
|
||||
AddrShift index = Int32Argument(2); /* 2 : 3rd parameter is index */
|
||||
@ -771,7 +770,6 @@ void GetPropertyByIndexStub::GenerateCircuit()
|
||||
void SetPropertyByIndexStub::GenerateCircuit()
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
env->SetFrameType(FrameType::OPTIMIZED_ENTRY_FRAME);
|
||||
AddrShift thread = PtrArgument(0);
|
||||
AddrShift receiver = PtrArgument(1);
|
||||
AddrShift index = Int32Argument(2); /* 2 : 3rd parameter is index */
|
||||
@ -1015,8 +1013,9 @@ void GetPropertyByNameStub::GenerateCircuit()
|
||||
void FastModStub::GenerateCircuit()
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
AddrShift x = Int64Argument(0);
|
||||
AddrShift y = Int64Argument(1);
|
||||
AddrShift thread = PtrArgument(0);
|
||||
AddrShift x = Int64Argument(1);
|
||||
AddrShift y = Int64Argument(2);
|
||||
DEFVARIABLE(intX, MachineType::INT32_TYPE, 0);
|
||||
DEFVARIABLE(intY, MachineType::INT32_TYPE, 0);
|
||||
DEFVARIABLE(doubleX, MachineType::FLOAT64_TYPE, 0);
|
||||
@ -1153,7 +1152,9 @@ void FastModStub::GenerateCircuit()
|
||||
Jump(&xIsZeroOryIsInf);
|
||||
Bind(&yNotInf);
|
||||
{
|
||||
doubleX = DoubleMod(*doubleX, *doubleY);
|
||||
StubDescriptor *floatMod = GET_STUBDESCRIPTOR(FloatMod);
|
||||
doubleX =CallRuntime(floatMod, thread, GetWord64Constant(FAST_STUB_ID(FloatMod)),
|
||||
{*doubleX, *doubleY});
|
||||
Return(DoubleBuildTagged(*doubleX));
|
||||
}
|
||||
Bind(&xIsZeroOryIsInf);
|
||||
@ -1226,8 +1227,8 @@ void FastTypeOfStub::GenerateCircuit()
|
||||
Bind(&defaultLabel);
|
||||
{
|
||||
Label objIsHeapObject(env);
|
||||
Label ObjNotHeapObject(env);
|
||||
Branch(TaggedIsHeapObject(obj), &objIsHeapObject, &ObjNotHeapObject);
|
||||
Label objNotHeapObject(env);
|
||||
Branch(TaggedIsHeapObject(obj), &objIsHeapObject, &objNotHeapObject);
|
||||
Bind(&objIsHeapObject);
|
||||
{
|
||||
Label objIsString(env);
|
||||
@ -1242,15 +1243,15 @@ void FastTypeOfStub::GenerateCircuit()
|
||||
Bind(&objNotString);
|
||||
{
|
||||
Label objIsSymbol(env);
|
||||
Label ObjNotSymbol(env);
|
||||
Branch(IsSymbol(obj), &objIsSymbol, &ObjNotSymbol);
|
||||
Label objNotSymbol(env);
|
||||
Branch(IsSymbol(obj), &objIsSymbol, &objNotSymbol);
|
||||
Bind(&objIsSymbol);
|
||||
{
|
||||
resultRep = Load(TAGGED_TYPE, gConstOffset,
|
||||
GetGlobalConstantString(ConstantIndex::SYMBOL_STRING_INDEX));
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&ObjNotSymbol);
|
||||
Bind(&objNotSymbol);
|
||||
{
|
||||
Label objIsCallable(env);
|
||||
Label objNotCallable(env);
|
||||
@ -1270,7 +1271,7 @@ void FastTypeOfStub::GenerateCircuit()
|
||||
}
|
||||
}
|
||||
}
|
||||
Bind(&ObjNotHeapObject);
|
||||
Bind(&objNotHeapObject);
|
||||
{
|
||||
Label objIsNum(env);
|
||||
Label objNotNum(env);
|
||||
|
@ -142,8 +142,11 @@ public:
|
||||
|
||||
class FastModStub : public Stub {
|
||||
public:
|
||||
// 2 means argument counts
|
||||
explicit FastModStub(Circuit *circuit) : Stub("FastMod", 2, circuit) {}
|
||||
// 3 means argument counts
|
||||
explicit FastModStub(Circuit *circuit) : Stub("FastMod", 3, circuit)
|
||||
{
|
||||
circuit->SetFrameType(panda::ecmascript::FrameType::OPTIMIZED_ENTRY_FRAME);
|
||||
}
|
||||
~FastModStub() = default;
|
||||
NO_MOVE_SEMANTIC(FastModStub);
|
||||
NO_COPY_SEMANTIC(FastModStub);
|
||||
|
@ -28,7 +28,8 @@ namespace kungfu {
|
||||
V(GetHash32, 2) \
|
||||
V(FindElementWithCache, 4) \
|
||||
V(Execute, 5) \
|
||||
V(StringGetHashCode, 1)
|
||||
V(StringGetHashCode, 1) \
|
||||
V(FloatMod, 2)
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define FAST_RUNTIME_STUB_LIST(V) \
|
||||
@ -36,7 +37,7 @@ namespace kungfu {
|
||||
V(FastSub, 2) \
|
||||
V(FastMul, 2) \
|
||||
V(FastDiv, 2) \
|
||||
V(FastMod, 2) \
|
||||
V(FastMod, 3) \
|
||||
V(FastEqual, 2) \
|
||||
V(FastTypeOf, 2) \
|
||||
V(FastStrictEqual, 2) \
|
||||
|
@ -1,123 +1,125 @@
|
||||
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
|
||||
index 0e85afa82c7..54a9152e44f 100644
|
||||
--- a/llvm/CMakeLists.txt
|
||||
+++ b/llvm/CMakeLists.txt
|
||||
@@ -505,8 +505,15 @@ option(LLVM_BUILD_RUNTIME
|
||||
"Build the LLVM runtime libraries." ON)
|
||||
option(LLVM_BUILD_EXAMPLES
|
||||
"Build the LLVM example programs. If OFF, just generate build targets." OFF)
|
||||
+option(BUILD_ARK_GC_SUPPORT
|
||||
+ "ARK support GC. If ON, support GC." OFF)
|
||||
+if(BUILD_ARK_GC_SUPPORT)
|
||||
+ add_definitions(-DARK_GC_SUPPORT)
|
||||
+endif(ARK_SUPPORT_GC)
|
||||
+
|
||||
option(LLVM_INCLUDE_EXAMPLES "Generate build targets for the LLVM examples" ON)
|
||||
|
||||
+
|
||||
if(LLVM_BUILD_EXAMPLES)
|
||||
add_definitions(-DBUILD_EXAMPLES)
|
||||
endif(LLVM_BUILD_EXAMPLES)
|
||||
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
|
||||
index 1da20371caf..60d9af0d833 100644
|
||||
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
|
||||
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include <cstdlib>
|
||||
+#include <iostream>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@@ -1168,6 +1169,28 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
|
||||
else
|
||||
MFI.setOffsetAdjustment(-StackSize);
|
||||
}
|
||||
+#ifdef ARK_GC_SUPPORT
|
||||
+ // push marker
|
||||
+ if (MF.getFunction().hasFnAttribute("js-stub-call"))
|
||||
+ {
|
||||
+ int64_t marker = 0x0;
|
||||
+ MF.getFunction()
|
||||
+ .getFnAttribute("js-stub-call")
|
||||
+ .getValueAsString()
|
||||
+ .getAsInteger(10, marker);//marker 1 break frame
|
||||
+ std::cout << __LINE__ << " marker:" << std::dec << marker << std::endl;
|
||||
+
|
||||
+ BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH64i32))
|
||||
+ .addImm(marker)
|
||||
+ .setMIFlag(MachineInstr::FrameSetup);
|
||||
+ /*reserve thread.fp */
|
||||
+ if (marker == 1) {
|
||||
+ BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH64i32))
|
||||
+ .addImm(marker)
|
||||
+ .setMIFlag(MachineInstr::FrameSetup);
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
// For EH funclets, only allocate enough space for outgoing calls. Save the
|
||||
// NumBytes value that we would've used for the parent frame.
|
||||
@@ -1635,6 +1658,27 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
uint64_t SEHStackAllocAmt = NumBytes;
|
||||
|
||||
if (HasFP) {
|
||||
+#ifdef ARK_GC_SUPPORT
|
||||
+ if (MF.getFunction().hasFnAttribute("js-stub-call"))
|
||||
+ {
|
||||
+ int64_t marker = 0x0;
|
||||
+ MF.getFunction()
|
||||
+ .getFnAttribute("js-stub-call")
|
||||
+ .getValueAsString()
|
||||
+ .getAsInteger(10, marker);//marker 1 break frame
|
||||
+
|
||||
+ // pop marker
|
||||
+ BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
|
||||
+ MachineFramePtr)
|
||||
+ .setMIFlag(MachineInstr::FrameDestroy);
|
||||
+ if (marker == 1) {
|
||||
+ // pop thread.fp
|
||||
+ BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
|
||||
+ MachineFramePtr)
|
||||
+ .setMIFlag(MachineInstr::FrameDestroy);
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
// Pop EBP.
|
||||
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
|
||||
MachineFramePtr)
|
||||
@@ -1993,8 +2037,33 @@ bool X86FrameLowering::assignCalleeSavedSpillSlots(
|
||||
|
||||
if (hasFP(MF)) {
|
||||
// emitPrologue always spills frame register the first thing.
|
||||
+#ifdef ARK_GC_SUPPORT
|
||||
+ if (MF.getFunction().hasFnAttribute("js-stub-call")) {
|
||||
+ int64_t marker = 0x0;
|
||||
+ MF.getFunction()
|
||||
+ .getFnAttribute("js-stub-call")
|
||||
+ .getValueAsString()
|
||||
+ .getAsInteger(10, marker);//marker 1 break frame
|
||||
+ if (marker == 1) {
|
||||
+ SpillSlotOffset -= 3 * SlotSize; // add type and thread.fp
|
||||
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
|
||||
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
|
||||
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
|
||||
+ CalleeSavedFrameSize += 16;
|
||||
+ } else {
|
||||
+ SpillSlotOffset -= 2 * SlotSize; // add type
|
||||
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
|
||||
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
|
||||
+ CalleeSavedFrameSize += 8;
|
||||
+ }
|
||||
+ } else {
|
||||
+ SpillSlotOffset -= SlotSize; // add type and thread.fp
|
||||
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
|
||||
+ }
|
||||
+#else
|
||||
SpillSlotOffset -= SlotSize;
|
||||
MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
|
||||
+#endif
|
||||
|
||||
// Since emitPrologue and emitEpilogue will handle spilling and restoring of
|
||||
// the frame register, we can delete it from CSI list and not have to worry
|
||||
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
|
||||
index 0e85afa82c7..43756892e40 100644
|
||||
--- a/llvm/CMakeLists.txt
|
||||
+++ b/llvm/CMakeLists.txt
|
||||
@@ -505,8 +505,15 @@ option(LLVM_BUILD_RUNTIME
|
||||
"Build the LLVM runtime libraries." ON)
|
||||
option(LLVM_BUILD_EXAMPLES
|
||||
"Build the LLVM example programs. If OFF, just generate build targets." OFF)
|
||||
+option(BUILD_ARK_GC_SUPPORT
|
||||
+ "ARK support GC. If ON, support GC." OFF)
|
||||
+if(BUILD_ARK_GC_SUPPORT)
|
||||
+ add_definitions(-DARK_GC_SUPPORT)
|
||||
+endif(BUILD_ARK_GC_SUPPORT)
|
||||
+
|
||||
option(LLVM_INCLUDE_EXAMPLES "Generate build targets for the LLVM examples" ON)
|
||||
|
||||
+
|
||||
if(LLVM_BUILD_EXAMPLES)
|
||||
add_definitions(-DBUILD_EXAMPLES)
|
||||
endif(LLVM_BUILD_EXAMPLES)
|
||||
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
|
||||
index 1da20371caf..e0264827556 100644
|
||||
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
|
||||
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
|
||||
@@ -1168,6 +1168,25 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
|
||||
else
|
||||
MFI.setOffsetAdjustment(-StackSize);
|
||||
}
|
||||
+#ifdef ARK_GC_SUPPORT
|
||||
+ // push marker
|
||||
+ if (MF.getFunction().hasFnAttribute("js-stub-call"))
|
||||
+ {
|
||||
+ int64_t marker = 0x0;
|
||||
+ MF.getFunction()
|
||||
+ .getFnAttribute("js-stub-call")
|
||||
+ .getValueAsString()
|
||||
+ .getAsInteger(10, marker);//marker 1 break frame
|
||||
+ BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64i32 : X86::PUSH32i8))
|
||||
+ .addImm(marker)
|
||||
+ .setMIFlag(MachineInstr::FrameSetup);
|
||||
+ if (marker == JS_ENTRY_FRAME_MARK) {
|
||||
+ BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64i32 : X86::PUSH32i8))
|
||||
+ .addImm(marker)
|
||||
+ .setMIFlag(MachineInstr::FrameSetup);
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
// For EH funclets, only allocate enough space for outgoing calls. Save the
|
||||
// NumBytes value that we would've used for the parent frame.
|
||||
@@ -1635,6 +1654,27 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
uint64_t SEHStackAllocAmt = NumBytes;
|
||||
|
||||
if (HasFP) {
|
||||
+#ifdef ARK_GC_SUPPORT
|
||||
+ if (MF.getFunction().hasFnAttribute("js-stub-call"))
|
||||
+ {
|
||||
+ int64_t marker = 0x0;
|
||||
+ MF.getFunction()
|
||||
+ .getFnAttribute("js-stub-call")
|
||||
+ .getValueAsString()
|
||||
+ .getAsInteger(10, marker);//marker 1 break frame
|
||||
+
|
||||
+ // pop marker
|
||||
+ BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
|
||||
+ MachineFramePtr)
|
||||
+ .setMIFlag(MachineInstr::FrameDestroy);
|
||||
+ if (marker == JS_ENTRY_FRAME_MARK) {
|
||||
+ // pop thread.fp
|
||||
+ BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
|
||||
+ MachineFramePtr)
|
||||
+ .setMIFlag(MachineInstr::FrameDestroy);
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
// Pop EBP.
|
||||
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
|
||||
MachineFramePtr)
|
||||
@@ -1993,8 +2033,33 @@ bool X86FrameLowering::assignCalleeSavedSpillSlots(
|
||||
|
||||
if (hasFP(MF)) {
|
||||
// emitPrologue always spills frame register the first thing.
|
||||
+#ifdef ARK_GC_SUPPORT
|
||||
+ if (MF.getFunction().hasFnAttribute("js-stub-call")) {
|
||||
+ int64_t marker = 0x0;
|
||||
+ MF.getFunction()
|
||||
+ .getFnAttribute("js-stub-call")
|
||||
+ .getValueAsString()
|
||||
+ .getAsInteger(10, marker);//marker 1 break frame
|
||||
+ if (marker == JS_ENTRY_FRAME_MARK) {
|
||||
+ SpillSlotOffset -= 3 * SlotSize; // add type and thread.fp
|
||||
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
|
||||
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
|
||||
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
|
||||
+ CalleeSavedFrameSize += (2 * SlotSize);
|
||||
+ } else {
|
||||
+ SpillSlotOffset -= 2 * SlotSize; // add type
|
||||
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
|
||||
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
|
||||
+ CalleeSavedFrameSize += SlotSize;
|
||||
+ }
|
||||
+ } else {
|
||||
+ SpillSlotOffset -= SlotSize; // add type and thread.fp
|
||||
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
|
||||
+ }
|
||||
+#else
|
||||
SpillSlotOffset -= SlotSize;
|
||||
MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
|
||||
+#endif
|
||||
|
||||
// Since emitPrologue and emitEpilogue will handle spilling and restoring of
|
||||
// the frame register, we can delete it from CSI list and not have to worry
|
||||
diff --git a/llvm/lib/Target/X86/X86FrameLowering.h b/llvm/lib/Target/X86/X86FrameLowering.h
|
||||
index 2103d6471ea..3fd89b0d9ee 100644
|
||||
--- a/llvm/lib/Target/X86/X86FrameLowering.h
|
||||
+++ b/llvm/lib/Target/X86/X86FrameLowering.h
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
#include "llvm/CodeGen/TargetFrameLowering.h"
|
||||
|
||||
+#define JS_ENTRY_FRAME_MARK 1
|
||||
+
|
||||
namespace llvm {
|
||||
|
||||
class MachineInstrBuilder;
|
||||
|
@ -153,6 +153,7 @@ void StubAotCompiler::BuildStubModuleAndSave(const char *triple, panda::ecmascri
|
||||
SET_STUB_TO_MODULE(module, FastMul) \
|
||||
SET_STUB_TO_MODULE(module, FastDiv) \
|
||||
SET_STUB_TO_MODULE(module, FastMod) \
|
||||
SET_STUB_TO_MODULE(module, FastTypeOf) \
|
||||
SET_STUB_TO_MODULE(module, FindOwnElement) \
|
||||
SET_STUB_TO_MODULE(module, GetElement) \
|
||||
SET_STUB_TO_MODULE(module, FindOwnElement2) \
|
||||
|
@ -81,17 +81,32 @@ CALL_STUB_INIT_DESCRIPTOR(FastDiv)
|
||||
|
||||
CALL_STUB_INIT_DESCRIPTOR(FastMod)
|
||||
{
|
||||
// 2 : 2 input parameters
|
||||
StubDescriptor fastMod("FastMod", 0, 2, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE);
|
||||
// 3 : 3 input parameters
|
||||
StubDescriptor fastMod("FastMod", 0, 3, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE);
|
||||
*descriptor = fastMod;
|
||||
// 2 : 2 input parameters
|
||||
std::array<MachineType, 2> params = {
|
||||
// 3 : 3 input parameters
|
||||
std::array<MachineType, 3> params = {
|
||||
MachineType::UINT64_TYPE,
|
||||
MachineType::UINT64_TYPE,
|
||||
MachineType::UINT64_TYPE,
|
||||
};
|
||||
descriptor->SetParameters(params.data());
|
||||
}
|
||||
|
||||
CALL_STUB_INIT_DESCRIPTOR(FloatMod)
|
||||
{
|
||||
// 2 : 2 input parameters
|
||||
StubDescriptor floatMod("FloatMod", 0, 2, ArgumentsOrder::DEFAULT_ORDER, FLOAT64_TYPE);
|
||||
*descriptor = floatMod;
|
||||
// 2 : 2 input parameters
|
||||
std::array<MachineType, 2> params = {
|
||||
MachineType::FLOAT64_TYPE,
|
||||
MachineType::FLOAT64_TYPE,
|
||||
};
|
||||
descriptor->SetParameters(params.data());
|
||||
descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB);
|
||||
}
|
||||
|
||||
CALL_STUB_INIT_DESCRIPTOR(FastEqual) {}
|
||||
|
||||
CALL_STUB_INIT_DESCRIPTOR(FastTypeOf)
|
||||
|
@ -442,19 +442,24 @@ HWTEST_F_L0(StubTest, FastModTest)
|
||||
llvmBuilder.Build();
|
||||
LLVMAssembler assembler(module, "x86_64-unknown-linux-gnu");
|
||||
assembler.Run();
|
||||
auto fn = reinterpret_cast<JSTaggedValue (*)(int64_t, int64_t)>(assembler.GetFuncPtrFromCompiledModule(function));
|
||||
|
||||
LLVMDumpModule(module);
|
||||
auto engine = assembler.GetEngine();
|
||||
uint64_t stub1Code = LLVMGetFunctionAddress(engine, "FastModStub");
|
||||
std::map<uint64_t, std::string> addr2name = {{stub1Code, "stub1"}};
|
||||
assembler.Disassemble(addr2name);
|
||||
auto fn = reinterpret_cast<JSTaggedValue (*)(JSThread *, int64_t, int64_t)>(
|
||||
assembler.GetFuncPtrFromCompiledModule(function));
|
||||
// test left, right are all integer
|
||||
int x = 7;
|
||||
int y = 3;
|
||||
auto result = fn(JSTaggedValue(x).GetRawData(), JSTaggedValue(y).GetRawData());
|
||||
auto result = fn(thread, JSTaggedValue(x).GetRawData(), JSTaggedValue(y).GetRawData());
|
||||
JSTaggedValue expectRes = FastRuntimeStub::FastMod(JSTaggedValue(x), JSTaggedValue(y));
|
||||
EXPECT_EQ(result, expectRes);
|
||||
|
||||
// test y == 0.0 || std::isnan(y) || std::isnan(x) || std::isinf(x) return NAN_VALUE
|
||||
double x2 = 7.3;
|
||||
int y2 = base::NAN_VALUE;
|
||||
auto result2 = fn(JSTaggedValue(x2).GetRawData(), JSTaggedValue(y2).GetRawData());
|
||||
auto result2 = fn(thread, JSTaggedValue(x2).GetRawData(), JSTaggedValue(y2).GetRawData());
|
||||
auto expectRes2 = FastRuntimeStub::FastMod(JSTaggedValue(x2), JSTaggedValue(y2));
|
||||
EXPECT_EQ(result2, expectRes2);
|
||||
LOG_ECMA(INFO) << "result2 for FastMod(7, 'helloworld') = " << result2.GetRawData();
|
||||
@ -463,14 +468,14 @@ HWTEST_F_L0(StubTest, FastModTest)
|
||||
// // test modular operation under normal conditions
|
||||
double x3 = 33.0;
|
||||
double y3 = 44.0;
|
||||
auto result3 = fn(JSTaggedValue(x3).GetRawData(), JSTaggedValue(y3).GetRawData());
|
||||
auto result3 = fn(thread, JSTaggedValue(x3).GetRawData(), JSTaggedValue(y3).GetRawData());
|
||||
auto expectRes3 = FastRuntimeStub::FastMod(JSTaggedValue(x3), JSTaggedValue(y3));
|
||||
EXPECT_EQ(result3, expectRes3);
|
||||
|
||||
// test x == 0.0 || std::isinf(y) return x
|
||||
double x4 = base::NAN_VALUE;
|
||||
int y4 = 7;
|
||||
auto result4 = fn(JSTaggedValue(x4).GetRawData(), JSTaggedValue(y4).GetRawData());
|
||||
auto result4 = fn(thread, JSTaggedValue(x4).GetRawData(), JSTaggedValue(y4).GetRawData());
|
||||
auto expectRes4 = FastRuntimeStub::FastMod(JSTaggedValue(x4), JSTaggedValue(y4));
|
||||
|
||||
LOG_ECMA(INFO) << "result4 for FastMod(base::NAN_VALUE, 7) = " << result4.GetRawData();
|
||||
@ -481,7 +486,7 @@ HWTEST_F_L0(StubTest, FastModTest)
|
||||
int x5 = 7;
|
||||
auto *factory = JSThread::Cast(thread)->GetEcmaVM()->GetFactory();
|
||||
auto y5 = factory->NewFromStdString("hello world");
|
||||
auto result5 = fn(JSTaggedValue(x5).GetRawData(), y5.GetTaggedValue().GetRawData());
|
||||
auto result5 = fn(thread, JSTaggedValue(x5).GetRawData(), y5.GetTaggedValue().GetRawData());
|
||||
EXPECT_EQ(result5, JSTaggedValue::Hole());
|
||||
auto expectRes5 = FastRuntimeStub::FastMod(JSTaggedValue(x5), y5.GetTaggedValue());
|
||||
LOG_ECMA(INFO) << "result1 for FastMod(7, 'helloworld') = " << result5.GetRawData();
|
||||
@ -1183,7 +1188,7 @@ HWTEST_F_L0(StubTest, GetPropertyByNameStub)
|
||||
HWTEST_F_L0(StubTest, FastTypeOfTest)
|
||||
{
|
||||
auto module = stubModule.GetModule();
|
||||
auto function = stubModule.GetStubFunction(FAST_STUB_ID(FastMod));
|
||||
auto function = stubModule.GetStubFunction(FAST_STUB_ID(FastTypeOf));
|
||||
Circuit netOfGates;
|
||||
FastTypeOfStub optimizer(&netOfGates);
|
||||
optimizer.GenerateCircuit();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -371,14 +371,14 @@
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define DECL_VISIT_OBJECT(BEGIN_OFFSET, SIZE) \
|
||||
void VisitRangeSlot(const EcmaObjectRangeVisitor &visitor) \
|
||||
void VisitRangeSlot(const EcmaObjectRangeVisitor &visitor) \
|
||||
{ \
|
||||
visitor(this, ObjectSlot(ToUintPtr(this) + BEGIN_OFFSET), ObjectSlot(ToUintPtr(this) + SIZE)); \
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define DECL_VISIT_OBJECT_FOR_JS_OBJECT(PARENTCLASS, BEGIN_OFFSET, SIZE) \
|
||||
void VisitRangeSlot(const EcmaObjectRangeVisitor &visitor) \
|
||||
void VisitRangeSlot(const EcmaObjectRangeVisitor &visitor) \
|
||||
{ \
|
||||
VisitObjects(visitor); \
|
||||
/* visit in object fields */ \
|
||||
@ -396,4 +396,9 @@
|
||||
visitor(this, ObjectSlot(ToUintPtr(this) + BEGIN_OFFSET), ObjectSlot(ToUintPtr(this) + SIZE)); \
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define CHECK_DUMP_FILEDS(begin, end, num) \
|
||||
LOG_IF(num != (end - begin) / JSTaggedValue::TaggedTypeSize(), FATAL, RUNTIME) \
|
||||
<< "Fileds in obj are not in dump list. ";
|
||||
|
||||
#endif // ECMASCRIPT_ECMA_MACROS_H
|
||||
|
@ -42,12 +42,13 @@ void EcmaModule::AddItem(const JSThread *thread, JSHandle<EcmaModule> module, JS
|
||||
JSHandle<JSTaggedValue> data(thread, module->GetNameDictionary());
|
||||
if (data->IsUndefined()) {
|
||||
JSHandle<NameDictionary> dict(thread, NameDictionary::Create(thread, DICTIONART_CAP));
|
||||
auto result = dict->Put(thread, dict, itemName, itemValue, PropertyAttributes::Default());
|
||||
module->SetNameDictionary(thread, JSTaggedValue(result));
|
||||
NameDictionary *newDict = NameDictionary::Put(thread, dict, itemName, itemValue, PropertyAttributes::Default());
|
||||
module->SetNameDictionary(thread, JSTaggedValue(newDict));
|
||||
} else {
|
||||
JSHandle<NameDictionary> dataDict = JSHandle<NameDictionary>::Cast(data);
|
||||
auto result = dataDict->Put(thread, dataDict, itemName, itemValue, PropertyAttributes::Default());
|
||||
module->SetNameDictionary(thread, JSTaggedValue(result));
|
||||
NameDictionary *newDict =
|
||||
NameDictionary::Put(thread, dataDict, itemName, itemValue, PropertyAttributes::Default());
|
||||
module->SetNameDictionary(thread, JSTaggedValue(newDict));
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,7 +61,7 @@ void EcmaModule::RemoveItem(const JSThread *thread, JSHandle<EcmaModule> module,
|
||||
JSHandle<NameDictionary> moduleItems(data);
|
||||
int entry = moduleItems->FindEntry(itemName.GetTaggedValue());
|
||||
if (entry != -1) {
|
||||
NameDictionary *newDict = NameDictionary::Remove(thread, moduleItems, entry); // discard return
|
||||
NameDictionary *newDict = NameDictionary::Remove(thread, moduleItems, entry);
|
||||
module->SetNameDictionary(thread, JSTaggedValue(newDict));
|
||||
}
|
||||
}
|
||||
@ -117,20 +118,21 @@ ModuleManager::ModuleManager(EcmaVM *vm) : vm_(vm)
|
||||
// class ModuleManager
|
||||
void ModuleManager::AddModule(JSHandle<JSTaggedValue> moduleName, JSHandle<JSTaggedValue> module)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(vm_->GetJSThread());
|
||||
JSHandle<NameDictionary> dict(vm_->GetJSThread(), ecmaModules_);
|
||||
JSThread *thread = vm_->GetJSThread();
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
JSHandle<NameDictionary> dict(thread, ecmaModules_);
|
||||
ecmaModules_ =
|
||||
JSTaggedValue(dict->Put(vm_->GetJSThread(), dict, moduleName, module, PropertyAttributes::Default()));
|
||||
JSTaggedValue(NameDictionary::Put(thread, dict, moduleName, module, PropertyAttributes::Default()));
|
||||
}
|
||||
|
||||
void ModuleManager::RemoveModule(JSHandle<JSTaggedValue> moduleName)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(vm_->GetJSThread());
|
||||
JSThread *thread = vm_->GetJSThread();
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
JSHandle<NameDictionary> moduleItems(thread, ecmaModules_);
|
||||
int entry = moduleItems->FindEntry(moduleName.GetTaggedValue());
|
||||
if (entry != -1) {
|
||||
NameDictionary::Remove(vm_->GetJSThread(), moduleItems, entry); // discard return
|
||||
ecmaModules_ = JSTaggedValue(NameDictionary::Remove(thread, moduleItems, entry));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
ACCESSORS(NameDictionary, NAME_DICTIONARY_OFFSET, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(ECMAObject, NAME_DICTIONARY_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
|
||||
protected:
|
||||
static void CopyModuleInternal(const JSThread *thread, JSHandle<EcmaModule> dstModule,
|
||||
|
@ -449,7 +449,7 @@ Expected<int, Runtime::Error> EcmaVM::InvokeEcmaEntrypoint(const panda_file::Fil
|
||||
params->MakeArgList(*jsargs);
|
||||
panda::ecmascript::InvokeJsFunction(thread_, func, global, newTarget, params);
|
||||
if (!thread_->HasPendingException()) {
|
||||
job::MicroJobQueue::Cast(microJobQueue_.GetTaggedObject())->ExecutePendingJob(thread_);
|
||||
job::MicroJobQueue::ExecutePendingJob(thread_, GetMicroJobQueue());
|
||||
}
|
||||
|
||||
// print exception information
|
||||
@ -650,7 +650,7 @@ void EcmaVM::ClearBufferData()
|
||||
bool EcmaVM::ExecutePromisePendingJob() const
|
||||
{
|
||||
if (!thread_->HasPendingException()) {
|
||||
job::MicroJobQueue::Cast(microJobQueue_.GetTaggedObject())->ExecutePendingJob(thread_);
|
||||
job::MicroJobQueue::ExecutePendingJob(thread_, GetMicroJobQueue());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -337,16 +337,6 @@ public:
|
||||
return moduleManager_;
|
||||
}
|
||||
|
||||
static constexpr uint32_t GetGlobalEnvOffset()
|
||||
{
|
||||
return MEMBER_OFFSET(EcmaVM, globalEnv_);
|
||||
}
|
||||
|
||||
static constexpr uint32_t GetMicroJobQueueOffset()
|
||||
{
|
||||
return MEMBER_OFFSET(EcmaVM, microJobQueue_);
|
||||
}
|
||||
|
||||
void SetupRegExpResultCache();
|
||||
JSHandle<JSTaggedValue> GetRegExpCache()
|
||||
{
|
||||
|
@ -217,8 +217,12 @@
|
||||
|
||||
#ifdef PANDA_TARGET_AMD64
|
||||
#define GET_CURRETN_FP(fp) asm("mov %%rbp, %0" : "=rm" (fp))
|
||||
#define POINTER_CAST(fp, type) static_cast<type>(static_cast<void *>(fp)
|
||||
#define GET_PREV_FP(fp) reinterpret_cast<uintptr_t *>(*(fp))
|
||||
#else
|
||||
#define GET_CURRETN_FP(fp)
|
||||
#define POINTER_CAST(fp, type) static_cast<type>(static_cast<void *>(fp))
|
||||
#define GET_PREV_FP(fp) reinterpret_cast<uintptr_t *>(*(POINTER_CAST(fp, uintptr_t *)))
|
||||
#endif
|
||||
|
||||
namespace panda::ecmascript {
|
||||
|
@ -34,7 +34,7 @@ HeapProfiler::~HeapProfiler()
|
||||
jsonSerializer_ = nullptr;
|
||||
}
|
||||
|
||||
bool HeapProfiler::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &filePath)
|
||||
bool HeapProfiler::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &filePath, bool isVmMode)
|
||||
{
|
||||
[[maybe_unused]] bool heapClean = ForceFullGC(thread);
|
||||
ASSERT(heapClean);
|
||||
@ -42,7 +42,7 @@ bool HeapProfiler::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, con
|
||||
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);
|
||||
HeapSnapShot *snapShot = MakeHeapSnapShot(thread, SampleType::ONE_SHOT, isVmMode);
|
||||
ASSERT(snapShot != nullptr);
|
||||
std::pair<bool, CString> realPath = FilePathValid(filePath);
|
||||
if (realPath.first) {
|
||||
@ -56,9 +56,9 @@ bool HeapProfiler::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, con
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
bool HeapProfiler::StartHeapTracking(JSThread *thread, double timeInterval)
|
||||
bool HeapProfiler::StartHeapTracking(JSThread *thread, double timeInterval, bool isVmMode)
|
||||
{
|
||||
HeapSnapShot *snapShot = MakeHeapSnapShot(thread, SampleType::REAL_TIME);
|
||||
HeapSnapShot *snapShot = MakeHeapSnapShot(thread, SampleType::REAL_TIME, isVmMode);
|
||||
if (snapShot == nullptr) {
|
||||
return false;
|
||||
}
|
||||
@ -158,14 +158,15 @@ bool HeapProfiler::ForceFullGC(JSThread *thread)
|
||||
return false;
|
||||
}
|
||||
|
||||
HeapSnapShot *HeapProfiler::MakeHeapSnapShot(JSThread *thread, SampleType sampleType)
|
||||
HeapSnapShot *HeapProfiler::MakeHeapSnapShot(JSThread *thread, SampleType sampleType, bool isVmMode)
|
||||
{
|
||||
LOG(ERROR, RUNTIME) << "HeapProfiler::MakeHeapSnapShot";
|
||||
DISALLOW_GARBAGE_COLLECTION;
|
||||
heap_->GetSweeper()->EnsureAllTaskFinish();
|
||||
switch (sampleType) {
|
||||
case SampleType::ONE_SHOT: {
|
||||
auto *snapShot = const_cast<RegionFactory *>(heap_->GetRegionFactory())->New<HeapSnapShot>(thread, heap_);
|
||||
auto *snapShot =
|
||||
const_cast<RegionFactory *>(heap_->GetRegionFactory())->New<HeapSnapShot>(thread, heap_, isVmMode);
|
||||
if (snapShot == nullptr) {
|
||||
LOG_ECMA(FATAL) << "alloc snapshot failed";
|
||||
UNREACHABLE();
|
||||
@ -175,7 +176,8 @@ HeapSnapShot *HeapProfiler::MakeHeapSnapShot(JSThread *thread, SampleType sample
|
||||
return snapShot;
|
||||
}
|
||||
case SampleType::REAL_TIME: {
|
||||
auto *snapShot = const_cast<RegionFactory *>(heap_->GetRegionFactory())->New<HeapSnapShot>(thread, heap_);
|
||||
auto *snapShot =
|
||||
const_cast<RegionFactory *>(heap_->GetRegionFactory())->New<HeapSnapShot>(thread, heap_, isVmMode);
|
||||
if (snapShot == nullptr) {
|
||||
LOG_ECMA(FATAL) << "alloc snapshot failed";
|
||||
UNREACHABLE();
|
||||
|
@ -44,10 +44,10 @@ public:
|
||||
/**
|
||||
* dump the specific snapshot in target format
|
||||
*/
|
||||
bool DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &path);
|
||||
bool DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &path, bool isVmMode = true);
|
||||
void AddSnapShot(HeapSnapShot *snapshot);
|
||||
|
||||
bool StartHeapTracking(JSThread *thread, double timeInterval) override;
|
||||
bool StartHeapTracking(JSThread *thread, double timeInterval, bool isVmMode = true) override;
|
||||
bool StopHeapTracking(JSThread *thread, DumpFormat dumpFormat, const CString &filePath) override;
|
||||
|
||||
private:
|
||||
@ -59,7 +59,7 @@ private:
|
||||
/**
|
||||
* make a new heap snapshot and put it into a container eg, vector
|
||||
*/
|
||||
HeapSnapShot *MakeHeapSnapShot(JSThread *thread, SampleType sampleType);
|
||||
HeapSnapShot *MakeHeapSnapShot(JSThread *thread, SampleType sampleType, bool isVmMode = true);
|
||||
std::pair<bool, CString> FilePathValid(const CString &filePath);
|
||||
CString GenDumpFileName(DumpFormat dumpFormat);
|
||||
CString GetTimeStamp();
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "ecmascript/mem/heap.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
void HeapProfilerInterface::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &filePath)
|
||||
void HeapProfilerInterface::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &filePath, bool isVmMode)
|
||||
{
|
||||
LOG(ERROR, RUNTIME) << "HeapProfilerInterface::DumpHeapSnapshot";
|
||||
const Heap *heap = thread->GetEcmaVM()->GetHeap();
|
||||
@ -27,7 +27,7 @@ void HeapProfilerInterface::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFo
|
||||
LOG_ECMA(FATAL) << "alloc hprof failed";
|
||||
UNREACHABLE();
|
||||
}
|
||||
hprof->DumpHeapSnapShot(thread, dumpFormat, filePath);
|
||||
hprof->DumpHeapSnapShot(thread, dumpFormat, filePath, isVmMode);
|
||||
const_cast<RegionFactory *>(heap->GetRegionFactory())->Delete(hprof);
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,8 @@ enum class DumpFormat { JSON, BINARY, OTHER };
|
||||
|
||||
class HeapProfilerInterface {
|
||||
public:
|
||||
static void DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &filePath);
|
||||
static void DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat,
|
||||
const CString &filePath, bool isVmMode = true);
|
||||
|
||||
static HeapProfilerInterface *CreateHeapProfiler(JSThread *thread);
|
||||
static void Destory(JSThread *thread, HeapProfilerInterface *heapProfiler);
|
||||
@ -32,7 +33,7 @@ public:
|
||||
HeapProfilerInterface() = default;
|
||||
virtual ~HeapProfilerInterface() = default;
|
||||
|
||||
virtual bool StartHeapTracking(JSThread *thread, double timeInterval) = 0;
|
||||
virtual bool StartHeapTracking(JSThread *thread, double timeInterval, bool isVmMode = true) = 0;
|
||||
virtual bool StopHeapTracking(JSThread *thread, DumpFormat dumpFormat, const CString &filePath) = 0;
|
||||
|
||||
NO_MOVE_SEMANTIC(HeapProfilerInterface);
|
||||
|
@ -142,204 +142,36 @@ void HeapSnapShot::MoveNode(uintptr_t address, uintptr_t forward_address)
|
||||
// NOLINTNEXTLINE(readability-function-size)
|
||||
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);
|
||||
if (hCls->IsDictionary()) {
|
||||
arrayName = "TaggedDict[";
|
||||
arrayName.append(ToCString(array->GetLength()));
|
||||
arrayName.append("]");
|
||||
} else {
|
||||
JSType type = hCls->GetObjectType();
|
||||
switch (type) {
|
||||
case JSType::TAGGED_ARRAY: {
|
||||
CString arrayName;
|
||||
TaggedArray *array = TaggedArray::Cast(entry);
|
||||
arrayName = "TaggedArray[";
|
||||
arrayName.append(ToCString(array->GetLength()));
|
||||
arrayName.append("]");
|
||||
return GetString(arrayName); // String type was handled singly, see#GenerateStringNode
|
||||
}
|
||||
name = GetString(arrayName); // String type was handled singly, see#GenerateStringNode
|
||||
} else if (hCls->IsHClass()) {
|
||||
name = GetString("HiddenClass");
|
||||
} else if (hCls->IsJSNativePointer()) {
|
||||
name = GetString("JSNativePointer");
|
||||
} else {
|
||||
if (hCls->IsRealm()) {
|
||||
name = GetString("JSRealm");
|
||||
} else if (hCls->IsString()) {
|
||||
name = GetString("JsString");
|
||||
} else if (hCls->IsJSSymbol()) {
|
||||
name = GetString("JSSymbol");
|
||||
} else if (hCls->IsJSArray()) {
|
||||
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()) {
|
||||
name = GetString("JSTypedArray");
|
||||
} else if (hCls->IsJSInt8Array()) {
|
||||
name = GetString("JSInt8Array");
|
||||
} else if (hCls->IsJSUint8Array()) {
|
||||
name = GetString("JSUint8Array");
|
||||
} else if (hCls->IsJSUint8ClampedArray()) {
|
||||
name = GetString("JSUint8ClampedArray");
|
||||
} else if (hCls->IsJSInt16Array()) {
|
||||
name = GetString("JSInt16Array");
|
||||
} else if (hCls->IsJSUint16Array()) {
|
||||
name = GetString("JSUint16Array");
|
||||
} else if (hCls->IsJSInt32Array()) {
|
||||
name = GetString("JSInt32Array");
|
||||
} else if (hCls->IsJSUint32Array()) {
|
||||
name = GetString("JSUint32Array");
|
||||
} else if (hCls->IsJSFloat32Array()) {
|
||||
name = GetString("JSFloat32Array");
|
||||
} else if (hCls->IsJSFloat64Array()) {
|
||||
name = GetString("JSFloat64Array");
|
||||
} else if (hCls->IsJsGlobalEnv()) {
|
||||
name = GetString("JSGlobalEnv");
|
||||
} else if (hCls->IsJSFunctionBase()) {
|
||||
name = GetString("JSFunctionBase");
|
||||
} else if (hCls->IsJsBoundFunction()) {
|
||||
name = GetString("JsBoundFunction");
|
||||
} else if (hCls->IsJSIntlBoundFunction()) {
|
||||
name = GetString("JSIntlBoundFunction");
|
||||
} else if (hCls->IsJSProxyRevocFunction()) {
|
||||
name = GetString("JSProxyRevocFunction");
|
||||
} else if (hCls->IsJSAsyncFunction()) {
|
||||
name = GetString("JSAsyncFunction");
|
||||
} else if (hCls->IsJSAsyncAwaitStatusFunction()) {
|
||||
name = GetString("JSAsyncAwaitStatusFunction");
|
||||
} else if (hCls->IsJSPromiseReactionFunction()) {
|
||||
name = GetString("JSPromiseReactionFunction");
|
||||
} else if (hCls->IsJSPromiseExecutorFunction()) {
|
||||
name = GetString("JSPromiseExecutorFuncton");
|
||||
} else if (hCls->IsJSPromiseAllResolveElementFunction()) {
|
||||
name = GetString("JSPromiseAllResolveElementFunction");
|
||||
} else if (hCls->IsJSFunctionExtraInfo()) {
|
||||
name = GetString("JSFunctionExtraInfo");
|
||||
} else if (hCls->IsMicroJobQueue()) {
|
||||
name = GetString("MicroJobQueue");
|
||||
} else if (hCls->IsPendingJob()) {
|
||||
name = GetString("PendingJob");
|
||||
} else if (hCls->IsJsPrimitiveRef()) {
|
||||
name = GetString("JsPrimitiveRef");
|
||||
} else if (hCls->IsJSSet()) {
|
||||
name = GetString("JSSet");
|
||||
} else if (hCls->IsJSMap()) {
|
||||
name = GetString("JSMap");
|
||||
} else if (hCls->IsJSWeakMap()) {
|
||||
name = GetString("JSWeakMap");
|
||||
} else if (hCls->IsJSWeakSet()) {
|
||||
name = GetString("JSWeakSet");
|
||||
} else if (hCls->IsJSFunction()) {
|
||||
name = GetString("JSFunction");
|
||||
} else if (hCls->IsJSError()) {
|
||||
name = GetString("JSError");
|
||||
} else if (hCls->IsArguments()) {
|
||||
name = GetString("Arguments");
|
||||
} else if (hCls->IsDate()) {
|
||||
name = GetString("Date");
|
||||
} else if (hCls->IsJSRegExp()) {
|
||||
name = GetString("JSRegExp");
|
||||
} else if (hCls->IsJSProxy()) {
|
||||
name = GetString("JSProxy");
|
||||
} else if (hCls->IsJSLocale()) {
|
||||
name = GetString("JSLocale");
|
||||
} else if (hCls->IsJSIntl()) {
|
||||
name = GetString("JSIntl");
|
||||
} else if (hCls->IsJSDateTimeFormat()) {
|
||||
name = GetString("JSDateTimeFormat");
|
||||
} else if (hCls->IsJSRelativeTimeFormat()) {
|
||||
name = GetString("JSRelativeTimeFormat");
|
||||
} else if (hCls->IsJSNumberFormat()) {
|
||||
name = GetString("JSNumberFormat");
|
||||
} else if (hCls->IsAccessorData()) {
|
||||
name = GetString("AccessorData");
|
||||
} else if (hCls->IsInternalAccessor()) {
|
||||
name = GetString("InternalAccessor");
|
||||
} else if (hCls->IsIterator()) {
|
||||
name = GetString("Iterator");
|
||||
} else if (hCls->IsForinIterator()) {
|
||||
name = GetString("ForinIterator");
|
||||
} else if (hCls->IsStringIterator()) {
|
||||
name = GetString("StringIterator");
|
||||
} else if (hCls->IsArrayBuffer()) {
|
||||
name = GetString("ArrayBuffer");
|
||||
} else if (hCls->IsDataView()) {
|
||||
name = GetString("DataView");
|
||||
} else if (hCls->IsJSSetIterator()) {
|
||||
name = GetString("JSSetIterator");
|
||||
} else if (hCls->IsJSMapIterator()) {
|
||||
name = GetString("JSMapIterator");
|
||||
} else if (hCls->IsJSArrayIterator()) {
|
||||
name = GetString("JSArrayIterator");
|
||||
} else if (hCls->IsPrototypeHandler()) {
|
||||
name = GetString("PrototypeHandler");
|
||||
} else if (hCls->IsTransitionHandler()) {
|
||||
name = GetString("TransitionHandler");
|
||||
} else if (hCls->IsPropertyBox()) {
|
||||
name = GetString("PropertyBox");
|
||||
} else if (hCls->IsProtoChangeMarker()) {
|
||||
name = GetString("ProtoChangeMarker");
|
||||
} else if (hCls->IsProtoChangeDetails()) {
|
||||
name = GetString("ProtoChangeDetails");
|
||||
} else if (hCls->IsProgram()) {
|
||||
name = GetString("Program");
|
||||
} else if (hCls->IsEcmaModule()) {
|
||||
name = GetString("EcmaModule");
|
||||
} else if (hCls->IsLexicalFunction()) {
|
||||
name = GetString("LexicalFunction");
|
||||
} else if (hCls->IsConstructor()) {
|
||||
name = GetString("Constructor");
|
||||
} else if (hCls->IsExtensible()) {
|
||||
name = GetString("Extensible");
|
||||
} else if (hCls->IsPrototype()) {
|
||||
name = GetString("Prototype");
|
||||
} else if (hCls->IsLiteral()) {
|
||||
name = GetString("Literal");
|
||||
} else if (hCls->IsClassConstructor()) {
|
||||
name = GetString("ClassConstructor");
|
||||
} else if (hCls->IsJSGlobalObject()) {
|
||||
name = GetString("JSGlobalObject");
|
||||
} else if (hCls->IsClassPrototype()) {
|
||||
name = GetString("ClassPrototype");
|
||||
} else if (hCls->IsGeneratorFunction()) {
|
||||
name = GetString("GeneratorFunction");
|
||||
} else if (hCls->IsGeneratorObject()) {
|
||||
name = GetString("GeneratorObject");
|
||||
} else if (hCls->IsAsyncFuncObject()) {
|
||||
name = GetString("AsyncFunction");
|
||||
} else if (hCls->IsJSPromise()) {
|
||||
name = GetString("JSPromise");
|
||||
} else if (hCls->IsResolvingFunctionsRecord()) {
|
||||
name = GetString("ResolvingFunctionsRecord");
|
||||
} else if (hCls->IsPromiseRecord()) {
|
||||
name = GetString("PromiseRecord");
|
||||
} else if (hCls->IsPromiseIteratorRecord()) {
|
||||
name = GetString("JSPromiseIteratorRecord");
|
||||
} else if (hCls->IsPromiseCapability()) {
|
||||
name = GetString("PromiseCapability");
|
||||
} else if (hCls->IsPromiseReaction()) {
|
||||
name = GetString("JSPromiseReaction");
|
||||
} else if (hCls->IsCompletionRecord()) {
|
||||
name = GetString("CompletionRecord");
|
||||
} else if (hCls->IsRecord()) {
|
||||
name = GetString("Record");
|
||||
} else if (hCls->IsTemplateMap()) {
|
||||
name = GetString("TemplateMap");
|
||||
} else if (hCls->IsFreeObjectWithOneField()) {
|
||||
name = GetString("FreeObjectWithOneField");
|
||||
} else if (hCls->IsFreeObjectWithTwoField()) {
|
||||
name = GetString("FreeObjectWithTwoField");
|
||||
} else if (hCls->IsJSObject()) {
|
||||
case JSType::HCLASS:
|
||||
return GetString("HiddenClass");
|
||||
case JSType::TAGGED_DICTIONARY: {
|
||||
CString dictName;
|
||||
TaggedArray *dict = TaggedArray::Cast(entry);
|
||||
dictName = "TaggedDict[";
|
||||
dictName.append(ToCString(dict->GetLength()));
|
||||
dictName.append("]");
|
||||
return GetString(dictName);
|
||||
}
|
||||
case JSType::STRING:
|
||||
return GetString("BaseString");
|
||||
case JSType::JS_OBJECT: {
|
||||
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
|
||||
CString objName = CString("JSOBJECT(Ctor="); // Ctor-name
|
||||
JSTaggedValue proto = JSObject::Cast(entry)->GetPrototype(thread);
|
||||
JSHandle<JSTaggedValue> protoHandle(thread, proto);
|
||||
if (protoHandle->IsNull() || protoHandle->IsUndefined()) {
|
||||
name = GetString("JSObject(Ctor=UnKnown)");
|
||||
return name;
|
||||
return GetString("JSObject(Ctor=UnKnown)");
|
||||
}
|
||||
JSHandle<JSTaggedValue> ctor =
|
||||
JSObject::GetProperty(thread, protoHandle, globalConst->GetHandledConstructorString()).GetValue();
|
||||
@ -348,16 +180,197 @@ CString *HeapSnapShot::GenerateNodeName(JSThread *thread, TaggedObject *entry)
|
||||
JSHandle<JSTaggedValue> value = JSObject::GetProperty(thread, ctor, nameKey).GetValue();
|
||||
CString ctorName = EntryVisitor::ConvertKey(value.GetTaggedValue());
|
||||
objName.append(ctorName).append(")");
|
||||
name = GetString(objName);
|
||||
}
|
||||
} else if (hCls->IsECMAObject()) {
|
||||
name = GetString("ECMAObject");
|
||||
} else {
|
||||
name = GetString("UnEmuratedJSType");
|
||||
return GetString(objName);
|
||||
}
|
||||
return name; // Cached in String-Table
|
||||
case JSType::FREE_OBJECT_WITH_ONE_FIELD:
|
||||
case JSType::FREE_OBJECT_WITH_NONE_FIELD:
|
||||
case JSType::FREE_OBJECT_WITH_TWO_FIELD:
|
||||
case JSType::JS_NATIVE_POINTER:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case JSType::JS_FUNCTION_BASE:
|
||||
return GetString("JSFunctionBase");
|
||||
case JSType::JS_FUNCTION:
|
||||
return GetString("JSFunction");
|
||||
case JSType::JS_ERROR:
|
||||
return GetString("Error");
|
||||
case JSType::JS_EVAL_ERROR:
|
||||
return GetString("Eval Error");
|
||||
case JSType::JS_RANGE_ERROR:
|
||||
return GetString("Range Error");
|
||||
case JSType::JS_TYPE_ERROR:
|
||||
return GetString("Type Error");
|
||||
case JSType::JS_REFERENCE_ERROR:
|
||||
return GetString("Reference Error");
|
||||
case JSType::JS_URI_ERROR:
|
||||
return GetString("Uri Error");
|
||||
case JSType::JS_SYNTAX_ERROR:
|
||||
return GetString("Syntax Error");
|
||||
case JSType::JS_REG_EXP:
|
||||
return GetString("Regexp");
|
||||
case JSType::JS_SET:
|
||||
return GetString("Set");
|
||||
case JSType::JS_MAP:
|
||||
return GetString("Map");
|
||||
case JSType::JS_WEAK_SET:
|
||||
return GetString("WeakSet");
|
||||
case JSType::JS_WEAK_MAP:
|
||||
return GetString("WeakMap");
|
||||
case JSType::JS_DATE:
|
||||
return GetString("Date");
|
||||
case JSType::JS_BOUND_FUNCTION:
|
||||
return GetString("Bound Function");
|
||||
case JSType::JS_ARRAY: {
|
||||
JSArray *jsArray = JSArray::Cast(entry);
|
||||
CString jsArrayName("JSArray[");
|
||||
jsArrayName.append(ToCString(jsArray->GetLength().GetInt()));
|
||||
jsArrayName.append("]");
|
||||
return GetString(jsArrayName);
|
||||
}
|
||||
case JSType::JS_TYPED_ARRAY:
|
||||
return GetString("Typed Array");
|
||||
case JSType::JS_INT8_ARRAY:
|
||||
return GetString("Int8 Array");
|
||||
case JSType::JS_UINT8_ARRAY:
|
||||
return GetString("Uint8 Array");
|
||||
case JSType::JS_UINT8_CLAMPED_ARRAY:
|
||||
return GetString("Uint8 Clamped Array");
|
||||
case JSType::JS_INT16_ARRAY:
|
||||
return GetString("Int16 Array");
|
||||
case JSType::JS_UINT16_ARRAY:
|
||||
return GetString("Uint16 Array");
|
||||
case JSType::JS_INT32_ARRAY:
|
||||
return GetString("Int32 Array");
|
||||
case JSType::JS_UINT32_ARRAY:
|
||||
return GetString("Uint32 Array");
|
||||
case JSType::JS_FLOAT32_ARRAY:
|
||||
return GetString("Float32 Array");
|
||||
case JSType::JS_FLOAT64_ARRAY:
|
||||
return GetString("Float64 Array");
|
||||
case JSType::JS_ARGUMENTS:
|
||||
return GetString("Arguments");
|
||||
case JSType::JS_PROXY:
|
||||
return GetString("Proxy");
|
||||
case JSType::JS_PRIMITIVE_REF:
|
||||
return GetString("Primitive");
|
||||
case JSType::JS_DATA_VIEW:
|
||||
return GetString("DataView");
|
||||
case JSType::JS_ITERATOR:
|
||||
return GetString("Iterator");
|
||||
case JSType::JS_FORIN_ITERATOR:
|
||||
return GetString("ForinInterator");
|
||||
case JSType::JS_MAP_ITERATOR:
|
||||
return GetString("MapIterator");
|
||||
case JSType::JS_SET_ITERATOR:
|
||||
return GetString("SetIterator");
|
||||
case JSType::JS_ARRAY_ITERATOR:
|
||||
return GetString("ArrayIterator");
|
||||
case JSType::JS_STRING_ITERATOR:
|
||||
return GetString("StringIterator");
|
||||
case JSType::JS_ARRAY_BUFFER:
|
||||
return GetString("ArrayBuffer");
|
||||
case JSType::JS_PROXY_REVOC_FUNCTION:
|
||||
return GetString("ProxyRevocFunction");
|
||||
case JSType::PROMISE_REACTIONS:
|
||||
return GetString("PromiseReaction");
|
||||
case JSType::PROMISE_CAPABILITY:
|
||||
return GetString("PromiseCapability");
|
||||
case JSType::PROMISE_ITERATOR_RECORD:
|
||||
return GetString("PromiseIteratorRecord");
|
||||
case JSType::PROMISE_RECORD:
|
||||
return GetString("PromiseRecord");
|
||||
case JSType::RESOLVING_FUNCTIONS_RECORD:
|
||||
return GetString("ResolvingFunctionsRecord");
|
||||
case JSType::JS_PROMISE:
|
||||
return GetString("Promise");
|
||||
case JSType::JS_PROMISE_REACTIONS_FUNCTION:
|
||||
return GetString("PromiseReactionsFunction");
|
||||
case JSType::JS_PROMISE_EXECUTOR_FUNCTION:
|
||||
return GetString("PromiseExecutorFunction");
|
||||
case JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION:
|
||||
return GetString("PromiseAllResolveElementFunction");
|
||||
case JSType::JS_GENERATOR_FUNCTION:
|
||||
return GetString("JSGeneratorFunction");
|
||||
case JSType::SYMBOL:
|
||||
return GetString("Symbol");
|
||||
case JSType::JS_ASYNC_FUNCTION:
|
||||
return GetString("AsyncFunction");
|
||||
case JSType::JS_INTL_BOUND_FUNCTION:
|
||||
return GetString("JSIntlBoundFunction");
|
||||
case JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION:
|
||||
return GetString("AsyncAwaitStatusFunction");
|
||||
case JSType::JS_ASYNC_FUNC_OBJECT:
|
||||
return GetString("AsyncFunctionObject");
|
||||
case JSType::JS_REALM:
|
||||
return GetString("Realm");
|
||||
case JSType::JS_GLOBAL_OBJECT:
|
||||
return GetString("GlobalObject");
|
||||
case JSType::JS_INTL:
|
||||
return GetString("JSIntl");
|
||||
case JSType::JS_LOCALE:
|
||||
return GetString("JSLocale");
|
||||
case JSType::JS_DATE_TIME_FORMAT:
|
||||
return GetString("JSDateTimeFormat");
|
||||
case JSType::JS_RELATIVE_TIME_FORMAT:
|
||||
return GetString("JSRelativeTimeFormat");
|
||||
case JSType::JS_NUMBER_FORMAT:
|
||||
return GetString("JSNumberFormat");
|
||||
case JSType::JS_COLLATOR:
|
||||
return GetString("JSCollator");
|
||||
case JSType::JS_PLURAL_RULES:
|
||||
return GetString("JSPluralRules");
|
||||
case JSType::JS_GENERATOR_OBJECT:
|
||||
return GetString("JSGeneratorObject");
|
||||
case JSType::JS_GENERATOR_CONTEXT:
|
||||
return GetString("JSGeneratorContext");
|
||||
case JSType::ACCESSOR_DATA:
|
||||
return GetString("AccessorData");
|
||||
case JSType::INTERNAL_ACCESSOR:
|
||||
return GetString("InternalAccessor");
|
||||
case JSType::FUNCTION_EXTRA_INFO:
|
||||
return GetString("FunctionExtraInfo");
|
||||
case JSType::MICRO_JOB_QUEUE:
|
||||
return GetString("MicroJobQueue");
|
||||
case JSType::PENDING_JOB:
|
||||
return GetString("PendingJob");
|
||||
case JSType::COMPLETION_RECORD:
|
||||
return GetString("CompletionRecord");
|
||||
case JSType::ECMA_MODULE:
|
||||
return GetString("EcmaModule");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return name;
|
||||
if (IsInVmMode()) {
|
||||
switch (type) {
|
||||
case JSType::PROPERTY_BOX:
|
||||
return GetString("PropertyBox");
|
||||
case JSType::GLOBAL_ENV:
|
||||
return GetString("GlobalEnv");
|
||||
case JSType::PROTOTYPE_HANDLER:
|
||||
return GetString("ProtoTypeHandler");
|
||||
case JSType::TRANSITION_HANDLER:
|
||||
return GetString("TransitionHandler");
|
||||
case JSType::PROTO_CHANGE_MARKER:
|
||||
return GetString("ProtoChangeMarker");
|
||||
case JSType::PROTOTYPE_INFO:
|
||||
return GetString("ProtoChangeDetails");
|
||||
case JSType::TEMPLATE_MAP:
|
||||
return GetString("TemplateMap");
|
||||
case JSType::PROGRAM:
|
||||
return GetString("Program");
|
||||
case JSType::LEXICAL_FUNCTION:
|
||||
return GetString("LexicalFunction");
|
||||
case JSType::MACHINE_CODE_OBJECT:
|
||||
return GetString("MachineCode");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return GetString("Hidden Object");
|
||||
}
|
||||
return GetString("UnKnownType");
|
||||
}
|
||||
|
||||
NodeType HeapSnapShot::GenerateNodeType(TaggedObject *entry)
|
||||
@ -367,7 +380,7 @@ NodeType HeapSnapShot::GenerateNodeType(TaggedObject *entry)
|
||||
if (hCls->IsTaggedArray()) {
|
||||
nodeType = NodeType::JS_ARRAY;
|
||||
} else if (hCls->IsHClass()) {
|
||||
nodeType = NodeType::PROPERTY_BOX;
|
||||
nodeType = NodeType::HCLASS;
|
||||
} else {
|
||||
nodeType = NodeType(hCls->GetObjectType());
|
||||
}
|
||||
@ -489,7 +502,7 @@ void HeapSnapShot::FillEdges(JSThread *thread)
|
||||
ASSERT(*iter != nullptr);
|
||||
auto *objFrom = reinterpret_cast<TaggedObject *>((*iter)->GetAddress());
|
||||
std::vector<std::pair<CString, JSTaggedValue>> nameResources;
|
||||
JSTaggedValue(objFrom).DumpForSnapshot(thread, nameResources);
|
||||
JSTaggedValue(objFrom).DumpForSnapshot(thread, nameResources, isVmMode_);
|
||||
JSTaggedValue objValue(objFrom);
|
||||
for (auto const &it : nameResources) {
|
||||
JSTaggedValue toValue = it.second;
|
||||
|
@ -236,8 +236,8 @@ public:
|
||||
static constexpr int SEQ_STEP = 2;
|
||||
NO_MOVE_SEMANTIC(HeapSnapShot);
|
||||
NO_COPY_SEMANTIC(HeapSnapShot);
|
||||
explicit HeapSnapShot(JSThread *thread, const Heap *heap)
|
||||
: stringTable_(heap), thread_(thread), heap_(heap)
|
||||
explicit HeapSnapShot(JSThread *thread, const Heap *heap, const bool isVmMode)
|
||||
: stringTable_(heap), thread_(thread), heap_(heap), isVmMode_(isVmMode)
|
||||
{
|
||||
}
|
||||
~HeapSnapShot();
|
||||
@ -293,6 +293,11 @@ public:
|
||||
|
||||
CString *GetString(const CString &as);
|
||||
|
||||
bool IsInVmMode() const
|
||||
{
|
||||
return isVmMode_;
|
||||
}
|
||||
|
||||
private:
|
||||
void FillNodes(JSThread *thread);
|
||||
Node *GenerateNode(JSThread *thread, JSTaggedValue entry, int sequenceId = -1);
|
||||
@ -320,6 +325,7 @@ private:
|
||||
panda::ecmascript::HeapRootVisitor rootVisitor_;
|
||||
JSThread *thread_;
|
||||
const Heap *heap_;
|
||||
bool isVmMode_{true};
|
||||
};
|
||||
|
||||
class EntryVisitor {
|
||||
|
@ -16,20 +16,76 @@
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
|
||||
#include "ecmascript/accessor_data.h"
|
||||
#include "ecmascript/class_linker/program_object-inl.h"
|
||||
#include "ecmascript/ecma_module.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/global_dictionary-inl.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/hprof/heap_profiler.h"
|
||||
#include "ecmascript/hprof/heap_profiler_interface.h"
|
||||
#include "ecmascript/hprof/heap_snapshot.h"
|
||||
#include "ecmascript/hprof/heap_snapshot_json_serializer.h"
|
||||
#include "ecmascript/hprof/string_hashmap.h"
|
||||
#include "ecmascript/ic/ic_handler.h"
|
||||
#include "ecmascript/ic/proto_change_details.h"
|
||||
#include "ecmascript/ic/property_box.h"
|
||||
#include "ecmascript/jobs/micro_job_queue.h"
|
||||
#include "ecmascript/jobs/pending_job.h"
|
||||
#include "ecmascript/js_arguments.h"
|
||||
#include "ecmascript/js_array.h"
|
||||
#include "ecmascript/js_array_iterator.h"
|
||||
#include "ecmascript/js_arraybuffer.h"
|
||||
#include "ecmascript/js_async_function.h"
|
||||
#include "ecmascript/js_collator.h"
|
||||
#include "ecmascript/js_dataview.h"
|
||||
#include "ecmascript/js_date.h"
|
||||
#include "ecmascript/js_date_time_format.h"
|
||||
#include "ecmascript/js_for_in_iterator.h"
|
||||
#include "ecmascript/js_function.h"
|
||||
#include "ecmascript/js_function_extra_info.h"
|
||||
#include "ecmascript/js_generator_object.h"
|
||||
#include "ecmascript/js_global_object.h"
|
||||
#include "ecmascript/js_handle.h"
|
||||
#include "ecmascript/js_intl.h"
|
||||
#include "ecmascript/js_locale.h"
|
||||
#include "ecmascript/js_map.h"
|
||||
#include "ecmascript/js_map_iterator.h"
|
||||
#include "ecmascript/js_number_format.h"
|
||||
#include "ecmascript/js_object-inl.h"
|
||||
#include "ecmascript/js_plural_rules.h"
|
||||
#include "ecmascript/js_primitive_ref.h"
|
||||
#include "ecmascript/js_promise.h"
|
||||
#include "ecmascript/js_realm.h"
|
||||
#include "ecmascript/js_regexp.h"
|
||||
#include "ecmascript/js_relative_time_format.h"
|
||||
#include "ecmascript/js_set.h"
|
||||
#include "ecmascript/js_set_iterator.h"
|
||||
#include "ecmascript/js_string_iterator.h"
|
||||
#include "ecmascript/js_tagged_number.h"
|
||||
#include "ecmascript/js_tagged_value-inl.h"
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/js_typed_array.h"
|
||||
#include "ecmascript/js_weak_container.h"
|
||||
#include "ecmascript/layout_info-inl.h"
|
||||
#include "ecmascript/lexical_env.h"
|
||||
#include "ecmascript/linked_hash_table-inl.h"
|
||||
#include "ecmascript/mem/assert_scope-inl.h"
|
||||
#include "ecmascript/mem/c_containers.h"
|
||||
#include "ecmascript/mem/machine_code.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
#include "ecmascript/tagged_array.h"
|
||||
#include "ecmascript/tagged_dictionary.h"
|
||||
#include "ecmascript/template_map.h"
|
||||
#include "ecmascript/tests/test_helper.h"
|
||||
#include "ecmascript/transitions_dictionary.h"
|
||||
|
||||
using namespace panda::ecmascript;
|
||||
using namespace panda::ecmascript::base;
|
||||
|
||||
namespace panda::test {
|
||||
using MicroJobQueue = panda::ecmascript::job::MicroJobQueue;
|
||||
using PendingJob = panda::ecmascript::job::PendingJob;
|
||||
class HProfTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase()
|
||||
@ -332,4 +388,502 @@ HWTEST_F_L0(HProfTest, ContrastTraceFunctionInfoCount)
|
||||
tester.ExtractCountFromPayload("\"trace_function_infos\":"));
|
||||
ASSERT_TRUE(tester.RemoveExistingFile());
|
||||
}
|
||||
|
||||
static JSHandle<JSMap> NewJSMap(JSThread *thread, ObjectFactory *factory, JSHandle<JSTaggedValue> proto)
|
||||
{
|
||||
JSHandle<JSHClass> mapClass = factory->NewEcmaDynClass(JSMap::SIZE, JSType::JS_MAP, proto);
|
||||
JSHandle<JSMap> jsMap = JSHandle<JSMap>::Cast(factory->NewJSObject(mapClass));
|
||||
JSHandle<JSTaggedValue> linkedMap(thread, LinkedHashMap::Create(thread));
|
||||
jsMap->SetLinkedMap(thread, linkedMap);
|
||||
return jsMap;
|
||||
}
|
||||
|
||||
static JSHandle<JSSet> NewJSSet(JSThread *thread, ObjectFactory *factory, JSHandle<JSTaggedValue> proto)
|
||||
{
|
||||
JSHandle<JSHClass> setClass = factory->NewEcmaDynClass(JSSet::SIZE, JSType::JS_SET, proto);
|
||||
JSHandle<JSSet> jsSet = JSHandle<JSSet>::Cast(factory->NewJSObject(setClass));
|
||||
JSHandle<JSTaggedValue> linkedSet(thread, LinkedHashSet::Create(thread));
|
||||
jsSet->SetLinkedSet(thread, linkedSet);
|
||||
return jsSet;
|
||||
}
|
||||
|
||||
static JSHandle<JSObject> NewJSObject(JSThread *thread, ObjectFactory *factory, JSHandle<GlobalEnv> globalEnv)
|
||||
{
|
||||
JSFunction *jsFunc = globalEnv->GetObjectFunction().GetObject<JSFunction>();
|
||||
JSHandle<JSTaggedValue> jsFunc1(thread, jsFunc);
|
||||
JSHandle<JSObject> jsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(jsFunc1), jsFunc1);
|
||||
return jsObj;
|
||||
}
|
||||
|
||||
HWTEST_F_L0(HProfTest, Dump)
|
||||
{
|
||||
[[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
|
||||
auto factory = thread->GetEcmaVM()->GetFactory();
|
||||
auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
|
||||
auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
|
||||
JSHandle<JSTaggedValue> proto = globalEnv->GetFunctionPrototype();
|
||||
std::vector<std::pair<CString, JSTaggedValue>> snapshotVector;
|
||||
|
||||
#define DUMP_FOR_HANDLE(dumpHandle) \
|
||||
dumpHandle.GetTaggedValue().Dump(thread); \
|
||||
dumpHandle.GetTaggedValue().DumpForSnapshot(thread, snapshotVector);
|
||||
|
||||
#define NEW_OBJECT_AND_DUMP(ClassName, TypeName) \
|
||||
JSHandle<JSHClass> class##ClassName = \
|
||||
factory->NewEcmaDynClass(ClassName::SIZE, JSType::TypeName, proto); \
|
||||
JSHandle<JSObject> object##ClassName = factory->NewJSObject(class##ClassName); \
|
||||
object##ClassName.GetTaggedValue().Dump(thread); \
|
||||
object##ClassName.GetTaggedValue().DumpForSnapshot(thread, snapshotVector);
|
||||
|
||||
for (JSType type = JSType::JS_OBJECT; type <= JSType::JS_TYPE_LAST; type = JSType(static_cast<int>(type) + 1)) {
|
||||
switch (type) {
|
||||
case JSType::JS_ERROR:
|
||||
case JSType::JS_EVAL_ERROR:
|
||||
case JSType::JS_RANGE_ERROR:
|
||||
case JSType::JS_TYPE_ERROR:
|
||||
case JSType::JS_REFERENCE_ERROR:
|
||||
case JSType::JS_URI_ERROR:
|
||||
case JSType::JS_SYNTAX_ERROR:
|
||||
case JSType::JS_OBJECT: {
|
||||
CHECK_DUMP_FILEDS(ECMAObject::SIZE, JSObject::SIZE, 2)
|
||||
JSHandle<JSObject> jsObj = NewJSObject(thread, factory, globalEnv);
|
||||
DUMP_FOR_HANDLE(jsObj)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_REALM: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSRealm::SIZE, 2)
|
||||
JSHandle<JSRealm> jsRealm = factory->NewJSRealm();
|
||||
DUMP_FOR_HANDLE(jsRealm)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_FUNCTION_BASE: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSFunctionBase::SIZE, 1)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_FUNCTION: {
|
||||
CHECK_DUMP_FILEDS(JSFunctionBase::SIZE, JSFunction::SIZE, 7)
|
||||
JSHandle<JSTaggedValue> jsFunc = globalEnv->GetFunctionFunction();
|
||||
DUMP_FOR_HANDLE(jsFunc)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_PROXY_REVOC_FUNCTION: {
|
||||
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSProxyRevocFunction::SIZE, 1)
|
||||
JSHandle<JSHClass> proxyRevocClass =
|
||||
JSHandle<JSHClass>::Cast(globalEnv->GetProxyRevocFunctionClass());
|
||||
JSHandle<JSObject> proxyRevocFunc = factory->NewJSObject(proxyRevocClass);
|
||||
DUMP_FOR_HANDLE(proxyRevocFunc)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_PROMISE_REACTIONS_FUNCTION: {
|
||||
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSPromiseReactionsFunction::SIZE, 2)
|
||||
JSHandle<JSHClass> promiseReactClass =
|
||||
JSHandle<JSHClass>::Cast(globalEnv->GetPromiseReactionFunctionClass());
|
||||
JSHandle<JSObject> promiseReactFunc = factory->NewJSObject(promiseReactClass);
|
||||
DUMP_FOR_HANDLE(promiseReactFunc)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_PROMISE_EXECUTOR_FUNCTION: {
|
||||
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSPromiseExecutorFunction::SIZE, 1)
|
||||
JSHandle<JSHClass> promiseExeClass =
|
||||
JSHandle<JSHClass>::Cast(globalEnv->GetPromiseExecutorFunctionClass());
|
||||
JSHandle<JSObject> promiseExeFunc = factory->NewJSObject(promiseExeClass);
|
||||
DUMP_FOR_HANDLE(promiseExeFunc)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION: {
|
||||
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSPromiseAllResolveElementFunction::SIZE, 5)
|
||||
JSHandle<JSHClass> promiseAllClass =
|
||||
JSHandle<JSHClass>::Cast(globalEnv->GetPromiseAllResolveElementFunctionClass());
|
||||
JSHandle<JSObject> promiseAllFunc = factory->NewJSObject(promiseAllClass);
|
||||
DUMP_FOR_HANDLE(promiseAllFunc)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_GENERATOR_FUNCTION: {
|
||||
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSGeneratorFunction::SIZE, 0)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_ASYNC_FUNCTION: {
|
||||
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSAsyncFunction::SIZE, 0)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_INTL_BOUND_FUNCTION: {
|
||||
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSIntlBoundFunction::SIZE, 3)
|
||||
JSHandle<JSIntlBoundFunction> intlBoundFunc = factory->NewJSIntlBoundFunction();
|
||||
DUMP_FOR_HANDLE(intlBoundFunc)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION: {
|
||||
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSAsyncAwaitStatusFunction::SIZE, 1)
|
||||
JSHandle<JSAsyncAwaitStatusFunction> asyncAwaitFunc = factory->NewJSAsyncAwaitStatusFunction();
|
||||
DUMP_FOR_HANDLE(asyncAwaitFunc)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_BOUND_FUNCTION: {
|
||||
CHECK_DUMP_FILEDS(JSFunctionBase::SIZE, JSBoundFunction::SIZE, 3)
|
||||
NEW_OBJECT_AND_DUMP(JSBoundFunction, JS_BOUND_FUNCTION)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_REG_EXP: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSRegExp::SIZE, 5)
|
||||
NEW_OBJECT_AND_DUMP(JSRegExp, JS_REG_EXP)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_SET: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSSet::SIZE, 1)
|
||||
JSHandle<JSSet> jsSet = NewJSSet(thread, factory, proto);
|
||||
DUMP_FOR_HANDLE(jsSet)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_MAP: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSMap::SIZE, 1)
|
||||
JSHandle<JSMap> jsMap = NewJSMap(thread, factory, proto);
|
||||
DUMP_FOR_HANDLE(jsMap)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_WEAK_MAP: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSWeakMap::SIZE, 1)
|
||||
JSHandle<JSHClass> weakMapClass = factory->NewEcmaDynClass(JSWeakMap::SIZE, JSType::JS_WEAK_MAP, proto);
|
||||
JSHandle<JSWeakMap> jsWeakMap = JSHandle<JSWeakMap>::Cast(factory->NewJSObject(weakMapClass));
|
||||
JSHandle<JSTaggedValue> weakLinkedMap(thread, LinkedHashMap::Create(thread));
|
||||
jsWeakMap->SetLinkedMap(thread, weakLinkedMap);
|
||||
DUMP_FOR_HANDLE(jsWeakMap)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_WEAK_SET: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSWeakSet::SIZE, 1)
|
||||
JSHandle<JSHClass> weakSetClass = factory->NewEcmaDynClass(JSWeakSet::SIZE, JSType::JS_WEAK_SET, proto);
|
||||
JSHandle<JSWeakSet> jsWeakSet = JSHandle<JSWeakSet>::Cast(factory->NewJSObject(weakSetClass));
|
||||
JSHandle<JSTaggedValue> weakLinkedSet(thread, LinkedHashSet::Create(thread));
|
||||
jsWeakSet->SetLinkedSet(thread, weakLinkedSet);
|
||||
DUMP_FOR_HANDLE(jsWeakSet)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_DATE: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSDate::SIZE, 2)
|
||||
JSHandle<JSHClass> dateClass = factory->NewEcmaDynClass(JSDate::SIZE, JSType::JS_DATE, proto);
|
||||
JSHandle<JSDate> date = JSHandle<JSDate>::Cast(factory->NewJSObject(dateClass));
|
||||
date->SetTimeValue(thread, JSTaggedValue(0.0));
|
||||
date->SetLocalOffset(thread, JSTaggedValue(0.0));
|
||||
DUMP_FOR_HANDLE(date)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_ITERATOR:
|
||||
// JS Iterate is a tool class, so we don't need to check it.
|
||||
break;
|
||||
case JSType::JS_FORIN_ITERATOR: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSForInIterator::SIZE, 4)
|
||||
JSHandle<JSTaggedValue> array(thread, factory->NewJSArray().GetTaggedValue());
|
||||
JSHandle<JSForInIterator> forInIter = factory->NewJSForinIterator(array);
|
||||
DUMP_FOR_HANDLE(forInIter)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_MAP_ITERATOR: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSMapIterator::SIZE, 3)
|
||||
JSHandle<JSMapIterator> jsMapIter =
|
||||
factory->NewJSMapIterator(NewJSMap(thread, factory, proto), IterationKind::KEY);
|
||||
DUMP_FOR_HANDLE(jsMapIter)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_SET_ITERATOR: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSSetIterator::SIZE, 3)
|
||||
JSHandle<JSSetIterator> jsSetIter =
|
||||
factory->NewJSSetIterator(NewJSSet(thread, factory, proto), IterationKind::KEY);
|
||||
DUMP_FOR_HANDLE(jsSetIter)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_ARRAY_ITERATOR: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSArrayIterator::SIZE, 3)
|
||||
JSHandle<JSArrayIterator> arrayIter =
|
||||
factory->NewJSArrayIterator(JSHandle<JSObject>::Cast(factory->NewJSArray()), IterationKind::KEY);
|
||||
DUMP_FOR_HANDLE(arrayIter)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_STRING_ITERATOR: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSStringIterator::SIZE, 2)
|
||||
JSHandle<JSTaggedValue> stringIter = globalEnv->GetStringIterator();
|
||||
DUMP_FOR_HANDLE(stringIter)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_INTL: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSIntl::SIZE, 1)
|
||||
NEW_OBJECT_AND_DUMP(JSIntl, JS_INTL)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_LOCALE: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSLocale::SIZE, 1)
|
||||
NEW_OBJECT_AND_DUMP(JSLocale, JS_LOCALE)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_DATE_TIME_FORMAT: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSDateTimeFormat::SIZE, 11)
|
||||
NEW_OBJECT_AND_DUMP(JSDateTimeFormat, JS_DATE_TIME_FORMAT)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_RELATIVE_TIME_FORMAT: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSRelativeTimeFormat::SIZE, 7)
|
||||
NEW_OBJECT_AND_DUMP(JSRelativeTimeFormat, JS_RELATIVE_TIME_FORMAT)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_NUMBER_FORMAT: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSNumberFormat::SIZE, 20)
|
||||
NEW_OBJECT_AND_DUMP(JSNumberFormat, JS_NUMBER_FORMAT)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_COLLATOR: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSCollator::SIZE, 9)
|
||||
NEW_OBJECT_AND_DUMP(JSCollator, JS_COLLATOR)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_PLURAL_RULES: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSPluralRules::SIZE, 11)
|
||||
NEW_OBJECT_AND_DUMP(JSPluralRules, JS_PLURAL_RULES)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_ARRAY_BUFFER: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSArrayBuffer::SIZE, 3)
|
||||
NEW_OBJECT_AND_DUMP(JSArrayBuffer, JS_ARRAY_BUFFER)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_PROMISE: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSPromise::SIZE, 5)
|
||||
NEW_OBJECT_AND_DUMP(JSPromise, JS_PROMISE)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_DATA_VIEW: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSDataView::SIZE, 4)
|
||||
NEW_OBJECT_AND_DUMP(JSDataView, JS_DATA_VIEW)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_ARGUMENTS: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSArguments::SIZE, 1)
|
||||
NEW_OBJECT_AND_DUMP(JSArguments, JS_ARGUMENTS)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_GENERATOR_OBJECT: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSGeneratorObject::SIZE, 4)
|
||||
NEW_OBJECT_AND_DUMP(JSGeneratorObject, JS_GENERATOR_OBJECT)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_ASYNC_FUNC_OBJECT: {
|
||||
CHECK_DUMP_FILEDS(JSGeneratorObject::SIZE, JSAsyncFuncObject::SIZE, 1)
|
||||
JSHandle<JSAsyncFuncObject> asyncFuncObject = factory->NewJSAsyncFuncObject();
|
||||
DUMP_FOR_HANDLE(asyncFuncObject)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_ARRAY: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSArray::SIZE, 1)
|
||||
JSHandle<JSArray> jsArray = factory->NewJSArray();
|
||||
DUMP_FOR_HANDLE(jsArray)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_TYPED_ARRAY:
|
||||
case JSType::JS_INT8_ARRAY:
|
||||
case JSType::JS_UINT8_ARRAY:
|
||||
case JSType::JS_UINT8_CLAMPED_ARRAY:
|
||||
case JSType::JS_INT16_ARRAY:
|
||||
case JSType::JS_UINT16_ARRAY:
|
||||
case JSType::JS_INT32_ARRAY:
|
||||
case JSType::JS_UINT32_ARRAY:
|
||||
case JSType::JS_FLOAT32_ARRAY:
|
||||
case JSType::JS_FLOAT64_ARRAY: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSTypedArray::SIZE, 5)
|
||||
NEW_OBJECT_AND_DUMP(JSTypedArray, JS_TYPED_ARRAY)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_PRIMITIVE_REF: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSPrimitiveRef::SIZE, 1)
|
||||
NEW_OBJECT_AND_DUMP(JSPrimitiveRef, JS_PRIMITIVE_REF)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_GLOBAL_OBJECT: {
|
||||
CHECK_DUMP_FILEDS(JSObject::SIZE, JSGlobalObject::SIZE, 0)
|
||||
JSHandle<JSTaggedValue> globalObject = globalEnv->GetJSGlobalObject();
|
||||
DUMP_FOR_HANDLE(globalObject)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_PROXY: {
|
||||
CHECK_DUMP_FILEDS(ECMAObject::SIZE, JSProxy::SIZE, 3)
|
||||
JSHandle<JSTaggedValue> emptyObj(thread, NewJSObject(thread, factory, globalEnv).GetTaggedValue());
|
||||
JSHandle<JSProxy> proxy = factory->NewJSProxy(emptyObj, emptyObj);
|
||||
DUMP_FOR_HANDLE(proxy)
|
||||
break;
|
||||
}
|
||||
case JSType::HCLASS: {
|
||||
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), JSHClass::SIZE, 9)
|
||||
JSHandle<JSHClass> hclass = factory->NewEcmaDynClass(JSHClass::SIZE, JSType::HCLASS, proto);
|
||||
DUMP_FOR_HANDLE(hclass)
|
||||
break;
|
||||
}
|
||||
case JSType::STRING: {
|
||||
DUMP_FOR_HANDLE(globalEnv->GetObjectFunction())
|
||||
break;
|
||||
}
|
||||
case JSType::TAGGED_ARRAY: {
|
||||
JSHandle<TaggedArray> taggedArray = factory->NewTaggedArray(4);
|
||||
DUMP_FOR_HANDLE(taggedArray)
|
||||
break;
|
||||
}
|
||||
case JSType::TAGGED_DICTIONARY: {
|
||||
JSHandle<TaggedArray> dict = factory->NewDictionaryArray(4);
|
||||
DUMP_FOR_HANDLE(dict)
|
||||
break;
|
||||
}
|
||||
case JSType::FREE_OBJECT_WITH_ONE_FIELD:
|
||||
case JSType::FREE_OBJECT_WITH_NONE_FIELD:
|
||||
case JSType::FREE_OBJECT_WITH_TWO_FIELD:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case JSType::JS_NATIVE_POINTER: {
|
||||
break;
|
||||
}
|
||||
case JSType::GLOBAL_ENV: {
|
||||
DUMP_FOR_HANDLE(globalEnv)
|
||||
break;
|
||||
}
|
||||
case JSType::ACCESSOR_DATA:
|
||||
case JSType::INTERNAL_ACCESSOR: {
|
||||
CHECK_DUMP_FILEDS(Record::SIZE, AccessorData::SIZE, 2)
|
||||
JSHandle<AccessorData> accessor = factory->NewAccessorData();
|
||||
DUMP_FOR_HANDLE(accessor)
|
||||
break;
|
||||
}
|
||||
case JSType::SYMBOL: {
|
||||
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), JSSymbol::SIZE, 3)
|
||||
JSHandle<JSSymbol> symbol = factory->NewJSSymbol();
|
||||
DUMP_FOR_HANDLE(symbol)
|
||||
break;
|
||||
}
|
||||
case JSType::JS_GENERATOR_CONTEXT: {
|
||||
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), GeneratorContext::SIZE, 7)
|
||||
JSHandle<GeneratorContext> genContext = factory->NewGeneratorContext();
|
||||
DUMP_FOR_HANDLE(genContext)
|
||||
break;
|
||||
}
|
||||
case JSType::PROTOTYPE_HANDLER: {
|
||||
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), PrototypeHandler::SIZE, 3)
|
||||
JSHandle<PrototypeHandler> protoHandler = factory->NewPrototypeHandler();
|
||||
DUMP_FOR_HANDLE(protoHandler)
|
||||
break;
|
||||
}
|
||||
case JSType::TRANSITION_HANDLER: {
|
||||
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), TransitionHandler::SIZE, 2)
|
||||
JSHandle<TransitionHandler> transitionHandler = factory->NewTransitionHandler();
|
||||
DUMP_FOR_HANDLE(transitionHandler)
|
||||
break;
|
||||
}
|
||||
case JSType::PROPERTY_BOX: {
|
||||
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), PropertyBox::SIZE, 1)
|
||||
JSHandle<PropertyBox> PropertyBox = factory->NewPropertyBox(globalEnv->GetEmptyArray());
|
||||
DUMP_FOR_HANDLE(PropertyBox)
|
||||
break;
|
||||
}
|
||||
case JSType::PROTO_CHANGE_MARKER: {
|
||||
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), ProtoChangeMarker::SIZE, 1)
|
||||
JSHandle<ProtoChangeMarker> protoMaker = factory->NewProtoChangeMarker();
|
||||
DUMP_FOR_HANDLE(protoMaker)
|
||||
break;
|
||||
}
|
||||
case JSType::PROTOTYPE_INFO: {
|
||||
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), ProtoChangeDetails::SIZE, 2)
|
||||
JSHandle<ProtoChangeDetails> protoDetails = factory->NewProtoChangeDetails();
|
||||
DUMP_FOR_HANDLE(protoDetails)
|
||||
break;
|
||||
}
|
||||
case JSType::TEMPLATE_MAP: {
|
||||
JSHandle<JSTaggedValue> templateMap = globalEnv->GetTemplateMap();
|
||||
DUMP_FOR_HANDLE(templateMap)
|
||||
break;
|
||||
}
|
||||
case JSType::PROGRAM: {
|
||||
CHECK_DUMP_FILEDS(ECMAObject::SIZE, Program::SIZE, 5)
|
||||
JSHandle<Program> program = factory->NewProgram();
|
||||
DUMP_FOR_HANDLE(program)
|
||||
break;
|
||||
}
|
||||
case JSType::LEXICAL_FUNCTION: {
|
||||
CHECK_DUMP_FILEDS(ECMAObject::SIZE, LexicalFunction::SIZE, 5)
|
||||
// unused
|
||||
break;
|
||||
}
|
||||
case JSType::PROMISE_CAPABILITY: {
|
||||
CHECK_DUMP_FILEDS(Record::SIZE, PromiseCapability::SIZE, 3)
|
||||
JSHandle<PromiseCapability> promiseCapa = factory->NewPromiseCapability();
|
||||
DUMP_FOR_HANDLE(promiseCapa)
|
||||
break;
|
||||
}
|
||||
case JSType::PROMISE_RECORD: {
|
||||
CHECK_DUMP_FILEDS(Record::SIZE, PromiseRecord::SIZE, 1)
|
||||
JSHandle<PromiseRecord> promiseRecord = factory->NewPromiseRecord();
|
||||
DUMP_FOR_HANDLE(promiseRecord)
|
||||
break;
|
||||
}
|
||||
case JSType::RESOLVING_FUNCTIONS_RECORD: {
|
||||
CHECK_DUMP_FILEDS(Record::SIZE, ResolvingFunctionsRecord::SIZE, 2)
|
||||
JSHandle<ResolvingFunctionsRecord> ResolvingFunc = factory->NewResolvingFunctionsRecord();
|
||||
DUMP_FOR_HANDLE(ResolvingFunc)
|
||||
break;
|
||||
}
|
||||
case JSType::PROMISE_REACTIONS: {
|
||||
CHECK_DUMP_FILEDS(Record::SIZE, PromiseReaction::SIZE, 3)
|
||||
JSHandle<PromiseReaction> promiseReact = factory->NewPromiseReaction();
|
||||
DUMP_FOR_HANDLE(promiseReact)
|
||||
break;
|
||||
}
|
||||
case JSType::PROMISE_ITERATOR_RECORD: {
|
||||
CHECK_DUMP_FILEDS(Record::SIZE, PromiseIteratorRecord::SIZE, 2)
|
||||
JSHandle<JSTaggedValue> emptyObj(thread, NewJSObject(thread, factory, globalEnv).GetTaggedValue());
|
||||
JSHandle<PromiseIteratorRecord> promiseIter = factory->NewPromiseIteratorRecord(emptyObj, emptyObj);
|
||||
DUMP_FOR_HANDLE(promiseIter)
|
||||
break;
|
||||
}
|
||||
case JSType::MICRO_JOB_QUEUE: {
|
||||
CHECK_DUMP_FILEDS(Record::SIZE, MicroJobQueue::SIZE, 2)
|
||||
JSHandle<MicroJobQueue> microJob = factory->NewMicroJobQueue();
|
||||
DUMP_FOR_HANDLE(microJob)
|
||||
break;
|
||||
}
|
||||
case JSType::PENDING_JOB: {
|
||||
CHECK_DUMP_FILEDS(Record::SIZE, PendingJob::SIZE, 2)
|
||||
JSHandle<JSHClass> pendingClass(thread,
|
||||
JSHClass::Cast(globalConst->GetPendingJobClass().GetTaggedObject()));
|
||||
JSHandle<TaggedObject> pendingJob(thread, factory->NewDynObject(pendingClass));
|
||||
DUMP_FOR_HANDLE(pendingJob)
|
||||
break;
|
||||
}
|
||||
case JSType::FUNCTION_EXTRA_INFO: {
|
||||
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), JSFunctionExtraInfo::SIZE, 2)
|
||||
JSHandle<JSHClass> funcExtraClass(thread,
|
||||
JSHClass::Cast(globalConst->GetFunctionExtraInfoClass().GetTaggedObject()));
|
||||
JSHandle<TaggedObject> funcInfo(thread, factory->NewDynObject(funcExtraClass));
|
||||
DUMP_FOR_HANDLE(funcInfo)
|
||||
break;
|
||||
}
|
||||
case JSType::COMPLETION_RECORD: {
|
||||
CHECK_DUMP_FILEDS(Record::SIZE, CompletionRecord::SIZE, 2)
|
||||
JSHandle<CompletionRecord> comRecord = factory->NewCompletionRecord(0, globalEnv->GetEmptyArray());
|
||||
DUMP_FOR_HANDLE(comRecord)
|
||||
break;
|
||||
}
|
||||
case JSType::MACHINE_CODE_OBJECT: {
|
||||
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), MachineCode::DATA_OFFSET, 1)
|
||||
JSHandle<MachineCode> machineCode = factory->NewMachineCodeObject(16, nullptr);
|
||||
DUMP_FOR_HANDLE(machineCode)
|
||||
break;
|
||||
}
|
||||
case JSType::ECMA_MODULE: {
|
||||
CHECK_DUMP_FILEDS(ECMAObject::SIZE, EcmaModule::SIZE, 1)
|
||||
JSHandle<EcmaModule> ecmaModule = factory->NewEmptyEcmaModule();
|
||||
DUMP_FOR_HANDLE(ecmaModule)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_ECMA_MEM(ERROR) << "JSType " << static_cast<int>(type) << " cannot be dumped.";
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
#undef NEW_OBJECT_AND_DUMP
|
||||
#undef DUMP_FOR_HANDLE
|
||||
}
|
||||
} // namespace panda::test
|
||||
|
@ -122,6 +122,7 @@ public:
|
||||
ACCESSORS(TransitionHClass, TRANSITION_HCLASS_OFFSET, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT(HANDLER_INFO_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
};
|
||||
|
||||
class PrototypeHandler : public TaggedObject {
|
||||
@ -146,6 +147,7 @@ public:
|
||||
ACCESSORS(Holder, HOLDER_OFFSET, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT(HANDLER_INFO_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_IC_IC_HANDLER_H
|
||||
|
@ -42,6 +42,7 @@ public:
|
||||
ACCESSORS(Value, VALUE_OFFSET, SIZE);
|
||||
|
||||
DECL_VISIT_OBJECT(VALUE_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
};
|
||||
} // namespace ecmascript
|
||||
} // namespace panda
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
|
||||
static constexpr size_t HAS_CHANGED_OFFSET = TaggedObjectSize();
|
||||
SET_GET_PRIMITIVE_FIELD(HasChanged, bool, HAS_CHANGED_OFFSET, SIZE);
|
||||
DECL_DUMP()
|
||||
};
|
||||
|
||||
class ProtoChangeDetails : public TaggedObject {
|
||||
@ -51,6 +52,7 @@ public:
|
||||
ACCESSORS(RegisterIndex, REGISTER_INDEX_OFFSET, SIZE);
|
||||
|
||||
DECL_VISIT_OBJECT(CHANGE_LISTENER_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
};
|
||||
|
||||
class ChangeListener : public WeakVector {
|
||||
|
@ -269,8 +269,8 @@ JSTaggedValue FastRuntimeStub::AddPropertyByName(JSThread *thread, JSTaggedValue
|
||||
// change to dictionary and add one.
|
||||
JSHandle<NameDictionary> dict(JSObject::TransitionToDictionary(thread, objHandle));
|
||||
attr.SetDictionaryOrder(PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES);
|
||||
auto result = JSTaggedValue(NameDictionary::PutIfAbsent(thread, dict, keyHandle, valueHandle, attr));
|
||||
objHandle->SetProperties(thread, result);
|
||||
NameDictionary *newDict = NameDictionary::PutIfAbsent(thread, dict, keyHandle, valueHandle, attr);
|
||||
objHandle->SetProperties(thread, JSTaggedValue(newDict));
|
||||
// index is not essential when fastMode is false;
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
@ -286,8 +286,8 @@ JSTaggedValue FastRuntimeStub::AddPropertyByName(JSThread *thread, JSTaggedValue
|
||||
array->Set(thread, outProps, valueHandle.GetTaggedValue());
|
||||
} else {
|
||||
JSHandle<NameDictionary> dictHandle(array);
|
||||
auto result = JSTaggedValue(NameDictionary::PutIfAbsent(thread, dictHandle, keyHandle, valueHandle, attr));
|
||||
objHandle->SetProperties(thread, result);
|
||||
NameDictionary *newDict = NameDictionary::PutIfAbsent(thread, dictHandle, keyHandle, valueHandle, attr);
|
||||
objHandle->SetProperties(thread, JSTaggedValue(newDict));
|
||||
}
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
@ -880,9 +880,9 @@ bool FastRuntimeStub::SetPropertyByName(JSThread *thread, JSTaggedValue receiver
|
||||
|
||||
if (receiver.IsJSGlobalObject()) {
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<GlobalDictionary> dict_handle(thread, properties);
|
||||
JSHandle<GlobalDictionary> dictHandle(thread, properties);
|
||||
// globalobj have no internal accessor
|
||||
GlobalDictionary::InvalidatePropertyBox(thread, dict_handle, indexOrEntry, attr);
|
||||
GlobalDictionary::InvalidatePropertyBox(thread, dictHandle, indexOrEntry, attr);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -961,7 +961,7 @@ bool FastRuntimeStub::SetGlobalOwnProperty(JSThread *thread, JSTaggedValue recei
|
||||
JSHandle<JSTaggedValue> keyHandle(thread, key);
|
||||
JSHandle<JSTaggedValue> valHandle(thread, value);
|
||||
JSHandle<JSObject> objHandle(thread, obj);
|
||||
JSHandle<GlobalDictionary> dict_handle(thread, GlobalDictionary::Create(thread));
|
||||
JSHandle<GlobalDictionary> dictHandle(thread, GlobalDictionary::Create(thread));
|
||||
|
||||
// Add PropertyBox to global dictionary
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
@ -970,9 +970,9 @@ bool FastRuntimeStub::SetGlobalOwnProperty(JSThread *thread, JSTaggedValue recei
|
||||
PropertyBoxType boxType = valHandle->IsUndefined() ? PropertyBoxType::UNDEFINED : PropertyBoxType::CONSTANT;
|
||||
attr.SetBoxType(boxType);
|
||||
|
||||
objHandle->SetProperties(
|
||||
thread, JSTaggedValue(GlobalDictionary::PutIfAbsent(thread, dict_handle, keyHandle,
|
||||
JSHandle<JSTaggedValue>(boxHandle), attr)));
|
||||
GlobalDictionary *properties =
|
||||
GlobalDictionary::PutIfAbsent(thread, dictHandle, keyHandle, JSHandle<JSTaggedValue>(boxHandle), attr);
|
||||
objHandle->SetProperties(thread, JSTaggedValue(properties));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -983,8 +983,8 @@ bool FastRuntimeStub::SetGlobalOwnProperty(JSThread *thread, JSTaggedValue recei
|
||||
if (!attr.IsAccessor()) {
|
||||
if (attr.IsWritable()) {
|
||||
// globalobj have no internal accessor
|
||||
JSHandle<GlobalDictionary> dict_handle(thread, dict);
|
||||
GlobalDictionary::InvalidatePropertyBox(thread, dict_handle, entry, attr);
|
||||
JSHandle<GlobalDictionary> dictHandle(thread, dict);
|
||||
GlobalDictionary::InvalidatePropertyBox(thread, dictHandle, entry, attr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1011,7 +1011,7 @@ bool FastRuntimeStub::SetGlobalOwnProperty(JSThread *thread, JSTaggedValue recei
|
||||
JSHandle<JSTaggedValue> keyHandle(thread, key);
|
||||
JSHandle<JSTaggedValue> valHandle(thread, value);
|
||||
JSHandle<JSObject> objHandle(thread, obj);
|
||||
JSHandle<GlobalDictionary> dict_handle(thread, dict);
|
||||
JSHandle<GlobalDictionary> dictHandle(thread, dict);
|
||||
|
||||
// Add PropertyBox to global dictionary
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
@ -1020,9 +1020,9 @@ bool FastRuntimeStub::SetGlobalOwnProperty(JSThread *thread, JSTaggedValue recei
|
||||
PropertyBoxType boxType = valHandle->IsUndefined() ? PropertyBoxType::UNDEFINED : PropertyBoxType::CONSTANT;
|
||||
attr.SetBoxType(boxType);
|
||||
|
||||
objHandle->SetProperties(thread, JSTaggedValue(GlobalDictionary::PutIfAbsent(
|
||||
thread, dict_handle, keyHandle,
|
||||
JSHandle<JSTaggedValue>(boxHandle), attr)));
|
||||
GlobalDictionary *properties =
|
||||
GlobalDictionary::PutIfAbsent(thread, dictHandle, keyHandle, JSHandle<JSTaggedValue>(boxHandle), attr);
|
||||
objHandle->SetProperties(thread, JSTaggedValue(properties));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1439,8 +1439,9 @@ JSTaggedValue SlowRuntimeStub::StGlobalRecord(JSThread *thread, JSTaggedValue pr
|
||||
PropertyBoxType boxType = valueHandle->IsUndefined() ? PropertyBoxType::UNDEFINED : PropertyBoxType::CONSTANT;
|
||||
attributes.SetBoxType(boxType);
|
||||
|
||||
dict->PutIfAbsent(thread, dictHandle, propHandle, JSHandle<JSTaggedValue>(box), attributes);
|
||||
dict = GlobalDictionary::PutIfAbsent(thread, dictHandle, propHandle, JSHandle<JSTaggedValue>(box), attributes);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
env->SetGlobalRecord(thread, JSTaggedValue(dict));
|
||||
return JSTaggedValue::True();
|
||||
}
|
||||
|
||||
|
@ -27,8 +27,8 @@
|
||||
#include "utils/expected.h"
|
||||
|
||||
namespace panda::ecmascript::job {
|
||||
void MicroJobQueue::EnqueueJob(JSThread *thread, QueueType queueType, const JSHandle<JSFunction> &job,
|
||||
const JSHandle<TaggedArray> &argv)
|
||||
void MicroJobQueue::EnqueueJob(JSThread *thread, JSHandle<MicroJobQueue> jobQueue, QueueType queueType,
|
||||
const JSHandle<JSFunction> &job, const JSHandle<TaggedArray> &argv)
|
||||
{
|
||||
// 1. Assert: Type(queueName) is String and its value is the name of a Job Queue recognized by this implementation.
|
||||
// 2. Assert: job is the name of a Job.
|
||||
@ -39,24 +39,22 @@ void MicroJobQueue::EnqueueJob(JSThread *thread, QueueType queueType, const JSHa
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<PendingJob> pendingJob(factory->NewPendingJob(job, argv));
|
||||
if (queueType == QueueType::QUEUE_PROMISE) {
|
||||
JSHandle<TaggedQueue> promiseQueue(thread, GetPromiseJobQueue());
|
||||
JSHandle<TaggedQueue> promiseQueue(thread, jobQueue->GetPromiseJobQueue());
|
||||
LOG_ECMA(DEBUG) << "promiseQueue start length: " << promiseQueue->Size();
|
||||
JSHandle<TaggedQueue> newPromiseQueue(
|
||||
thread, TaggedQueue::Push(thread, promiseQueue, JSHandle<JSTaggedValue>::Cast(pendingJob)));
|
||||
SetPromiseJobQueue(thread, newPromiseQueue.GetTaggedValue());
|
||||
TaggedQueue *newPromiseQueue = TaggedQueue::Push(thread, promiseQueue, JSHandle<JSTaggedValue>(pendingJob));
|
||||
jobQueue->SetPromiseJobQueue(thread, JSTaggedValue(newPromiseQueue));
|
||||
LOG_ECMA(DEBUG) << "promiseQueue end length: " << newPromiseQueue->Size();
|
||||
} else if (queueType == QueueType::QUEUE_SCRIPT) {
|
||||
JSHandle<TaggedQueue> scriptQueue(thread, GetScriptJobQueue());
|
||||
JSHandle<TaggedQueue> newScriptQueue(
|
||||
thread, TaggedQueue::Push(thread, scriptQueue, JSHandle<JSTaggedValue>::Cast(pendingJob)));
|
||||
SetScriptJobQueue(thread, newScriptQueue.GetTaggedValue());
|
||||
JSHandle<TaggedQueue> scriptQueue(thread, jobQueue->GetScriptJobQueue());
|
||||
TaggedQueue *newScriptQueue = TaggedQueue::Push(thread, scriptQueue, JSHandle<JSTaggedValue>(pendingJob));
|
||||
jobQueue->SetScriptJobQueue(thread, JSTaggedValue(newScriptQueue));
|
||||
}
|
||||
}
|
||||
|
||||
void MicroJobQueue::ExecutePendingJob(JSThread *thread)
|
||||
void MicroJobQueue::ExecutePendingJob(JSThread *thread, JSHandle<MicroJobQueue> jobQueue)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<TaggedQueue> promiseQueue(thread, GetPromiseJobQueue());
|
||||
JSMutableHandle<TaggedQueue> promiseQueue(thread, jobQueue->GetPromiseJobQueue());
|
||||
JSMutableHandle<PendingJob> pendingJob(thread, JSTaggedValue::Undefined());
|
||||
while (!promiseQueue->Empty()) {
|
||||
LOG_ECMA(DEBUG) << "promiseQueue start length: " << promiseQueue->Size();
|
||||
@ -66,10 +64,10 @@ void MicroJobQueue::ExecutePendingJob(JSThread *thread)
|
||||
if (thread->HasPendingException()) {
|
||||
return;
|
||||
}
|
||||
promiseQueue = JSHandle<TaggedQueue>(thread, GetPromiseJobQueue());
|
||||
promiseQueue.Update(jobQueue->GetPromiseJobQueue());
|
||||
}
|
||||
|
||||
JSHandle<TaggedQueue> scriptQueue(thread, GetScriptJobQueue());
|
||||
JSHandle<TaggedQueue> scriptQueue(thread, jobQueue->GetScriptJobQueue());
|
||||
while (!scriptQueue->Empty()) {
|
||||
pendingJob.Update(scriptQueue->Pop(thread));
|
||||
PendingJob::ExecutePendingJob(pendingJob, thread);
|
||||
|
@ -40,9 +40,9 @@ public:
|
||||
return static_cast<MicroJobQueue *>(object);
|
||||
}
|
||||
|
||||
void EnqueueJob(JSThread *thread, QueueType queueType, const JSHandle<JSFunction> &job,
|
||||
const JSHandle<TaggedArray> &argv);
|
||||
void ExecutePendingJob(JSThread *thread);
|
||||
static void EnqueueJob(JSThread *thread, JSHandle<MicroJobQueue> jobQueue, QueueType queueType,
|
||||
const JSHandle<JSFunction> &job, const JSHandle<TaggedArray> &argv);
|
||||
static void ExecutePendingJob(JSThread *thread, JSHandle<MicroJobQueue> jobQueue);
|
||||
|
||||
static constexpr size_t PROMISE_JOB_QUEUE_OFFSET = Record::SIZE;
|
||||
ACCESSORS(PromiseJobQueue, PROMISE_JOB_QUEUE_OFFSET, SCRIPT_JOB_QUEUE_OFFSET);
|
||||
|
@ -190,8 +190,8 @@ void JSArray::SetCapacity(JSThread *thread, const JSHandle<JSObject> &array, uin
|
||||
uint32_t attr = dictHandle->GetAttributes(entry).GetValue();
|
||||
PropertyAttributes propAttr(attr);
|
||||
if (propAttr.IsConfigurable()) {
|
||||
NumberDictionary *dictionary = NumberDictionary::Remove(thread, dictHandle, entry);
|
||||
array->SetElements(thread, JSTaggedValue(dictionary));
|
||||
NumberDictionary *newDict = NumberDictionary::Remove(thread, dictHandle, entry);
|
||||
array->SetElements(thread, JSTaggedValue(newDict));
|
||||
if (i == 0) {
|
||||
newNumOfElements = i;
|
||||
break;
|
||||
|
@ -54,6 +54,7 @@ public:
|
||||
ACCESSORS(BoundCompare, BOUND_COMPARE_OFFSET, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, ICU_FIELD_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
|
||||
icu::Collator *GetIcuCollator() const
|
||||
{
|
||||
|
@ -107,6 +107,7 @@ public:
|
||||
ACCESSORS(BoundFormat, BOUND_FORMAT_OFFSET, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, LOCALE_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
|
||||
icu::Locale *GetIcuLocale() const;
|
||||
void SetIcuLocale(JSThread *thread, const icu::Locale &icuLocale, const DeleteEntryPoint &callback);
|
||||
|
@ -197,7 +197,8 @@ void JSForInIterator::SlowGetAllEnumKeys(JSThread *thread, const JSHandle<JSForI
|
||||
for (array_size_t i = 0; i < len; i++) {
|
||||
value.Update(arr->Get(i));
|
||||
if (value->IsString()) {
|
||||
remaining.Update(JSTaggedValue(TaggedQueue::Push(thread, remaining, value)));
|
||||
TaggedQueue *newQueue = TaggedQueue::Push(thread, remaining, value);
|
||||
remaining.Update(JSTaggedValue(newQueue));
|
||||
}
|
||||
}
|
||||
it->SetRemainingKeys(thread, remaining);
|
||||
@ -244,9 +245,9 @@ std::pair<JSTaggedValue, bool> JSForInIterator::NextInternal(JSThread *thread, c
|
||||
PropertyDescriptor desc(thread);
|
||||
bool has = JSTaggedValue::GetOwnProperty(thread, object, key, desc);
|
||||
if (has) {
|
||||
auto queue = JSTaggedValue(TaggedQueue::Push(thread, visited, key));
|
||||
visited.Update(queue);
|
||||
it->SetVisitedKeys(thread, queue);
|
||||
auto newQueue = JSTaggedValue(TaggedQueue::Push(thread, visited, key));
|
||||
visited.Update(newQueue);
|
||||
it->SetVisitedKeys(thread, newQueue);
|
||||
if (desc.IsEnumerable()) {
|
||||
return std::make_pair(key.GetTaggedValue(), false);
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ public:
|
||||
ACCESSORS(RemainingKeys, REMAINING_KEYS_OFFSET, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, OBJECT_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
|
||||
|
@ -431,6 +431,7 @@ public:
|
||||
ACCESSORS(Collator, COLLATOR_OFFSET, SIZE);
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, NUMBER_FORMAT_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
ACCESSORS(Data, DATA_OFFSET, SIZE);
|
||||
|
||||
DECL_VISIT_OBJECT(CALL_BACK_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif
|
||||
|
@ -46,6 +46,7 @@ public:
|
||||
ACCESSORS(LexicalEnv, GENERATOR_LEXICALENV_OFFSET, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT(GENERATOR_REGS_ARRAY_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
};
|
||||
|
||||
class JSGeneratorObject : public JSObject {
|
||||
@ -84,6 +85,7 @@ public:
|
||||
}
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, GENERATOR_STATE_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
};
|
||||
|
||||
class JSAsyncFuncObject : public JSGeneratorObject {
|
||||
@ -98,6 +100,7 @@ public:
|
||||
ACCESSORS(Promise, GENERATOR_PROMISE_OFFSET, SIZE);
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSGeneratorObject, GENERATOR_PROMISE_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
};
|
||||
} // namespace ecmascript
|
||||
} // namespace panda
|
||||
|
@ -38,6 +38,7 @@ void JSHClass::AddTransitions(const JSThread *thread, const JSHandle<JSHClass> &
|
||||
child->SetParent(thread, parent.GetTaggedValue());
|
||||
return;
|
||||
}
|
||||
JSMutableHandle<TransitionsDictionary> dict(thread, JSTaggedValue::Undefined());
|
||||
if (transitions.IsJSHClass()) {
|
||||
auto cachedHClass = JSHClass::Cast(transitions.GetTaggedObject());
|
||||
int last = cachedHClass->GetPropertiesNumber() - 1;
|
||||
@ -45,11 +46,11 @@ void JSHClass::AddTransitions(const JSThread *thread, const JSHandle<JSHClass> &
|
||||
auto attr = JSHandle<JSTaggedValue>(thread, JSTaggedValue(layoutInfo->GetAttr(last).GetPropertyMetaData()));
|
||||
auto lastKey = JSHandle<JSTaggedValue>(thread, layoutInfo->GetKey(last));
|
||||
auto lastHClass = JSHandle<JSTaggedValue>(thread, cachedHClass);
|
||||
auto dict = JSHandle<TransitionsDictionary>(thread, TransitionsDictionary::Create(thread));
|
||||
dict.Update(JSTaggedValue(TransitionsDictionary::Create(thread)));
|
||||
transitions = JSTaggedValue(TransitionsDictionary::PutIfAbsent(thread, dict, lastKey, lastHClass, attr));
|
||||
}
|
||||
auto attr = JSHandle<JSTaggedValue>(thread, JSTaggedValue(attributes.GetPropertyMetaData()));
|
||||
JSHandle<TransitionsDictionary> dict(thread, transitions);
|
||||
dict.Update(transitions);
|
||||
transitions =
|
||||
JSTaggedValue(TransitionsDictionary::PutIfAbsent(thread, dict, key, JSHandle<JSTaggedValue>(child), attr));
|
||||
parent->SetTransitions(thread, transitions);
|
||||
@ -68,6 +69,7 @@ void JSHClass::AddProtoTransitions(const JSThread *thread, const JSHandle<JSHCla
|
||||
const JSHandle<JSTaggedValue> &proto)
|
||||
{
|
||||
JSTaggedValue transitions = parent->GetTransitions();
|
||||
JSMutableHandle<TransitionsDictionary> dict(thread, JSTaggedValue::Undefined());
|
||||
if (transitions.IsNull()) {
|
||||
transitions = JSTaggedValue(TransitionsDictionary::Create(thread));
|
||||
} else if (transitions.IsJSHClass()) {
|
||||
@ -77,11 +79,11 @@ void JSHClass::AddProtoTransitions(const JSThread *thread, const JSHandle<JSHCla
|
||||
auto attr = JSHandle<JSTaggedValue>(thread, JSTaggedValue(layoutInfo->GetAttr(last).GetPropertyMetaData()));
|
||||
auto lastKey = JSHandle<JSTaggedValue>(thread, layoutInfo->GetKey(last));
|
||||
auto lastHClass = JSHandle<JSTaggedValue>(thread, cachedHClass);
|
||||
auto dict = JSHandle<TransitionsDictionary>(thread, TransitionsDictionary::Create(thread));
|
||||
dict.Update(JSTaggedValue(TransitionsDictionary::Create(thread)));
|
||||
transitions = JSTaggedValue(TransitionsDictionary::PutIfAbsent(thread, dict, lastKey, lastHClass, attr));
|
||||
}
|
||||
|
||||
JSHandle<TransitionsDictionary> dict(thread, transitions);
|
||||
dict.Update(transitions);
|
||||
transitions =
|
||||
JSTaggedValue(TransitionsDictionary::PutIfAbsent(thread, dict, key, JSHandle<JSTaggedValue>(child), proto));
|
||||
parent->SetTransitions(thread, transitions);
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
ACCESSORS(FallbackSymbol, FALLBACK_SYMBOL, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, FALLBACK_SYMBOL, SIZE)
|
||||
DECL_DUMP()
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
|
||||
|
@ -159,6 +159,7 @@ public:
|
||||
ACCESSORS(IcuField, ICU_FIELD_OFFSET, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, ICU_FIELD_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
|
||||
icu::Locale *GetIcuLocale() const
|
||||
{
|
||||
|
@ -28,8 +28,8 @@ void JSMap::Set(JSThread *thread, const JSHandle<JSMap> &map, const JSHandle<JST
|
||||
}
|
||||
JSHandle<LinkedHashMap> mapHandle(thread, LinkedHashMap::Cast(map->GetLinkedMap().GetTaggedObject()));
|
||||
|
||||
auto result = LinkedHashMap::Set(thread, mapHandle, key, value);
|
||||
map->SetLinkedMap(thread, result);
|
||||
JSTaggedValue newMap = LinkedHashMap::Set(thread, mapHandle, key, value);
|
||||
map->SetLinkedMap(thread, newMap);
|
||||
}
|
||||
|
||||
bool JSMap::Delete(const JSThread *thread, const JSHandle<JSMap> &map, const JSHandle<JSTaggedValue> &key)
|
||||
@ -41,8 +41,8 @@ bool JSMap::Delete(const JSThread *thread, const JSHandle<JSMap> &map, const JSH
|
||||
}
|
||||
mapHandle->RemoveEntry(thread, entry);
|
||||
|
||||
auto result = LinkedHashMap::Shrink(thread, mapHandle);
|
||||
map->SetLinkedMap(thread, result);
|
||||
JSTaggedValue newMap = LinkedHashMap::Shrink(thread, mapHandle);
|
||||
map->SetLinkedMap(thread, newMap);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,7 @@ public:
|
||||
ACCESSORS(IcuField, BOUND_FORMAT_OFFSET, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, LOCALE_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
|
||||
icu::number::LocalizedNumberFormatter *GetIcuCallTarget() const
|
||||
{
|
||||
|
@ -127,7 +127,8 @@ JSHandle<NameDictionary> JSObject::TransitionToDictionary(const JSThread *thread
|
||||
attr.SetBoxType(PropertyBoxType::UNDEFINED);
|
||||
valueHandle.Update(value);
|
||||
keyHandle.Update(key);
|
||||
dict.Update(JSTaggedValue(NameDictionary::PutIfAbsent(thread, dict, keyHandle, valueHandle, attr)));
|
||||
NameDictionary *newDict = NameDictionary::PutIfAbsent(thread, dict, keyHandle, valueHandle, attr);
|
||||
dict.Update(JSTaggedValue(newDict));
|
||||
}
|
||||
|
||||
receiver->SetProperties(thread, dict);
|
||||
@ -152,7 +153,8 @@ void JSObject::ElementsToDictionary(const JSThread *thread, JSHandle<JSObject> o
|
||||
}
|
||||
key.Update(JSTaggedValue(i));
|
||||
valueHandle.Update(value);
|
||||
dict.Update(JSTaggedValue(NumberDictionary::PutIfAbsent(thread, dict, key, valueHandle, attr)));
|
||||
NumberDictionary *newDict = NumberDictionary::PutIfAbsent(thread, dict, key, valueHandle, attr);
|
||||
dict.Update(JSTaggedValue(newDict));
|
||||
}
|
||||
obj->SetElements(thread, dict);
|
||||
|
||||
@ -193,9 +195,9 @@ bool JSObject::AddElementInternal(JSThread *thread, const JSHandle<JSObject> &re
|
||||
if (isDictionary) {
|
||||
ASSERT(elements->IsDictionaryMode());
|
||||
JSHandle<JSTaggedValue> keyHandle(thread, JSTaggedValue(static_cast<int32_t>(index)));
|
||||
NumberDictionary *dict =
|
||||
NumberDictionary *newDict =
|
||||
NumberDictionary::Put(thread, JSHandle<NumberDictionary>(thread, elements), keyHandle, value, attr);
|
||||
receiver->SetElements(thread, JSTaggedValue(dict));
|
||||
receiver->SetElements(thread, JSTaggedValue(newDict));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -205,8 +207,8 @@ bool JSObject::AddElementInternal(JSThread *thread, const JSHandle<JSObject> &re
|
||||
JSObject::ElementsToDictionary(thread, receiver);
|
||||
JSHandle<JSTaggedValue> keyHandle(thread, JSTaggedValue(static_cast<int32_t>(index)));
|
||||
JSHandle<NumberDictionary> dict(thread, receiver->GetElements());
|
||||
auto key = JSTaggedValue(NumberDictionary::Put(thread, dict, keyHandle, value, attr));
|
||||
receiver->SetElements(thread, key);
|
||||
NumberDictionary *newKey = NumberDictionary::Put(thread, dict, keyHandle, value, attr);
|
||||
receiver->SetElements(thread, JSTaggedValue(newKey));
|
||||
return true;
|
||||
}
|
||||
elements = *JSObject::GrowElementsCapacity(thread, receiver, index + 1);
|
||||
@ -223,8 +225,8 @@ void JSObject::DeletePropertyInternal(JSThread *thread, const JSHandle<JSObject>
|
||||
|
||||
if (obj->IsJSGlobalObject()) {
|
||||
JSHandle<GlobalDictionary> dictHandle(thread, obj->GetProperties());
|
||||
GlobalDictionary *dict = GlobalDictionary::Remove(thread, dictHandle, index);
|
||||
obj->SetProperties(thread, JSTaggedValue(dict));
|
||||
GlobalDictionary *newDict = GlobalDictionary::Remove(thread, dictHandle, index);
|
||||
obj->SetProperties(thread, JSTaggedValue(newDict));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -232,14 +234,14 @@ void JSObject::DeletePropertyInternal(JSThread *thread, const JSHandle<JSObject>
|
||||
JSHandle<NameDictionary> dictHandle(TransitionToDictionary(thread, obj));
|
||||
int entry = dictHandle->FindEntry(key.GetTaggedValue());
|
||||
ASSERT(entry != -1);
|
||||
NameDictionary *dict = NameDictionary::Remove(thread, dictHandle, entry);
|
||||
obj->SetProperties(thread, JSTaggedValue(dict));
|
||||
NameDictionary *newDict = NameDictionary::Remove(thread, dictHandle, entry);
|
||||
obj->SetProperties(thread, JSTaggedValue(newDict));
|
||||
return;
|
||||
}
|
||||
|
||||
JSHandle<NameDictionary> dictHandle(array);
|
||||
NameDictionary *dict = NameDictionary::Remove(thread, dictHandle, index);
|
||||
obj->SetProperties(thread, JSTaggedValue(dict));
|
||||
NameDictionary *newDict = NameDictionary::Remove(thread, dictHandle, index);
|
||||
obj->SetProperties(thread, JSTaggedValue(newDict));
|
||||
}
|
||||
|
||||
void JSObject::GetAllKeys(const JSThread *thread, const JSHandle<JSObject> &obj, int offset,
|
||||
|
@ -591,7 +591,7 @@ public:
|
||||
|
||||
ACCESSORS(Properties, PROPERTIES_OFFSET, ELEMENTS_OFFSET);
|
||||
ACCESSORS(Elements, ELEMENTS_OFFSET, SIZE);
|
||||
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(ECMAObject, PROPERTIES_OFFSET, SIZE)
|
||||
|
||||
DECL_DUMP()
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
ACCESSORS(IcuNF, ICU_NUMBER_FORMAT_OFFSET, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, LOCALE_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
|
||||
icu::number::LocalizedNumberFormatter *GetIcuNumberFormatter() const;
|
||||
|
||||
|
@ -178,7 +178,7 @@ JSTaggedValue JSPromise::TriggerPromiseReactions(JSThread *thread, const JSHandl
|
||||
JSHandle<TaggedArray> arguments = factory->NewTaggedArray(2); // 2 means the length of new array
|
||||
arguments->Set(thread, 0, reaction);
|
||||
arguments->Set(thread, 1, argument);
|
||||
job->EnqueueJob(thread, job::QueueType::QUEUE_PROMISE, promiseReactionsJob, arguments);
|
||||
job::MicroJobQueue::EnqueueJob(thread, job, job::QueueType::QUEUE_PROMISE, promiseReactionsJob, arguments);
|
||||
}
|
||||
// 2. Return undefined.
|
||||
return globalConst->GetUndefined();
|
||||
|
@ -29,6 +29,9 @@ public:
|
||||
static constexpr size_t VALUE_OFFSET = JSObject::SIZE;
|
||||
ACCESSORS(Value, VALUE_OFFSET, GLOBAL_ENV_OFFSET)
|
||||
ACCESSORS(GlobalEnv, GLOBAL_ENV_OFFSET, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, VALUE_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
|
||||
|
@ -55,6 +55,7 @@ public:
|
||||
ACCESSORS(IcuField, ICU_FIELD_OFFSET, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, LOCALE_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
|
||||
// 14.1.1 InitializeRelativeTimeFormat ( relativeTimeFormat, locales, options )
|
||||
static JSHandle<JSRelativeTimeFormat> InitializeRelativeTimeFormat(
|
||||
|
@ -28,8 +28,8 @@ void JSSet::Add(JSThread *thread, const JSHandle<JSSet> &set, const JSHandle<JST
|
||||
}
|
||||
JSHandle<LinkedHashSet> setHandle(thread, LinkedHashSet::Cast(set->GetLinkedSet().GetTaggedObject()));
|
||||
|
||||
auto table = LinkedHashSet::Add(thread, setHandle, value);
|
||||
set->SetLinkedSet(thread, table);
|
||||
JSTaggedValue newSet = LinkedHashSet::Add(thread, setHandle, value);
|
||||
set->SetLinkedSet(thread, newSet);
|
||||
}
|
||||
|
||||
bool JSSet::Delete(const JSThread *thread, const JSHandle<JSSet> &set, const JSHandle<JSTaggedValue> &value)
|
||||
@ -40,8 +40,8 @@ bool JSSet::Delete(const JSThread *thread, const JSHandle<JSSet> &set, const JSH
|
||||
return false;
|
||||
}
|
||||
setHandle->RemoveEntry(thread, entry);
|
||||
auto table = LinkedHashSet::Shrink(thread, setHandle);
|
||||
set->SetLinkedSet(thread, table);
|
||||
JSTaggedValue newSet = LinkedHashSet::Shrink(thread, setHandle);
|
||||
set->SetLinkedSet(thread, newSet);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ public:
|
||||
ACCESSORS(StringIteratorNextIndex, STRING_ITERATOR_NEXT_INDEX_OFFSET, SIZE)
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, ITERATED_STRING_OFFSET, SIZE)
|
||||
DECL_DUMP()
|
||||
};
|
||||
} // namespace ecmascript
|
||||
} // namespace panda
|
||||
|
@ -332,7 +332,8 @@ public:
|
||||
void DumpTaggedValue(JSThread *thread, std::ostream &os) const DUMP_API_ATTR;
|
||||
void Dump(JSThread *thread, std::ostream &os) const DUMP_API_ATTR;
|
||||
void Dump(JSThread *thread) const DUMP_API_ATTR;
|
||||
void DumpForSnapshot(JSThread *thread, std::vector<std::pair<CString, JSTaggedValue>> &vec) const;
|
||||
void DumpForSnapshot(JSThread *thread, std::vector<std::pair<CString, JSTaggedValue>> &vec,
|
||||
bool isVmMode = true) const;
|
||||
static void DumpVal(JSThread *thread, JSTaggedType val) DUMP_API_ATTR;
|
||||
|
||||
private:
|
||||
|
@ -86,6 +86,9 @@ void JSThread::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1)
|
||||
if (!exception_.IsHole()) {
|
||||
v0(Root::ROOT_VM, ObjectSlot(ToUintPtr(&exception_)));
|
||||
}
|
||||
if (!stubCode_.IsHole()) {
|
||||
v0(Root::ROOT_VM, ObjectSlot(ToUintPtr(&stubCode_)));
|
||||
}
|
||||
// visit global Constant
|
||||
globalConst_.VisitRangeSlot(v1);
|
||||
// visit stack roots
|
||||
|
@ -204,6 +204,14 @@ public:
|
||||
|
||||
void IterateWeakEcmaGlobalStorage(const WeakRootVisitor &visitor);
|
||||
|
||||
uintptr_t* GetLastOptCallRuntimePc() const
|
||||
{
|
||||
return lastOptCallRuntimePc_;
|
||||
}
|
||||
void SetLastOptCallRuntimePc(uintptr_t* pc)
|
||||
{
|
||||
lastOptCallRuntimePc_ = pc;
|
||||
}
|
||||
private:
|
||||
NO_COPY_SEMANTIC(JSThread);
|
||||
NO_MOVE_SEMANTIC(JSThread);
|
||||
@ -238,6 +246,7 @@ private:
|
||||
bool stableArrayElementsGuardians_ {true};
|
||||
GlobalEnvConstants globalConst_; // Place-Holder
|
||||
InternalCallParams *internalCallParams_ {nullptr};
|
||||
uintptr_t *lastOptCallRuntimePc_ {nullptr};
|
||||
|
||||
friend class EcmaHandleScope;
|
||||
friend class GlobalHandleCollection;
|
||||
|
@ -30,8 +30,8 @@ void JSWeakMap::Set(JSThread *thread, const JSHandle<JSWeakMap> &map, const JSHa
|
||||
}
|
||||
JSHandle<LinkedHashMap> mapHandle(thread, LinkedHashMap::Cast(map->GetLinkedMap().GetTaggedObject()));
|
||||
|
||||
auto result = LinkedHashMap::SetWeakRef(thread, mapHandle, key, value);
|
||||
map->SetLinkedMap(thread, result);
|
||||
JSTaggedValue newMap = LinkedHashMap::SetWeakRef(thread, mapHandle, key, value);
|
||||
map->SetLinkedMap(thread, newMap);
|
||||
}
|
||||
|
||||
bool JSWeakMap::Delete(JSThread *thread, const JSHandle<JSWeakMap> &map, const JSHandle<JSTaggedValue> &key)
|
||||
@ -43,8 +43,8 @@ bool JSWeakMap::Delete(JSThread *thread, const JSHandle<JSWeakMap> &map, const J
|
||||
}
|
||||
mapHandle->RemoveEntry(thread, entry);
|
||||
|
||||
auto result = LinkedHashMap::Shrink(thread, mapHandle);
|
||||
map->SetLinkedMap(thread, result);
|
||||
JSTaggedValue newMap = LinkedHashMap::Shrink(thread, mapHandle);
|
||||
map->SetLinkedMap(thread, newMap);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -70,8 +70,8 @@ void JSWeakSet::Add(JSThread *thread, const JSHandle<JSWeakSet> &weakSet, const
|
||||
}
|
||||
JSHandle<LinkedHashSet> weakSetHandle(thread, LinkedHashSet::Cast(weakSet->GetLinkedSet().GetTaggedObject()));
|
||||
|
||||
auto result = LinkedHashSet::AddWeakRef(thread, weakSetHandle, value);
|
||||
weakSet->SetLinkedSet(thread, result);
|
||||
JSTaggedValue newSet = LinkedHashSet::AddWeakRef(thread, weakSetHandle, value);
|
||||
weakSet->SetLinkedSet(thread, newSet);
|
||||
}
|
||||
|
||||
bool JSWeakSet::Delete(JSThread *thread, const JSHandle<JSWeakSet> &weakSet, const JSHandle<JSTaggedValue> &value)
|
||||
@ -82,8 +82,8 @@ bool JSWeakSet::Delete(JSThread *thread, const JSHandle<JSWeakSet> &weakSet, con
|
||||
return false;
|
||||
}
|
||||
weakSetHandle->RemoveEntry(thread, entry);
|
||||
auto result = LinkedHashSet::Shrink(thread, weakSetHandle);
|
||||
weakSet->SetLinkedSet(thread, result);
|
||||
JSTaggedValue newSet = LinkedHashSet::Shrink(thread, weakSetHandle);
|
||||
weakSet->SetLinkedSet(thread, newSet);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -142,10 +142,10 @@ void FreeListAllocator::Free(uintptr_t begin, uintptr_t end, bool isAdd)
|
||||
{
|
||||
ASSERT(heap_ != nullptr);
|
||||
size_t size = end - begin;
|
||||
FreeObject::FillFreeObject(heap_->GetEcmaVM(), begin, size);
|
||||
if (UNLIKELY(size < FreeObject::SIZE_OFFSET)) {
|
||||
return;
|
||||
}
|
||||
FreeObject::FillFreeObject(heap_->GetEcmaVM(), begin, size);
|
||||
|
||||
freeList_->Free(begin, size, isAdd);
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "ecmascript/js_array_iterator.h"
|
||||
#include "ecmascript/js_arraybuffer.h"
|
||||
#include "ecmascript/js_async_function.h"
|
||||
#include "ecmascript/js_collator.h"
|
||||
#include "ecmascript/js_dataview.h"
|
||||
#include "ecmascript/js_date.h"
|
||||
#include "ecmascript/js_date_time_format.h"
|
||||
@ -43,8 +44,10 @@
|
||||
#include "ecmascript/js_map_iterator.h"
|
||||
#include "ecmascript/js_number_format.h"
|
||||
#include "ecmascript/js_object-inl.h"
|
||||
#include "ecmascript/js_plural_rules.h"
|
||||
#include "ecmascript/js_primitive_ref.h"
|
||||
#include "ecmascript/js_promise.h"
|
||||
#include "ecmascript/js_realm.h"
|
||||
#include "ecmascript/js_regexp.h"
|
||||
#include "ecmascript/js_relative_time_format.h"
|
||||
#include "ecmascript/js_set.h"
|
||||
@ -53,6 +56,7 @@
|
||||
#include "ecmascript/js_typed_array.h"
|
||||
#include "ecmascript/js_weak_container.h"
|
||||
#include "ecmascript/mem/heap_roots.h"
|
||||
#include "ecmascript/mem/machine_code.h"
|
||||
#include "ecmascript/mem/mem.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
@ -196,6 +200,7 @@ void HeapRootManager::MarkObjectBody(TaggedObject *object, JSHClass *klass, cons
|
||||
break;
|
||||
case JSType::TAGGED_ARRAY:
|
||||
case JSType::TAGGED_DICTIONARY:
|
||||
case JSType::TEMPLATE_MAP:
|
||||
TaggedArray::Cast(object)->VisitRangeSlot(visitor);
|
||||
break;
|
||||
case JSType::GLOBAL_ENV:
|
||||
@ -225,9 +230,6 @@ void HeapRootManager::MarkObjectBody(TaggedObject *object, JSHClass *klass, cons
|
||||
case JSType::PROTOTYPE_INFO:
|
||||
ProtoChangeDetails::Cast(object)->VisitRangeSlot(visitor);
|
||||
break;
|
||||
case JSType::TEMPLATE_MAP:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
case JSType::PROMISE_CAPABILITY:
|
||||
PromiseCapability::Cast(object)->VisitRangeSlot(visitor);
|
||||
break;
|
||||
@ -282,6 +284,18 @@ void HeapRootManager::MarkObjectBody(TaggedObject *object, JSHClass *klass, cons
|
||||
case JSType::JS_INTL_BOUND_FUNCTION:
|
||||
JSIntlBoundFunction::Cast(object)->VisitRangeSlot(visitor);
|
||||
break;
|
||||
case JSType::JS_REALM:
|
||||
JSRealm::Cast(object)->VisitRangeSlot(visitor);
|
||||
break;
|
||||
case JSType::JS_COLLATOR:
|
||||
JSCollator::Cast(object)->VisitRangeSlot(visitor);
|
||||
break;
|
||||
case JSType::JS_PLURAL_RULES:
|
||||
JSPluralRules::Cast(object)->VisitRangeSlot(visitor);
|
||||
break;
|
||||
case JSType::MACHINE_CODE_OBJECT:
|
||||
MachineCode::Cast(object)->VisitRangeSlot(visitor);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ public:
|
||||
ACCESSORS(InstructionSizeInBytes, INS_SIZE_OFFSET, DATA_OFFSET);
|
||||
static constexpr size_t SIZE = DATA_OFFSET;
|
||||
|
||||
DECL_DUMP()
|
||||
|
||||
uintptr_t GetDataOffsetAddress(void)
|
||||
{
|
||||
return reinterpret_cast<uintptr_t>(this) + DATA_OFFSET;
|
||||
@ -53,10 +55,19 @@ public:
|
||||
return;
|
||||
}
|
||||
}
|
||||
void VisitRangeSlot(const EcmaObjectRangeVisitor &v)
|
||||
{
|
||||
// left blank deliberately,only need to visit TaggedObject type object.
|
||||
}
|
||||
|
||||
void VisitObjects([[maybe_unused]] const EcmaObjectRangeVisitor &visitor) const
|
||||
{
|
||||
// left blank deliberately,only need to visit TaggedObject type object.
|
||||
}
|
||||
|
||||
size_t GetMachineCodeObjectSize(void)
|
||||
{
|
||||
return sizeof(MachineCode) + this->GetInstructionSizeInBytes().GetInt();
|
||||
return SIZE + this->GetInstructionSizeInBytes().GetInt();
|
||||
}
|
||||
};
|
||||
} // namespace ecmascript
|
||||
|
@ -2106,7 +2106,7 @@ uintptr_t ObjectFactory::NewSpaceBySnapShotAllocator(size_t size)
|
||||
JSHandle<MachineCode> ObjectFactory::NewMachineCodeObject(size_t length, const uint8_t *data)
|
||||
{
|
||||
NewObjectHook();
|
||||
TaggedObject *obj = heapHelper_.AllocateMachineCodeSpaceObject(machineCodeClass_, length + sizeof(MachineCode));
|
||||
TaggedObject *obj = heapHelper_.AllocateMachineCodeSpaceObject(machineCodeClass_, length + MachineCode::SIZE);
|
||||
MachineCode *code = MachineCode::Cast(obj);
|
||||
code->SetInstructionSizeInBytes(thread_, JSTaggedValue(static_cast<int>(length)));
|
||||
if (data != nullptr) {
|
||||
|
@ -104,7 +104,6 @@ using base::ErrorType;
|
||||
using DeleteEntryPoint = void (*)(void *, void *);
|
||||
|
||||
enum class RemoveSlots { YES, NO };
|
||||
|
||||
class ObjectFactory {
|
||||
public:
|
||||
explicit ObjectFactory(JSThread *thread, Heap *heap);
|
||||
@ -358,6 +357,11 @@ public:
|
||||
JSHandle<EcmaString> NewFromString(EcmaString *str);
|
||||
JSHandle<EcmaString> ConcatFromString(const JSHandle<EcmaString> &prefix, const JSHandle<EcmaString> &suffix);
|
||||
|
||||
// used for creating Function
|
||||
JSHandle<JSObject> NewJSObject(const JSHandle<JSHClass> &jshclass);
|
||||
// used for creating jshclass in Builtins, Function, Class_Linker
|
||||
JSHandle<JSHClass> NewEcmaDynClass(uint32_t size, JSType type, const JSHandle<JSTaggedValue> &prototype);
|
||||
|
||||
private:
|
||||
friend class GlobalEnv;
|
||||
friend class GlobalEnvConstants;
|
||||
@ -419,11 +423,6 @@ private:
|
||||
JSHandle<JSHClass> NewEcmaDynClass(uint32_t size, JSType type);
|
||||
// used for creating jshclass in GlobalEnv, EcmaVM
|
||||
JSHandle<JSHClass> NewEcmaDynClass(JSHClass *hclass, uint32_t size, JSType type);
|
||||
// used for creating jshclass in Builtins, Function, Class_Linker
|
||||
JSHandle<JSHClass> NewEcmaDynClass(uint32_t size, JSType type, const JSHandle<JSTaggedValue> &prototype);
|
||||
|
||||
// used for creating Function
|
||||
JSHandle<JSObject> NewJSObject(const JSHandle<JSHClass> &jshclass);
|
||||
|
||||
// used to create nonmovable js_object
|
||||
JSHandle<JSObject> NewNonMovableJSObject(const JSHandle<JSHClass> &jshclass);
|
||||
|
@ -568,8 +568,8 @@ void ObjectOperator::DeleteElementInHolder() const
|
||||
JSObject::ElementsToDictionary(thread_, JSHandle<JSObject>(holder_));
|
||||
} else {
|
||||
JSHandle<NumberDictionary> dictHandle(thread_, elements);
|
||||
NumberDictionary *dict = NumberDictionary::Remove(thread_, dictHandle, GetIndex());
|
||||
obj->SetElements(thread_, JSTaggedValue(dict));
|
||||
NumberDictionary *newDict = NumberDictionary::Remove(thread_, dictHandle, GetIndex());
|
||||
obj->SetElements(thread_, JSTaggedValue(newDict));
|
||||
}
|
||||
}
|
||||
|
||||
@ -661,9 +661,9 @@ void ObjectOperator::AddPropertyInternal(const JSHandle<JSTaggedValue> &value)
|
||||
PropertyBoxType cellType = value->IsUndefined() ? PropertyBoxType::UNDEFINED : PropertyBoxType::CONSTANT;
|
||||
attr.SetBoxType(cellType);
|
||||
|
||||
JSTaggedValue properties(
|
||||
GlobalDictionary::PutIfAbsent(thread_, dict, key_, JSHandle<JSTaggedValue>(cellHandle), attr));
|
||||
obj->SetProperties(thread_, properties);
|
||||
GlobalDictionary *properties =
|
||||
GlobalDictionary::PutIfAbsent(thread_, dict, key_, JSHandle<JSTaggedValue>(cellHandle), attr);
|
||||
obj->SetProperties(thread_, JSTaggedValue(properties));
|
||||
// index and fastMode is not essential for global obj;
|
||||
SetFound(0, cellHandle.GetTaggedValue(), attr.GetValue(), true);
|
||||
return;
|
||||
@ -704,8 +704,8 @@ void ObjectOperator::AddPropertyInternal(const JSHandle<JSTaggedValue> &value)
|
||||
// change to dictionary and add one.
|
||||
JSHandle<NameDictionary> dict(JSObject::TransitionToDictionary(thread_, obj));
|
||||
attr.SetDictionaryOrder(PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES);
|
||||
auto result = JSTaggedValue(NameDictionary::PutIfAbsent(thread_, dict, key_, value, attr));
|
||||
obj->SetProperties(thread_, result);
|
||||
NameDictionary *newDict = NameDictionary::PutIfAbsent(thread_, dict, key_, value, attr);
|
||||
obj->SetProperties(thread_, JSTaggedValue(newDict));
|
||||
// index is not essential when fastMode is false;
|
||||
SetFound(0, value.GetTaggedValue(), attr.GetValue(), false);
|
||||
return;
|
||||
@ -724,8 +724,8 @@ void ObjectOperator::AddPropertyInternal(const JSHandle<JSTaggedValue> &value)
|
||||
}
|
||||
|
||||
JSHandle<NameDictionary> dictHandle(array);
|
||||
auto result = JSTaggedValue(NameDictionary::PutIfAbsent(thread_, dictHandle, key_, value, attr));
|
||||
obj->SetProperties(thread_, result);
|
||||
NameDictionary *newDict = NameDictionary::PutIfAbsent(thread_, dictHandle, key_, value, attr);
|
||||
obj->SetProperties(thread_, JSTaggedValue(newDict));
|
||||
SetFound(0, value.GetTaggedValue(), attr.GetValue(), false);
|
||||
}
|
||||
|
||||
|
@ -28,10 +28,11 @@ namespace panda::ecmascript {
|
||||
bool RuntimeTrampolines::AddElementInternal(uint64_t argThread, uint64_t argReceiver, uint32_t argIndex,
|
||||
uint64_t argValue, uint32_t argAttr)
|
||||
{
|
||||
JSTaggedType *fp = nullptr;
|
||||
GET_CURRETN_FP(fp);
|
||||
uintptr_t *curFp = nullptr;
|
||||
auto thread = reinterpret_cast<JSThread *>(argThread);
|
||||
CallRuntimeTrampolinesScope scope(thread, fp);
|
||||
GET_CURRETN_FP(curFp);
|
||||
uintptr_t *prevFp = GET_PREV_FP(curFp);
|
||||
CallRuntimeTrampolinesScope scope(thread, prevFp, curFp);
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSObject> receiver(thread, reinterpret_cast<TaggedObject *>(argReceiver));
|
||||
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(argValue)));
|
||||
@ -42,11 +43,11 @@ bool RuntimeTrampolines::AddElementInternal(uint64_t argThread, uint64_t argRece
|
||||
bool RuntimeTrampolines::CallSetter(uint64_t argThread, uint64_t argSetter, uint64_t argReceiver, uint64_t argValue,
|
||||
bool argMayThrow)
|
||||
{
|
||||
JSTaggedType *fp = nullptr;
|
||||
GET_CURRETN_FP(fp);
|
||||
uintptr_t *curFp = nullptr;
|
||||
auto thread = reinterpret_cast<JSThread *>(argThread);
|
||||
CallRuntimeTrampolinesScope scope(thread, fp);
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
GET_CURRETN_FP(curFp);
|
||||
uintptr_t * prevFp = GET_PREV_FP(curFp);
|
||||
CallRuntimeTrampolinesScope scope(thread, prevFp, curFp);
|
||||
JSHandle<JSTaggedValue> receiver(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(argReceiver)));
|
||||
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(argValue)));
|
||||
auto setter = AccessorData::Cast((reinterpret_cast<panda::ObjectHeader *>(argSetter)));
|
||||
@ -55,10 +56,11 @@ bool RuntimeTrampolines::CallSetter(uint64_t argThread, uint64_t argSetter, uint
|
||||
|
||||
void RuntimeTrampolines::ThrowTypeError(uint64_t argThread, int argMessageStringId)
|
||||
{
|
||||
JSTaggedType *fp = nullptr;
|
||||
GET_CURRETN_FP(fp);
|
||||
uintptr_t *curFp = nullptr;
|
||||
auto thread = reinterpret_cast<JSThread *>(argThread);
|
||||
CallRuntimeTrampolinesScope scope(thread, fp);
|
||||
GET_CURRETN_FP(curFp);
|
||||
uintptr_t *prevFp = GET_PREV_FP(curFp);
|
||||
CallRuntimeTrampolinesScope scope(thread, prevFp, curFp);
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
std::string message = MessageString::GetMessageString(argMessageStringId);
|
||||
ObjectFactory *factory = JSThread::Cast(thread)->GetEcmaVM()->GetFactory();
|
||||
@ -69,10 +71,11 @@ void RuntimeTrampolines::ThrowTypeError(uint64_t argThread, int argMessageString
|
||||
bool RuntimeTrampolines::JSProxySetProperty(uint64_t argThread, uint64_t argProxy, uint64_t argKey, uint64_t argValue,
|
||||
uint64_t argReceiver, bool argMayThrow)
|
||||
{
|
||||
JSTaggedType *fp = nullptr;
|
||||
GET_CURRETN_FP(fp);
|
||||
uintptr_t *curFp = nullptr;
|
||||
auto thread = reinterpret_cast<JSThread *>(argThread);
|
||||
CallRuntimeTrampolinesScope scope(thread, fp);
|
||||
GET_CURRETN_FP(curFp);
|
||||
uintptr_t *prevFp = GET_PREV_FP(curFp);
|
||||
CallRuntimeTrampolinesScope scope(thread, prevFp, curFp);
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSProxy> proxy(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(argProxy)));
|
||||
JSHandle<JSTaggedValue> index(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(argKey)));
|
||||
@ -90,10 +93,11 @@ uint32_t RuntimeTrampolines::GetHash32(uint64_t key, uint64_t len)
|
||||
|
||||
uint64_t RuntimeTrampolines::CallGetter(uint64_t argThread, uint64_t argGetter, uint64_t argReceiver)
|
||||
{
|
||||
JSTaggedType *fp = nullptr;
|
||||
GET_CURRETN_FP(fp);
|
||||
uintptr_t *curFp = nullptr;
|
||||
auto thread = reinterpret_cast<JSThread *>(argThread);
|
||||
CallRuntimeTrampolinesScope scope(thread, fp);
|
||||
GET_CURRETN_FP(curFp);
|
||||
uintptr_t *prevFp = GET_PREV_FP(curFp);
|
||||
CallRuntimeTrampolinesScope scope(thread, prevFp, curFp);
|
||||
auto accessor = AccessorData::Cast(reinterpret_cast<TaggedObject *>(argGetter));
|
||||
JSHandle<JSTaggedValue> objHandle(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(argReceiver)));
|
||||
return JSObject::CallGetter(thread, accessor, objHandle).GetRawData();
|
||||
@ -101,10 +105,11 @@ uint64_t RuntimeTrampolines::CallGetter(uint64_t argThread, uint64_t argGetter,
|
||||
|
||||
uint64_t RuntimeTrampolines::AccessorGetter(uint64_t argThread, uint64_t argGetter, uint64_t argReceiver)
|
||||
{
|
||||
JSTaggedType *fp = nullptr;
|
||||
GET_CURRETN_FP(fp);
|
||||
uintptr_t *curFp = nullptr;
|
||||
auto thread = reinterpret_cast<JSThread *>(argThread);
|
||||
CallRuntimeTrampolinesScope scope(thread, fp);
|
||||
GET_CURRETN_FP(curFp);
|
||||
uintptr_t *prevFp = GET_PREV_FP(curFp);
|
||||
CallRuntimeTrampolinesScope scope(thread, prevFp, curFp);
|
||||
auto accessor = AccessorData::Cast(reinterpret_cast<TaggedObject *>(argGetter));
|
||||
JSHandle<JSObject> objHandle(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(argReceiver)));
|
||||
return accessor->CallInternalGet(thread, objHandle).GetRawData();
|
||||
@ -139,4 +144,9 @@ uint64_t RuntimeTrampolines::Execute(uint64_t argThread, uint64_t argFunc,
|
||||
|
||||
return EcmaInterpreter::Execute(thread, params).GetRawData();
|
||||
}
|
||||
|
||||
double RuntimeTrampolines::FloatMod(double left, double right)
|
||||
{
|
||||
return std::fmod(left, right);
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -49,35 +49,44 @@ public:
|
||||
static int32_t FindElementWithCache(uint64_t argThread, uint64_t hClass, uint64_t key, int32_t num);
|
||||
static uint32_t StringGetHashCode(uint64_t ecmaString);
|
||||
static uint64_t Execute(uint64_t argThread, uint64_t argFunc, uint64_t thisArg, uint32_t argc, uint64_t argArgv);
|
||||
static double FloatMod(double left, double right);
|
||||
};
|
||||
|
||||
class CallRuntimeTrampolinesScope {
|
||||
public:
|
||||
CallRuntimeTrampolinesScope(JSThread *thread, JSTaggedType *newFp)
|
||||
:oldRbp_(const_cast<JSTaggedType *>(thread->GetCurrentSPFrame())),
|
||||
CallRuntimeTrampolinesScope(JSThread *thread, uintptr_t *newFp, uintptr_t *pc)
|
||||
:lastFp_(nullptr),
|
||||
thread_(thread)
|
||||
{
|
||||
thread_->SetCurrentSPFrame(newFp);
|
||||
lastOptCallRuntimePc_ = thread->GetLastOptCallRuntimePc();
|
||||
thread->SetLastOptCallRuntimePc(pc);
|
||||
JSTaggedType *cursp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
|
||||
lastFp_ = static_cast<uintptr_t *>(static_cast<void *>(cursp));
|
||||
JSTaggedType *newSp = static_cast<JSTaggedType *>(static_cast<void *>(newFp));
|
||||
thread_->SetCurrentSPFrame(newSp);
|
||||
// print newfp and type for debug
|
||||
std::cout << "CallRuntimeTrampolinesScope newFp: " << newFp << " oldRbp_ : " << oldRbp_
|
||||
<< " thread_->fp:" << thread_->GetCurrentSPFrame() <<std::endl;
|
||||
std::cout << "CallRuntimeTrampolinesScope newFp: " << newFp << " lastFp_ : " << lastFp_
|
||||
<< std::endl;
|
||||
FrameType type = *(reinterpret_cast<FrameType*>(
|
||||
reinterpret_cast<long long>(newFp) + FrameConst::kFrameType));
|
||||
std::cout << "type = " << as_integer(type) << std::endl;
|
||||
std::cout << __FUNCTION__ << " type = " << as_integer(type) << std::endl;
|
||||
}
|
||||
~CallRuntimeTrampolinesScope()
|
||||
{
|
||||
// print oldfp and type for debug
|
||||
std::cout << "~CallRuntimeTrampolinesScope oldRbp_: " << oldRbp_ <<
|
||||
std::cout << "~CallRuntimeTrampolinesScope lastFp_: " << lastFp_ <<
|
||||
" thread_->fp:" << thread_->GetCurrentSPFrame() << std::endl;
|
||||
FrameType type = *(reinterpret_cast<FrameType*>(
|
||||
reinterpret_cast<long long>(oldRbp_) + FrameConst::kFrameType));
|
||||
std::cout << "type = " << as_integer(type) << std::endl;
|
||||
thread_->SetCurrentSPFrame(oldRbp_);
|
||||
reinterpret_cast<long long>(lastFp_) + FrameConst::kFrameType));
|
||||
std::cout << __FUNCTION__ << "type = " << as_integer(type) << std::endl;
|
||||
JSTaggedType *oldSp = static_cast<JSTaggedType *>(static_cast<void *>(lastFp_));
|
||||
thread_->SetCurrentSPFrame(oldSp);
|
||||
thread_->SetLastOptCallRuntimePc(lastOptCallRuntimePc_);
|
||||
}
|
||||
private:
|
||||
JSTaggedType *oldRbp_;
|
||||
uintptr_t *lastFp_;
|
||||
JSThread *thread_;
|
||||
uintptr_t *lastOptCallRuntimePc_;
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif
|
@ -179,6 +179,33 @@ host_unittest_action("GlueRegsTest") {
|
||||
}
|
||||
}
|
||||
|
||||
host_unittest_action("JsArrayIteratorTest") {
|
||||
module_out_path = module_output_path
|
||||
|
||||
sources = [
|
||||
# test file
|
||||
"js_array_iterator_test.cpp",
|
||||
]
|
||||
|
||||
configs = [
|
||||
"//ark/js_runtime:ecma_test_config",
|
||||
"//ark/js_runtime:ark_jsruntime_public_config", # should add before
|
||||
# arkruntime_public_config
|
||||
"//ark/js_runtime:ark_jsruntime_common_config",
|
||||
"$ark_root/runtime:arkruntime_public_config",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"$ark_root/libpandabase:libarkbase",
|
||||
"//ark/js_runtime:libark_jsruntime_test",
|
||||
sdk_libc_secshared_dep,
|
||||
]
|
||||
|
||||
if (!is_standard_system) {
|
||||
deps += [ "$ark_root/runtime:libarkruntime" ]
|
||||
}
|
||||
}
|
||||
|
||||
host_unittest_action("JsArrayTest") {
|
||||
module_out_path = module_output_path
|
||||
|
||||
@ -206,6 +233,33 @@ host_unittest_action("JsArrayTest") {
|
||||
}
|
||||
}
|
||||
|
||||
host_unittest_action("JsDataViewTest") {
|
||||
module_out_path = module_output_path
|
||||
|
||||
sources = [
|
||||
# test file
|
||||
"js_dataview_test.cpp",
|
||||
]
|
||||
|
||||
configs = [
|
||||
"//ark/js_runtime:ecma_test_config",
|
||||
"//ark/js_runtime:ark_jsruntime_public_config", # should add before
|
||||
# arkruntime_public_config
|
||||
"//ark/js_runtime:ark_jsruntime_common_config",
|
||||
"$ark_root/runtime:arkruntime_public_config",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"$ark_root/libpandabase:libarkbase",
|
||||
"//ark/js_runtime:libark_jsruntime_test",
|
||||
sdk_libc_secshared_dep,
|
||||
]
|
||||
|
||||
if (!is_standard_system) {
|
||||
deps += [ "$ark_root/runtime:libarkruntime" ]
|
||||
}
|
||||
}
|
||||
|
||||
host_unittest_action("JsDateTest") {
|
||||
module_out_path = module_output_path
|
||||
|
||||
@ -922,7 +976,9 @@ group("unittest") {
|
||||
":GlueRegsTest",
|
||||
":HugeObjectTest",
|
||||
":JsArgumentsTest",
|
||||
":JsArrayIteratorTest",
|
||||
":JsArrayTest",
|
||||
":JsDataViewTest",
|
||||
":JsDateTest",
|
||||
":JsForinIteratorTest",
|
||||
":JsFunctionTest",
|
||||
@ -963,7 +1019,9 @@ group("host_unittest") {
|
||||
":GlueRegsTestAction",
|
||||
":HugeObjectTestAction",
|
||||
":JsArgumentsTestAction",
|
||||
":JsArrayIteratorTestAction",
|
||||
":JsArrayTestAction",
|
||||
":JsDataViewTestAction",
|
||||
":JsDateTestAction",
|
||||
":JsForinIteratorTestAction",
|
||||
":JsFunctionTestAction",
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
GTEST_LOG_(INFO) << "SetUpTestCase";
|
||||
}
|
||||
|
||||
static void TesrDownTestCase()
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
GTEST_LOG_(INFO) << "TearDownCase";
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
GTEST_LOG_(INFO) << "SetUpTestCase";
|
||||
}
|
||||
|
||||
static void TesrDownTestCase()
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
GTEST_LOG_(INFO) << "TearDownCase";
|
||||
}
|
||||
|
178
ecmascript/tests/js_array_iterator_test.cpp
Normal file
178
ecmascript/tests/js_array_iterator_test.cpp
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* 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/global_env.h"
|
||||
#include "ecmascript/js_array_iterator.h"
|
||||
#include "ecmascript/js_array.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
#include "ecmascript/tests/test_helper.h"
|
||||
|
||||
using namespace panda::ecmascript;
|
||||
|
||||
namespace panda::test {
|
||||
class JSArrayIteratorTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
GTEST_LOG_(INFO) << "SetUpTestCase";
|
||||
}
|
||||
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
GTEST_LOG_(INFO) << "TearDownCase";
|
||||
}
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
TestHelper::DestroyEcmaVMWithScope(instance, scope);
|
||||
}
|
||||
PandaVM *instance {nullptr};
|
||||
ecmascript::EcmaHandleScope *scope {nullptr};
|
||||
JSThread *thread {nullptr};
|
||||
};
|
||||
|
||||
/*
|
||||
* Feature: JSArrayIterator
|
||||
* Function: SetIteratedArray
|
||||
* SubFunction: GetIteratedArray
|
||||
* FunctionPoints: Set Iterated Array
|
||||
* CaseDescription: Call the "SetIteratedArray" function, check whether the result returned through "GetIteratedArray"
|
||||
* function from the JSArrayIterator is within expectations.
|
||||
*/
|
||||
HWTEST_F_L0(JSArrayIteratorTest, SetIteratedArray)
|
||||
{
|
||||
EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = ecmaVMPtr->GetFactory();
|
||||
|
||||
uint32_t arrayFrom1[10] = {0, 6, 8, 99, 200, 1, -1, -199, 33, 100};
|
||||
uint32_t arrayFrom2[10] = {1111, 3211, 737, 0, 1267, 174, 2763, 832, 11, 93};
|
||||
int numArrayFrom1 = sizeof(arrayFrom1)/sizeof(arrayFrom1[0]);
|
||||
int numArrayFrom2 = sizeof(arrayFrom2)/sizeof(arrayFrom2[0]);
|
||||
JSHandle<TaggedArray> handleTaggedArrayFrom1(factory->NewTaggedArray(numArrayFrom1));
|
||||
JSHandle<TaggedArray> handleTaggedArrayFrom2(factory->NewTaggedArray(numArrayFrom2));
|
||||
for (int i = 0; i < numArrayFrom1; i++) {
|
||||
handleTaggedArrayFrom1->Set(thread, i, JSTaggedValue(arrayFrom1[i]));
|
||||
}
|
||||
for (int i = 0; i < numArrayFrom2; i++) {
|
||||
handleTaggedArrayFrom2->Set(thread, i, JSTaggedValue(arrayFrom2[i]));
|
||||
}
|
||||
JSHandle<JSObject> handleJSObjectTaggedArrayFrom1(JSArray::CreateArrayFromList(thread, handleTaggedArrayFrom1));
|
||||
JSHandle<JSObject> handleJSObjectTaggedArrayFrom2(JSArray::CreateArrayFromList(thread, handleTaggedArrayFrom2));
|
||||
|
||||
// Call "SetIteratedArray" function through "NewJSArrayIterator" function of "object_factory.cpp".
|
||||
JSHandle<JSArrayIterator> handleJSArrayIter = factory->NewJSArrayIterator(handleJSObjectTaggedArrayFrom1,
|
||||
IterationKind::KEY);
|
||||
|
||||
JSHandle<JSArray> handleJSArrayTo1(thread, JSArray::Cast(handleJSArrayIter->GetIteratedArray().GetTaggedObject()));
|
||||
EXPECT_EQ(handleJSArrayTo1->GetArrayLength(), numArrayFrom1);
|
||||
for (int i = 0; i < numArrayFrom1; i++) {
|
||||
EXPECT_EQ(JSArray::FastGetPropertyByValue(thread, JSHandle<JSTaggedValue>(handleJSArrayTo1), i)->GetNumber(),
|
||||
arrayFrom1[i]);
|
||||
}
|
||||
|
||||
// Call "SetIteratedArray" function in this HWTEST_F_L0.
|
||||
handleJSArrayIter->SetIteratedArray(thread, handleJSObjectTaggedArrayFrom2);
|
||||
|
||||
JSHandle<JSArray> handleJSArrayTo2(thread, JSArray::Cast(handleJSArrayIter->GetIteratedArray().GetTaggedObject()));
|
||||
EXPECT_EQ(handleJSArrayTo2->GetArrayLength(), numArrayFrom2);
|
||||
for (int i = 0; i < numArrayFrom2; i++) {
|
||||
EXPECT_EQ(JSArray::FastGetPropertyByValue(thread, JSHandle<JSTaggedValue>(handleJSArrayTo2), i)->GetNumber(),
|
||||
arrayFrom2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Feature: JSArrayIterator
|
||||
* Function: SetNextIndex
|
||||
* SubFunction: GetNextIndex
|
||||
* FunctionPoints: Set Next Index
|
||||
* CaseDescription: Call the "SetNextIndex" function, check whether the result returned through "GetNextIndex" function
|
||||
* from the JSArrayIterator is within expectations.
|
||||
*/
|
||||
HWTEST_F_L0(JSArrayIteratorTest, SetNextIndex)
|
||||
{
|
||||
EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = ecmaVMPtr->GetFactory();
|
||||
|
||||
uint32_t array[10] = {0, 6, 8, 99, 200, 1, -1, -199, 33, 100};
|
||||
int numArray = sizeof(array)/sizeof(array[0]);
|
||||
JSHandle<TaggedArray> handleTaggedArray(factory->NewTaggedArray(numArray));
|
||||
for (int i = 0; i < numArray; i++) {
|
||||
handleTaggedArray->Set(thread, i, JSTaggedValue(array[i]));
|
||||
}
|
||||
JSHandle<JSObject> handleJSObjectTaggedArray(JSArray::CreateArrayFromList(thread, handleTaggedArray));
|
||||
|
||||
// Call "SetNextIndex" function through "NewJSArrayIterator" function of "object_factory.cpp".
|
||||
JSHandle<JSArrayIterator> handleJSArrayIter = factory->NewJSArrayIterator(handleJSObjectTaggedArray,
|
||||
IterationKind::KEY);
|
||||
EXPECT_EQ(handleJSArrayIter->GetNextIndex().GetNumber(), 0);
|
||||
|
||||
int testQuantity = 100;
|
||||
for (int i = 1; i <= testQuantity; i++) {
|
||||
JSHandle<JSTaggedValue> handleTagValNextIndex(thread, JSTaggedValue(i));
|
||||
|
||||
// Call "SetNextIndex" function in this HWTEST_F_L0.
|
||||
handleJSArrayIter->SetNextIndex(thread, handleTagValNextIndex);
|
||||
EXPECT_EQ(handleJSArrayIter->GetNextIndex().GetNumber(), i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Feature: JSArrayIterator
|
||||
* Function: SetIterationKind
|
||||
* SubFunction: GetIterationKind
|
||||
* FunctionPoints: Set Iteration Kind
|
||||
* CaseDescription: Call the "SetIterationKind" function, check whether the result returned through "GetIterationKind"
|
||||
* function from the JSArrayIterator is within expectations.
|
||||
*/
|
||||
HWTEST_F_L0(JSArrayIteratorTest, SetIterationKind)
|
||||
{
|
||||
EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = ecmaVMPtr->GetFactory();
|
||||
|
||||
uint32_t array[10] = {0, 6, 8, 99, 200, 1, -1, -199, 33, 100};
|
||||
int numArray = sizeof(array)/sizeof(array[0]);
|
||||
JSHandle<TaggedArray> handleTaggedArray(factory->NewTaggedArray(numArray));
|
||||
for (int i = 0; i < numArray; i++) {
|
||||
handleTaggedArray->Set(thread, i, JSTaggedValue(array[i]));
|
||||
}
|
||||
JSHandle<JSTaggedValue> handleTagVal0(thread, JSTaggedValue(0));
|
||||
JSHandle<JSTaggedValue> handleTagVal1(thread, JSTaggedValue(1));
|
||||
JSHandle<JSTaggedValue> handleTagVal2(thread, JSTaggedValue(2));
|
||||
JSHandle<JSObject> handleJSObjectTaggedArray(JSArray::CreateArrayFromList(thread, handleTaggedArray));
|
||||
|
||||
// Call "SetIterationKind" function through "NewJSArrayIterator" function of "object_factory.cpp".
|
||||
JSHandle<JSArrayIterator> handleJSArrayIter = factory->NewJSArrayIterator(handleJSObjectTaggedArray,
|
||||
IterationKind::KEY);
|
||||
EXPECT_EQ(handleJSArrayIter->GetIterationKind().GetNumber(), 0);
|
||||
handleJSArrayIter = factory->NewJSArrayIterator(handleJSObjectTaggedArray, IterationKind::VALUE);
|
||||
EXPECT_EQ(handleJSArrayIter->GetIterationKind().GetNumber(), 1);
|
||||
handleJSArrayIter = factory->NewJSArrayIterator(handleJSObjectTaggedArray, IterationKind::KEY_AND_VALUE);
|
||||
EXPECT_EQ(handleJSArrayIter->GetIterationKind().GetNumber(), 2);
|
||||
|
||||
// Call "SetIterationKind" function in this HWTEST_F_L0.
|
||||
handleJSArrayIter->SetIterationKind(thread, handleTagVal0);
|
||||
EXPECT_EQ(handleJSArrayIter->GetIterationKind().GetNumber(), 0);
|
||||
handleJSArrayIter->SetIterationKind(thread, handleTagVal1);
|
||||
EXPECT_EQ(handleJSArrayIter->GetIterationKind().GetNumber(), 1);
|
||||
handleJSArrayIter->SetIterationKind(thread, handleTagVal2);
|
||||
EXPECT_EQ(handleJSArrayIter->GetIterationKind().GetNumber(), 2);
|
||||
}
|
||||
} // namespace panda::ecmascript
|
214
ecmascript/tests/js_dataview_test.cpp
Normal file
214
ecmascript/tests/js_dataview_test.cpp
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* 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/global_env.h"
|
||||
#include "ecmascript/js_arraybuffer.h"
|
||||
#include "ecmascript/js_dataview.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
#include "ecmascript/tests/test_helper.h"
|
||||
|
||||
using namespace panda::ecmascript;
|
||||
|
||||
namespace panda::test {
|
||||
class JSDataViewTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
GTEST_LOG_(INFO) << "SetUpTestCase";
|
||||
}
|
||||
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
GTEST_LOG_(INFO) << "TearDownCase";
|
||||
}
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
TestHelper::DestroyEcmaVMWithScope(instance, scope);
|
||||
}
|
||||
PandaVM *instance {nullptr};
|
||||
ecmascript::EcmaHandleScope *scope {nullptr};
|
||||
JSThread *thread {nullptr};
|
||||
};
|
||||
|
||||
/*
|
||||
* Feature: JSDataView
|
||||
* Function: GetElementSize
|
||||
* SubFunction: N/A
|
||||
* FunctionPoints: Get ElementSize
|
||||
* CaseDescription: Check whether the returned value through "GetElementSize" function is within expectations.
|
||||
*/
|
||||
HWTEST_F_L0(JSDataViewTest, GetElementSize)
|
||||
{
|
||||
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::INT8), 1);
|
||||
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::UINT8), 1);
|
||||
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::UINT8_CLAMPED), 1);
|
||||
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::INT16), 2);
|
||||
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::UINT16), 2);
|
||||
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::INT32), 4);
|
||||
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::UINT32), 4);
|
||||
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::FLOAT32), 4);
|
||||
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::FLOAT64), 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Feature: JSDataView
|
||||
* Function: SetDataView
|
||||
* SubFunction: GetDataView
|
||||
* FunctionPoints: Set DataView
|
||||
* CaseDescription: Check whether the returned value through "GetDataView" function is within expectations after
|
||||
* calling "SetDataView" function.
|
||||
*/
|
||||
HWTEST_F_L0(JSDataViewTest, SetDataView)
|
||||
{
|
||||
EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = ecmaVMPtr->GetFactory();
|
||||
JSHandle<GlobalEnv> handleGlobalEnv = ecmaVMPtr->GetGlobalEnv();
|
||||
|
||||
int32_t lengthDataArrayBuf = 8;
|
||||
int32_t offsetDataView = 4;
|
||||
int32_t lengthDataView = 4;
|
||||
JSHandle<JSFunction> handleFuncArrayBuf(handleGlobalEnv->GetArrayBufferFunction());
|
||||
JSHandle<JSTaggedValue> handleTagValFuncArrayBuf(handleFuncArrayBuf);
|
||||
JSHandle<JSArrayBuffer> handleArrayBuf(
|
||||
factory->NewJSObjectByConstructor(handleFuncArrayBuf, handleTagValFuncArrayBuf));
|
||||
handleArrayBuf->SetArrayBufferByteLength(thread, JSTaggedValue(lengthDataArrayBuf));
|
||||
|
||||
// Call "SetDataView" function through "NewJSDataView" function of "object_factory.cpp"
|
||||
JSHandle<JSDataView> handleDataView = factory->NewJSDataView(handleArrayBuf, offsetDataView,
|
||||
lengthDataView);
|
||||
EXPECT_TRUE(handleDataView->GetDataView().IsTrue());
|
||||
|
||||
// Call "SetDataView" function in this HWTEST_F_L0.
|
||||
handleDataView->SetDataView(thread, JSTaggedValue::False());
|
||||
EXPECT_TRUE(handleDataView->GetDataView().IsFalse());
|
||||
handleDataView->SetDataView(thread, JSTaggedValue::True());
|
||||
EXPECT_TRUE(handleDataView->GetDataView().IsTrue());
|
||||
}
|
||||
|
||||
/*
|
||||
* Feature: JSDataView
|
||||
* Function: SetViewedArrayBuffer
|
||||
* SubFunction: GetViewedArrayBuffer
|
||||
* FunctionPoints: Set ViewedArrayBuffer
|
||||
* CaseDescription: Check whether the returned value through "GetViewedArrayBuffer" function is within expectations
|
||||
* after calling "SetViewedArrayBuffer" function.
|
||||
*/
|
||||
HWTEST_F_L0(JSDataViewTest, SetViewedArrayBuffer)
|
||||
{
|
||||
EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = ecmaVMPtr->GetFactory();
|
||||
JSHandle<JSFunction> handleFuncArrayBuf(ecmaVMPtr->GetGlobalEnv()->GetArrayBufferFunction());
|
||||
JSHandle<JSTaggedValue> handleTagValFuncArrayBuf(handleFuncArrayBuf);
|
||||
|
||||
int32_t lengthDataArrayBuf1 = 8;
|
||||
int32_t lengthDataArrayBuf2 = 16;
|
||||
int32_t offsetDataView = 4;
|
||||
int32_t lengthDataView = 4;
|
||||
JSHandle<JSArrayBuffer> handleArrayBuf1(
|
||||
factory->NewJSObjectByConstructor(handleFuncArrayBuf, handleTagValFuncArrayBuf));
|
||||
JSHandle<JSArrayBuffer> handleArrayBuf2(
|
||||
factory->NewJSObjectByConstructor(handleFuncArrayBuf, handleTagValFuncArrayBuf));
|
||||
handleArrayBuf1->SetArrayBufferByteLength(thread, JSTaggedValue(lengthDataArrayBuf1));
|
||||
handleArrayBuf2->SetArrayBufferByteLength(thread, JSTaggedValue(lengthDataArrayBuf2));
|
||||
|
||||
// Call "SetViewedArrayBuffer" function through "NewJSDataView" function of "object_factory.cpp"
|
||||
JSHandle<JSDataView> handleDataView = factory->NewJSDataView(handleArrayBuf1, offsetDataView,
|
||||
lengthDataView);
|
||||
JSHandle<JSTaggedValue> handleTagValDataViewFrom1(thread, handleArrayBuf1.GetTaggedValue());
|
||||
JSHandle<JSTaggedValue> handleTagValDataViewTo1(thread, handleDataView->GetViewedArrayBuffer());
|
||||
EXPECT_TRUE(JSTaggedValue::Equal(thread, handleTagValDataViewFrom1, handleTagValDataViewTo1));
|
||||
|
||||
// Call "SetViewedArrayBuffer" function in this HWTEST_F_L0.
|
||||
handleDataView->SetViewedArrayBuffer(thread, handleArrayBuf2.GetTaggedValue());
|
||||
JSHandle<JSTaggedValue> handleTagValDataViewFrom2(thread, handleArrayBuf2.GetTaggedValue());
|
||||
JSHandle<JSTaggedValue> handleTagValDataViewTo2(thread, handleDataView->GetViewedArrayBuffer());
|
||||
EXPECT_TRUE(JSTaggedValue::Equal(thread, handleTagValDataViewFrom2, handleTagValDataViewTo2));
|
||||
EXPECT_FALSE(JSTaggedValue::Equal(thread, handleTagValDataViewFrom1, handleTagValDataViewFrom2));
|
||||
}
|
||||
|
||||
/*
|
||||
* Feature: JSDataView
|
||||
* Function: SetByteLength
|
||||
* SubFunction: GetByteLength
|
||||
* FunctionPoints: Set ByteLength
|
||||
* CaseDescription: Check whether the returned value through "GetByteLength" function is within expectations after
|
||||
* calling "SetByteLength" function.
|
||||
*/
|
||||
HWTEST_F_L0(JSDataViewTest, SetByteLength)
|
||||
{
|
||||
EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = ecmaVMPtr->GetFactory();
|
||||
JSHandle<JSFunction> handleFuncArrayBuf(ecmaVMPtr->GetGlobalEnv()->GetArrayBufferFunction());
|
||||
JSHandle<JSTaggedValue> handleTagValFuncArrayBuf(handleFuncArrayBuf);
|
||||
|
||||
int32_t lengthDataArrayBuf = 8;
|
||||
int32_t offsetDataView = 4;
|
||||
int32_t lengthDataView1 = 4;
|
||||
int32_t lengthDataView2 = 2;
|
||||
JSHandle<JSTaggedValue> handleTagValLengthDataView2(thread, JSTaggedValue(lengthDataView2));
|
||||
JSHandle<JSArrayBuffer> handleArrayBuf(
|
||||
factory->NewJSObjectByConstructor(handleFuncArrayBuf, handleTagValFuncArrayBuf));
|
||||
handleArrayBuf->SetArrayBufferByteLength(thread, JSTaggedValue(lengthDataArrayBuf));
|
||||
|
||||
// Call "SetByteLength" function through "NewJSDataView" function of "object_factory.cpp"
|
||||
JSHandle<JSDataView> handleDataView = factory->NewJSDataView(handleArrayBuf, offsetDataView,
|
||||
lengthDataView1);
|
||||
EXPECT_EQ(handleDataView->GetByteLength().GetNumber(), lengthDataView1);
|
||||
|
||||
// Call "SetByteLength" function in this HWTEST_F_L0.
|
||||
handleDataView->SetByteLength(thread, handleTagValLengthDataView2);
|
||||
EXPECT_EQ(handleDataView->GetByteLength().GetNumber(), lengthDataView2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Feature: JSDataView
|
||||
* Function: SetByteOffset
|
||||
* SubFunction: GetByteOffset
|
||||
* FunctionPoints: Set ByteOffset
|
||||
* CaseDescription: Check whether the returned value through "GetByteOffset" function is within expectations after
|
||||
* calling "SetByteOffset" function.
|
||||
*/
|
||||
HWTEST_F_L0(JSDataViewTest, SetByteOffset)
|
||||
{
|
||||
EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = ecmaVMPtr->GetFactory();
|
||||
JSHandle<JSFunction> handleFuncArrayBuf1(ecmaVMPtr->GetGlobalEnv()->GetArrayBufferFunction());
|
||||
JSHandle<JSTaggedValue> handleTagValFuncArrayBuf1(handleFuncArrayBuf1);
|
||||
|
||||
int32_t lengthDataArrayBuf = 8;
|
||||
int32_t offsetDataView1 = 4;
|
||||
int32_t offsetDataView2 = 6;
|
||||
int32_t lengthDataView = 2;
|
||||
JSHandle<JSTaggedValue> handleTagValOffsetDataView2(thread, JSTaggedValue(offsetDataView2));
|
||||
JSHandle<JSArrayBuffer> handleArrayBuf(
|
||||
factory->NewJSObjectByConstructor(handleFuncArrayBuf1, handleTagValFuncArrayBuf1));
|
||||
handleArrayBuf->SetArrayBufferByteLength(thread, JSTaggedValue(lengthDataArrayBuf));
|
||||
|
||||
// Call "SetByteOffset" function through "NewJSDataView" function of "object_factory.cpp"
|
||||
JSHandle<JSDataView> handleDataView = factory->NewJSDataView(handleArrayBuf, offsetDataView1,
|
||||
lengthDataView);
|
||||
EXPECT_EQ(handleDataView->GetByteOffset().GetNumber(), offsetDataView1);
|
||||
|
||||
// Call "SetByteOffset" function in this HWTEST_F_L0.
|
||||
handleDataView->SetByteOffset(thread, handleTagValOffsetDataView2);
|
||||
EXPECT_EQ(handleDataView->GetByteOffset().GetNumber(), offsetDataView2);
|
||||
}
|
||||
} // namespace panda::ecmascript
|
@ -78,7 +78,7 @@ HWTEST_F_L0(NameDictionaryTest, addKeyAndValue)
|
||||
int numOfElement = 64;
|
||||
JSHandle<NameDictionary> dictJShandle(thread, NameDictionary::Create(thread, numOfElement));
|
||||
EXPECT_TRUE(*dictJShandle != nullptr);
|
||||
JSHandle<NameDictionary> dictHandle(dictJShandle);
|
||||
JSMutableHandle<NameDictionary> dictHandle(dictJShandle);
|
||||
JSHandle<JSTaggedValue> objFun = GetGlobalEnv(thread)->GetObjectFunction();
|
||||
|
||||
// create key and values
|
||||
@ -103,7 +103,8 @@ HWTEST_F_L0(NameDictionaryTest, addKeyAndValue)
|
||||
PropertyAttributes metaData2;
|
||||
|
||||
// test insert()
|
||||
JSHandle<NameDictionary> dict(thread, NameDictionary::PutIfAbsent(thread, dictHandle, key1, value1, metaData1));
|
||||
NameDictionary *dict = NameDictionary::PutIfAbsent(thread, dictHandle, key1, value1, metaData1);
|
||||
dictHandle.Update(JSTaggedValue(dict));
|
||||
EXPECT_EQ(dict->EntriesCount(), 1);
|
||||
|
||||
// test find() and lookup()
|
||||
@ -111,10 +112,10 @@ HWTEST_F_L0(NameDictionaryTest, addKeyAndValue)
|
||||
EXPECT_EQ(key1.GetTaggedValue(), JSTaggedValue(dict->GetKey(entry1).GetRawData()));
|
||||
EXPECT_EQ(value1.GetTaggedValue(), JSTaggedValue(dict->GetValue(entry1).GetRawData()));
|
||||
|
||||
JSHandle<NameDictionary> dict2(thread, dict->PutIfAbsent(thread, dictHandle, key2, value2, metaData2));
|
||||
JSHandle<NameDictionary> dict2(thread, NameDictionary::PutIfAbsent(thread, dictHandle, key2, value2, metaData2));
|
||||
EXPECT_EQ(dict2->EntriesCount(), 2);
|
||||
// test remove()
|
||||
dict->Remove(thread, dictHandle, entry1);
|
||||
dict = NameDictionary::Remove(thread, dictHandle, entry1);
|
||||
EXPECT_EQ(-1, dict->FindEntry(key1.GetTaggedValue()));
|
||||
EXPECT_EQ(dict->EntriesCount(), 1);
|
||||
}
|
||||
@ -172,7 +173,8 @@ HWTEST_F_L0(NameDictionaryTest, ShrinkCapacity)
|
||||
PropertyAttributes metaData;
|
||||
|
||||
// test insert()
|
||||
dictHandle.Update(JSTaggedValue(NameDictionary::PutIfAbsent(thread, dictHandle, key, value, metaData)));
|
||||
NameDictionary *newDict = NameDictionary::PutIfAbsent(thread, dictHandle, key, value, metaData);
|
||||
dictHandle.Update(JSTaggedValue(newDict));
|
||||
}
|
||||
|
||||
keyArray[5] = '2';
|
||||
@ -183,7 +185,8 @@ HWTEST_F_L0(NameDictionaryTest, ShrinkCapacity)
|
||||
int entry = dictHandle->FindEntry(arrayHandle.GetTaggedValue());
|
||||
EXPECT_NE(entry, -1);
|
||||
|
||||
dictHandle.Update(JSTaggedValue(NameDictionary::Remove(thread, dictHandle, entry)));
|
||||
NameDictionary *newDict1 = NameDictionary::Remove(thread, dictHandle, entry);
|
||||
dictHandle.Update(JSTaggedValue(newDict1));
|
||||
EXPECT_EQ(dictHandle->EntriesCount(), 9);
|
||||
EXPECT_EQ(dictHandle->Size(), 16);
|
||||
}
|
||||
|
@ -47,8 +47,8 @@ source_set("libark_ecma_debugger_static") {
|
||||
deps = [
|
||||
"$ark_root/libpandabase:libarkbase",
|
||||
"$ark_root/libpandafile:libarkfile",
|
||||
"$ark_root/runtime:arkruntime_header_deps",
|
||||
]
|
||||
deps += arkruntime_header_gen_deps
|
||||
|
||||
cflags_cc = [ "-fvisibility=hidden" ]
|
||||
}
|
||||
@ -84,8 +84,8 @@ source_set("libark_ecma_debugger_test_static") {
|
||||
deps = [
|
||||
"$ark_root/libpandabase:libarkbase",
|
||||
"$ark_root/libpandafile:libarkfile",
|
||||
"$ark_root/runtime:arkruntime_header_deps",
|
||||
]
|
||||
deps += arkruntime_header_gen_deps
|
||||
}
|
||||
|
||||
ohos_shared_library("libark_ecma_debugger_test") {
|
||||
|
@ -19,10 +19,6 @@
|
||||
namespace panda::tooling::ecmascript {
|
||||
void JSPtHooks::Breakpoint([[maybe_unused]] PtThread thread, const PtLocation &location)
|
||||
{
|
||||
if (thread.GetId() != ManagedThread::NON_INITIALIZED_THREAD_ID) {
|
||||
// Skip none-js thread
|
||||
return;
|
||||
}
|
||||
LOG(DEBUG, DEBUGGER) << "JSPtHooks: Breakpoint => " << location.GetMethodId() << ": "
|
||||
<< location.GetBytecodeOffset();
|
||||
|
||||
@ -38,13 +34,9 @@ void JSPtHooks::Paused(PauseReason reason)
|
||||
backend_->NotifyPaused({}, reason);
|
||||
}
|
||||
|
||||
void JSPtHooks::Exception(PtThread thread, [[maybe_unused]] const PtLocation &location,
|
||||
void JSPtHooks::Exception([[maybe_unused]] PtThread thread, [[maybe_unused]] const PtLocation &location,
|
||||
[[maybe_unused]] PtObject exceptionObject, [[maybe_unused]] const PtLocation &catchLocation)
|
||||
{
|
||||
if (thread.GetId() != ManagedThread::NON_INITIALIZED_THREAD_ID) {
|
||||
// Skip none-js thread
|
||||
return;
|
||||
}
|
||||
LOG(DEBUG, DEBUGGER) << "JSPtHooks: Exception";
|
||||
|
||||
[[maybe_unused]] LocalScope scope(backend_->ecmaVm_);
|
||||
@ -58,12 +50,8 @@ void JSPtHooks::Exception(PtThread thread, [[maybe_unused]] const PtLocation &lo
|
||||
}
|
||||
}
|
||||
|
||||
void JSPtHooks::SingleStep(PtThread thread, const PtLocation &location)
|
||||
void JSPtHooks::SingleStep([[maybe_unused]] PtThread thread, const PtLocation &location)
|
||||
{
|
||||
if (thread.GetId() != ManagedThread::NON_INITIALIZED_THREAD_ID) {
|
||||
// Skip none-js thread
|
||||
return;
|
||||
}
|
||||
LOG(DEBUG, DEBUGGER) << "JSPtHooks: SingleStep => " << location.GetBytecodeOffset();
|
||||
|
||||
[[maybe_unused]] LocalScope scope(backend_->ecmaVm_);
|
||||
|
@ -73,8 +73,7 @@ void JSDebugger::BytecodePcChanged(ManagedThread *thread, Method *method, uint32
|
||||
HandleBreakpoint(JSThread::Cast(thread), JSMethod::Cast(method), bcOffset);
|
||||
}
|
||||
|
||||
bool JSDebugger::HandleBreakpoint([[maybe_unused]] const JSThread *thread, const JSMethod *method,
|
||||
uint32_t bcOffset)
|
||||
bool JSDebugger::HandleBreakpoint(const JSThread *thread, const JSMethod *method, uint32_t bcOffset)
|
||||
{
|
||||
if (!FindBreakpoint(method, bcOffset)) {
|
||||
return false;
|
||||
@ -83,7 +82,7 @@ bool JSDebugger::HandleBreakpoint([[maybe_unused]] const JSThread *thread, const
|
||||
auto *pf = method->GetPandaFile();
|
||||
PtLocation location {pf->GetFilename().c_str(), method->GetFileId(), bcOffset};
|
||||
if (hooks_ != nullptr) {
|
||||
hooks_->Breakpoint(PtThread(ManagedThread::NON_INITIALIZED_THREAD_ID), location);
|
||||
hooks_->Breakpoint(PtThread(thread->GetId()), location);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -99,7 +98,7 @@ void JSDebugger::HandleExceptionThrowEvent(const JSThread *thread, const JSMetho
|
||||
PtLocation throwLocation {pf->GetFilename().c_str(), method->GetFileId(), bcOffset};
|
||||
|
||||
if (hooks_ != nullptr) {
|
||||
hooks_->Exception(PtThread(ManagedThread::NON_INITIALIZED_THREAD_ID), throwLocation, PtObject(), throwLocation);
|
||||
hooks_->Exception(PtThread(thread->GetId()), throwLocation, PtObject(), throwLocation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ JSTaggedValue WeakVector::Get(array_size_t index) const
|
||||
void WeakVector::Set(const JSThread *thread, array_size_t index, JSTaggedValue value)
|
||||
{
|
||||
ASSERT(index < GetCapacity());
|
||||
return TaggedArray::Set(thread, VectorToArrayIndex(index), value);
|
||||
TaggedArray::Set(thread, VectorToArrayIndex(index), value);
|
||||
}
|
||||
|
||||
void WeakVector::SetEnd(const JSThread *thread, array_size_t end)
|
||||
|
@ -21,14 +21,6 @@ asan_lib_path = "/usr/lib/llvm-10/lib/clang/10.0.0/lib/linux"
|
||||
sdk_libc_secshared_dep = "//utils/native/base:utilsecurec"
|
||||
sdk_libc_secshared_config = "//utils/native/base:utils_config"
|
||||
|
||||
# Add for header file dependence, should dependent this when include
|
||||
# header file of runtime, but not dependent libarkruntime
|
||||
arkruntime_header_gen_deps = [
|
||||
"$ark_root/runtime:arkruntime_gen_intrinsics_intrinsics_h",
|
||||
"$ark_root/runtime:libarkruntime_options_gen_h",
|
||||
"$ark_root/verification/gen:verification_verifier_messages_h",
|
||||
]
|
||||
|
||||
# Generate file for a template and YAML data provided.
|
||||
#
|
||||
# Mandatory arguments:
|
||||
|
@ -35,21 +35,20 @@ def parse_args():
|
||||
return args
|
||||
|
||||
|
||||
def copy_xml(args):
|
||||
"""copy resource xml to test direction."""
|
||||
def copy_res(args):
|
||||
"""copy resources to test direction."""
|
||||
src_xml_file = os.path.join(args.src_path, args.src_xml)
|
||||
dst_xml_file = os.path.join(args.dst_path, args.src_xml)
|
||||
|
||||
if not os.path.isfile(src_xml_file):
|
||||
print(args.src_xml + " not exist.")
|
||||
return
|
||||
|
||||
if not os.path.exists(args.dst_path):
|
||||
os.makedirs(args.dst_path)
|
||||
if os.path.exists(args.dst_path):
|
||||
shutil.rmtree(args.dst_path)
|
||||
|
||||
shutil.copyfile(src_xml_file, dst_xml_file)
|
||||
shutil.copytree(args.src_path, args.dst_path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
input_args = parse_args()
|
||||
copy_xml(input_args)
|
||||
copy_res(input_args)
|
||||
|
Loading…
Reference in New Issue
Block a user