From 955521eaf0809e379cdf43d21a16d89b016d1951 Mon Sep 17 00:00:00 2001 From: Alexander Shabalin Date: Tue, 11 Aug 2020 21:01:45 +0300 Subject: [PATCH] Disable CycleDetector on WASM (#4325) --- backend.native/tests/build.gradle | 3 ++- runtime/src/main/cpp/Memory.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index 3bd5610eb24..1bdaf4bcb81 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -2825,7 +2825,8 @@ task memory_stable_ref_cross_thread_check(type: KonanLocalTest) { } standaloneTest("cycle_detector") { - disabled = project.globalTestArgs.contains('-opt') || (project.testTarget == 'wasm32') // Needs debug build. + disabled = project.globalTestArgs.contains('-opt') || // Needs debug build. + (project.testTarget == 'wasm32') // CycleDetector is disabled on WASM. flags = ['-tr', '-g'] source = "runtime/memory/cycle_detector.kt" } diff --git a/runtime/src/main/cpp/Memory.cpp b/runtime/src/main/cpp/Memory.cpp index 0e6e5207c5c..a830b922cc9 100644 --- a/runtime/src/main/cpp/Memory.cpp +++ b/runtime/src/main/cpp/Memory.cpp @@ -22,6 +22,14 @@ // Allow concurrent global cycle collector. #define USE_CYCLIC_GC 0 +// CycleDetector internally uses static local with runtime initialization, +// which requires atomics. Atomics are not available on WASM. +#ifdef KONAN_WASM +#define USE_CYCLE_DETECTOR 0 +#else +#define USE_CYCLE_DETECTOR 1 +#endif + #include "Alloc.h" #include "KAssert.h" #include "Atomic.h" @@ -164,6 +172,8 @@ class ScopedRefHolder { KRef obj_ = nullptr; }; +#if USE_CYCLE_DETECTOR + struct CycleDetectorRootset { // Orders roots. KStdVector roots; @@ -230,6 +240,8 @@ class CycleDetector { KStdUnorderedMap candidateInList_; }; +#endif // USE_CYCLE_DETECTOR + // TODO: can we pass this variable as an explicit argument? THREAD_LOCAL_VARIABLE MemoryState* memoryState = nullptr; THREAD_LOCAL_VARIABLE FrameOverlay* currentFrame = nullptr; @@ -1065,7 +1077,9 @@ ALWAYS_INLINE void runDeallocationHooks(ContainerHeader* container) { cyclicRemoveAtomicRoot(obj); } #endif // USE_CYCLIC_GC +#if USE_CYCLE_DETECTOR CycleDetector::removeCandidateIfNeeded(obj); +#endif // USE_CYCLE_DETECTOR if (obj->has_meta_object()) { ObjHeader::destroyMetaObject(&obj->typeInfoOrMeta_); } @@ -2135,7 +2149,9 @@ OBJ_GETTER(allocInstance, const TypeInfo* type_info) { makeShareable(container.header()); } #endif // USE_GC +#if USE_CYCLE_DETECTOR CycleDetector::insertCandidateIfNeeded(obj); +#endif // USE_CYCLE_DETECTOR #if USE_CYCLIC_GC if ((obj->type_info()->flags_ & TF_LEAK_DETECTOR_CANDIDATE) != 0) { // Note: this should be performed after [rememberNewContainer] (above). @@ -2827,6 +2843,8 @@ ScopedRefHolder::~ScopedRefHolder() { } } +#if USE_CYCLE_DETECTOR + // static CycleDetectorRootset CycleDetector::collectRootset() { auto& detector = instance(); @@ -2934,6 +2952,8 @@ OBJ_GETTER(findCycle, KRef root) { RETURN_RESULT_OF(createAndFillArray, cycle); } +#endif // USE_CYCLE_DETECTOR + } // namespace MetaObjHeader* ObjHeader::createMetaObject(TypeInfo** location) { @@ -3362,12 +3382,20 @@ KBoolean Kotlin_native_internal_GC_getTuneThreshold(KRef) { } OBJ_GETTER(Kotlin_native_internal_GC_detectCycles, KRef) { +#if USE_CYCLE_DETECTOR if (!KonanNeedDebugInfo || !Kotlin_memoryLeakCheckerEnabled()) RETURN_OBJ(nullptr); RETURN_RESULT_OF0(detectCyclicReferences); +#else + RETURN_OBJ(nullptr); +#endif } OBJ_GETTER(Kotlin_native_internal_GC_findCycle, KRef, KRef root) { +#if USE_CYCLE_DETECTOR RETURN_RESULT_OF(findCycle, root); +#else + RETURN_OBJ(nullptr); +#endif } KNativePtr CreateStablePointer(KRef any) {