diff options
author | Mathieu Chartier <mathieuc@google.com> | 2014-06-10 11:22:31 -0700 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2014-06-19 12:57:05 -0700 |
commit | 52e4b43d62896b56f8c2bd041e528472bb4a0d8d (patch) | |
tree | 3a9367c391418c1375a6c86f678b3f047cacc03f /runtime/mirror | |
parent | ef38670cae8462d579da983c1863f96717cccee6 (diff) | |
download | art-52e4b43d62896b56f8c2bd041e528472bb4a0d8d.zip art-52e4b43d62896b56f8c2bd041e528472bb4a0d8d.tar.gz art-52e4b43d62896b56f8c2bd041e528472bb4a0d8d.tar.bz2 |
Add mark compact collector.
The mark compact collector is a 4 phase collection, doing a normal
full mark_sweep, calculating forwarding addresses of objects in the
from space, updating references of objects in the from space, and
moving the objects in the from space.
Support is diabled by default since it needs to have non movable
classes and field arrays. Performance numbers is around 50% as fast.
The main advantage that this has over semispace is that the worst
case memory usage is 50% since we only need one space isntead of two.
TODO: Make field arrays and classes movable. This causes complication
since Object::VisitReferences relies on these, so if we update the
fields of an object but another future object uses this object to
figure out what fields are reference fields it doesn't work.
Bug: 14059466
Change-Id: I661ed3b71ad4dde124ef80312c95696b4a5665a1
Diffstat (limited to 'runtime/mirror')
-rw-r--r-- | runtime/mirror/class-inl.h | 4 | ||||
-rw-r--r-- | runtime/mirror/iftable-inl.h | 5 | ||||
-rw-r--r-- | runtime/mirror/object-inl.h | 24 |
3 files changed, 17 insertions, 16 deletions
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h index 512a66f..6205f70 100644 --- a/runtime/mirror/class-inl.h +++ b/runtime/mirror/class-inl.h @@ -505,8 +505,10 @@ inline Object* Class::AllocNonMovableObject(Thread* self) { template <bool kVisitClass, typename Visitor> inline void Class::VisitReferences(mirror::Class* klass, const Visitor& visitor) { - VisitInstanceFieldsReferences<kVisitClass>(klass, visitor); + // Visit the static fields first so that we don't overwrite the SFields / IFields instance + // fields. VisitStaticFieldsReferences<kVisitClass>(this, visitor); + VisitInstanceFieldsReferences<kVisitClass>(klass, visitor); } inline bool Class::IsArtFieldClass() const { diff --git a/runtime/mirror/iftable-inl.h b/runtime/mirror/iftable-inl.h index ec3e514..3f20bf4 100644 --- a/runtime/mirror/iftable-inl.h +++ b/runtime/mirror/iftable-inl.h @@ -25,8 +25,9 @@ namespace mirror { inline void IfTable::SetInterface(int32_t i, Class* interface) { DCHECK(interface != NULL); DCHECK(interface->IsInterface()); - DCHECK(Get((i * kMax) + kInterface) == NULL); - Set<false>((i * kMax) + kInterface, interface); + const size_t idx = i * kMax + kInterface; + DCHECK_EQ(Get(idx), static_cast<Object*>(nullptr)); + Set<false>(idx, interface); } } // namespace mirror diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h index 567ce3e..15ecd3c 100644 --- a/runtime/mirror/object-inl.h +++ b/runtime/mirror/object-inl.h @@ -26,6 +26,7 @@ #include "class.h" #include "lock_word-inl.h" #include "monitor.h" +#include "object_array-inl.h" #include "read_barrier-inl.h" #include "runtime.h" #include "reference.h" @@ -667,10 +668,9 @@ inline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& v mirror::ArtField* field = kIsStatic ? klass->GetStaticField(i) : klass->GetInstanceField(i); MemberOffset field_offset = field->GetOffset(); // TODO: Do a simpler check? - if (!kVisitClass && UNLIKELY(field_offset.Uint32Value() == ClassOffset().Uint32Value())) { - continue; + if (kVisitClass || field_offset.Uint32Value() != ClassOffset().Uint32Value()) { + visitor(this, field_offset, kIsStatic); } - visitor(this, field_offset, kIsStatic); } } } @@ -693,18 +693,16 @@ template <const bool kVisitClass, VerifyObjectFlags kVerifyFlags, typename Visit inline void Object::VisitReferences(const Visitor& visitor, const JavaLangRefVisitor& ref_visitor) { mirror::Class* klass = GetClass<kVerifyFlags>(); - if (klass->IsVariableSize()) { - if (klass->IsClassClass()) { - AsClass<kVerifyNone>()->VisitReferences<kVisitClass>(klass, visitor); - } else { - DCHECK(klass->IsArrayClass<kVerifyFlags>()); - if (klass->IsObjectArrayClass<kVerifyNone>()) { - AsObjectArray<mirror::Object, kVerifyNone>()->VisitReferences<kVisitClass>(visitor); - } else if (kVisitClass) { - visitor(this, ClassOffset(), false); - } + if (klass == Class::GetJavaLangClass()) { + AsClass<kVerifyNone>()->VisitReferences<kVisitClass>(klass, visitor); + } else if (klass->IsArrayClass()) { + if (klass->IsObjectArrayClass<kVerifyNone>()) { + AsObjectArray<mirror::Object, kVerifyNone>()->VisitReferences<kVisitClass>(visitor); + } else if (kVisitClass) { + visitor(this, ClassOffset(), false); } } else { + DCHECK(!klass->IsVariableSize()); VisitInstanceFieldsReferences<kVisitClass>(klass, visitor); if (UNLIKELY(klass->IsReferenceClass<kVerifyNone>())) { ref_visitor(klass, AsReference()); |