diff options
author | Mathieu Chartier <mathieuc@google.com> | 2013-11-20 12:33:14 -0800 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2013-11-20 13:09:20 -0800 |
commit | 1febddf359ae500ef1bb01ab4883b076fcb56440 (patch) | |
tree | abcb59ae807d3b8efae95ee0a2e34d6b66e52275 /runtime | |
parent | e768dfd50aa893b2956a59f59f3ed4033aed8cef (diff) | |
download | art-1febddf359ae500ef1bb01ab4883b076fcb56440.zip art-1febddf359ae500ef1bb01ab4883b076fcb56440.tar.gz art-1febddf359ae500ef1bb01ab4883b076fcb56440.tar.bz2 |
Set array length before fence in allocation code path.
Could not delete SetLength since it is required by
space_test.
Bug: 11747779
Change-Id: Icf1ead216b6ff1b519240ab0d0ca30d68429d5b6
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/gc/heap-inl.h | 21 | ||||
-rw-r--r-- | runtime/gc/heap.h | 7 | ||||
-rw-r--r-- | runtime/mirror/array-inl.h | 24 |
3 files changed, 31 insertions, 21 deletions
diff --git a/runtime/gc/heap-inl.h b/runtime/gc/heap-inl.h index fcc07a0..9b28555 100644 --- a/runtime/gc/heap-inl.h +++ b/runtime/gc/heap-inl.h @@ -32,10 +32,11 @@ namespace art { namespace gc { -template <const bool kInstrumented> -inline mirror::Object* Heap::AllocObjectWithAllocator(Thread* self, mirror::Class* c, - size_t byte_count, AllocatorType allocator) { - DebugCheckPreconditionsForAllocObject(c, byte_count); +template <bool kInstrumented, typename PreFenceVisitor> +inline mirror::Object* Heap::AllocObjectWithAllocator(Thread* self, mirror::Class* klass, + size_t byte_count, AllocatorType allocator, + const PreFenceVisitor& pre_fence_visitor) { + DebugCheckPreconditionsForAllocObject(klass, byte_count); // Since allocation can cause a GC which will need to SuspendAll, make sure all allocations are // done in the runnable state where suspension is expected. DCHECK_EQ(self->GetState(), kRunnable); @@ -43,7 +44,7 @@ inline mirror::Object* Heap::AllocObjectWithAllocator(Thread* self, mirror::Clas mirror::Object* obj; size_t bytes_allocated; AllocationTimer alloc_timer(this, &obj); - if (UNLIKELY(ShouldAllocLargeObject(c, byte_count))) { + if (UNLIKELY(ShouldAllocLargeObject(klass, byte_count))) { obj = TryToAllocate<kInstrumented>(self, kAllocatorTypeLOS, byte_count, false, &bytes_allocated); allocator = kAllocatorTypeLOS; @@ -52,16 +53,16 @@ inline mirror::Object* Heap::AllocObjectWithAllocator(Thread* self, mirror::Clas } if (UNLIKELY(obj == nullptr)) { - SirtRef<mirror::Class> sirt_c(self, c); + SirtRef<mirror::Class> sirt_c(self, klass); obj = AllocateInternalWithGc(self, allocator, byte_count, &bytes_allocated); if (obj == nullptr) { return nullptr; } else { - c = sirt_c.get(); + klass = sirt_c.get(); } } - obj->SetClass(c); - // TODO: Set array length here. + obj->SetClass(klass); + pre_fence_visitor(obj); DCHECK_GT(bytes_allocated, 0u); const size_t new_num_bytes_allocated = static_cast<size_t>(num_bytes_allocated_.fetch_add(bytes_allocated)) + bytes_allocated; @@ -87,7 +88,7 @@ inline mirror::Object* Heap::AllocObjectWithAllocator(Thread* self, mirror::Clas } if (kInstrumented) { if (Dbg::IsAllocTrackingEnabled()) { - Dbg::RecordAllocation(c, bytes_allocated); + Dbg::RecordAllocation(klass, bytes_allocated); } } else { DCHECK(!Dbg::IsAllocTrackingEnabled()); diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h index 5a0372a..470bacd 100644 --- a/runtime/gc/heap.h +++ b/runtime/gc/heap.h @@ -162,9 +162,10 @@ class Heap { return AllocObjectWithAllocator<kInstrumented>(self, klass, num_bytes, GetCurrentNonMovingAllocator()); } - template <bool kInstrumented> - ALWAYS_INLINE mirror::Object* AllocObjectWithAllocator(Thread* self, mirror::Class* klass, - size_t num_bytes, AllocatorType allocator) + template <bool kInstrumented, typename PreFenceVisitor = VoidFunctor> + ALWAYS_INLINE mirror::Object* AllocObjectWithAllocator( + Thread* self, mirror::Class* klass, size_t byte_count, AllocatorType allocator, + const PreFenceVisitor& pre_fence_visitor = VoidFunctor()) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); AllocatorType GetCurrentAllocator() const { diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h index 2955faa..46ffaae 100644 --- a/runtime/mirror/array-inl.h +++ b/runtime/mirror/array-inl.h @@ -58,13 +58,20 @@ static inline size_t ComputeArraySize(Thread* self, Class* array_class, int32_t return size; } -static inline Array* SetArrayLength(Array* array, size_t length) { - if (LIKELY(array != nullptr)) { +class SetLengthVisitor { + public: + explicit SetLengthVisitor(int32_t length) : length_(length) { + } + + void operator()(mirror::Object* obj) const { + mirror::Array* array = obj->AsArray(); DCHECK(array->IsArrayInstance()); - array->SetLength(length); + array->SetLength(length_); } - return array; -} + + private: + const int32_t length_; +}; template <bool kIsInstrumented> inline Array* Array::Alloc(Thread* self, Class* array_class, int32_t component_count, @@ -74,9 +81,10 @@ inline Array* Array::Alloc(Thread* self, Class* array_class, int32_t component_c return nullptr; } gc::Heap* heap = Runtime::Current()->GetHeap(); - Array* array = down_cast<Array*>( - heap->AllocObjectWithAllocator<kIsInstrumented>(self, array_class, size, allocator_type)); - return SetArrayLength(array, component_count); + SetLengthVisitor visitor(component_count); + return down_cast<Array*>( + heap->AllocObjectWithAllocator<kIsInstrumented>(self, array_class, size, allocator_type, + visitor)); } template <bool kIsInstrumented> |