Skip to content

Commit

Permalink
Use a specialized storage for shared shadow
Browse files Browse the repository at this point in the history
  • Loading branch information
projedi committed Mar 24, 2020
1 parent d28f122 commit 39d678b
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -921,7 +921,6 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
}
val singleton = context.llvmDeclarations.forSingleton(irClass)
val instanceAddress = singleton.instanceStorage
val instanceShadowAddress = singleton.instanceShadowStorage

if (storageKind == ObjectStorageKind.PERMANENT) {
return loadSlot(instanceAddress.getAddress(this), false)
Expand All @@ -938,13 +937,13 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
val typeInfo = codegen.typeInfoForAllocation(irClass)
val defaultConstructor = irClass.constructors.single { it.valueParameters.size == 0 }
val ctor = codegen.llvmFunction(defaultConstructor)
val (initFunction, args) =
val initFunction =
if (storageKind == ObjectStorageKind.SHARED && context.config.threadsAreAllowed) {
val shadowObjectPtr = instanceShadowAddress!!.getAddress(this)
context.llvm.initSharedInstanceFunction to listOf(objectPtr, shadowObjectPtr, typeInfo, ctor)
context.llvm.initSharedInstanceFunction
} else {
context.llvm.initInstanceFunction to listOf(objectPtr, typeInfo, ctor)
context.llvm.initInstanceFunction
}
val args = listOf(objectPtr, typeInfo, ctor)
val newValue = call(initFunction, args, Lifetime.GLOBAL, exceptionHandler)
val bbInitResult = currentBlock
br(bbExit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ internal class ClassLlvmDeclarations(
val singletonDeclarations: SingletonLlvmDeclarations?,
val objCDeclarations: KotlinObjCClassLlvmDeclarations?)

internal class SingletonLlvmDeclarations(val instanceStorage: AddressAccess, val instanceShadowStorage: AddressAccess?)
internal class SingletonLlvmDeclarations(val instanceStorage: AddressAccess)

internal class KotlinObjCClassLlvmDeclarations(
val classPointerGlobal: StaticData.Global,
Expand Down Expand Up @@ -279,12 +279,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
val symbolName = "kobjref:" + qualifyInternalName(irClass)
val instanceAddress = addKotlinGlobal(symbolName, getLLVMType(irClass.defaultType), threadLocal = threadLocal)

val instanceShadowAddress = if (threadLocal || storageKind == ObjectStorageKind.PERMANENT) null else {
val shadowSymbolName = "kshadowobjref:" + qualifyInternalName(irClass)
addKotlinGlobal(shadowSymbolName, getLLVMType(irClass.defaultType), threadLocal = true)
}

return SingletonLlvmDeclarations(instanceAddress, instanceShadowAddress)
return SingletonLlvmDeclarations(instanceAddress)
}

private fun createKotlinObjCClassDeclarations(irClass: IrClass): KotlinObjCClassLlvmDeclarations {
Expand Down
30 changes: 21 additions & 9 deletions runtime/src/main/cpp/Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,8 @@ struct MemoryState {
uint64_t allocSinceLastGcThreshold;
#endif // USE_GC

KStdUnorderedMap<ObjHeader**, ObjHeader*> initializingSingletons;

#if COLLECT_STATISTIC
#define CONTAINER_ALLOC_STAT(state, size, container) state->statistic.incAlloc(size, container);
#define CONTAINER_DESTROY_STAT(state, container) \
Expand Down Expand Up @@ -1999,7 +2001,7 @@ OBJ_GETTER(initInstance,

template <bool Strict>
OBJ_GETTER(initSharedInstance,
ObjHeader** location, ObjHeader** localLocation, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) {
ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) {
#if KONAN_NO_THREADS
ObjHeader* value = *location;
if (value != nullptr) {
Expand All @@ -2025,25 +2027,32 @@ OBJ_GETTER(initSharedInstance,
}
#endif // KONAN_NO_EXCEPTIONS
#else // KONAN_NO_THREADS
ObjHeader* value = *localLocation;
if (value != nullptr) RETURN_OBJ(value);
auto it = memoryState->initializingSingletons.find(location);
if (it != memoryState->initializingSingletons.end()) {
RETURN_OBJ(it->second);
}

ObjHeader* initializing = reinterpret_cast<ObjHeader*>(1);

// Spin lock.
ObjHeader* value = nullptr;
while ((value = __sync_val_compare_and_swap(location, nullptr, initializing)) == initializing);
if (value != nullptr) {
// OK'ish, inited by someone else.
RETURN_OBJ(value);
}
ObjHeader* object = AllocInstance(typeInfo, OBJ_RESULT);
UpdateHeapRef(localLocation, object);
auto insertIt = memoryState->initializingSingletons.insert({location, object});
RuntimeCheck(insertIt.second, "object cannot be assigned twice into initializingSingletons");
addHeapRef(object);
#if KONAN_NO_EXCEPTIONS
ctor(object);
if (Strict)
FreezeSubgraph(object);
UpdateHeapRef(location, object);
synchronize();
memoryState->initializingSingletons.erase(location);
releaseHeapRef<Strict>(object);
return object;
#else // KONAN_NO_EXCEPTIONS
try {
Expand All @@ -2052,11 +2061,14 @@ OBJ_GETTER(initSharedInstance,
FreezeSubgraph(object);
UpdateHeapRef(location, object);
synchronize();
memoryState->initializingSingletons.erase(location);
releaseHeapRef<Strict>(object);
return object;
} catch (...) {
UpdateReturnRef(OBJ_RESULT, nullptr);
zeroHeapRef(location);
zeroHeapRef(localLocation);
memoryState->initializingSingletons.erase(location);
releaseHeapRef<Strict>(object);
synchronize();
throw;
}
Expand Down Expand Up @@ -2803,12 +2815,12 @@ OBJ_GETTER(InitInstanceRelaxed,
}

OBJ_GETTER(InitSharedInstanceStrict,
ObjHeader** location, ObjHeader** localLocation, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) {
RETURN_RESULT_OF(initSharedInstance<true>, location, localLocation, typeInfo, ctor);
ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) {
RETURN_RESULT_OF(initSharedInstance<true>, location, typeInfo, ctor);
}
OBJ_GETTER(InitSharedInstanceRelaxed,
ObjHeader** location, ObjHeader** localLocation, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) {
RETURN_RESULT_OF(initSharedInstance<false>, location, localLocation, typeInfo, ctor);
ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) {
RETURN_RESULT_OF(initSharedInstance<false>, location, typeInfo, ctor);
}

void SetStackRefStrict(ObjHeader** location, const ObjHeader* object) {
Expand Down
6 changes: 3 additions & 3 deletions runtime/src/main/cpp/Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,11 +461,11 @@ OBJ_GETTER(InitInstance,
ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*));

OBJ_GETTER(InitSharedInstanceStrict,
ObjHeader** location, ObjHeader** localLocation, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*));
ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*));
OBJ_GETTER(InitSharedInstanceRelaxed,
ObjHeader** location, ObjHeader** localLocation, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*));
ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*));
OBJ_GETTER(InitSharedInstance,
ObjHeader** location, ObjHeader** localLocation, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*));
ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*));

// Weak reference operations.
// Atomically clears counter object reference.
Expand Down
4 changes: 2 additions & 2 deletions runtime/src/relaxed/cpp/MemoryImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ OBJ_GETTER(InitInstance,
}

OBJ_GETTER(InitSharedInstance,
ObjHeader** location, ObjHeader** localLocation, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) {
RETURN_RESULT_OF(InitSharedInstanceRelaxed, location, localLocation, typeInfo, ctor);
ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) {
RETURN_RESULT_OF(InitSharedInstanceRelaxed, location, typeInfo, ctor);
}

void ReleaseHeapRef(const ObjHeader* object) {
Expand Down
4 changes: 2 additions & 2 deletions runtime/src/strict/cpp/MemoryImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ OBJ_GETTER(InitInstance,
}

OBJ_GETTER(InitSharedInstance,
ObjHeader** location, ObjHeader** localLocation, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) {
RETURN_RESULT_OF(InitSharedInstanceStrict, location, localLocation, typeInfo, ctor);
ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) {
RETURN_RESULT_OF(InitSharedInstanceStrict, location, typeInfo, ctor);
}

void ReleaseHeapRef(const ObjHeader* object) {
Expand Down

0 comments on commit 39d678b

Please sign in to comment.