Added extra GC call before analyzing subgraph during freeze operation… (#4314)

This commit is contained in:
LepilkinaElena
2020-07-31 09:50:37 +03:00
committed by GitHub
parent e675ea67d8
commit ddc9428d4f
+21 -3
View File
@@ -1679,7 +1679,7 @@ void garbageCollect(MemoryState* state, bool force) {
GC_LOG("||| GC: collectCyclesDuration = %lld\n", cyclicGcEndTime - cyclicGcStartTime);
#endif
auto cyclicGcDuration = cyclicGcEndTime - cyclicGcStartTime;
if (state->gcErgonomics && cyclicGcDuration > kGcCollectCyclesMinimumDuration &&
if (!force && state->gcErgonomics && cyclicGcDuration > kGcCollectCyclesMinimumDuration &&
double(cyclicGcDuration) / (cyclicGcStartTime - state->lastCyclicGcTimestamp + 1) > kGcCollectCyclesLoadRatio) {
increaseGcCollectCyclesThreshold(state);
GC_LOG("Adjusting GC collecting cycles threshold to %lld\n", state->gcCollectCyclesThreshold);
@@ -1692,7 +1692,7 @@ void garbageCollect(MemoryState* state, bool force) {
if (state->gcErgonomics) {
auto gcToComputeRatio = double(gcEndTime - gcStartTime) / (gcStartTime - state->lastGcTimestamp + 1);
if (gcToComputeRatio > kGcToComputeRatioThreshold) {
if (!force && gcToComputeRatio > kGcToComputeRatioThreshold) {
increaseGcThreshold(state);
GC_LOG("Adjusting GC threshold to %d\n", state->gcThreshold);
}
@@ -1997,6 +1997,16 @@ inline void checkIfGcNeeded(MemoryState* state) {
}
}
inline void checkIfForceCyclicGcNeeded(MemoryState* state) {
if (state != nullptr && state->toFree != nullptr && state->toFree->size() > kMaxToFreeSizeThreshold) {
// To avoid GC trashing check that at least 10ms passed since last GC.
if (konan::getTimeMicros() - state->lastGcTimestamp > 10 * 1000) {
GC_LOG("Calling GC from checkIfForceCyclicGcNeeded: %d\n", state->toFree->size())
garbageCollect(state, true);
}
}
}
template <bool Strict>
OBJ_GETTER(allocInstance, const TypeInfo* type_info) {
RuntimeAssert(type_info->instanceSize_ >= 0, "must be an object");
@@ -2400,6 +2410,9 @@ bool clearSubgraphReferences(ObjHeader* root, bool checked) {
// TODO: assert for that?
return true;
// Free cyclic garbage to decrease number of analyzed objects.
checkIfForceCyclicGcNeeded(state);
ContainerHeaderSet visited;
if (!checked) {
hasExternalRefs(container, &visited);
@@ -2601,6 +2614,12 @@ void freezeSubgraph(ObjHeader* root) {
MEMORY_LOG("Freeze subgraph of %p\n", root)
#if USE_GC
auto state = memoryState;
// Free cyclic garbage to decrease number of analyzed objects.
checkIfForceCyclicGcNeeded(state);
#endif
// Do DFS cycle detection.
bool hasCycles = false;
KRef firstBlocker = root->has_meta_object() && ((root->meta_object()->flags_ & MF_NEVER_FROZEN) != 0) ?
@@ -2624,7 +2643,6 @@ void freezeSubgraph(ObjHeader* root) {
// Now remove frozen objects from the toFree list.
// TODO: optimize it by keeping ignored (i.e. freshly frozen) objects in the set,
// and use it when analyzing toFree during collection.
auto state = memoryState;
for (auto& container : *(state->toFree)) {
if (!isMarkedAsRemoved(container) && container->frozen()) {
RuntimeAssert(newlyFrozen.count(container) != 0, "Must be newly frozen");