diff --git a/runtime/builtins/builtins_global.cpp b/runtime/builtins/builtins_global.cpp index 5fdbf9dbedcd0ee758a98e515970364f9d28eef7..607ab1abacc8b4ed56c7e9b6343a140f6abfa9a1 100644 --- a/runtime/builtins/builtins_global.cpp +++ b/runtime/builtins/builtins_global.cpp @@ -79,6 +79,9 @@ void BuiltinsGlobal::GCTaskTracker::GCPhaseStarted(mem::GCPhase phase) JSHandle global(thread, thread->GetGlobalObject()); JSHandle new_target(thread, JSTaggedValue::Undefined()); auto info = NewRuntimeCallInfo(thread, fn, global, JSTaggedValue::Undefined(), 1); + // JS has only one thread, therefore, we run this callback from the mutator thread during concurrent marking. + ASSERT(!thread->GetVM()->GetMutatorLock()->HasLock()); + os::memory::ReadLockHolder lock(*thread->GetVM()->GetMutatorLock()); info->SetCallArgs(thread->GetEcmaVM()->GetGlobalEnv()->GetGcMarker()); JSFunction::Call(info.Get()); } diff --git a/tests/runtime/mem/g1gc_barrier_test.cpp b/tests/runtime/mem/g1gc_barrier_test.cpp index af01683df6c8f09d07095e5bf72e6e52bfb41f4b..729db8b58ca655b48b1f528ee2383f8e33d9cf97 100644 --- a/tests/runtime/mem/g1gc_barrier_test.cpp +++ b/tests/runtime/mem/g1gc_barrier_test.cpp @@ -102,6 +102,7 @@ public: TEST_F(G1GCBarrierTest, TestPreBarrier) { + ScopedManagedCodeThread s(thread); [[maybe_unused]] EcmaHandleScope scope(thread); mem::GC *gc = thread->GetVM()->GetGC(); JSHandle array(thread, AllocArray(2)); @@ -113,8 +114,11 @@ TEST_F(G1GCBarrierTest, TestPreBarrier) ConcurrentMarkListener listener(this, array, obj, replacement); gc->AddListener(&listener); - GCTask task(GCTaskCause::HEAP_USAGE_THRESHOLD_CAUSE); // trigger concurrent marking - task.Run(*gc); + { + ScopedNativeCodeThread sn(thread); + GCTask task(GCTaskCause::HEAP_USAGE_THRESHOLD_CAUSE); // trigger concurrent marking + task.Run(*gc); + } ASSERT_TRUE(listener.has_concurrent_mark); } @@ -163,6 +167,7 @@ public: TEST_P(G1GCClassCollectionTest, TestCollectClasses) { + ScopedManagedCodeThread s(thread); JSHClass *hclass = nullptr; { [[maybe_unused]] EcmaHandleScope scope(thread); @@ -175,8 +180,11 @@ TEST_P(G1GCClassCollectionTest, TestCollectClasses) ASSERT_TRUE(region->HasFlag(mem::IS_NONMOVABLE)); mem::GC *gc = thread->GetVM()->GetGC(); - GCTask task(GCTaskCause::HEAP_USAGE_THRESHOLD_CAUSE); // trigger concurrent marking - task.Run(*gc); + { + ScopedNativeCodeThread sn(thread); + GCTask task(GCTaskCause::HEAP_USAGE_THRESHOLD_CAUSE); // trigger concurrent marking + task.Run(*gc); + } bool found = false; GetAllocator()->IterateRegularSizeObjects([hclass, &found](ObjectHeader *obj) { if (obj == hclass) { diff --git a/tests/runtime/mem/object_helpers_test.cpp b/tests/runtime/mem/object_helpers_test.cpp index cc5c9227adcfabf3c8000fd7657a067bb6c462ee..76dec39ef7adb43972cd3657a77b85dda216e70f 100644 --- a/tests/runtime/mem/object_helpers_test.cpp +++ b/tests/runtime/mem/object_helpers_test.cpp @@ -10,6 +10,7 @@ #include "plugins/ecmascript/runtime/object_factory.h" #include "runtime/include/runtime.h" #include "runtime/include/panda_vm.h" +#include "runtime/include/thread_scopes.h" #include "runtime/mem/object_helpers-inl.h" namespace panda::ecmascript { @@ -42,6 +43,7 @@ public: thread_ = vm_->GetAssociatedJSThread(); factory_ = vm_->GetFactory(); handle_scope_ = new EcmaHandleScope(thread_); + vm_->GetMutatorLock()->ReadLock(); initial_dyn_class_ = factory_->NewEcmaDynClassClass(nullptr, JSHClass::SIZE, JSType::HCLASS); JSHClass *dynclass = reinterpret_cast(initial_dyn_class_.GetTaggedValue().GetTaggedObject()); dynclass->SetClass(dynclass); @@ -50,6 +52,7 @@ public: ~DynamicObjectHelpersTest() { + vm_->GetMutatorLock()->Unlock(); delete handle_scope_; Runtime::Destroy(); }