Smarter process abandoned foreign references. (#3568)
This commit is contained in:
@@ -375,22 +375,23 @@ private:
|
|||||||
|
|
||||||
void processAbandoned() {
|
void processAbandoned() {
|
||||||
if (this->releaseList != nullptr) {
|
if (this->releaseList != nullptr) {
|
||||||
bool hadNoRuntimeInitialized = (memoryState == nullptr);
|
bool hadNoStateInitialized = (memoryState == nullptr);
|
||||||
|
|
||||||
if (hadNoRuntimeInitialized) {
|
if (hadNoStateInitialized) {
|
||||||
Kotlin_initRuntimeIfNeeded(); // Required by ReleaseHeapRef.
|
// Disregard request if all runtimes are no longer alive.
|
||||||
|
if (atomicGet(&aliveMemoryStatesCount) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memoryState = InitMemory(); // Required by ReleaseHeapRef.
|
||||||
}
|
}
|
||||||
|
|
||||||
processEnqueuedReleaseRefsWith([](ObjHeader* obj) {
|
processEnqueuedReleaseRefsWith([](ObjHeader* obj) {
|
||||||
ReleaseHeapRef(obj);
|
ReleaseHeapRef(obj);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (hadNoRuntimeInitialized) {
|
if (hadNoStateInitialized) {
|
||||||
// This thread is likely not intended to run Kotlin code.
|
// Discard the memory state.
|
||||||
// In this case it has no chances to process the release-refs enqueued above using
|
DeinitMemory(memoryState);
|
||||||
// the general heuristics, so do this manually:
|
|
||||||
garbageCollect();
|
|
||||||
// TODO: how to handle subsequent processAbandoned() calls?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ inline bool isValidRuntime() {
|
|||||||
return ::runtimeState != kInvalidRuntime;
|
return ::runtimeState != kInvalidRuntime;
|
||||||
}
|
}
|
||||||
|
|
||||||
int aliveRuntimesCount = 0;
|
volatile int aliveRuntimesCount = 0;
|
||||||
|
|
||||||
RuntimeState* initRuntime() {
|
RuntimeState* initRuntime() {
|
||||||
SetKonanTerminateHandler();
|
SetKonanTerminateHandler();
|
||||||
|
|||||||
Reference in New Issue
Block a user