diff options
author | Hiroshi Yamauchi <yamauchi@google.com> | 2014-07-17 16:16:31 -0700 |
---|---|---|
committer | Hiroshi Yamauchi <yamauchi@google.com> | 2014-07-17 16:16:31 -0700 |
commit | 0fbd6e6ec3241b7163b95f9f001bfe9b08f8b200 (patch) | |
tree | 8750bd3360999fa19d8f0f5892baa60348623911 /runtime/mirror/class.cc | |
parent | 635561b86ac03f5562bdb779baa6db12f31b3cae (diff) | |
download | art-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.cc | 43 |
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 |