Remove remaining recursive memory manager operations. (#2541)

This commit is contained in:
Nikolay Igotti
2019-01-15 17:52:38 +02:00
committed by GitHub
parent 1596155182
commit 6c970f4c9f
3 changed files with 46 additions and 28 deletions
+1 -1
View File
@@ -66,7 +66,7 @@ fun <T: Any> checkThrows(e: KClass<T>, string: String, action: () -> Unit) {
assertTrue(e.isInstance(exception),""" assertTrue(e.isInstance(exception),"""
Wrong exception was thrown for string: $string Wrong exception was thrown for string: $string
Expected: ${e.qualifiedName} Expected: ${e.qualifiedName}
Actual: ${exception!!::class.qualifiedName} Actual: ${exception::class.qualifiedName}
""".trimIndent()) """.trimIndent())
} }
@@ -13,7 +13,7 @@ object Immutable {
var x = 1 var x = 1
} }
@kotlin.native.ThreadLocal @ThreadLocal
object Mutable { object Mutable {
var x = 2 var x = 2
} }
+44 -26
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * Copyright 2010-2018 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -1685,12 +1685,17 @@ bool ClearSubgraphReferences(ObjHeader* root, bool checked) {
* - not 'marked' and not 'seen' as WHITE marker (object is unprocessed) * - not 'marked' and not 'seen' as WHITE marker (object is unprocessed)
* When we see GREY during DFS, it means we see cycle. * When we see GREY during DFS, it means we see cycle.
*/ */
void depthFirstTraversal(ContainerHeader* container, bool* hasCycles, void depthFirstTraversal(ContainerHeader* start, bool* hasCycles,
KRef* firstBlocker, KStdVector<ContainerHeader*>& order) { KRef* firstBlocker, KStdVector<ContainerHeader*>* order) {
// Mark GRAY. ContainerHeaderDeque toVisit;
container->setSeen(); toVisit.push_back(start);
start->setSeen();
traverseContainerReferredObjects(container, [hasCycles, firstBlocker, &order](ObjHeader* obj) { while (!toVisit.empty()) {
auto* container = toVisit.front();
toVisit.pop_front();
traverseContainerReferredObjects(container, [hasCycles, firstBlocker, &order, &toVisit](ObjHeader* obj) {
if (*firstBlocker != nullptr) if (*firstBlocker != nullptr)
return; return;
if (obj->has_meta_object() && ((obj->meta_object()->flags_ & MF_NEVER_FROZEN) != 0)) { if (obj->has_meta_object() && ((obj->meta_object()->flags_ & MF_NEVER_FROZEN) != 0)) {
@@ -1704,26 +1709,39 @@ void depthFirstTraversal(ContainerHeader* container, bool* hasCycles,
// Go deeper if WHITE. // Go deeper if WHITE.
if (!objContainer->seen() && !objContainer->marked()) { if (!objContainer->seen() && !objContainer->marked()) {
depthFirstTraversal(objContainer, hasCycles, firstBlocker, order); // Mark GRAY.
objContainer->setSeen();
toVisit.push_front(objContainer);
} }
} }
}); });
// Mark BLACK. // Mark BLACK.
container->resetSeen(); container->resetSeen();
container->mark(); container->mark();
order.push_back(container); order->push_back(container);
}
} }
void traverseStronglyConnectedComponent(ContainerHeader* container, void traverseStronglyConnectedComponent(ContainerHeader* start,
KStdUnorderedMap<ContainerHeader*, KStdVector<ContainerHeader*>> const& reversedEdges, KStdUnorderedMap<ContainerHeader*,
KStdVector<ContainerHeader*>& component) { KStdVector<ContainerHeader*>> const* reversedEdges,
component.push_back(container); KStdVector<ContainerHeader*>* component) {
container->mark(); ContainerHeaderDeque toVisit;
auto it = reversedEdges.find(container); toVisit.push_back(start);
RuntimeAssert(it != reversedEdges.end(), "unknown node during condensation building"); start->mark();
for (auto* nextContainer : it->second) {
if (!nextContainer->marked()) while (!toVisit.empty()) {
traverseStronglyConnectedComponent(nextContainer, reversedEdges, component); auto* container = toVisit.front();
toVisit.pop_front();
component->push_back(container);
auto it = reversedEdges->find(container);
RuntimeAssert(it != reversedEdges->end(), "unknown node during condensation building");
for (auto* nextContainer : it->second) {
if (!nextContainer->marked()) {
nextContainer->mark();
toVisit.push_front(nextContainer);
}
}
} }
} }
@@ -1775,10 +1793,10 @@ void freezeCyclic(ContainerHeader* rootContainer, const KStdVector<ContainerHead
auto* container = *it; auto* container = *it;
if (container->marked()) continue; if (container->marked()) continue;
KStdVector<ContainerHeader*> component; KStdVector<ContainerHeader*> component;
traverseStronglyConnectedComponent(container, reversedEdges, component); traverseStronglyConnectedComponent(container, &reversedEdges, &component);
MEMORY_LOG("SCC:\n"); MEMORY_LOG("SCC:\n");
#if TRACE_MEMORY #if TRACE_MEMORY
for (auto c : component) for (auto c: component)
konan::consolePrintf(" %p\n", c); konan::consolePrintf(" %p\n", c);
#endif #endif
components.push_back(std::move(component)); components.push_back(std::move(component));
@@ -1832,7 +1850,7 @@ void freezeCyclic(ContainerHeader* rootContainer, const KStdVector<ContainerHead
* - put all objects in each strongly connected component into an artificial container * - put all objects in each strongly connected component into an artificial container
* (we assume that they all were in single element containers initially), single-object * (we assume that they all were in single element containers initially), single-object
* components remain in the same container * components remain in the same container
* - artifical container sums up outer reference counters of all its objects (i.e. * - artificial container sums up outer reference counters of all its objects (i.e.
* incoming references from the same strongly connected component are not counted) * incoming references from the same strongly connected component are not counted)
* - mark all object's headers as frozen * - mark all object's headers as frozen
* *
@@ -1851,7 +1869,7 @@ void FreezeSubgraph(ObjHeader* root) {
KRef firstBlocker = root->has_meta_object() && ((root->meta_object()->flags_ & MF_NEVER_FROZEN) != 0) ? KRef firstBlocker = root->has_meta_object() && ((root->meta_object()->flags_ & MF_NEVER_FROZEN) != 0) ?
root : nullptr; root : nullptr;
KStdVector<ContainerHeader*> order; KStdVector<ContainerHeader*> order;
depthFirstTraversal(rootContainer, &hasCycles, &firstBlocker, order); depthFirstTraversal(rootContainer, &hasCycles, &firstBlocker, &order);
if (firstBlocker != nullptr) { if (firstBlocker != nullptr) {
ThrowFreezingException(root, firstBlocker); ThrowFreezingException(root, firstBlocker);
} }