summaryrefslogtreecommitdiffstats
path: root/runtime/mirror/class.cc
diff options
context:
space:
mode:
authorHiroshi Yamauchi <yamauchi@google.com>2014-07-17 16:16:31 -0700
committerHiroshi Yamauchi <yamauchi@google.com>2014-07-17 16:16:31 -0700
commit0fbd6e6ec3241b7163b95f9f001bfe9b08f8b200 (patch)
tree8750bd3360999fa19d8f0f5892baa60348623911 /runtime/mirror/class.cc
parent635561b86ac03f5562bdb779baa6db12f31b3cae (diff)
downloadart-0fbd6e6ec3241b7163b95f9f001bfe9b08f8b200.zip
art-0fbd6e6ec3241b7163b95f9f001bfe9b08f8b200.tar.gz
art-0fbd6e6ec3241b7163b95f9f001bfe9b08f8b200.tar.bz2
Fix two read barrier bugs introduced in CL 97882.
Bug: 12687968 Change-Id: Ib28da4c33977cc58b09913ef5b738dec75365714
Diffstat (limited to 'runtime/mirror/class.cc')
-rw-r--r--runtime/mirror/class.cc43
1 files changed, 31 insertions, 12 deletions
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index be05fb8..b499a5d 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -834,13 +834,42 @@ void Class::PopulateEmbeddedImtAndVTable() SHARED_LOCKS_REQUIRED(Locks::mutator_
}
}
+// The pre-fence visitor for Class::CopyOf().
+class CopyClassVisitor {
+ public:
+ explicit CopyClassVisitor(Thread* self, Handle<mirror::Class>* orig,
+ size_t new_length, size_t copy_bytes)
+ : self_(self), orig_(orig), new_length_(new_length),
+ copy_bytes_(copy_bytes) {
+ }
+
+ void operator()(Object* obj, size_t usable_size) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ UNUSED(usable_size);
+ mirror::Class* new_class_obj = obj->AsClass();
+ mirror::Object::CopyObject(self_, new_class_obj, orig_->Get(), copy_bytes_);
+ new_class_obj->SetStatus(Class::kStatusResolving, self_);
+ new_class_obj->PopulateEmbeddedImtAndVTable();
+ new_class_obj->SetClassSize(new_length_);
+ }
+
+ private:
+ Thread* const self_;
+ Handle<mirror::Class>* const orig_;
+ const size_t new_length_;
+ const size_t copy_bytes_;
+ DISALLOW_COPY_AND_ASSIGN(CopyClassVisitor);
+};
+
Class* Class::CopyOf(Thread* self, int32_t new_length) {
DCHECK_GE(new_length, static_cast<int32_t>(sizeof(Class)));
// We may get copied by a compacting GC.
StackHandleScope<1> hs(self);
Handle<mirror::Class> h_this(hs.NewHandle(this));
gc::Heap* heap = Runtime::Current()->GetHeap();
- InitializeClassVisitor visitor(new_length);
+ // The num_bytes (3rd param) is sizeof(Class) as opposed to SizeOf()
+ // to skip copying the tail part that we will overwrite here.
+ CopyClassVisitor visitor(self, &h_this, new_length, sizeof(Class));
mirror::Object* new_class =
kMovingClasses ? heap->AllocObject<true>(self, java_lang_Class_, new_length, visitor)
@@ -850,17 +879,7 @@ Class* Class::CopyOf(Thread* self, int32_t new_length) {
return NULL;
}
- mirror::Class* new_class_obj = new_class->AsClass();
- memcpy(new_class_obj, h_this.Get(), sizeof(Class));
-
- new_class_obj->SetStatus(kStatusResolving, self);
- new_class_obj->PopulateEmbeddedImtAndVTable();
- // Correct some fields.
- new_class_obj->SetLockWord(LockWord(), false);
- new_class_obj->SetClassSize(new_length);
-
- Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(new_class_obj);
- return new_class_obj;
+ return new_class->AsClass();
}
} // namespace mirror