diff --git a/BUILD.gn b/BUILD.gn index 2dec2fe2712b71e6e362fb24f37a1b5f016e4e1d..af65466ab0167480c6d7cb9c2f0f275f0abce4c0 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1042,8 +1042,6 @@ ecma_source = [ "ecmascript/mem/shared_heap/shared_full_gc.cpp", "ecmascript/mem/shared_heap/shared_gc_marker.cpp", "ecmascript/mem/shared_heap/shared_space.cpp", - "ecmascript/mem/unified_gc/unified_gc.cpp", - "ecmascript/mem/unified_gc/unified_gc_marker.cpp", "ecmascript/mem/space.cpp", "ecmascript/mem/sparse_space.cpp", "ecmascript/mem/tagged_object.cpp", @@ -1180,6 +1178,15 @@ if (enable_next_optimization) { ecma_source += [ "ecmascript/base/json_stringifier.cpp" ] } +ecma_source += [ + "ecmascript/cross_vm/unified_gc/unified_gc.cpp", + "ecmascript/cross_vm/unified_gc/unified_gc_marker.cpp", + "ecmascript/cross_vm/builtins_gc_hybrid.cpp", + "ecmascript/cross_vm/heap_hybrid.cpp", + "ecmascript/cross_vm/jsnapi_expo_hybrid.cpp", + "ecmascript/cross_vm/object_factory_hybrid.cpp", +] + hitrace_scope_source = [] if (is_ohos && is_standard_system && enable_hitrace) { hitrace_scope_source += [ "ecmascript/jobs/hitrace_scope.cpp" ] diff --git a/compiler_service/test/BUILD.gn b/compiler_service/test/BUILD.gn index 933eb0eae8ca4208b6bf9d8a1565894e712d7bd4..f457e8ad7fd3d4e61415608bab2a886310f3c423 100644 --- a/compiler_service/test/BUILD.gn +++ b/compiler_service/test/BUILD.gn @@ -14,20 +14,20 @@ group("compiler_service_unittest") { testonly = true deps = [ - #"unittest/aotcompilerargshandler_unit:AotCompilerArgsHandlerUnitTest", - #"unittest/aotcompilerclient_unit:AotCompilerClientUnitTest", - #"unittest/aotcompilererrorutils_unit:AotCompilerErrorUtilsUnitTest", - #"unittest/aotcompilerimpl_unit:AotCompilerImplUnitTest", - #"unittest/aotcompilerproxy_unit:AotCompilerProxyUnitTest", - #"unittest/aotcompilerservice_unit:AotCompilerServiceUnitTest", - #"unittest/aotcompilerstub_unit:AotCompilerStubUnitTest", + "unittest/aotcompilerargshandler_unit:AotCompilerArgsHandlerUnitTest", + "unittest/aotcompilerclient_unit:AotCompilerClientUnitTest", + "unittest/aotcompilererrorutils_unit:AotCompilerErrorUtilsUnitTest", + "unittest/aotcompilerimpl_unit:AotCompilerImplUnitTest", + "unittest/aotcompilerproxy_unit:AotCompilerProxyUnitTest", + "unittest/aotcompilerservice_unit:AotCompilerServiceUnitTest", + "unittest/aotcompilerstub_unit:AotCompilerStubUnitTest", ] } group("compiler_service_fuzztest") { testonly = true deps = [ - #"fuzztest/aotcompilerargsprepare_fuzzer:AotCompilerArgsPrepareFuzzTest", - #"fuzztest/compilerinterfacestub_fuzzer:CompilerInterfaceStubFuzzTest", + "fuzztest/aotcompilerargsprepare_fuzzer:AotCompilerArgsPrepareFuzzTest", + "fuzztest/compilerinterfacestub_fuzzer:CompilerInterfaceStubFuzzTest", ] } diff --git a/compiler_service/test/fuzztest/aotcompilerargsprepare_fuzzer/BUILD.gn b/compiler_service/test/fuzztest/aotcompilerargsprepare_fuzzer/BUILD.gn index 6270be63b00baa99fc57a19ac25c0227b39053bc..59e3407cf1718a1e2deafa95e3f72659675122d5 100644 --- a/compiler_service/test/fuzztest/aotcompilerargsprepare_fuzzer/BUILD.gn +++ b/compiler_service/test/fuzztest/aotcompilerargsprepare_fuzzer/BUILD.gn @@ -31,7 +31,6 @@ ohos_fuzztest("AotCompilerArgsPrepareFuzzTest") { ] configs = [ "$js_root:ark_jsruntime_public_config", - "$js_root:ark_jsruntime_common_config", ] version_script = "${compiler_service_root}/libaot_compiler_service.map" sources = [ diff --git a/compiler_service/test/fuzztest/compilerinterfacestub_fuzzer/BUILD.gn b/compiler_service/test/fuzztest/compilerinterfacestub_fuzzer/BUILD.gn index 9fe719bfbe140becadc147fed4c537971f435235..4f40c2415082cf9fdccfdbbd4ea75f5df20f61d2 100644 --- a/compiler_service/test/fuzztest/compilerinterfacestub_fuzzer/BUILD.gn +++ b/compiler_service/test/fuzztest/compilerinterfacestub_fuzzer/BUILD.gn @@ -31,7 +31,6 @@ ohos_fuzztest("CompilerInterfaceStubFuzzTest") { ] configs = [ "$js_root:ark_jsruntime_public_config", - "$js_root:ark_jsruntime_common_config", ] version_script = "${compiler_service_root}/libaot_compiler_service.map" sources = [ diff --git a/compiler_service/test/unittest/aotcompilerargshandler_unit/BUILD.gn b/compiler_service/test/unittest/aotcompilerargshandler_unit/BUILD.gn index 328a9661ac291c075cdb84f9e435aa36570a2cdf..1a8f27f92120f59cb5fed51448272ccade6827ec 100644 --- a/compiler_service/test/unittest/aotcompilerargshandler_unit/BUILD.gn +++ b/compiler_service/test/unittest/aotcompilerargshandler_unit/BUILD.gn @@ -28,7 +28,6 @@ ohos_unittest("AotCompilerArgsHandlerUnitTest") { configs = [ ":module_private_config", "$js_root:ark_jsruntime_public_config", - "$js_root:ark_jsruntime_common_config", ] version_script = "${compiler_service_root}/libaot_compiler_service.map" sources = [ diff --git a/compiler_service/test/unittest/aotcompilerclient_unit/BUILD.gn b/compiler_service/test/unittest/aotcompilerclient_unit/BUILD.gn index 3c928442cae3c25048aa370f0847eb8bda06ae7b..5299c50d77a85f38aca85d43d7db407c687d1000 100644 --- a/compiler_service/test/unittest/aotcompilerclient_unit/BUILD.gn +++ b/compiler_service/test/unittest/aotcompilerclient_unit/BUILD.gn @@ -29,7 +29,6 @@ ohos_unittest("AotCompilerClientUnitTest") { configs = [ ":module_private_config", "$js_root:ark_jsruntime_public_config", - "$js_root:ark_jsruntime_common_config", ] version_script = "${compiler_service_root}/libaot_compiler_service.map" sources = [ diff --git a/compiler_service/test/unittest/aotcompilererrorutils_unit/BUILD.gn b/compiler_service/test/unittest/aotcompilererrorutils_unit/BUILD.gn index 0dc8b62f619a4e0425870d1a5060804cf7a51f80..0648707e85660890a074c36e3b9be758bca7aafd 100644 --- a/compiler_service/test/unittest/aotcompilererrorutils_unit/BUILD.gn +++ b/compiler_service/test/unittest/aotcompilererrorutils_unit/BUILD.gn @@ -28,7 +28,6 @@ ohos_unittest("AotCompilerErrorUtilsUnitTest") { configs = [ ":module_private_config", "$js_root:ark_jsruntime_public_config", - "$js_root:ark_jsruntime_common_config", ] version_script = "${compiler_service_root}/libaot_compiler_service.map" sources = [ diff --git a/compiler_service/test/unittest/aotcompilerimpl_unit/BUILD.gn b/compiler_service/test/unittest/aotcompilerimpl_unit/BUILD.gn index 544ca595423ce88531917a7c891cf08fc60bde5f..5ac62e3f4164b24f9b4ee944d518ae859502b528 100644 --- a/compiler_service/test/unittest/aotcompilerimpl_unit/BUILD.gn +++ b/compiler_service/test/unittest/aotcompilerimpl_unit/BUILD.gn @@ -29,7 +29,6 @@ ohos_unittest("AotCompilerImplUnitTest") { configs = [ ":module_private_config", "$js_root:ark_jsruntime_public_config", - "$js_root:ark_jsruntime_common_config", ] version_script = "${compiler_service_root}/libaot_compiler_service.map" sources = [ diff --git a/compiler_service/test/unittest/aotcompilerproxy_unit/BUILD.gn b/compiler_service/test/unittest/aotcompilerproxy_unit/BUILD.gn index 7d92ac28acd95bbebf169cfbf1f86939a2e414f9..d530ab72999f48c90e687fb31b86bff25aa24783 100644 --- a/compiler_service/test/unittest/aotcompilerproxy_unit/BUILD.gn +++ b/compiler_service/test/unittest/aotcompilerproxy_unit/BUILD.gn @@ -28,7 +28,6 @@ ohos_unittest("AotCompilerProxyUnitTest") { configs = [ ":module_private_config", "$js_root:ark_jsruntime_public_config", - "$js_root:ark_jsruntime_common_config", ] version_script = "${compiler_service_root}/libaot_compiler_service.map" sources = [ diff --git a/compiler_service/test/unittest/aotcompilerservice_unit/BUILD.gn b/compiler_service/test/unittest/aotcompilerservice_unit/BUILD.gn index c8517a6fe2768940b6dcf20f136e25b6b4ec5d23..9db3234f84b32e7202f67aa23c6a4cdb21c8adbf 100644 --- a/compiler_service/test/unittest/aotcompilerservice_unit/BUILD.gn +++ b/compiler_service/test/unittest/aotcompilerservice_unit/BUILD.gn @@ -29,7 +29,6 @@ ohos_unittest("AotCompilerServiceUnitTest") { configs = [ ":module_private_config", "$js_root:ark_jsruntime_public_config", - "$js_root:ark_jsruntime_common_config", ] version_script = "${compiler_service_root}/libaot_compiler_service.map" sources = [ diff --git a/compiler_service/test/unittest/aotcompilerstub_unit/BUILD.gn b/compiler_service/test/unittest/aotcompilerstub_unit/BUILD.gn index c451bf646afa1fbf00f29d7209fd2a20ad3bf502..a417cf0a9755c3a438949d4767f435a5d703b871 100644 --- a/compiler_service/test/unittest/aotcompilerstub_unit/BUILD.gn +++ b/compiler_service/test/unittest/aotcompilerstub_unit/BUILD.gn @@ -28,7 +28,6 @@ ohos_unittest("AotCompilerStubUnitTest") { configs = [ ":module_private_config", "$js_root:ark_jsruntime_public_config", - "$js_root:ark_jsruntime_common_config", ] version_script = "${compiler_service_root}/libaot_compiler_service.map" sources = [ diff --git a/ecmascript/builtins/builtins_gc.cpp b/ecmascript/builtins/builtins_gc.cpp index 0e39d658d4cda38111ecc737a82bb9d93cea29f9..9ee844f51ca4f0fb994f1211c9c7078947739c18 100644 --- a/ecmascript/builtins/builtins_gc.cpp +++ b/ecmascript/builtins/builtins_gc.cpp @@ -100,18 +100,6 @@ JSTaggedValue BuiltinsGc::RegisterNativeFree(EcmaRuntimeCallInfo *info) return JSTaggedValue::Undefined(); } -JSTaggedValue BuiltinsGc::ClearWeakRefForTest(EcmaRuntimeCallInfo *info) -{ - RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread()); - ASSERT(info); - JSThread *thread = info->GetThread(); - if (!((thread)->GetEcmaVM()->GetJSOptions().IsOpenArkTools())) { - return JSTaggedValue::Undefined(); - } - EcmaVM::ClearKeptObjects(thread); - return JSTaggedValue::Undefined(); -} - JSTaggedValue BuiltinsGc::WaitForFinishGC(EcmaRuntimeCallInfo *info) { RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread()); @@ -270,6 +258,7 @@ TriggerGCType BuiltinsGc::StringToGcType(JSThread *thread, JSTaggedValue cause) if (JSTaggedValue::StrictEqual(thread->GlobalConstants()->GetAppSpawnSharedFullGcCause(), cause)) { return APPSPAWN_SHARED_FULL_GC; } + // if (Runtime::GetInstance()->IsHybridVm() && if (JSTaggedValue::StrictEqual(thread->GlobalConstants()->GetUnifiedGcCause(), cause)) { return UNIFIED_GC; } diff --git a/ecmascript/builtins/builtins_gc.h b/ecmascript/builtins/builtins_gc.h index 78c921b83ec810aab3795365ebe6e1f4ed91dbfc..83bfd15ad8550b86a6eecb8688e9c588f7d2f13d 100644 --- a/ecmascript/builtins/builtins_gc.h +++ b/ecmascript/builtins/builtins_gc.h @@ -18,6 +18,7 @@ #include "ecmascript/base/builtins_base.h" #include "ecmascript/js_thread.h" +#include "ecmascript/cross_vm/builtins_gc_hybrid.h" namespace panda::ecmascript::builtins { class BuiltinsGc : public base::BuiltinsBase { @@ -38,8 +39,6 @@ public: static JSTaggedValue WaitForFinishGC(EcmaRuntimeCallInfo *info); - static JSTaggedValue ClearWeakRefForTest(EcmaRuntimeCallInfo *info); - static JSTaggedValue StartGC(EcmaRuntimeCallInfo *info); static JSTaggedValue AllocateArrayObject(EcmaRuntimeCallInfo *info); @@ -49,6 +48,8 @@ public: return Span(GC_FUNCTIONS); } + BUILDINS_GC_HYBRID_EXTENSION + private: #define BUILTINS_GC_FUNCTION_ENTRY(name, method, length, id) \ base::BuiltinFunctionEntry::Create(name, BuiltinsGc::method, length, BUILTINS_STUB_ID(id)), @@ -68,7 +69,7 @@ private: BUILTINS_GC_FUNCTION_ENTRY("waitForFinishGC", WaitForFinishGC, 1, INVALID) BUILTINS_GC_FUNCTION_ENTRY("startGC", StartGC, 3, INVALID) BUILTINS_GC_FUNCTION_ENTRY("allocateArrayObject", AllocateArrayObject, 1, INVALID) - BUILTINS_GC_FUNCTION_ENTRY("clearWeakRefForTest", ClearWeakRefForTest, 1, INVALID) + BUILTINS_GC_HYBRID_FUNCTION_ENTRY }; #undef BUILTINS_GC_FUNCTION_ENTRY diff --git a/ecmascript/cross_vm/builtins_gc_hybrid.cpp b/ecmascript/cross_vm/builtins_gc_hybrid.cpp new file mode 100644 index 0000000000000000000000000000000000000000..27bbef6263335c61361b39678a516eb96e829a15 --- /dev/null +++ b/ecmascript/cross_vm/builtins_gc_hybrid.cpp @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "ecmascript/builtins/builtins_gc.h" +#include "ecmascript/builtins/builtins_ark_tools.h" + +namespace panda::ecmascript::builtins { + +JSTaggedValue BuiltinsGc::ClearWeakRefForTest(EcmaRuntimeCallInfo *info) +{ + RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread()); + ASSERT(info); + JSThread *thread = info->GetThread(); + if (!((thread)->GetEcmaVM()->GetJSOptions().IsOpenArkTools())) { + return JSTaggedValue::Undefined(); + } + EcmaVM::ClearKeptObjects(thread); + return JSTaggedValue::Undefined(); +} +} // namespace panda::ecmascript::builtins diff --git a/ecmascript/cross_vm/builtins_gc_hybrid.h b/ecmascript/cross_vm/builtins_gc_hybrid.h new file mode 100644 index 0000000000000000000000000000000000000000..7d2446899f9c303dcb59f00bb14474f60fc15d9b --- /dev/null +++ b/ecmascript/cross_vm/builtins_gc_hybrid.h @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef ECMASCRIPT_CROSS_VM_BUILTINS_GC_HYBRID_H +#define ECMASCRIPT_CROSS_VM_BUILTINS_GC_HYBRID_H + +namespace panda::ecmascript::builtins { +#define BUILDINS_GC_HYBRID_EXTENSION \ + static JSTaggedValue ClearWeakRefForTest(EcmaRuntimeCallInfo *info); + +#define BUILTINS_GC_HYBRID_FUNCTION_ENTRY \ + BUILTINS_GC_FUNCTION_ENTRY("clearWeakRefForTest", ClearWeakRefForTest, 1, INVALID) + +} // namespace panda::ecmascript::builtins +#endif // ECMASCRIPT_CROSS_VM_BUILTINS_GC_HYBRID_H \ No newline at end of file diff --git a/ecmascript/cross_vm/cross_vm_operator.cpp b/ecmascript/cross_vm/cross_vm_operator.cpp index 1d71b59f50fbf9fb4cae3297052606847e0c9bee..9dce9fa56057090a1399ed21ec197e5b88fe00ad 100644 --- a/ecmascript/cross_vm/cross_vm_operator.cpp +++ b/ecmascript/cross_vm/cross_vm_operator.cpp @@ -17,8 +17,8 @@ #include "ecmascript/ecma_vm.h" #include "ecmascript/mem/heap-inl.h" -#include "ecmascript/mem/unified_gc/unified_gc.h" -#include "ecmascript/mem/unified_gc/unified_gc_marker.h" +#include "ecmascript/cross_vm/unified_gc/unified_gc.h" +#include "ecmascript/cross_vm/unified_gc/unified_gc_marker.h" namespace panda::ecmascript { diff --git a/ecmascript/cross_vm/daemon_task_hybrid.h b/ecmascript/cross_vm/daemon_task_hybrid.h new file mode 100644 index 0000000000000000000000000000000000000000..1965c6fd1c6459c886acbfbb7a904f8ea663d81a --- /dev/null +++ b/ecmascript/cross_vm/daemon_task_hybrid.h @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef ECMASCRIPT_CROSS_VM_DAEMON_TASK_HYBRID_H +#define ECMASCRIPT_CROSS_VM_DAEMON_TASK_HYBRID_H + +namespace panda::ecmascript { +#define DAEMON_TASK_HYBRID_DEF_EXTENSION \ +template \ +void TriggerUnifiedGCMarkTaskRunner() \ +{ \ + SharedHeap::GetInstance()->StartUnifiedGCMark(gcType, gcReason); \ +} \ +template \ +TriggerUnifiedGCMarkTask::TriggerUnifiedGCMarkTask(JSThread *thread) \ + : DaemonTask(thread, DaemonTaskType::TRIGGER_UNIFIED_GC_MARK, DaemonTaskGroup::GC_GROUP, \ + &TriggerUnifiedGCMarkTaskRunner) {} + + +#define DAEMON_TASK_HYBRID_DECL_EXTENSION \ + template \ + class TriggerUnifiedGCMarkTask : public DaemonTask { \ + public: \ + explicit TriggerUnifiedGCMarkTask(JSThread *thread); \ + }; +} // namespace panda::ecmascript +#endif // ECMASCRIPT_CROSS_VM_DAEMON_TASK_HYBRID_H diff --git a/ecmascript/cross_vm/ecma_global_storage_hybrid.h b/ecmascript/cross_vm/ecma_global_storage_hybrid.h new file mode 100644 index 0000000000000000000000000000000000000000..47241298f93f373c0cabe005c70240672bcf6ad2 --- /dev/null +++ b/ecmascript/cross_vm/ecma_global_storage_hybrid.h @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef ECMASCRIPT_CROSS_VM_ECMA_GLOBAL_STORAGE_HYBRID_H +#define ECMASCRIPT_CROSS_VM_ECMA_GLOBAL_STORAGE_HYBRID_H + +namespace panda::ecmascript { +// todo liuhongchen +enum class NodeKind : uint8_t { + NORMAL_NODE, + UNIFIED_NODE, +}; + +#define ECMA_GLOBAL_STORAGE_HYBRID_EXTENSION \ + void SetNodeKind(NodeKind nodeKind) \ + { \ + nodeKind_ = nodeKind; \ + } \ + NodeKind GetNodeKind() \ + { \ + return nodeKind_; \ + } \ +private: \ + NodeKind nodeKind_ {NodeKind::NORMAL_NODE}; \ + NodeList *topXRefGlobalNodes_ {nullptr}; \ + NodeList *lastXRefGlobalNodes_ {nullptr}; \ + NodeList *xRefFreeListNodes_ {nullptr}; +} // namespace panda::ecmascript +#endif // ECMASCRIPT_CROSS_VM_ECMA_GLOBAL_STORAGE_HYBRID_H diff --git a/ecmascript/cross_vm/ecma_vm_hybrid.h b/ecmascript/cross_vm/ecma_vm_hybrid.h new file mode 100644 index 0000000000000000000000000000000000000000..c5d556218fe9dd7549286f18b0b8f3598946a063 --- /dev/null +++ b/ecmascript/cross_vm/ecma_vm_hybrid.h @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef ECMASCRIPT_CROSS_VM_ECMA_VM_HYBRID_H +#define ECMASCRIPT_CROSS_VM_ECMA_VM_HYBRID_H + +namespace panda::ecmascript { +// #define ECMA_VM_HYBRID_EXTENSION \ +// #ifdef PANDA_JS_ETS_HYBRID_MODE \ +// CrossVMOperator* GetCrossVMOperator() const \ +// { \ +// /* if (Runtime::GetInstance()->IsHybridVm()) */ \ +// return crossVMOperator_; \ +// } \ +// #endif /* PANDA_JS_ETS_HYBRID_MODE */ \ +// private: \ +// #ifdef PANDA_JS_ETS_HYBRID_MODE \ +// CrossVMOperator* crossVMOperator_ {nullptr}; \ +// #endif /* PANDA_JS_ETS_HYBRID_MODE */ \ +// protected: \ +// void PrintJSErrorInfo(const JSHandle &exceptionInfo) const; + + +#define ECMA_VM_HYBRID_GET_CROSS_VM_OP_EXTENSION \ + CrossVMOperator* GetCrossVMOperator() const \ + { \ + /* if (Runtime::GetInstance()->IsHybridVm()) */ \ + return crossVMOperator_; \ + } + + +#define ECMA_VM_HYBRID_GET_CROSS_VM_OP_DECL_EXTENSION \ + CrossVMOperator* crossVMOperator_ {nullptr}; +} // namespace panda::ecmascript +#endif // ECMASCRIPT_CROSS_VM_ECMA_VM_HYBRID_H diff --git a/ecmascript/cross_vm/global_env_constants_hybrid.h b/ecmascript/cross_vm/global_env_constants_hybrid.h new file mode 100644 index 0000000000000000000000000000000000000000..53aed164585562915215751ceee6da8d2a346d17 --- /dev/null +++ b/ecmascript/cross_vm/global_env_constants_hybrid.h @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef ECMASCRIPT_CROSS_VM_GLOBAL_ENV_CONSTANTS_HYBRID_H +#define ECMASCRIPT_CROSS_VM_GLOBAL_ENV_CONSTANTS_HYBRID_H + +namespace panda::ecmascript { +#define SHARED_GLOBAL_ENV_CONSTANT_STRING_HYBRID(V) \ + V(ProxyNapiWrapperString, PROXY_NAPI_WRAPPER_INDEX, "_proxynapiwrapper") \ + V(UnifiedGcCause, UNIFIED_GC_CAUSE, "unified") + +#define GLOBAL_ENV_CONSTANT_CLASS_HYBRID(V) \ + V(JSTaggedValue, XRefObjectClass, XREF_OBJECT_HCLASS_INDEX, ecma_roots_class) + +} // namespace panda::ecmascript +#endif // ECMASCRIPT_CROSS_VM_GLOBAL_ENV_CONSTANTS_HYBRID_H diff --git a/ecmascript/cross_vm/heap_hybrid.cpp b/ecmascript/cross_vm/heap_hybrid.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5a4c3249845bfa46746e8228b1bd729ea0982220 --- /dev/null +++ b/ecmascript/cross_vm/heap_hybrid.cpp @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2025 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/mem/heap.h" +#include "ecmascript/checkpoint/thread_state_transition.h" +#include "ecmascript/cross_vm/unified_gc/unified_gc.h" +#include "ecmascript/mem/concurrent_sweeper.h" +#include "ecmascript/mem/verification.h" + +namespace panda::ecmascript { +void SharedHeap::StartUnifiedGCMark([[maybe_unused]]TriggerGCType gcType, [[maybe_unused]]GCReason gcReason) +{ + ASSERT(gcType == TriggerGCType::UNIFIED_GC && gcReason == GCReason::CROSSREF_CAUSE); + ASSERT(JSThread::GetCurrent() == dThread_); + { + ThreadManagedScope runningScope(dThread_); + SuspendAllScope scope(dThread_); + Runtime *runtime = Runtime::GetInstance(); + std::vector recurScopes; + // The approximate size is enough, because even if some thread creates and registers after here, it will keep + // waiting in transition to RUNNING state before JSThread::SetReadyForGCIterating. + recurScopes.reserve(runtime->ApproximateThreadListSize()); + runtime->GCIterateThreadList([&recurScopes](JSThread *thread) { + Heap *heap = const_cast(thread->GetEcmaVM()->GetHeap()); + recurScopes.emplace_back(heap, HeapType::LOCAL_HEAP); + }); +#ifdef PANDA_JS_ETS_HYBRID_MODE + if (!unifiedGC_->StartXGCBarrier()) { + unifiedGC_->SetInterruptUnifiedGC(false); + dThread_->FinishRunningTask(); + return; + } +#endif // PANDA_JS_ETS_HYBRID_MODE + runtime->GCIterateThreadList([gcType](JSThread *thread) { + Heap *heap = const_cast(thread->GetEcmaVM()->GetHeap()); + if (UNLIKELY(heap->ShouldVerifyHeap())) { // LCOV_EXCL_BR_LINE + // pre unified gc heap verify + LOG_ECMA(DEBUG) << "pre unified gc heap verify"; + heap->ProcessSharedGCRSetWorkList(); + Verification(heap, VerifyKind::VERIFY_PRE_GC).VerifyAll(); + } + heap->SetGCType(gcType); + }); + unifiedGC_->RunPhases(); + runtime->GCIterateThreadList([](JSThread *thread) { + Heap *heap = const_cast(thread->GetEcmaVM()->GetHeap()); + if (UNLIKELY(heap->ShouldVerifyHeap())) { // LCOV_EXCL_BR_LINE + // post unified gc heap verify + LOG_ECMA(DEBUG) << "post unified gc heap verify"; + Verification(heap, VerifyKind::VERIFY_POST_GC).VerifyAll(); + } + }); +#ifdef PANDA_JS_ETS_HYBRID_MODE + unifiedGC_->FinishXGCBarrier(); +#endif // PANDA_JS_ETS_HYBRID_MODE + } +} + + +void Heap::UnifiedGCPrepare() +{ + WaitRunningTaskFinished(); + sweeper_->EnsureAllTaskFinished(); + WaitClearTaskFinished(); +} + +uint32_t BaseHeap::GetRunningTaskCount() +{ + LockHolder holder(waitTaskFinishedMutex_); + return runningTaskCount_; +} +} // namespace panda::ecmascript diff --git a/ecmascript/cross_vm/heap_hybrid.h b/ecmascript/cross_vm/heap_hybrid.h new file mode 100644 index 0000000000000000000000000000000000000000..23db9d782ab6517117a8a325d21fdf2d0b4e3420 --- /dev/null +++ b/ecmascript/cross_vm/heap_hybrid.h @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef ECMASCRIPT_CROSS_VM_HEAP_HYBRID_H +#define ECMASCRIPT_CROSS_VM_HEAP_HYBRID_H + +namespace panda::ecmascript { +#define HEAP_HYBRID_BASE_HEAP_EXTENSION \ + void SetGCType(TriggerGCType gcType) \ + { \ + gcType_ = gcType; \ + } \ + uint32_t GetRunningTaskCount(); + +#define HEAP_HYBRID_SHARED_HEAP_EXTENSION \ + UnifiedGC *GetUnifiedGC() const \ + { \ + return unifiedGC_; \ + } \ + template \ + bool TriggerUnifiedGCMark(JSThread *thread) const \ + { \ + ASSERT(gcType == TriggerGCType::UNIFIED_GC && gcReason == GCReason::CROSSREF_CAUSE); \ + return DaemonThread::GetInstance()->CheckAndPostTask(TriggerUnifiedGCMarkTask(thread)); \ + } \ + void StartUnifiedGCMark(TriggerGCType gcType, GCReason gcReason); \ +private: \ + UnifiedGC *unifiedGC_ {nullptr}; + + +#define HEAP_HYBRID_EXTENSION \ + void UnifiedGCPrepare(); \ + UnifiedGCMarker *GetUnifiedGCMarker() const \ + { \ + return unifiedGCMarker_; \ + } \ + bool IsUnifiedGC() const \ + { \ + return gcType_ == TriggerGCType::UNIFIED_GC; \ + } \ +private: \ + UnifiedGCMarker *unifiedGCMarker_ {nullptr}; +} // namespace panda::ecmascript +#endif // ECMASCRIPT_CROSS_VM_HEAP_HYBRID_H diff --git a/ecmascript/cross_vm/js_hclass_hybrid.h b/ecmascript/cross_vm/js_hclass_hybrid.h new file mode 100644 index 0000000000000000000000000000000000000000..90ca3b7dac7e250f044122e10552a6142ebbb90a --- /dev/null +++ b/ecmascript/cross_vm/js_hclass_hybrid.h @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef ECMASCRIPT_CROSS_VM_JS_HCLASS_HYBRID_H +#define ECMASCRIPT_CROSS_VM_JS_HCLASS_HYBRID_H + +namespace panda::ecmascript { +#define JS_HCLASS_HYBRID_EXTENSION \ + inline bool IsJSXRefObject() const \ + { \ + return GetObjectType() == JSType::JS_XREF_OBJECT; \ + } + +} // namespace panda::ecmascript +#endif // ECMASCRIPT_CROSS_VM_JS_HCLASS_HYBRID_H diff --git a/ecmascript/cross_vm/js_tagged_value_hybrid.h b/ecmascript/cross_vm/js_tagged_value_hybrid.h new file mode 100644 index 0000000000000000000000000000000000000000..faa3864a60eda7fe793535e003073144b87bfbe4 --- /dev/null +++ b/ecmascript/cross_vm/js_tagged_value_hybrid.h @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef ECMASCRIPT_CROSS_VM_JS_TAGGED_VALUE_HYBRID_H +#define ECMASCRIPT_CROSS_VM_JS_TAGGED_VALUE_HYBRID_H + +namespace panda::ecmascript { +#define JS_TAGGED_VALUE_HYBRID_DEF_EXTENSION \ + inline bool JSTaggedValue::IsJSXRefObject() const \ + { \ + return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSXRefObject(); \ + } + +#define JS_TAGGED_VALUE_HYBRID_DECL_EXTENSION \ + bool IsJSXRefObject() const; +} // namespace panda::ecmascript +#endif // ECMASCRIPT_CROSS_VM_JS_HCLASS_HYBRID_H diff --git a/ecmascript/cross_vm/js_thread_hybrid.h b/ecmascript/cross_vm/js_thread_hybrid.h new file mode 100644 index 0000000000000000000000000000000000000000..a34b667d0deae2ec2ce9a04db4ef64dcb12ac221 --- /dev/null +++ b/ecmascript/cross_vm/js_thread_hybrid.h @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef ECMASCRIPT_CROSS_VM_JS_THREAD_HYBRID_H +#define ECMASCRIPT_CROSS_VM_JS_THREAD_HYBRID_H + +namespace panda::ecmascript { +#define JS_THREAD_HYBRID_EXTENSION \ +inline uintptr_t NewXRefGlobalHandle(JSTaggedType value) \ +{ \ + return newXRefGlobalHandle_(value); \ +} \ +inline void DisposeXRefGlobalHandle(uintptr_t nodeAddr) \ +{ \ + disposeXRefGlobalHandle_(nodeAddr); \ +} \ +inline void SetNodeKind(NodeKind nodeKind) \ +{ \ + setNodeKind_(nodeKind); \ +} \ +void SetStackStart(uint64_t stackStart) \ +{ \ + glueData_.stackStart_ = stackStart; \ +} \ +void SetStackLimit(uint64_t stackLimit) \ +{ \ + glueData_.stackLimit_ = stackLimit; \ +} \ +private: \ + std::function newXRefGlobalHandle_; \ + std::function disposeXRefGlobalHandle_; \ + std::function setNodeKind_; +} // namespace panda::ecmascript +#endif // ECMASCRIPT_CROSS_VM_JS_THREAD_HYBRID_H \ No newline at end of file diff --git a/ecmascript/cross_vm/jsnapi_expo_hybrid.cpp b/ecmascript/cross_vm/jsnapi_expo_hybrid.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f6cda9418a78e3381723083c12e15c2c8c7dc123 --- /dev/null +++ b/ecmascript/cross_vm/jsnapi_expo_hybrid.cpp @@ -0,0 +1,145 @@ +/* +* Copyright (c) 2025 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/napi/include/jsnapi_expo.h" +#include "ecmascript/napi/jsnapi_helper.h" +#include "ecmascript/napi/include/jsnapi.h" +#include "ecmascript/checkpoint/thread_state_transition.h" +#include "ecmascript/ecma_global_storage.h" +#include "ecmascript/module/napi_module_loader.h" +#include "ecmascript/module/module_path_helper.h" + +namespace panda { +using ecmascript::JSTaggedValue; +template +using JSHandle = ecmascript::JSHandle; + +using ModulePathHelper = ecmascript::ModulePathHelper; +using ecmascript::ObjectFactory; + +Local StringRef::GetProxyNapiWrapperString(const EcmaVM *vm) +{ + // Omit exception check because ark calls here may not + // cause side effect even pending exception exists. + CROSS_THREAD_CHECK(vm); + ecmascript::ThreadManagedScope managedScope(thread); + JSHandle proxyNapiWapperString = thread->GlobalConstants()->GetHandledProxyNapiWrapperString(); + return JSNApiHelper::ToLocal(proxyNapiWapperString); +} + +Local ObjectRef::NewJSXRefObject(const EcmaVM *vm) +{ + CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm)); + ecmascript::ThreadManagedScope managedScope(thread); + ObjectFactory *factory = vm->GetFactory(); + JSHandle object(factory->NewJSXRefObject()); + return JSNApiHelper::ToLocal(object); +} + +void JSNApi::SetStackInfo(const EcmaVM *vm, const panda::StackInfo &info) +{ + JSThread *thread = vm->GetJSThread(); + thread->SetStackStart(info.stackStart); + thread->SetStackLimit(info.stackStart - info.stackSize); +} + +panda::StackInfo JSNApi::GetStackInfo(const EcmaVM *vm) +{ + JSThread *thread = vm->GetJSThread(); + size_t stackStart = thread->GetStackStart(); + size_t stackSize = stackStart - thread->GetStackLimit(); + return {stackStart, stackSize}; +} + +uintptr_t JSNApi::GetXRefGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress) +{ + CROSS_THREAD_CHECK(vm); + if (localAddress == 0) { + return 0; + } + ecmascript::ThreadManagedScope scope(thread); + JSTaggedType value = *(reinterpret_cast(localAddress)); + return thread->NewXRefGlobalHandle(value); +} + + +void JSNApi::DisposeXRefGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr) +{ + CROSS_THREAD_CHECK(vm); + if (addr == 0 || !reinterpret_cast(addr)->IsUsing()) { + return; + } + thread->DisposeXRefGlobalHandle(addr); +} + +#ifdef PANDA_JS_ETS_HYBRID_MODE +void JSNApi::MarkFromObject(const EcmaVM *vm, uintptr_t addr, std::function &visitor) +{ + if (addr == 0 || !reinterpret_cast(addr)->IsUsing()) { + return; + } + JSTaggedType value = *(reinterpret_cast(addr)); + vm->GetCrossVMOperator()->MarkFromObject(value, visitor); +} + +void JSNApi::MarkFromObject(const EcmaVM *vm, uintptr_t addr) +{ + if (addr == 0 || !reinterpret_cast(addr)->IsUsing()) { + return; + } + JSTaggedType value = *(reinterpret_cast(addr)); + vm->GetCrossVMOperator()->MarkFromObject(value); +} + +bool JSNApi::IsObjectAlive(const EcmaVM *vm, uintptr_t addr) +{ + if (addr == 0 || !reinterpret_cast(addr)->IsUsing()) { + return false; + } + JSTaggedType value = *(reinterpret_cast(addr)); + return vm->GetCrossVMOperator()->IsObjectAlive(value); +} + +bool JSNApi::IsValidHeapObject(const EcmaVM *vm, uintptr_t addr) +{ + if (addr == 0 || !reinterpret_cast(addr)->IsUsing()) { + return false; + } + JSTaggedType value = *(reinterpret_cast(addr)); + return vm->GetCrossVMOperator()->IsValidHeapObject(value); +} +#endif // PANDA_JS_ETS_HYBRID_MODE + +Local JSNApi::GetModuleNameSpaceWithPath(const EcmaVM *vm, const char *path) +{ + CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm)); + auto [filePath, recordName] = ModulePathHelper::ResolvePath(path); + ecmascript::ThreadManagedScope managedScope(thread); + JSHandle moduleNamespace = + ecmascript::NapiModuleLoader::LoadModuleNameSpaceFromFile(thread, recordName, filePath); + return JSNApiHelper::ToLocal(moduleNamespace); +} + +std::pair JSNApi::ResolveOhmUrl(std::string ohmUrl) +{ + return ModulePathHelper::ResolveOhmUrl(ohmUrl); +} + +#ifdef PANDA_JS_ETS_HYBRID_MODE +void HandshakeHelper::DoHandshake([[maybe_unused]] EcmaVM *vm, void *stsIface, void **ecmaIface) +{ + ecmascript::CrossVMOperator::DoHandshake(vm, stsIface, ecmaIface); +} +#endif // PANDA_JS_ETS_HYBRID_MODE +} // namespace panda diff --git a/ecmascript/cross_vm/jsnapi_expo_hybrid.h b/ecmascript/cross_vm/jsnapi_expo_hybrid.h new file mode 100644 index 0000000000000000000000000000000000000000..076c54f568b2f0487e0c8c07eeac47eb9a6ccdab --- /dev/null +++ b/ecmascript/cross_vm/jsnapi_expo_hybrid.h @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef ECMASCRIPT_CROSS_VM_JS_NAPI_EXPO_HYBRID_H +#define ECMASCRIPT_CROSS_VM_JS_NAPI_EXPO_HYBRID_H + +namespace panda { +// #define JS_NAPI_EXPO_HYBRID_EXTENSION \ +// struct StackInfo { \ +// size_t stackStart; \ +// size_t stackSize; \ +// }; \ +// #ifdef PANDA_JS_ETS_HYBRID_MODE \ +// class PUBLIC_API HandshakeHelper final { \ +// public: \ +// static void DoHandshake(EcmaVM *vm, void *stsiface, void **ecmaiface); \ +// }; \ +// #endif // PANDA_JS_ETS_HYBRID_MODE + +#define JS_NAPI_EXPO_HYBRID_STACK_INFO_EXTENSION \ + struct StackInfo { \ + size_t stackStart; \ + size_t stackSize; \ + }; + +#define JS_NAPI_EXPO_HYBRID_HAND_SHAKE_HELPER_EXTENSION \ + class PUBLIC_API HandshakeHelper final { \ + public: \ + static void DoHandshake(EcmaVM *vm, void *stsiface, void **ecmaiface); \ + }; + + +#define JS_NAPI_EXPO_HYBRID_GLOBAL_EXTENSION \ + template \ + void CreateXRefGloablReference(const EcmaVM *vm, const Local ¤t); \ + /* This method must be called before Global is released.*/ \ + void FreeGlobalHandleAddr(); \ + void FreeXRefGlobalHandleAddr(); \ + void MarkFromObject(std::function &visitor); \ + void MarkFromObject(); \ + bool IsObjectAlive() const; \ + bool IsValidHeapObject() const; + +#define JS_NAPI_EXPO_HYBRID_OBJECT_REF_EXTENSION \ + static Local NewJSXRefObject(const EcmaVM *vm); + +#define JS_NAPI_EXPO_HYBRID_STRING_REF_EXTENSION \ + static Local GetProxyNapiWrapperString(const EcmaVM *vm); + +#define JS_NAPI_EXPO_HYBRID_JS_NAPI_EXTENSION \ + static void SetStackInfo(const EcmaVM *vm, const panda::StackInfo &info); \ + static panda::StackInfo GetStackInfo(const EcmaVM *vm); \ + static Local GetModuleNameSpaceWithPath(const EcmaVM *vm, const char *path); \ + static std::pair ResolveOhmUrl(std::string ohmUrl); \ + static void SetHostResolveBufferTracker(EcmaVM *vm, std::function cb); \ + static bool IsObjectAlive(const EcmaVM *vm, uintptr_t addr); \ + static bool IsValidHeapObject(const EcmaVM *vm, uintptr_t addr); \ +private: \ + static uintptr_t GetXRefGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress); \ + static void DisposeXRefGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr); + +#define JS_NAPI_EXPO_HYBRID_JS_NAPI_MARK_FROM_OBJ_EXTENSION \ + static void MarkFromObject(const EcmaVM *vm, uintptr_t addr, std::function &visitor); \ + static void MarkFromObject(const EcmaVM *vm, uintptr_t addr); +} // namespace panda +#endif // ECMASCRIPT_CROSS_VM_JS_NAPI_EXPO_HYBRID_H diff --git a/ecmascript/cross_vm/jsnapi_hybrid.h b/ecmascript/cross_vm/jsnapi_hybrid.h new file mode 100644 index 0000000000000000000000000000000000000000..bc1e5f8890c8f543a1baaf576414d65d8c0a5801 --- /dev/null +++ b/ecmascript/cross_vm/jsnapi_hybrid.h @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef ECMASCRIPT_CROSS_VM_JS_NAPI_HYBRID_H +#define ECMASCRIPT_CROSS_VM_JS_NAPI_HYBRID_H + +namespace panda::ecmascript { +#define JS_NAPI_HYBRID_EXTENSION \ + template \ + template \ + void Global::CreateXRefGloablReference(const EcmaVM *vm, const Local ¤t) \ + { \ + vm_ = vm; \ + if (!current.IsEmpty()) { \ + address_ = JSNApi::GetXRefGlobalHandleAddr(vm_, reinterpret_cast(*current));\ + } \ + } \ + template \ + void Global::FreeXRefGlobalHandleAddr() \ + { \ + if (address_ == 0) { \ + return; \ + } \ + JSNApi::DisposeXRefGlobalHandleAddr(vm_, address_); \ + address_ = 0; \ + } + +#define JS_NAPI_HYBRID_MODE_MIC_EXTENSION \ + template \ + void Global::MarkFromObject(std::function &visitor) \ + { \ + if (address_ == 0) { \ + return; \ + } \ + JSNApi::MarkFromObject(vm_, address_, visitor); \ + } \ + template \ + void Global::MarkFromObject() \ + { \ + if (address_ == 0) { \ + return; \ + } \ + JSNApi::MarkFromObject(vm_, address_); \ + } \ + template \ + bool Global::IsObjectAlive() const \ + { \ + if (address_ == 0) { \ + return false ; \ + } \ + return JSNApi::IsObjectAlive(vm_, address_); \ + } \ + template \ + bool Global::IsValidHeapObject() const \ + { \ + if (address_ == 0) { \ + return false; \ + } \ + return JSNApi::IsValidHeapObject(vm_, address_); \ + } +} // namespace panda::ecmascript +#endif // ECMASCRIPT_CROSS_VM_JS_NAPI_HYBRID_H diff --git a/ecmascript/cross_vm/object_factory_hybrid.cpp b/ecmascript/cross_vm/object_factory_hybrid.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ee20863947029eac5f0f922f3eb10b14499a18f1 --- /dev/null +++ b/ecmascript/cross_vm/object_factory_hybrid.cpp @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2025 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/object_factory.h" +#include "ecmascript/global_env_constants.h" +#include "ecmascript/dfx/native_module_failure_info.h" + +namespace panda::ecmascript { +JSHandle ObjectFactory::NewJSXRefObject() +{ + JSHandle jsXRefHClass = JSHandle::Cast(thread_->GlobalConstants()->GetHandledXRefObjectClass()); + JSHandle object(NewJSObject(jsXRefHClass)); + return object; +} +} // namespace panda::ecmascript diff --git a/ecmascript/cross_vm/object_factory_hybrid.h b/ecmascript/cross_vm/object_factory_hybrid.h new file mode 100644 index 0000000000000000000000000000000000000000..ebee95ceafebfd92a53d91be7ea0120e55d38554 --- /dev/null +++ b/ecmascript/cross_vm/object_factory_hybrid.h @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef ECMASCRIPT_CROSS_VM_OBJECT_FACTORY_HYBRID_H +#define ECMASCRIPT_CROSS_VM_OBJECT_FACTORY_HYBRID_H + +namespace panda::ecmascript { + +#define OBJECT_FACTORY_HYBRID_EXTENSION \ + JSHandle PUBLIC_API NewJSXRefObject(); + +} // namespace panda::ecmascript +#endif // ECMASCRIPT_CROSS_VM_OBJECT_FACTORY_HYBRID_H diff --git a/ecmascript/mem/unified_gc/unified_gc.cpp b/ecmascript/cross_vm/unified_gc/unified_gc.cpp similarity index 96% rename from ecmascript/mem/unified_gc/unified_gc.cpp rename to ecmascript/cross_vm/unified_gc/unified_gc.cpp index 11939a04a3ab2cf4f7c77ff036b105a64e9a242f..386d24dc8010fa3e4061e0eeb737badd7b3130e5 100644 --- a/ecmascript/mem/unified_gc/unified_gc.cpp +++ b/ecmascript/cross_vm/unified_gc/unified_gc.cpp @@ -13,11 +13,12 @@ * limitations under the License. */ -#include "ecmascript/mem/unified_gc/unified_gc.h" +#include "ecmascript/cross_vm/unified_gc/unified_gc.h" #include "ecmascript/mem/concurrent_marker.h" -#include "ecmascript/mem/unified_gc/unified_gc_marker.h" +#include "ecmascript/cross_vm/unified_gc/unified_gc_marker.h" #include "ecmascript/mem/verification.h" +#include "ecmascript/mem/heap.h" namespace panda::ecmascript { #ifdef PANDA_JS_ETS_HYBRID_MODE diff --git a/ecmascript/mem/unified_gc/unified_gc.h b/ecmascript/cross_vm/unified_gc/unified_gc.h similarity index 100% rename from ecmascript/mem/unified_gc/unified_gc.h rename to ecmascript/cross_vm/unified_gc/unified_gc.h diff --git a/ecmascript/mem/unified_gc/unified_gc_marker-inl.h b/ecmascript/cross_vm/unified_gc/unified_gc_marker-inl.h similarity index 97% rename from ecmascript/mem/unified_gc/unified_gc_marker-inl.h rename to ecmascript/cross_vm/unified_gc/unified_gc_marker-inl.h index 8be85b175365081e625b0ed66fef4fe39898eaf9..31ee16f590efbce23b8b6398d4152cea1e243cd0 100644 --- a/ecmascript/mem/unified_gc/unified_gc_marker-inl.h +++ b/ecmascript/cross_vm/unified_gc/unified_gc_marker-inl.h @@ -16,10 +16,11 @@ #ifndef ECMASCRIPT_MEM_UNIFIED_GC_UNIFIED_GC_MARKER_INL_H #define ECMASCRIPT_MEM_UNIFIED_GC_UNIFIED_GC_MARKER_INL_H -#include "ecmascript/mem/unified_gc/unified_gc_marker.h" +#include "ecmascript/cross_vm/unified_gc/unified_gc_marker.h" #include "ecmascript/layout_info.h" #include "ecmascript/mem/work_manager-inl.h" +#include "ecmascript/cross_vm/work_manager_hybrid-inl.h" namespace panda::ecmascript { diff --git a/ecmascript/mem/unified_gc/unified_gc_marker.cpp b/ecmascript/cross_vm/unified_gc/unified_gc_marker.cpp similarity index 97% rename from ecmascript/mem/unified_gc/unified_gc_marker.cpp rename to ecmascript/cross_vm/unified_gc/unified_gc_marker.cpp index 188c4b1e0906a625e51eecfe9e0a5923d3bf5f37..f1ffc13a44954d394a4cf0b2d3abae5cacf4fd20 100644 --- a/ecmascript/mem/unified_gc/unified_gc_marker.cpp +++ b/ecmascript/cross_vm/unified_gc/unified_gc_marker.cpp @@ -15,7 +15,7 @@ #include "ecmascript/checkpoint/thread_state_transition.h" #include "ecmascript/mem/concurrent_marker.h" -#include "ecmascript/mem/unified_gc/unified_gc_marker-inl.h" +#include "ecmascript/cross_vm/unified_gc/unified_gc_marker-inl.h" #include "ecmascript/mem/verification.h" namespace panda::ecmascript { diff --git a/ecmascript/mem/unified_gc/unified_gc_marker.h b/ecmascript/cross_vm/unified_gc/unified_gc_marker.h similarity index 100% rename from ecmascript/mem/unified_gc/unified_gc_marker.h rename to ecmascript/cross_vm/unified_gc/unified_gc_marker.h diff --git a/ecmascript/cross_vm/work_manager_hybrid-inl.h b/ecmascript/cross_vm/work_manager_hybrid-inl.h new file mode 100644 index 0000000000000000000000000000000000000000..fdeafddf761e48ae40eade01f467c6de3fdc078d --- /dev/null +++ b/ecmascript/cross_vm/work_manager_hybrid-inl.h @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef ECMASCRIPT_CROSS_VM_WORK_MANAGER_INL_H +#define ECMASCRIPT_CROSS_VM_WORK_MANAGER_INL_H + +#include "ecmascript/mem/work_manager.h" + +#include "ecmascript/mem/incremental_marker.h" +#include "ecmascript/mem/tlab_allocator-inl.h" + +namespace panda::ecmascript { + void WorkManager::PushObjectToGlobal(TaggedObject *object) + { + WorkNode *tempNode = AllocateWorkNode(); + ASSERT(tempNode != nullptr); + tempNode->PushObject(ToUintPtr(object)); + workStack_.Push(tempNode); + if (heap_->IsParallelGCEnabled() && heap_->CheckCanDistributeTask() && !heap_->IsMarking()) { + heap_->PostParallelGCTask(parallelGCTaskPhase_); + } + } +} // namespace panda::ecmascript +#endif // ECMASCRIPT_CROSS_VM_WORK_MANAGER_HYBRID_H diff --git a/ecmascript/cross_vm/work_manager_hybrid.h b/ecmascript/cross_vm/work_manager_hybrid.h new file mode 100644 index 0000000000000000000000000000000000000000..f01a6b3455359915113c19264168e04b6878a1ed --- /dev/null +++ b/ecmascript/cross_vm/work_manager_hybrid.h @@ -0,0 +1,23 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef ECMASCRIPT_CROSS_VM_WORK_MANAGER_HYBRID_H +#define ECMASCRIPT_CROSS_VM_WORK_MANAGER_HYBRID_H + +namespace panda::ecmascript { +#define WORK_MANAGER_HYBRID_DECL_EXTENSION \ + void PushObjectToGlobal(TaggedObject *object); + +} // namespace panda::ecmascript +#endif // ECMASCRIPT_CROSS_VM_WORK_MANAGER_HYBRID_H diff --git a/ecmascript/daemon/daemon_task-inl.h b/ecmascript/daemon/daemon_task-inl.h index 6ed420f24a4eba4633578d1c1112a188e7e5cece..0477f4069a57f8b2a06d7f82b13a8c16a2b90fcc 100644 --- a/ecmascript/daemon/daemon_task-inl.h +++ b/ecmascript/daemon/daemon_task-inl.h @@ -44,17 +44,6 @@ TriggerCollectGarbageTask::TriggerCollectGarbageTask(JSThread : DaemonTask(thread, DaemonTaskType::TRIGGER_COLLECT_GARBAGE, DaemonTaskGroup::GC_GROUP, &TriggerCollectGarbageTaskRunner) {} -template -void TriggerUnifiedGCMarkTaskRunner() -{ - SharedHeap::GetInstance()->StartUnifiedGCMark(gcType, gcReason); -} - -template -TriggerUnifiedGCMarkTask::TriggerUnifiedGCMarkTask(JSThread *thread) - : DaemonTask(thread, DaemonTaskType::TRIGGER_UNIFIED_GC_MARK, DaemonTaskGroup::GC_GROUP, - &TriggerUnifiedGCMarkTaskRunner) {} - inline void TerminateDaemonTaskRunner() { DaemonThread *thread = DaemonThread::GetInstance(); @@ -65,5 +54,7 @@ inline void TerminateDaemonTaskRunner() inline TerminateDaemonTask::TerminateDaemonTask(JSThread *thread) : DaemonTask(thread, DaemonTaskType::TERMINATE_DAEMON, DaemonTaskGroup::TERMINATE_GROUP, &TerminateDaemonTaskRunner) {} + +DAEMON_TASK_HYBRID_DEF_EXTENSION } // namespace panda::ecmascript #endif //ECMASCRIPT_DAEMON_TASK_INL_H \ No newline at end of file diff --git a/ecmascript/daemon/daemon_task.h b/ecmascript/daemon/daemon_task.h index 0b8d6acaef9a9d444df9d15aef01befd8d38744d..f4f74ad383e9f22761a663c327a084c157a22e62 100644 --- a/ecmascript/daemon/daemon_task.h +++ b/ecmascript/daemon/daemon_task.h @@ -17,6 +17,7 @@ #define ECMASCRIPT_DAEMON_TASK_H #include "ecmascript/common.h" +#include "ecmascript/cross_vm/daemon_task_hybrid.h" namespace panda::ecmascript { class JSThread; @@ -90,15 +91,11 @@ public: explicit TriggerCollectGarbageTask(JSThread *thread); }; -template -class TriggerUnifiedGCMarkTask : public DaemonTask { -public: - explicit TriggerUnifiedGCMarkTask(JSThread *thread); -}; - class TerminateDaemonTask : public DaemonTask { public: explicit TerminateDaemonTask(JSThread *thread); }; + +DAEMON_TASK_HYBRID_DECL_EXTENSION } // namespace panda::ecmascript #endif //ECMASCRIPT_DAEMON_TASK_H \ No newline at end of file diff --git a/ecmascript/ecma_global_storage.h b/ecmascript/ecma_global_storage.h index 5771c92d6f3db3d667b642cd9b9805cf43124d19..976e38e1afeb5978d24746fffe6867405f7f3bb9 100644 --- a/ecmascript/ecma_global_storage.h +++ b/ecmascript/ecma_global_storage.h @@ -20,6 +20,7 @@ #include "ecmascript/mem/native_area_allocator.h" #include "ecmascript/mem/c_containers.h" #include "ecmascript/platform/backtrace.h" +#include "ecmascript/cross_vm/ecma_global_storage_hybrid.h" #ifdef HOOK_ENABLE #include "memory_trace.h" #endif @@ -389,11 +390,6 @@ private: NodeList *freePrev_ {nullptr}; }; -enum class NodeKind : uint8_t { - NORMAL_NODE, - UNIFIED_NODE, -}; - template class EcmaGlobalStorage { public: @@ -511,20 +507,10 @@ public: IterateNodeList(callback, topWeakGlobalNodes_); } - void SetNodeKind(NodeKind nodeKind) - { - nodeKind_ = nodeKind; - } - - NodeKind GetNodeKind() - { - return nodeKind_; - } - + ECMA_GLOBAL_STORAGE_HYBRID_EXTENSION private: NO_COPY_SEMANTIC(EcmaGlobalStorage); NO_MOVE_SEMANTIC(EcmaGlobalStorage); - template inline void DisposeGlobalHandleInner(S *node, NodeList **freeList, NodeList **topNodes, NodeList **lastNodes) @@ -598,16 +584,11 @@ private: } [[maybe_unused]] JSThread *thread_ {nullptr}; - NodeKind nodeKind_ {NodeKind::NORMAL_NODE}; NativeAreaAllocator *allocator_ {nullptr}; NodeList *topGlobalNodes_ {nullptr}; NodeList *lastGlobalNodes_ {nullptr}; NodeList *freeListNodes_ {nullptr}; - NodeList *topXRefGlobalNodes_ {nullptr}; - NodeList *lastXRefGlobalNodes_ {nullptr}; - NodeList *xRefFreeListNodes_ {nullptr}; - NodeList *topWeakGlobalNodes_ {nullptr}; NodeList *lastWeakGlobalNodes_ {nullptr}; NodeList *weakFreeListNodes_ {nullptr}; diff --git a/ecmascript/ecma_vm.cpp b/ecmascript/ecma_vm.cpp index 96be55323f4a1a2d03146806f75fd9ad1e7703a1..4183bdba04965a30a6b82f01deb458b3b112a223 100644 --- a/ecmascript/ecma_vm.cpp +++ b/ecmascript/ecma_vm.cpp @@ -336,7 +336,12 @@ bool EcmaVM::Initialize() heap_ = new Heap(this); heap_->Initialize(); #ifdef PANDA_JS_ETS_HYBRID_MODE + // todo liuhongchen,加判断后,GetCrossVMOperator会返回nullptr,好多调用地方未加nullptr判断 + // 只在调用的地方加判断,不建议加 + // if (Runtime::GetInstance()->IsHybridVm()) { crossVMOperator_ = new CrossVMOperator(this); + // } + #endif // PANDA_JS_ETS_HYBRID_MODE gcStats_ = chunk_.New(heap_, options_.GetLongPauseTime()); gcKeyStats_ = chunk_.New(heap_, gcStats_); @@ -497,6 +502,7 @@ EcmaVM::~EcmaVM() } #ifdef PANDA_JS_ETS_HYBRID_MODE + // if (Runtime::GetInstance()->IsHybridVm()) { if (crossVMOperator_ != nullptr) { delete crossVMOperator_; crossVMOperator_ = nullptr; diff --git a/ecmascript/ecma_vm.h b/ecmascript/ecma_vm.h index f944146181defb7fd4e2e15d133f229b6d74c437..70563b6a34901f4caadd3dae94196e6d5518d9dd 100644 --- a/ecmascript/ecma_vm.h +++ b/ecmascript/ecma_vm.h @@ -40,6 +40,7 @@ #include "ecmascript/platform/mutex.h" #include "ecmascript/waiter_list.h" #include "libpandafile/bytecode_instruction-inl.h" +#include "ecmascript/cross_vm/ecma_vm_hybrid.h" namespace panda { class JSNApi; @@ -1311,17 +1312,9 @@ public: static void ClearKeptObjects(JSThread *thread); static void AddToKeptObjects(JSThread *thread, JSHandle value); void AddModuleManager(ModuleManager *moduleManager); - -#ifdef PANDA_JS_ETS_HYBRID_MODE - CrossVMOperator* GetCrossVMOperator() const - { - return crossVMOperator_; - } -#endif // PANDA_JS_ETS_HYBRID_MODE - -protected: - - void PrintJSErrorInfo(const JSHandle &exceptionInfo) const; +#ifdef PANDA_JS_ETS_HYBRID_MODE + ECMA_VM_HYBRID_GET_CROSS_VM_OP_EXTENSION +#endif /* PANDA_JS_ETS_HYBRID_MODE */ private: void ClearBufferData(); @@ -1531,10 +1524,6 @@ private: JSTaggedValue microJobQueue_ {JSTaggedValue::Hole()}; std::atomic isProcessingPendingJob_{false}; -#ifdef PANDA_JS_ETS_HYBRID_MODE - CrossVMOperator* crossVMOperator_ {nullptr}; -#endif // PANDA_JS_ETS_HYBRID_MODE - #if ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT // Stats for Thread-State-Transition and String-Table Locks bool isCollectingScopeLockStats_ = false; @@ -1584,6 +1573,9 @@ private: // store Application versionCode uint32_t applicationVersionCode_ {0}; +#ifdef PANDA_JS_ETS_HYBRID_MODE + ECMA_VM_HYBRID_GET_CROSS_VM_OP_DECL_EXTENSION +#endif /* PANDA_JS_ETS_HYBRID_MODE */ }; } // namespace ecmascript } // namespace panda diff --git a/ecmascript/global_env_constants.cpp b/ecmascript/global_env_constants.cpp index 13f38b68dccd6eb2e61d8f2603223e2abd6e8100..ab2c271e99f58f554a32f57ad54e71a171c64844 100644 --- a/ecmascript/global_env_constants.cpp +++ b/ecmascript/global_env_constants.cpp @@ -449,8 +449,10 @@ void GlobalEnvConstants::InitRootsClassesPartTwo(JSHClass *hClass, ObjectFactory JSType::JS_API_LIGHT_WEIGHT_SET_ITERATOR)); SetConstant(ConstantIndex::JS_API_BITVECTOR_ITERATOR_CLASS_INDEX, factory->NewEcmaHClass(hClass, JSAPIBitVectorIterator::SIZE, JSType::JS_API_BITVECTOR_ITERATOR)); + // if (Runtime::GetInstance()->IsHybridVm()) { SetConstant(ConstantIndex::XREF_OBJECT_HCLASS_INDEX, - factory->NewEcmaHClass(hClass, JSObject::SIZE, JSType::JS_XREF_OBJECT)); + factory->NewEcmaHClass(hClass, JSObject::SIZE, JSType::JS_XREF_OBJECT)); + // } } void GlobalEnvConstants::InitRootsClasses(ObjectFactory *factory) diff --git a/ecmascript/global_env_constants.h b/ecmascript/global_env_constants.h index da4320cd0e40927e1a858a1c7d4ca631edc58f33..f4de30d9cd9b8832cdd16122828ed4ccd1767fba 100644 --- a/ecmascript/global_env_constants.h +++ b/ecmascript/global_env_constants.h @@ -21,6 +21,7 @@ #include "ecmascript/js_tagged_value.h" #include "ecmascript/mem/visitor.h" #include "libpandabase/macros.h" +#include "ecmascript/cross_vm/global_env_constants_hybrid.h" namespace panda::ecmascript { // Forward Declaration @@ -143,9 +144,9 @@ class ObjectFactory; V(JSTaggedValue, JSAPITreeMapIteratorClass, JS_API_TREE_MAP_ITERATOR_CLASS_INDEX, ecma_roots_class) \ V(JSTaggedValue, JSAPITreeSetIteratorClass, JS_API_TREE_SET_ITERATOR_CLASS_INDEX, ecma_roots_class) \ V(JSTaggedValue, ObjectClass, OBJECT_HCLASS_INDEX, initial_object_hclass) \ - V(JSTaggedValue, XRefObjectClass, XREF_OBJECT_HCLASS_INDEX, ecma_roots_class) \ V(JSTaggedValue, ClassPrototypeClass, CLASS_PROTOTYPE_HCLASS_INDEX, ecma_roots_class) \ - V(JSTaggedValue, ClassConstructorClass, CLASS_CONSTRUCTOR_HCLASS_INDEX, ecma_roots_class) + V(JSTaggedValue, ClassConstructorClass, CLASS_CONSTRUCTOR_HCLASS_INDEX, ecma_roots_class) \ + GLOBAL_ENV_CONSTANT_CLASS_HYBRID(V) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define GLOBAL_ENV_CONSTANT_SPECIAL(V) \ @@ -461,7 +462,6 @@ class ObjectFactory; V(CjsExportsString, CJS_EXPORTS_INDEX, "exports") \ V(CjsCacheString, CJS_CACHE_INDEX, "_cache") \ V(NapiWrapperString, NAPI_WRAPPER_INDEX, "_napiwrapper") \ - V(ProxyNapiWrapperString, PROXY_NAPI_WRAPPER_INDEX, "_proxynapiwrapper") \ /* for require native module */ \ V(RequireNativeModuleString, REQUIRE_NATIVE_MOUDULE_FUNC_INDEX, "requireNativeModule") \ V(RequireNapiString, REQUIRE_NAPI_FUNC_INDEX, "requireNapi") \ @@ -497,10 +497,10 @@ class ObjectFactory; V(SharedPartialGcCause, SHARED_PARTIAL_GC_CAUSE, "shared_partial") \ V(SharedFullGcCause, SHARED_FULL_GC_CAUSE, "shared_full") \ V(AppSpawnSharedFullGcCause, APP_SPAWN_SHARED_FULL_GC_CAUSE, "app_spawn_shared_full") \ - V(UnifiedGcCause, UNIFIED_GC_CAUSE, "unified") \ V(SymbolLeftParentheses, SYMBOL_LEFT_PARENTHESES, "Symbol(") \ V(InteropJsNapiString, INTEROP_JS_NAPI, "ets_interop_js_napi") \ - V(GetModuleString, GET_MODULE, "getModule") + V(GetModuleString, GET_MODULE, "getModule") \ + SHARED_GLOBAL_ENV_CONSTANT_STRING_HYBRID(V) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define SHARED_GLOBAL_ENV_CONSTANT_ACCESSOR(V) \ diff --git a/ecmascript/js_hclass.h b/ecmascript/js_hclass.h index 8c706e4ae228f931a66ba687e554d6cf5e3c8b4c..35010c968e2d678d6cad9856f3c64b0831dd2ac1 100644 --- a/ecmascript/js_hclass.h +++ b/ecmascript/js_hclass.h @@ -25,6 +25,7 @@ #include "ecmascript/mem/visitor.h" #include "ecmascript/property_attributes.h" #include "common_interfaces/objects/composite_base_class.h" +#include "ecmascript/cross_vm/js_hclass_hybrid.h" #include "libpandabase/utils/bit_field.h" @@ -1649,11 +1650,6 @@ public: return GetObjectType() == JSType::JS_PROMISE; } - inline bool IsJSXRefObject() const - { - return GetObjectType() == JSType::JS_XREF_OBJECT; - } - inline bool IsResolvingFunctionsRecord() const { return GetObjectType() == JSType::RESOLVING_FUNCTIONS_RECORD; @@ -2162,6 +2158,7 @@ public: bool isFunction = false); static JSHandle CreateSConstructorHClass(JSThread *thread, const std::vector &descs); static JSHandle CreateSPrototypeHClass(JSThread *thread, const std::vector &descs); + JS_HCLASS_HYBRID_EXTENSION private: diff --git a/ecmascript/js_tagged_value-inl.h b/ecmascript/js_tagged_value-inl.h index 70538a483904f1b3d4ddf5c02577727cb348b4fa..16cd10f10f83fe9e4138d987d3ef9fe3954fc0d3 100644 --- a/ecmascript/js_tagged_value-inl.h +++ b/ecmascript/js_tagged_value-inl.h @@ -405,11 +405,6 @@ inline bool JSTaggedValue::IsJSPromise() const return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSPromise(); } -inline bool JSTaggedValue::IsJSXRefObject() const -{ - return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSXRefObject(); -} - inline bool JSTaggedValue::IsRecord() const { return IsHeapObject() && GetTaggedObject()->GetClass()->IsRecord(); @@ -1476,5 +1471,7 @@ inline JSHandle JSTaggedValue::PublishSharedValue(JSThread *threa } return value; } + +JS_TAGGED_VALUE_HYBRID_DEF_EXTENSION } // namespace panda::ecmascript #endif // ECMASCRIPT_TAGGED_VALUE_INL_H diff --git a/ecmascript/js_tagged_value.h b/ecmascript/js_tagged_value.h index 5e65e815be4b854b97869e562f2944f6438f77d7..cca8ec2cebd186b79a2c2c77ed65a7217095301c 100644 --- a/ecmascript/js_tagged_value.h +++ b/ecmascript/js_tagged_value.h @@ -21,6 +21,7 @@ #include "ecmascript/mem/c_string.h" #include "ecmascript/mem/mem_common.h" #include "ecmascript/js_tagged_value_internals.h" +#include "ecmascript/cross_vm/js_tagged_value_hybrid.h" namespace panda::ecmascript { class JSArray; @@ -638,7 +639,6 @@ public: bool IsAsyncGeneratorObject() const; bool IsAsyncFuncObject() const; bool IsJSPromise() const; - bool IsJSXRefObject() const; bool IsRecord() const; bool IsPromiseReaction() const; bool IsProgram() const; @@ -784,7 +784,7 @@ public: value.Dump(os); return os; } - + JS_TAGGED_VALUE_HYBRID_DECL_EXTENSION private: JSTaggedType value_; diff --git a/ecmascript/js_thread.cpp b/ecmascript/js_thread.cpp index a1eb03517d5895694eea83c35a5b587e810bcd56..ce73e30226be25dcac8160f4a3f0984ac568ef30 100644 --- a/ecmascript/js_thread.cpp +++ b/ecmascript/js_thread.cpp @@ -166,43 +166,47 @@ JSThread::JSThread(EcmaVM *vm) : id_(os::thread::GetCurrentThreadId()), vm_(vm) newGlobalHandle_ = [this](JSTaggedType value) { return globalStorage_->NewGlobalHandle(value); }; - newXRefGlobalHandle_ = [this](JSTaggedType value) { - return globalStorage_->NewGlobalHandle(value); - }; disposeGlobalHandle_ = [this](uintptr_t nodeAddr) { globalStorage_->DisposeGlobalHandle(nodeAddr); }; + // if (Runtime::GetInstance()->IsHybridVm()) { + newXRefGlobalHandle_ = [this](JSTaggedType value) { + return globalStorage_->NewGlobalHandle(value); + }; disposeXRefGlobalHandle_ = [this](uintptr_t nodeAddr) { globalStorage_->DisposeGlobalHandle(nodeAddr); }; + setNodeKind_ = [this](NodeKind nodeKind) { globalStorage_->SetNodeKind(nodeKind); }; + // } setWeak_ = [this](uintptr_t nodeAddr, void *ref, WeakClearCallback freeGlobalCallBack, WeakClearCallback nativeFinalizeCallBack) { return globalStorage_->SetWeak(nodeAddr, ref, freeGlobalCallBack, nativeFinalizeCallBack); }; clearWeak_ = [this](uintptr_t nodeAddr) { return globalStorage_->ClearWeak(nodeAddr); }; isWeak_ = [this](uintptr_t addr) { return globalStorage_->IsWeak(addr); }; - setNodeKind_ = [this](NodeKind nodeKind) { globalStorage_->SetNodeKind(nodeKind); }; } else { globalDebugStorage_ = chunk->New>(this, vm->GetNativeAreaAllocator()); newGlobalHandle_ = [this](JSTaggedType value) { return globalDebugStorage_->NewGlobalHandle(value); }; - newXRefGlobalHandle_ = [this](JSTaggedType value) { - return globalDebugStorage_->NewGlobalHandle(value); - }; disposeGlobalHandle_ = [this](uintptr_t nodeAddr) { globalDebugStorage_->DisposeGlobalHandle(nodeAddr); }; - disposeXRefGlobalHandle_ = [this](uintptr_t nodeAddr) { - globalDebugStorage_->DisposeGlobalHandle(nodeAddr); - }; setWeak_ = [this](uintptr_t nodeAddr, void *ref, WeakClearCallback freeGlobalCallBack, WeakClearCallback nativeFinalizeCallBack) { return globalDebugStorage_->SetWeak(nodeAddr, ref, freeGlobalCallBack, nativeFinalizeCallBack); }; clearWeak_ = [this](uintptr_t nodeAddr) { return globalDebugStorage_->ClearWeak(nodeAddr); }; isWeak_ = [this](uintptr_t addr) { return globalDebugStorage_->IsWeak(addr); }; + // if (Runtime::GetInstance()->IsHybridVm()) { + newXRefGlobalHandle_ = [this](JSTaggedType value) { + return globalDebugStorage_->NewGlobalHandle(value); + }; + disposeXRefGlobalHandle_ = [this](uintptr_t nodeAddr) { + globalDebugStorage_->DisposeGlobalHandle(nodeAddr); + }; setNodeKind_ = [this](NodeKind nodeKind) { globalDebugStorage_->SetNodeKind(nodeKind); }; + // } } vmThreadControl_ = new VmThreadControl(this); SetBCStubStatus(BCStubStatus::NORMAL_BC_STUB); diff --git a/ecmascript/mem/heap.cpp b/ecmascript/mem/heap.cpp index cd603ad5b1ebfd8e203d9dcbbd95f2bb98d8ef9f..2ff0bd66c34f0ccfa2c401ed62173ea73f2000be 100644 --- a/ecmascript/mem/heap.cpp +++ b/ecmascript/mem/heap.cpp @@ -30,8 +30,8 @@ #include "ecmascript/mem/shared_heap/shared_gc.h" #include "ecmascript/mem/shared_heap/shared_full_gc.h" #include "ecmascript/mem/shared_heap/shared_concurrent_marker.h" -#include "ecmascript/mem/unified_gc/unified_gc.h" -#include "ecmascript/mem/unified_gc/unified_gc_marker.h" +#include "ecmascript/cross_vm/unified_gc/unified_gc.h" +#include "ecmascript/cross_vm/unified_gc/unified_gc_marker.h" #include "ecmascript/mem/verification.h" #include "ecmascript/runtime_call_id.h" #include "ecmascript/jit/jit.h" diff --git a/ecmascript/tests/unified_gc_test.cpp b/ecmascript/tests/unified_gc_test.cpp index 7bc01f392d664998d59b880ffb821af3aa09b8f5..f9251f0a272f651c4221280a6f7669f91e73f9bb 100644 --- a/ecmascript/tests/unified_gc_test.cpp +++ b/ecmascript/tests/unified_gc_test.cpp @@ -16,7 +16,7 @@ #include "ecmascript/tests/unified_gc_test_helper.h" #include "ecmascript/mem/concurrent_marker.h" #include "ecmascript/mem/region-inl.h" -#include "ecmascript/mem/unified_gc/unified_gc_marker.h" +#include "ecmascript/cross_vm/unified_gc/unified_gc_marker.h" using namespace panda::ecmascript;