Try using stack

This commit is contained in:
Alexander Shabalin
2020-03-24 18:44:30 +03:00
parent 783e0524bc
commit b52658eb38
+11 -11
View File
@@ -451,9 +451,8 @@ struct MemoryState {
uint64_t allocSinceLastGcThreshold;
#endif // USE_GC
// This map is expected to be small, std::map consumes less memory than
// std::unordered_map and is just as efficient.
KStdOrderedMap<ObjHeader**, ObjHeader*> initializingSingletons;
// A stack of initializing singletons.
KStdVector<std::pair<ObjHeader**, ObjHeader*>> initializingSingletons;
#if COLLECT_STATISTIC
#define CONTAINER_ALLOC_STAT(state, size, container) state->statistic.incAlloc(size, container);
@@ -2029,9 +2028,11 @@ OBJ_GETTER(initSharedInstance,
}
#endif // KONAN_NO_EXCEPTIONS
#else // KONAN_NO_THREADS
auto it = memoryState->initializingSingletons.find(location);
if (it != memoryState->initializingSingletons.end()) {
RETURN_OBJ(it->second);
// Search from the top of the stack.
for (auto it = memoryState->initializingSingletons.rbegin(); it != memoryState->initializingSingletons.rend(); ++it) {
if (it->first == location) {
RETURN_OBJ(it->second);
}
}
ObjHeader* initializing = reinterpret_cast<ObjHeader*>(1);
@@ -2044,8 +2045,7 @@ OBJ_GETTER(initSharedInstance,
RETURN_OBJ(value);
}
ObjHeader* object = AllocInstance(typeInfo, OBJ_RESULT);
auto insertIt = memoryState->initializingSingletons.insert({location, object});
RuntimeCheck(insertIt.second, "object cannot be assigned twice into initializingSingletons");
memoryState->initializingSingletons.push_back(std::make_pair(location, object));
addHeapRef(object);
#if KONAN_NO_EXCEPTIONS
ctor(object);
@@ -2053,7 +2053,7 @@ OBJ_GETTER(initSharedInstance,
FreezeSubgraph(object);
UpdateHeapRef(location, object);
synchronize();
memoryState->initializingSingletons.erase(location);
memoryState->initializingSingletons.pop_back();
releaseHeapRef<Strict>(object);
return object;
#else // KONAN_NO_EXCEPTIONS
@@ -2063,13 +2063,13 @@ OBJ_GETTER(initSharedInstance,
FreezeSubgraph(object);
UpdateHeapRef(location, object);
synchronize();
memoryState->initializingSingletons.erase(location);
memoryState->initializingSingletons.pop_back();
releaseHeapRef<Strict>(object);
return object;
} catch (...) {
UpdateReturnRef(OBJ_RESULT, nullptr);
zeroHeapRef(location);
memoryState->initializingSingletons.erase(location);
memoryState->initializingSingletons.pop_back();
releaseHeapRef<Strict>(object);
synchronize();
throw;