summaryrefslogtreecommitdiffstats
path: root/compiler
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2014-03-24 16:54:46 -0700
committerMathieu Chartier <mathieuc@google.com>2014-03-24 18:12:41 -0700
commitb7ea3acf7b83975a9effadb350c0b62ce4ab2142 (patch)
tree7442e7b83f13c91b7871960246d27660cda8e5d1 /compiler
parent572396010f292f9ba0c1509d2160b97ff886460e (diff)
downloadart-b7ea3acf7b83975a9effadb350c0b62ce4ab2142.zip
art-b7ea3acf7b83975a9effadb350c0b62ce4ab2142.tar.gz
art-b7ea3acf7b83975a9effadb350c0b62ce4ab2142.tar.bz2
Refactor image writer reference visiting logic.
Now uses Object::VisitReferences. Change-Id: I5a4557e10796d6f34596f2e8796ad9382121c567
Diffstat (limited to 'compiler')
-rw-r--r--compiler/image_writer.cc129
-rw-r--r--compiler/image_writer.h16
2 files changed, 38 insertions, 107 deletions
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index 5078182..6824183 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -579,37 +579,51 @@ void ImageWriter::CopyAndFixupObjectsCallback(Object* obj, void* arg) {
image_writer->FixupObject(obj, copy);
}
+class FixupVisitor {
+ public:
+ FixupVisitor(ImageWriter* image_writer, Object* copy) : image_writer_(image_writer), copy_(copy) {
+ }
+
+ void operator()(Object* obj, MemberOffset offset, bool /*is_static*/) const
+ EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_) {
+ Object* ref = obj->GetFieldObject<Object, kVerifyNone>(offset, false);
+ // Use SetFieldObjectWithoutWriteBarrier to avoid card marking since we are writing to the
+ // image.
+ copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(
+ offset, image_writer_->GetImageAddress(ref), false);
+ }
+
+ // java.lang.ref.Reference visitor.
+ void operator()(mirror::Class* /*klass*/, mirror::Reference* ref) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
+ copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(
+ mirror::Reference::ReferentOffset(), image_writer_->GetImageAddress(ref->GetReferent()),
+ false);
+ }
+
+ private:
+ ImageWriter* const image_writer_;
+ mirror::Object* const copy_;
+};
+
void ImageWriter::FixupObject(Object* orig, Object* copy) {
- DCHECK(orig != NULL);
- DCHECK(copy != NULL);
- copy->SetClass<kVerifyNone>(down_cast<Class*>(GetImageAddress(orig->GetClass())));
+ DCHECK(orig != nullptr);
+ DCHECK(copy != nullptr);
if (kUseBrooksPointer) {
orig->AssertSelfBrooksPointer();
// Note the address 'copy' isn't the same as the image address of 'orig'.
copy->SetBrooksPointer(GetImageAddress(orig));
- DCHECK(copy->GetBrooksPointer() == GetImageAddress(orig));
- }
- // TODO: special case init of pointers to malloc data (or removal of these pointers)
- if (orig->IsClass<kVerifyNone>()) {
- FixupClass(orig->AsClass<kVerifyNone>(), down_cast<Class*>(copy));
- } else if (orig->IsObjectArray<kVerifyNone>()) {
- FixupObjectArray(orig->AsObjectArray<Object, kVerifyNone>(),
- down_cast<ObjectArray<Object>*>(copy));
- } else if (orig->IsArtMethod<kVerifyNone>()) {
+ DCHECK_EQ(copy->GetBrooksPointer(), GetImageAddress(orig));
+ }
+ FixupVisitor visitor(this, copy);
+ orig->VisitReferences<true /*visit class*/>(visitor, visitor);
+ if (orig->IsArtMethod<kVerifyNone>()) {
FixupMethod(orig->AsArtMethod<kVerifyNone>(), down_cast<ArtMethod*>(copy));
- } else {
- FixupInstanceFields(orig, copy);
}
}
-void ImageWriter::FixupClass(Class* orig, Class* copy) {
- FixupInstanceFields(orig, copy);
- FixupStaticFields(orig, copy);
-}
-
void ImageWriter::FixupMethod(ArtMethod* orig, ArtMethod* copy) {
- FixupInstanceFields(orig, copy);
-
// OatWriter replaces the code_ with an offset value. Here we re-adjust to a pointer relative to
// oat_begin_
@@ -680,79 +694,6 @@ void ImageWriter::FixupMethod(ArtMethod* orig, ArtMethod* copy) {
}
}
-void ImageWriter::FixupObjectArray(ObjectArray<Object>* orig, ObjectArray<Object>* copy) {
- for (int32_t i = 0; i < orig->GetLength(); ++i) {
- Object* element = orig->Get(i);
- copy->SetWithoutChecksAndWriteBarrier<false, true, kVerifyNone>(i, GetImageAddress(element));
- }
-}
-
-void ImageWriter::FixupInstanceFields(Object* orig, Object* copy) {
- DCHECK(orig != NULL);
- DCHECK(copy != NULL);
- Class* klass = orig->GetClass();
- DCHECK(klass != NULL);
- FixupFields(orig, copy, klass->GetReferenceInstanceOffsets(), false);
-}
-
-void ImageWriter::FixupStaticFields(Class* orig, Class* copy) {
- DCHECK(orig != NULL);
- DCHECK(copy != NULL);
- FixupFields(orig, copy, orig->GetReferenceStaticOffsets(), true);
-}
-
-void ImageWriter::FixupFields(Object* orig,
- Object* copy,
- uint32_t ref_offsets,
- bool is_static) {
- if (ref_offsets != CLASS_WALK_SUPER) {
- // Found a reference offset bitmap. Fixup the specified offsets.
- while (ref_offsets != 0) {
- size_t right_shift = CLZ(ref_offsets);
- MemberOffset byte_offset = CLASS_OFFSET_FROM_CLZ(right_shift);
- Object* ref = orig->GetFieldObject<Object, kVerifyNone>(byte_offset, false);
- // Use SetFieldObjectWithoutWriteBarrier to avoid card marking since we are writing to the
- // image.
- copy->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(
- byte_offset, GetImageAddress(ref), false);
- ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift);
- }
- } else {
- // There is no reference offset bitmap. In the non-static case,
- // walk up the class inheritance hierarchy and find reference
- // offsets the hard way. In the static case, just consider this
- // class.
- for (Class *klass = is_static ? orig->AsClass() : orig->GetClass();
- klass != NULL;
- klass = is_static ? NULL : klass->GetSuperClass()) {
- size_t num_reference_fields = (is_static
- ? klass->NumReferenceStaticFields()
- : klass->NumReferenceInstanceFields());
- for (size_t i = 0; i < num_reference_fields; ++i) {
- ArtField* field = (is_static
- ? klass->GetStaticField(i)
- : klass->GetInstanceField(i));
- MemberOffset field_offset = field->GetOffset();
- Object* ref = orig->GetFieldObject<Object, kVerifyNone>(field_offset, false);
- // Use SetFieldObjectWithoutWriteBarrier to avoid card marking since we are writing to the
- // image.
- copy->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(
- field_offset, GetImageAddress(ref), false);
- }
- }
- }
- if (!is_static && orig->IsReferenceInstance()) {
- // Fix-up referent, that isn't marked as an object field, for References.
- ArtField* field = orig->GetClass()->FindInstanceField("referent", "Ljava/lang/Object;");
- MemberOffset field_offset = field->GetOffset();
- Object* ref = orig->GetFieldObject<Object>(field_offset, false);
- // Use SetFieldObjectWithoutWriteBarrier to avoid card marking since we are writing to the
- // image.
- copy->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(
- field_offset, GetImageAddress(ref), false);
- }
-}
-
static ArtMethod* GetTargetMethod(const CompilerDriver::CallPatchInformation* patch)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
diff --git a/compiler/image_writer.h b/compiler/image_writer.h
index dff33ba..92b24f6 100644
--- a/compiler/image_writer.h
+++ b/compiler/image_writer.h
@@ -141,22 +141,10 @@ class ImageWriter {
void CopyAndFixupObjects();
static void CopyAndFixupObjectsCallback(mirror::Object* obj, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupClass(mirror::Class* orig, mirror::Class* copy)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void FixupMethod(mirror::ArtMethod* orig, mirror::ArtMethod* copy)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void FixupObject(mirror::Object* orig, mirror::Object* copy)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupObjectArray(mirror::ObjectArray<mirror::Object>* orig,
- mirror::ObjectArray<mirror::Object>* copy)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupInstanceFields(mirror::Object* orig, mirror::Object* copy)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupStaticFields(mirror::Class* orig, mirror::Class* copy)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupFields(mirror::Object* orig, mirror::Object* copy, uint32_t ref_offsets,
- bool is_static)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Patches references in OatFile to expect runtime addresses.
void PatchOatCodeAndMethods()
@@ -164,7 +152,6 @@ class ImageWriter {
void SetPatchLocation(const CompilerDriver::PatchInformation* patch, uint32_t value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
const CompilerDriver& compiler_driver_;
// oat file with code for this image
@@ -199,6 +186,9 @@ class ImageWriter {
uint32_t quick_imt_conflict_trampoline_offset_;
uint32_t quick_resolution_trampoline_offset_;
uint32_t quick_to_interpreter_bridge_offset_;
+
+ friend class FixupVisitor;
+ DISALLOW_COPY_AND_ASSIGN(ImageWriter);
};
} // namespace art