[K/N] Support escape analysis with new mm
This commit is contained in:
@@ -24,7 +24,6 @@ void Mark(KStdVector<ObjHeader*> graySet) noexcept {
|
||||
graySet.pop_back();
|
||||
|
||||
RuntimeAssert(!isNullOrMarker(top), "Got invalid reference %p in gray set", top);
|
||||
RuntimeAssert(!top->local(), "TODO: Stack objects are not supported yet, top=%p", top);
|
||||
|
||||
if (top->heap()) {
|
||||
if (!Traits::TryMark(top)) {
|
||||
@@ -32,9 +31,9 @@ void Mark(KStdVector<ObjHeader*> graySet) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
if (!top->permanent()) {
|
||||
if (top->heap() || top->local()) {
|
||||
traverseReferredObjects(top, [&graySet](ObjHeader* field) noexcept {
|
||||
if (!isNullOrMarker(field) && !field->permanent() && !Traits::IsMarked(field)) {
|
||||
if (!isNullOrMarker(field) && field->heap() && !Traits::IsMarked(field)) {
|
||||
graySet.push_back(field);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -38,6 +38,7 @@ class BaseObject {
|
||||
public:
|
||||
enum class Kind {
|
||||
kPermanent,
|
||||
kStackLocal,
|
||||
kHeapLike // Treated as heap object for the purposes of the test.
|
||||
};
|
||||
|
||||
@@ -60,6 +61,11 @@ protected:
|
||||
case Kind::kHeapLike:
|
||||
RuntimeAssert(GetObjHeader()->heap(), "Must be heap");
|
||||
break;
|
||||
case Kind::kStackLocal:
|
||||
GetObjHeader()->typeInfoOrMeta_ = setPointerBits(GetObjHeader()->typeInfoOrMeta_,
|
||||
OBJECT_TAG_PERMANENT_CONTAINER | OBJECT_TAG_NONTRIVIAL_CONTAINER);
|
||||
RuntimeAssert(GetObjHeader()->local(), "Must be stack local");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,6 +211,31 @@ TEST_F(MarkAndSweepUtilsMarkTest, MarkSinglePermanentCharArray) {
|
||||
EXPECT_MARKED();
|
||||
}
|
||||
|
||||
TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleStackObject) {
|
||||
Object object{BaseObject::Kind::kStackLocal};
|
||||
|
||||
Mark({object});
|
||||
|
||||
EXPECT_MARKED();
|
||||
}
|
||||
|
||||
TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleStackObjectArray) {
|
||||
ObjectArray array{BaseObject::Kind::kStackLocal};
|
||||
|
||||
Mark({array});
|
||||
|
||||
EXPECT_MARKED();
|
||||
}
|
||||
|
||||
TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleStackCharArray) {
|
||||
CharArray array{BaseObject::Kind::kStackLocal};
|
||||
|
||||
Mark({array});
|
||||
|
||||
EXPECT_MARKED();
|
||||
}
|
||||
|
||||
|
||||
TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleObjectWithInvalidFields) {
|
||||
Object object;
|
||||
object->field1 = kInitializingSingleton;
|
||||
@@ -416,6 +447,28 @@ TEST_F(MarkAndSweepUtilsMarkTest, MarkTreeWithPermanentLeaf) {
|
||||
EXPECT_MARKED(root, root_field1, root_field1_field2, root_field3, root_field3_element1, root_field3_element2, root_field3_element3);
|
||||
}
|
||||
|
||||
TEST_F(MarkAndSweepUtilsMarkTest, MarkTreeWithStackRoot) {
|
||||
Object root{BaseObject::Kind::kStackLocal};
|
||||
Object root_field1{BaseObject::Kind::kPermanent};
|
||||
Object root_field1_field1{BaseObject::Kind::kPermanent};
|
||||
Object root_field1_field2{BaseObject::Kind::kPermanent};
|
||||
ObjectArray root_field3{BaseObject::Kind::kStackLocal};
|
||||
Object root_field3_element1{BaseObject::Kind::kHeapLike};
|
||||
ObjectArray root_field3_element2{BaseObject::Kind::kHeapLike};
|
||||
CharArray root_field3_element3{BaseObject::Kind::kPermanent};
|
||||
root->field1 = root_field1.header();
|
||||
root_field1->field1 = root_field1_field1.header();
|
||||
root_field1->field2 = root_field1_field2.header();
|
||||
root->field3 = root_field3.header();
|
||||
root_field3.elements()[0] = root_field3_element1.header();
|
||||
root_field3.elements()[1] = root_field3_element2.header();
|
||||
root_field3.elements()[2] = root_field3_element3.header();
|
||||
|
||||
Mark({root, root_field3});
|
||||
|
||||
EXPECT_MARKED(root_field3_element1, root_field3_element2);
|
||||
}
|
||||
|
||||
TEST_F(MarkAndSweepUtilsMarkTest, MarkRecursiveTree) {
|
||||
Object root;
|
||||
Object inner1;
|
||||
@@ -442,6 +495,25 @@ TEST_F(MarkAndSweepUtilsMarkTest, MarkRecursiveTreeWithPermanentRoot) {
|
||||
EXPECT_MARKED();
|
||||
}
|
||||
|
||||
TEST_F(MarkAndSweepUtilsMarkTest, MarkRecursiveTreeWithStackRoot) {
|
||||
Object root{BaseObject::Kind::kStackLocal};
|
||||
Object inner1{BaseObject::Kind::kStackLocal};
|
||||
ObjectArray inner2{BaseObject::Kind::kStackLocal};
|
||||
Object inner3{BaseObject::Kind::kHeapLike};
|
||||
Object inner2_element1{BaseObject::Kind::kHeapLike};
|
||||
root->field1 = inner1.header();
|
||||
inner1->field1 = inner2.header();
|
||||
inner2.elements()[0] = root.header();
|
||||
inner2.elements()[1] = inner2_element1.header();
|
||||
root->field2 = inner3.header();
|
||||
inner3->field1 = inner2.header();
|
||||
|
||||
Mark({root, inner1, inner2});
|
||||
|
||||
EXPECT_MARKED(inner3, inner2_element1);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(MarkAndSweepUtilsMarkTest, MarkForest) {
|
||||
Object root1;
|
||||
ObjectArray root2;
|
||||
|
||||
Reference in New Issue
Block a user