Cleanup Stubs.cpp (#4593)
This commit is contained in:
committed by
Stanislav Erokhin
parent
f160d8ec36
commit
92f8eff958
@@ -73,6 +73,10 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
ALWAYS_INLINE bool IsStrictMemoryModel() noexcept {
|
||||||
|
return CurrentMemoryModel == MemoryModel::kStrict;
|
||||||
|
}
|
||||||
|
|
||||||
typedef uint32_t container_size_t;
|
typedef uint32_t container_size_t;
|
||||||
|
|
||||||
// Granularity of arena container chunks.
|
// Granularity of arena container chunks.
|
||||||
@@ -1026,7 +1030,7 @@ inline void unlock(KInt* spinlock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool canFreeze(ContainerHeader* container) {
|
inline bool canFreeze(ContainerHeader* container) {
|
||||||
if (IsStrictMemoryModel)
|
if (IsStrictMemoryModel())
|
||||||
// In strict memory model we ignore permanent, frozen and shared object when recursively freezing.
|
// In strict memory model we ignore permanent, frozen and shared object when recursively freezing.
|
||||||
return container != nullptr && !container->shareable();
|
return container != nullptr && !container->shareable();
|
||||||
else
|
else
|
||||||
@@ -1393,14 +1397,14 @@ inline void decrementRC(ContainerHeader* container) {
|
|||||||
|
|
||||||
inline void decrementRC(ContainerHeader* container) {
|
inline void decrementRC(ContainerHeader* container) {
|
||||||
auto* state = memoryState;
|
auto* state = memoryState;
|
||||||
RuntimeAssert(!IsStrictMemoryModel || state->gcInProgress, "Must only be called during GC");
|
RuntimeAssert(!IsStrictMemoryModel() || state->gcInProgress, "Must only be called during GC");
|
||||||
// TODO: enable me, once account for inner references in frozen objects correctly.
|
// TODO: enable me, once account for inner references in frozen objects correctly.
|
||||||
// RuntimeAssert(container->refCount() > 0, "Must be positive");
|
// RuntimeAssert(container->refCount() > 0, "Must be positive");
|
||||||
bool useCycleCollector = container->local();
|
bool useCycleCollector = container->local();
|
||||||
if (container->decRefCount() == 0) {
|
if (container->decRefCount() == 0) {
|
||||||
freeContainer(container);
|
freeContainer(container);
|
||||||
} else if (useCycleCollector && state->toFree != nullptr) {
|
} else if (useCycleCollector && state->toFree != nullptr) {
|
||||||
RuntimeAssert(IsStrictMemoryModel, "No cycle collector in relaxed mode yet");
|
RuntimeAssert(IsStrictMemoryModel(), "No cycle collector in relaxed mode yet");
|
||||||
RuntimeAssert(container->refCount() > 0, "Must be positive");
|
RuntimeAssert(container->refCount() > 0, "Must be positive");
|
||||||
RuntimeAssert(!container->shareable(), "Cycle collector shalln't be used with shared objects yet");
|
RuntimeAssert(!container->shareable(), "Cycle collector shalln't be used with shared objects yet");
|
||||||
RuntimeAssert(container->objectCount() == 1, "cycle collector shall only work with single object containers");
|
RuntimeAssert(container->objectCount() == 1, "cycle collector shall only work with single object containers");
|
||||||
@@ -1819,7 +1823,7 @@ void incrementStack(MemoryState* state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void processDecrements(MemoryState* state) {
|
void processDecrements(MemoryState* state) {
|
||||||
RuntimeAssert(IsStrictMemoryModel, "Only works in strict model now");
|
RuntimeAssert(IsStrictMemoryModel(), "Only works in strict model now");
|
||||||
auto* toRelease = state->toRelease;
|
auto* toRelease = state->toRelease;
|
||||||
state->gcSuspendCount++;
|
state->gcSuspendCount++;
|
||||||
while (toRelease->size() > 0) {
|
while (toRelease->size() > 0) {
|
||||||
@@ -1840,7 +1844,7 @@ void processDecrements(MemoryState* state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void decrementStack(MemoryState* state) {
|
void decrementStack(MemoryState* state) {
|
||||||
RuntimeAssert(IsStrictMemoryModel, "Only works in strict model now");
|
RuntimeAssert(IsStrictMemoryModel(), "Only works in strict model now");
|
||||||
state->gcSuspendCount++;
|
state->gcSuspendCount++;
|
||||||
FrameOverlay* frame = currentFrame;
|
FrameOverlay* frame = currentFrame;
|
||||||
while (frame != nullptr) {
|
while (frame != nullptr) {
|
||||||
@@ -1868,7 +1872,7 @@ void garbageCollect(MemoryState* state, bool force) {
|
|||||||
#endif // TRACE_GC
|
#endif // TRACE_GC
|
||||||
state->allocSinceLastGc = 0;
|
state->allocSinceLastGc = 0;
|
||||||
|
|
||||||
if (!IsStrictMemoryModel) {
|
if (!IsStrictMemoryModel()) {
|
||||||
// In relaxed model we just process finalizer queue and be done with it.
|
// In relaxed model we just process finalizer queue and be done with it.
|
||||||
processFinalizerQueue(state);
|
processFinalizerQueue(state);
|
||||||
return;
|
return;
|
||||||
@@ -1988,7 +1992,7 @@ void garbageCollect() {
|
|||||||
#endif // USE_GC
|
#endif // USE_GC
|
||||||
|
|
||||||
ForeignRefManager* initLocalForeignRef(ObjHeader* object) {
|
ForeignRefManager* initLocalForeignRef(ObjHeader* object) {
|
||||||
if (!IsStrictMemoryModel) return nullptr;
|
if (!IsStrictMemoryModel()) return nullptr;
|
||||||
|
|
||||||
return memoryState->foreignRefManager;
|
return memoryState->foreignRefManager;
|
||||||
}
|
}
|
||||||
@@ -1996,7 +2000,7 @@ ForeignRefManager* initLocalForeignRef(ObjHeader* object) {
|
|||||||
ForeignRefManager* initForeignRef(ObjHeader* object) {
|
ForeignRefManager* initForeignRef(ObjHeader* object) {
|
||||||
addHeapRef(object);
|
addHeapRef(object);
|
||||||
|
|
||||||
if (!IsStrictMemoryModel) return nullptr;
|
if (!IsStrictMemoryModel()) return nullptr;
|
||||||
|
|
||||||
// Note: it is possible to return nullptr for shared object as an optimization,
|
// Note: it is possible to return nullptr for shared object as an optimization,
|
||||||
// but this will force the implementation to release objects on uninitialized threads
|
// but this will force the implementation to release objects on uninitialized threads
|
||||||
@@ -2007,7 +2011,7 @@ ForeignRefManager* initForeignRef(ObjHeader* object) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isForeignRefAccessible(ObjHeader* object, ForeignRefManager* manager) {
|
bool isForeignRefAccessible(ObjHeader* object, ForeignRefManager* manager) {
|
||||||
if (!IsStrictMemoryModel) return true;
|
if (!IsStrictMemoryModel()) return true;
|
||||||
|
|
||||||
if (manager == memoryState->foreignRefManager) {
|
if (manager == memoryState->foreignRefManager) {
|
||||||
// Note: it is important that this code neither crashes nor returns false-negative result
|
// Note: it is important that this code neither crashes nor returns false-negative result
|
||||||
@@ -2021,7 +2025,7 @@ bool isForeignRefAccessible(ObjHeader* object, ForeignRefManager* manager) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void deinitForeignRef(ObjHeader* object, ForeignRefManager* manager) {
|
void deinitForeignRef(ObjHeader* object, ForeignRefManager* manager) {
|
||||||
if (IsStrictMemoryModel) {
|
if (IsStrictMemoryModel()) {
|
||||||
if (memoryState != nullptr && isForeignRefAccessible(object, manager)) {
|
if (memoryState != nullptr && isForeignRefAccessible(object, manager)) {
|
||||||
releaseHeapRef<true>(object);
|
releaseHeapRef<true>(object);
|
||||||
} else {
|
} else {
|
||||||
@@ -2127,13 +2131,13 @@ void deinitMemory(MemoryState* memoryState, bool destroyRuntime) {
|
|||||||
atomicAdd(&pendingDeinit, -1);
|
atomicAdd(&pendingDeinit, -1);
|
||||||
|
|
||||||
#if TRACE_MEMORY
|
#if TRACE_MEMORY
|
||||||
if (IsStrictMemoryModel && destroyRuntime && allocCount > 0) {
|
if (IsStrictMemoryModel() && destroyRuntime && allocCount > 0) {
|
||||||
MEMORY_LOG("*** Memory leaks, leaked %d containers ***\n", allocCount);
|
MEMORY_LOG("*** Memory leaks, leaked %d containers ***\n", allocCount);
|
||||||
dumpReachable("", memoryState->containers);
|
dumpReachable("", memoryState->containers);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#if USE_GC
|
#if USE_GC
|
||||||
if (IsStrictMemoryModel && allocCount > 0 && checkLeaks) {
|
if (IsStrictMemoryModel() && allocCount > 0 && checkLeaks) {
|
||||||
konan::consoleErrorf(
|
konan::consoleErrorf(
|
||||||
"Memory leaks detected, %d objects leaked!\n"
|
"Memory leaks detected, %d objects leaked!\n"
|
||||||
"Use `Platform.isMemoryLeakCheckerActive = false` to avoid this check.\n", allocCount);
|
"Use `Platform.isMemoryLeakCheckerActive = false` to avoid this check.\n", allocCount);
|
||||||
@@ -2441,7 +2445,7 @@ OBJ_GETTER(swapHeapRefLocked,
|
|||||||
lock(spinlock);
|
lock(spinlock);
|
||||||
ObjHeader* oldValue = *location;
|
ObjHeader* oldValue = *location;
|
||||||
bool shallRemember = false;
|
bool shallRemember = false;
|
||||||
if (IsStrictMemoryModel) {
|
if (IsStrictMemoryModel()) {
|
||||||
auto realCookie = computeCookie();
|
auto realCookie = computeCookie();
|
||||||
shallRemember = *cookie != realCookie;
|
shallRemember = *cookie != realCookie;
|
||||||
if (shallRemember) *cookie = realCookie;
|
if (shallRemember) *cookie = realCookie;
|
||||||
@@ -2455,7 +2459,7 @@ OBJ_GETTER(swapHeapRefLocked,
|
|||||||
}
|
}
|
||||||
UpdateReturnRef(OBJ_RESULT, oldValue);
|
UpdateReturnRef(OBJ_RESULT, oldValue);
|
||||||
|
|
||||||
if (IsStrictMemoryModel && shallRemember && oldValue != nullptr && oldValue != expectedValue) {
|
if (IsStrictMemoryModel() && shallRemember && oldValue != nullptr && oldValue != expectedValue) {
|
||||||
// Only remember container if it is not known to this thread (i.e. != expectedValue).
|
// Only remember container if it is not known to this thread (i.e. != expectedValue).
|
||||||
rememberNewContainer(containerFor(oldValue));
|
rememberNewContainer(containerFor(oldValue));
|
||||||
}
|
}
|
||||||
@@ -2491,7 +2495,7 @@ OBJ_GETTER(readHeapRefLocked, ObjHeader** location, int32_t* spinlock, int32_t*
|
|||||||
if (shallRemember) *cookie = realCookie;
|
if (shallRemember) *cookie = realCookie;
|
||||||
UpdateReturnRef(OBJ_RESULT, value);
|
UpdateReturnRef(OBJ_RESULT, value);
|
||||||
#if USE_GC
|
#if USE_GC
|
||||||
if (IsStrictMemoryModel && shallRemember && value != nullptr) {
|
if (IsStrictMemoryModel() && shallRemember && value != nullptr) {
|
||||||
auto* container = containerFor(value);
|
auto* container = containerFor(value);
|
||||||
rememberNewContainer(container);
|
rememberNewContainer(container);
|
||||||
}
|
}
|
||||||
@@ -2506,7 +2510,7 @@ OBJ_GETTER(readHeapRefNoLock, ObjHeader* object, KInt index) {
|
|||||||
reinterpret_cast<uintptr_t>(object) + object->type_info()->objOffsets_[index]);
|
reinterpret_cast<uintptr_t>(object) + object->type_info()->objOffsets_[index]);
|
||||||
ObjHeader* value = *location;
|
ObjHeader* value = *location;
|
||||||
#if USE_GC
|
#if USE_GC
|
||||||
if (IsStrictMemoryModel && (value != nullptr)) {
|
if (IsStrictMemoryModel() && (value != nullptr)) {
|
||||||
// Maybe not so good to do that under lock.
|
// Maybe not so good to do that under lock.
|
||||||
rememberNewContainer(containerFor(value));
|
rememberNewContainer(containerFor(value));
|
||||||
}
|
}
|
||||||
@@ -3300,7 +3304,7 @@ bool IsForeignRefAccessible(ObjHeader* object, ForeignRefContext context) {
|
|||||||
|
|
||||||
void AdoptReferenceFromSharedVariable(ObjHeader* object) {
|
void AdoptReferenceFromSharedVariable(ObjHeader* object) {
|
||||||
#if USE_GC
|
#if USE_GC
|
||||||
if (IsStrictMemoryModel && object != nullptr && isShareable(containerFor(object)))
|
if (IsStrictMemoryModel() && object != nullptr && isShareable(containerFor(object)))
|
||||||
rememberNewContainer(containerFor(object));
|
rememberNewContainer(containerFor(object));
|
||||||
#endif // USE_GC
|
#endif // USE_GC
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,19 @@
|
|||||||
|
|
||||||
RUNTIME_NORETURN void RuntimeAssertFailed(const char* location, const char* message);
|
RUNTIME_NORETURN void RuntimeAssertFailed(const char* location, const char* message);
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
inline RUNTIME_NORETURN void TODOImpl(const char* location) {
|
||||||
|
RuntimeAssertFailed(location, "Unimplemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Support format string when `RuntimeAssertFailed` supports it.
|
||||||
|
inline RUNTIME_NORETURN void TODOImpl(const char* location, const char* message) {
|
||||||
|
RuntimeAssertFailed(location, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
// During codegeneration we set this constant to 1 or 0 to allow bitcode optimizer
|
// During codegeneration we set this constant to 1 or 0 to allow bitcode optimizer
|
||||||
// to get rid of code behind condition.
|
// to get rid of code behind condition.
|
||||||
extern "C" const int KonanNeedDebugInfo;
|
extern "C" const int KonanNeedDebugInfo;
|
||||||
@@ -48,4 +61,9 @@ if (KonanNeedDebugInfo && (!(condition))) { \
|
|||||||
RuntimeAssertFailed(nullptr, message); \
|
RuntimeAssertFailed(nullptr, message); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define TODO(...) \
|
||||||
|
do { \
|
||||||
|
::internal::TODOImpl(__FILE__ ":" TOSTRING(__LINE__), ##__VA_ARGS__); \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
#endif // RUNTIME_ASSERT_H
|
#endif // RUNTIME_ASSERT_H
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "KAssert.h"
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
TEST(TODODeathTest, EmptyTODO) {
|
||||||
|
EXPECT_DEATH({
|
||||||
|
TODO();
|
||||||
|
}, "KAssertTest.cpp:12: runtime assert: Unimplemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TODODeathTest, TODOWithMessage) {
|
||||||
|
EXPECT_DEATH({
|
||||||
|
TODO("Nope");
|
||||||
|
}, "KAssertTest.cpp:18: runtime assert: Nope");
|
||||||
|
}
|
||||||
@@ -173,8 +173,15 @@ void InitAndRegisterGlobal(ObjHeader** location, const ObjHeader* initialValue)
|
|||||||
// in intermediate frames when throwing
|
// in intermediate frames when throwing
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// NOTE: Must match `MemoryModel` in `Platform.kt`
|
||||||
|
enum class MemoryModel {
|
||||||
|
kStrict = 0,
|
||||||
|
kRelaxed = 1,
|
||||||
|
kExperimental = 2,
|
||||||
|
};
|
||||||
|
|
||||||
// Controls the current memory model, is compile-time constant.
|
// Controls the current memory model, is compile-time constant.
|
||||||
extern const bool IsStrictMemoryModel;
|
extern const MemoryModel CurrentMemoryModel;
|
||||||
|
|
||||||
// Sets stack location.
|
// Sets stack location.
|
||||||
void SetStackRef(ObjHeader** location, const ObjHeader* object) RUNTIME_NOTHROW;
|
void SetStackRef(ObjHeader** location, const ObjHeader* object) RUNTIME_NOTHROW;
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ KInt Konan_Platform_getCpuArchitecture() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
KInt Konan_Platform_getMemoryModel() {
|
KInt Konan_Platform_getMemoryModel() {
|
||||||
return IsStrictMemoryModel ? 0 : 1;
|
return static_cast<KInt>(CurrentMemoryModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
KBoolean Konan_Platform_isDebugBinary() {
|
KBoolean Konan_Platform_isDebugBinary() {
|
||||||
|
|||||||
@@ -36,9 +36,11 @@ public enum class CpuArchitecture(val bitness: Int) {
|
|||||||
/**
|
/**
|
||||||
* Memory model.
|
* Memory model.
|
||||||
*/
|
*/
|
||||||
|
// NOTE: Must match `MemoryModel` in `Memory.h`
|
||||||
public enum class MemoryModel {
|
public enum class MemoryModel {
|
||||||
STRICT,
|
STRICT,
|
||||||
RELAXED
|
RELAXED,
|
||||||
|
EXPERIMENTAL,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
|
|
||||||
#include "GlobalsRegistry.hpp"
|
#include "GlobalsRegistry.hpp"
|
||||||
|
#include "KAssert.h"
|
||||||
|
#include "Porting.h"
|
||||||
#include "StableRefRegistry.hpp"
|
#include "StableRefRegistry.hpp"
|
||||||
#include "ThreadData.hpp"
|
#include "ThreadData.hpp"
|
||||||
#include "ThreadRegistry.hpp"
|
#include "ThreadRegistry.hpp"
|
||||||
@@ -55,6 +57,11 @@ ALWAYS_INLINE mm::ThreadData* GetThreadData(MemoryState* state) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
ALWAYS_INLINE bool isShareable(const ObjHeader* obj) {
|
||||||
|
// TODO: Remove when legacy MM is gone.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" MemoryState* InitMemory(bool firstRuntime) {
|
extern "C" MemoryState* InitMemory(bool firstRuntime) {
|
||||||
return ToMemoryState(mm::ThreadRegistry::Instance().RegisterCurrentThread());
|
return ToMemoryState(mm::ThreadRegistry::Instance().RegisterCurrentThread());
|
||||||
}
|
}
|
||||||
@@ -63,21 +70,27 @@ extern "C" void DeinitMemory(MemoryState* state, bool destroyRuntime) {
|
|||||||
mm::ThreadRegistry::Instance().Unregister(FromMemoryState(state));
|
mm::ThreadRegistry::Instance().Unregister(FromMemoryState(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void RestoreMemory(MemoryState*) {
|
||||||
|
// TODO: Remove when legacy MM is gone.
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" OBJ_GETTER(InitSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) {
|
extern "C" OBJ_GETTER(InitSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) {
|
||||||
auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData();
|
auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData();
|
||||||
// TODO: This should only be called if singleton is actually created here. It's possible that the
|
// TODO: This should only be called if singleton is actually created here. It's possible that the
|
||||||
// singleton will be created on a different thread and here we should check that, instead of creating
|
// singleton will be created on a different thread and here we should check that, instead of creating
|
||||||
// another one (and registering `location` twice).
|
// another one (and registering `location` twice).
|
||||||
mm::GlobalsRegistry::Instance().RegisterStorageForGlobal(threadData, location);
|
mm::GlobalsRegistry::Instance().RegisterStorageForGlobal(threadData, location);
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" RUNTIME_NOTHROW void InitAndRegisterGlobal(ObjHeader** location, const ObjHeader* initialValue) {
|
extern "C" RUNTIME_NOTHROW void InitAndRegisterGlobal(ObjHeader** location, const ObjHeader* initialValue) {
|
||||||
auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData();
|
auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData();
|
||||||
mm::GlobalsRegistry::Instance().RegisterStorageForGlobal(threadData, location);
|
mm::GlobalsRegistry::Instance().RegisterStorageForGlobal(threadData, location);
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" const MemoryModel CurrentMemoryModel = MemoryModel::kExperimental;
|
||||||
|
|
||||||
extern "C" RUNTIME_NOTHROW void AddTLSRecord(MemoryState* memory, void** key, int size) {
|
extern "C" RUNTIME_NOTHROW void AddTLSRecord(MemoryState* memory, void** key, int size) {
|
||||||
GetThreadData(memory)->tls().AddRecord(key, size);
|
GetThreadData(memory)->tls().AddRecord(key, size);
|
||||||
}
|
}
|
||||||
@@ -94,6 +107,31 @@ extern "C" RUNTIME_NOTHROW ObjHeader** LookupTLS(void** key, int index) {
|
|||||||
return mm::ThreadRegistry::Instance().CurrentThreadData()->tls().Lookup(key, index);
|
return mm::ThreadRegistry::Instance().CurrentThreadData()->tls().Lookup(key, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" RUNTIME_NOTHROW void GC_RegisterWorker(void* worker) {
|
||||||
|
// TODO: Remove when legacy MM is gone.
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" RUNTIME_NOTHROW void GC_UnregisterWorker(void* worker) {
|
||||||
|
// TODO: Remove when legacy MM is gone.
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" RUNTIME_NOTHROW void GC_CollectorCallback(void* worker) {
|
||||||
|
// TODO: Remove when legacy MM is gone.
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" bool Kotlin_Any_isShareable(ObjHeader* thiz) {
|
||||||
|
// TODO: Remove when legacy MM is gone.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" RUNTIME_NOTHROW bool ClearSubgraphReferences(ObjHeader* root, bool checked) {
|
||||||
|
// TODO: Remove when legacy MM is gone.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" RUNTIME_NOTHROW void* CreateStablePointer(ObjHeader* object) {
|
extern "C" RUNTIME_NOTHROW void* CreateStablePointer(ObjHeader* object) {
|
||||||
auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData();
|
auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData();
|
||||||
return mm::StableRefRegistry::Instance().RegisterStableRef(threadData, object);
|
return mm::StableRefRegistry::Instance().RegisterStableRef(threadData, object);
|
||||||
@@ -120,6 +158,14 @@ extern "C" RUNTIME_NOTHROW OBJ_GETTER(AdoptStablePointer, void* pointer) {
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" RUNTIME_NOTHROW void CheckLifetimesConstraint(ObjHeader* obj, ObjHeader* pointee) {
|
||||||
|
if (!obj->local() && pointee != nullptr && pointee->local()) {
|
||||||
|
konan::consolePrintf("Attempt to store a stack object %p into a heap object %p\n", pointee, obj);
|
||||||
|
konan::consolePrintf("This is a compiler bug, please report it to https://kotl.in/issue\n");
|
||||||
|
konan::abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" ForeignRefContext InitForeignRef(ObjHeader* object) {
|
extern "C" ForeignRefContext InitForeignRef(ObjHeader* object) {
|
||||||
auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData();
|
auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData();
|
||||||
auto* node = mm::StableRefRegistry::Instance().RegisterStableRef(threadData, object);
|
auto* node = mm::StableRefRegistry::Instance().RegisterStableRef(threadData, object);
|
||||||
@@ -142,3 +188,8 @@ extern "C" void AdoptReferenceFromSharedVariable(ObjHeader* object) {
|
|||||||
// TODO: Remove when legacy MM is gone.
|
// TODO: Remove when legacy MM is gone.
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckGlobalsAccessible() {
|
||||||
|
// TODO: Remove when legacy MM is gone.
|
||||||
|
// Always accessible
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,181 +5,145 @@
|
|||||||
|
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
|
|
||||||
|
#include "KAssert.h"
|
||||||
|
|
||||||
ALWAYS_INLINE bool isFrozen(const ObjHeader* obj) {
|
ALWAYS_INLINE bool isFrozen(const ObjHeader* obj) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE bool isPermanentOrFrozen(const ObjHeader* obj) {
|
ALWAYS_INLINE bool isPermanentOrFrozen(const ObjHeader* obj) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
|
||||||
|
|
||||||
ALWAYS_INLINE bool isShareable(const ObjHeader* obj) {
|
|
||||||
RuntimeCheck(false, "Unimplemented");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjHeader** ObjHeader::GetWeakCounterLocation() {
|
ObjHeader** ObjHeader::GetWeakCounterLocation() {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef KONAN_OBJC_INTEROP
|
#ifdef KONAN_OBJC_INTEROP
|
||||||
|
|
||||||
void* ObjHeader::GetAssociatedObject() {
|
void* ObjHeader::GetAssociatedObject() {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
void** ObjHeader::GetAssociatedObjectLocation() {
|
void** ObjHeader::GetAssociatedObjectLocation() {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjHeader::SetAssociatedObject(void* obj) {
|
void ObjHeader::SetAssociatedObject(void* obj) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // KONAN_OBJC_INTEROP
|
#endif // KONAN_OBJC_INTEROP
|
||||||
|
|
||||||
static MetaObjHeader* createMetaObject(TypeInfo** location) {
|
static MetaObjHeader* createMetaObject(TypeInfo** location) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroyMetaObject(TypeInfo** location) {
|
static void destroyMetaObject(TypeInfo** location) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
void RestoreMemory(MemoryState*) {
|
|
||||||
// TODO: Remove this function when legacy MM is gone.
|
|
||||||
}
|
|
||||||
|
|
||||||
RUNTIME_NOTHROW OBJ_GETTER(AllocInstance, const TypeInfo* type_info) {
|
RUNTIME_NOTHROW OBJ_GETTER(AllocInstance, const TypeInfo* type_info) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
OBJ_GETTER(AllocArrayInstance, const TypeInfo* type_info, int32_t elements) {
|
OBJ_GETTER(AllocArrayInstance, const TypeInfo* type_info, int32_t elements) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
OBJ_GETTER(InitThreadLocalSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) {
|
OBJ_GETTER(InitThreadLocalSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const bool IsStrictMemoryModel = true;
|
|
||||||
|
|
||||||
RUNTIME_NOTHROW void SetStackRef(ObjHeader** location, const ObjHeader* object) {
|
RUNTIME_NOTHROW void SetStackRef(ObjHeader** location, const ObjHeader* object) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW void SetHeapRef(ObjHeader** location, const ObjHeader* object) {
|
RUNTIME_NOTHROW void SetHeapRef(ObjHeader** location, const ObjHeader* object) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW void ZeroHeapRef(ObjHeader** location) {
|
RUNTIME_NOTHROW void ZeroHeapRef(ObjHeader** location) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW void ZeroArrayRefs(ArrayHeader* array) {
|
RUNTIME_NOTHROW void ZeroArrayRefs(ArrayHeader* array) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW void ZeroStackRef(ObjHeader** location) {
|
RUNTIME_NOTHROW void ZeroStackRef(ObjHeader** location) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW void UpdateStackRef(ObjHeader** location, const ObjHeader* object) {
|
RUNTIME_NOTHROW void UpdateStackRef(ObjHeader** location, const ObjHeader* object) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW void UpdateHeapRef(ObjHeader** location, const ObjHeader* object) {
|
RUNTIME_NOTHROW void UpdateHeapRef(ObjHeader** location, const ObjHeader* object) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW void UpdateHeapRefIfNull(ObjHeader** location, const ObjHeader* object) {
|
RUNTIME_NOTHROW void UpdateHeapRefIfNull(ObjHeader** location, const ObjHeader* object) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW void UpdateReturnRef(ObjHeader** returnSlot, const ObjHeader* object) {
|
RUNTIME_NOTHROW void UpdateReturnRef(ObjHeader** returnSlot, const ObjHeader* object) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW OBJ_GETTER(
|
RUNTIME_NOTHROW OBJ_GETTER(
|
||||||
SwapHeapRefLocked, ObjHeader** location, ObjHeader* expectedValue, ObjHeader* newValue, int32_t* spinlock, int32_t* cookie) {
|
SwapHeapRefLocked, ObjHeader** location, ObjHeader* expectedValue, ObjHeader* newValue, int32_t* spinlock, int32_t* cookie) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW void SetHeapRefLocked(ObjHeader** location, ObjHeader* newValue, int32_t* spinlock, int32_t* cookie) {
|
RUNTIME_NOTHROW void SetHeapRefLocked(ObjHeader** location, ObjHeader* newValue, int32_t* spinlock, int32_t* cookie) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW OBJ_GETTER(ReadHeapRefLocked, ObjHeader** location, int32_t* spinlock, int32_t* cookie) {
|
RUNTIME_NOTHROW OBJ_GETTER(ReadHeapRefLocked, ObjHeader** location, int32_t* spinlock, int32_t* cookie) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW void EnterFrame(ObjHeader** start, int parameters, int count) {
|
RUNTIME_NOTHROW void EnterFrame(ObjHeader** start, int parameters, int count) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW void LeaveFrame(ObjHeader** start, int parameters, int count) {
|
RUNTIME_NOTHROW void LeaveFrame(ObjHeader** start, int parameters, int count) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
|
||||||
|
|
||||||
RUNTIME_NOTHROW bool ClearSubgraphReferences(ObjHeader* root, bool checked) {
|
|
||||||
RuntimeCheck(false, "Unimplemented");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MutationCheck(ObjHeader* obj) {
|
void MutationCheck(ObjHeader* obj) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
|
||||||
|
|
||||||
RUNTIME_NOTHROW void CheckLifetimesConstraint(ObjHeader* obj, ObjHeader* pointee) {
|
|
||||||
RuntimeCheck(false, "Unimplemented");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreezeSubgraph(ObjHeader* obj) {
|
void FreezeSubgraph(ObjHeader* obj) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnsureNeverFrozen(ObjHeader* obj) {
|
void EnsureNeverFrozen(ObjHeader* obj) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
|
||||||
|
|
||||||
RUNTIME_NOTHROW void GC_RegisterWorker(void* worker) {
|
|
||||||
RuntimeCheck(false, "Unimplemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
RUNTIME_NOTHROW void GC_UnregisterWorker(void* worker) {
|
|
||||||
RuntimeCheck(false, "Unimplemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
RUNTIME_NOTHROW void GC_CollectorCallback(void* worker) {
|
|
||||||
RuntimeCheck(false, "Unimplemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Kotlin_Any_isShareable(ObjHeader* thiz) {
|
|
||||||
RuntimeCheck(false, "Unimplemented");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW void PerformFullGC(MemoryState* memory) {
|
RUNTIME_NOTHROW void PerformFullGC(MemoryState* memory) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TryAddHeapRef(const ObjHeader* object) {
|
bool TryAddHeapRef(const ObjHeader* object) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW void ReleaseHeapRef(const ObjHeader* object) {
|
RUNTIME_NOTHROW void ReleaseHeapRef(const ObjHeader* object) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NOTHROW void ReleaseHeapRefNoCollect(const ObjHeader* object) {
|
RUNTIME_NOTHROW void ReleaseHeapRefNoCollect(const ObjHeader* object) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
ForeignRefContext InitLocalForeignRef(ObjHeader* object) {
|
ForeignRefContext InitLocalForeignRef(ObjHeader* object) {
|
||||||
RuntimeCheck(false, "Unimplemented");
|
TODO();
|
||||||
}
|
|
||||||
|
|
||||||
void CheckGlobalsAccessible() {
|
|
||||||
// Globals are always accessible.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
const bool IsStrictMemoryModel = false;
|
const MemoryModel CurrentMemoryModel = MemoryModel::kRelaxed;
|
||||||
|
|
||||||
OBJ_GETTER(AllocInstance, const TypeInfo* typeInfo) {
|
OBJ_GETTER(AllocInstance, const TypeInfo* typeInfo) {
|
||||||
RETURN_RESULT_OF(AllocInstanceRelaxed, typeInfo);
|
RETURN_RESULT_OF(AllocInstanceRelaxed, typeInfo);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
const bool IsStrictMemoryModel = true;
|
const MemoryModel CurrentMemoryModel = MemoryModel::kStrict;
|
||||||
|
|
||||||
OBJ_GETTER(AllocInstance, const TypeInfo* typeInfo) {
|
OBJ_GETTER(AllocInstance, const TypeInfo* typeInfo) {
|
||||||
RETURN_RESULT_OF(AllocInstanceStrict, typeInfo);
|
RETURN_RESULT_OF(AllocInstanceStrict, typeInfo);
|
||||||
|
|||||||
Reference in New Issue
Block a user