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