1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_GC_SPACE_ROSALLOC_SPACE_INL_H_ 18 #define ART_RUNTIME_GC_SPACE_ROSALLOC_SPACE_INL_H_ 19 20 #include "gc/allocator/rosalloc-inl.h" 21 #include "gc/space/valgrind_settings.h" 22 #include "rosalloc_space.h" 23 #include "thread.h" 24 25 namespace art { 26 namespace gc { 27 namespace space { 28 29 template<bool kMaybeRunningOnValgrind> 30 inline size_t RosAllocSpace::AllocationSizeNonvirtual(mirror::Object* obj, size_t* usable_size) { 31 // obj is a valid object. Use its class in the header to get the size. 32 // Don't use verification since the object may be dead if we are sweeping. 33 size_t size = obj->SizeOf<kVerifyNone>(); 34 bool running_on_valgrind = false; 35 if (kMaybeRunningOnValgrind) { 36 running_on_valgrind = RUNNING_ON_VALGRIND != 0; 37 if (running_on_valgrind) { 38 size += 2 * kDefaultValgrindRedZoneBytes; 39 } 40 } else { 41 DCHECK_EQ(RUNNING_ON_VALGRIND, 0U); 42 } 43 size_t size_by_size = rosalloc_->UsableSize(size); 44 if (kIsDebugBuild) { 45 // On valgrind, the red zone has an impact... 46 const uint8_t* obj_ptr = reinterpret_cast<const uint8_t*>(obj); 47 size_t size_by_ptr = rosalloc_->UsableSize( 48 obj_ptr - (running_on_valgrind ? kDefaultValgrindRedZoneBytes : 0)); 49 if (size_by_size != size_by_ptr) { 50 LOG(INFO) << "Found a bad sized obj of size " << size 51 << " at " << std::hex << reinterpret_cast<intptr_t>(obj_ptr) << std::dec 52 << " size_by_size=" << size_by_size << " size_by_ptr=" << size_by_ptr; 53 } 54 DCHECK_EQ(size_by_size, size_by_ptr); 55 } 56 if (usable_size != nullptr) { 57 *usable_size = size_by_size; 58 } 59 return size_by_size; 60 } 61 62 template<bool kThreadSafe> 63 inline mirror::Object* RosAllocSpace::AllocCommon(Thread* self, size_t num_bytes, 64 size_t* bytes_allocated, size_t* usable_size, 65 size_t* bytes_tl_bulk_allocated) { 66 size_t rosalloc_bytes_allocated = 0; 67 size_t rosalloc_usable_size = 0; 68 size_t rosalloc_bytes_tl_bulk_allocated = 0; 69 if (!kThreadSafe) { 70 Locks::mutator_lock_->AssertExclusiveHeld(self); 71 } 72 mirror::Object* result = reinterpret_cast<mirror::Object*>( 73 rosalloc_->Alloc<kThreadSafe>(self, num_bytes, &rosalloc_bytes_allocated, 74 &rosalloc_usable_size, 75 &rosalloc_bytes_tl_bulk_allocated)); 76 if (LIKELY(result != nullptr)) { 77 if (kDebugSpaces) { 78 CHECK(Contains(result)) << "Allocation (" << reinterpret_cast<void*>(result) 79 << ") not in bounds of allocation space " << *this; 80 } 81 DCHECK(bytes_allocated != nullptr); 82 *bytes_allocated = rosalloc_bytes_allocated; 83 DCHECK_EQ(rosalloc_usable_size, rosalloc_->UsableSize(result)); 84 if (usable_size != nullptr) { 85 *usable_size = rosalloc_usable_size; 86 } 87 DCHECK(bytes_tl_bulk_allocated != nullptr); 88 *bytes_tl_bulk_allocated = rosalloc_bytes_tl_bulk_allocated; 89 } 90 return result; 91 } 92 93 inline bool RosAllocSpace::CanAllocThreadLocal(Thread* self, size_t num_bytes) { 94 return rosalloc_->CanAllocFromThreadLocalRun(self, num_bytes); 95 } 96 97 inline mirror::Object* RosAllocSpace::AllocThreadLocal(Thread* self, size_t num_bytes, 98 size_t* bytes_allocated) { 99 DCHECK(bytes_allocated != nullptr); 100 return reinterpret_cast<mirror::Object*>( 101 rosalloc_->AllocFromThreadLocalRun(self, num_bytes, bytes_allocated)); 102 } 103 104 inline size_t RosAllocSpace::MaxBytesBulkAllocatedForNonvirtual(size_t num_bytes) { 105 return rosalloc_->MaxBytesBulkAllocatedFor(num_bytes); 106 } 107 108 } // namespace space 109 } // namespace gc 110 } // namespace art 111 112 #endif // ART_RUNTIME_GC_SPACE_ROSALLOC_SPACE_INL_H_ 113