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 "base/memory_tool.h" 21 #include "gc/allocator/rosalloc-inl.h" 22 #include "gc/space/memory_tool_settings.h" 23 #include "rosalloc_space.h" 24 #include "thread.h" 25 26 namespace art { 27 namespace gc { 28 namespace space { 29 30 template<bool kMaybeIsRunningOnMemoryTool> 31 inline size_t RosAllocSpace::AllocationSizeNonvirtual(mirror::Object* obj, size_t* usable_size) { 32 // obj is a valid object. Use its class in the header to get the size. 33 // Don't use verification since the object may be dead if we are sweeping. 34 size_t size = obj->SizeOf<kVerifyNone>(); 35 bool add_redzones = false; 36 if (kMaybeIsRunningOnMemoryTool) { 37 add_redzones = RUNNING_ON_MEMORY_TOOL ? kMemoryToolAddsRedzones : 0; 38 if (add_redzones) { 39 size += 2 * kDefaultMemoryToolRedZoneBytes; 40 } 41 } else { 42 DCHECK_EQ(RUNNING_ON_MEMORY_TOOL, 0U); 43 } 44 size_t size_by_size = rosalloc_->UsableSize(size); 45 if (kIsDebugBuild) { 46 // On memory tool, the red zone has an impact... 47 const uint8_t* obj_ptr = reinterpret_cast<const uint8_t*>(obj); 48 size_t size_by_ptr = rosalloc_->UsableSize( 49 obj_ptr - (add_redzones ? kDefaultMemoryToolRedZoneBytes : 0)); 50 if (size_by_size != size_by_ptr) { 51 LOG(INFO) << "Found a bad sized obj of size " << size 52 << " at " << std::hex << reinterpret_cast<intptr_t>(obj_ptr) << std::dec 53 << " size_by_size=" << size_by_size << " size_by_ptr=" << size_by_ptr; 54 } 55 DCHECK_EQ(size_by_size, size_by_ptr); 56 } 57 if (usable_size != nullptr) { 58 *usable_size = size_by_size; 59 } 60 return size_by_size; 61 } 62 63 template<bool kThreadSafe> 64 inline mirror::Object* RosAllocSpace::AllocCommon(Thread* self, size_t num_bytes, 65 size_t* bytes_allocated, size_t* usable_size, 66 size_t* bytes_tl_bulk_allocated) { 67 size_t rosalloc_bytes_allocated = 0; 68 size_t rosalloc_usable_size = 0; 69 size_t rosalloc_bytes_tl_bulk_allocated = 0; 70 if (!kThreadSafe) { 71 Locks::mutator_lock_->AssertExclusiveHeld(self); 72 } 73 mirror::Object* result = reinterpret_cast<mirror::Object*>( 74 rosalloc_->Alloc<kThreadSafe>(self, num_bytes, &rosalloc_bytes_allocated, 75 &rosalloc_usable_size, 76 &rosalloc_bytes_tl_bulk_allocated)); 77 if (LIKELY(result != nullptr)) { 78 if (kDebugSpaces) { 79 CHECK(Contains(result)) << "Allocation (" << reinterpret_cast<void*>(result) 80 << ") not in bounds of allocation space " << *this; 81 } 82 DCHECK(bytes_allocated != nullptr); 83 *bytes_allocated = rosalloc_bytes_allocated; 84 DCHECK_EQ(rosalloc_usable_size, rosalloc_->UsableSize(result)); 85 if (usable_size != nullptr) { 86 *usable_size = rosalloc_usable_size; 87 } 88 DCHECK(bytes_tl_bulk_allocated != nullptr); 89 *bytes_tl_bulk_allocated = rosalloc_bytes_tl_bulk_allocated; 90 } 91 return result; 92 } 93 94 inline bool RosAllocSpace::CanAllocThreadLocal(Thread* self, size_t num_bytes) { 95 return rosalloc_->CanAllocFromThreadLocalRun(self, num_bytes); 96 } 97 98 inline mirror::Object* RosAllocSpace::AllocThreadLocal(Thread* self, size_t num_bytes, 99 size_t* bytes_allocated) { 100 DCHECK(bytes_allocated != nullptr); 101 return reinterpret_cast<mirror::Object*>( 102 rosalloc_->AllocFromThreadLocalRun(self, num_bytes, bytes_allocated)); 103 } 104 105 inline size_t RosAllocSpace::MaxBytesBulkAllocatedForNonvirtual(size_t num_bytes) { 106 return rosalloc_->MaxBytesBulkAllocatedFor(num_bytes); 107 } 108 109 } // namespace space 110 } // namespace gc 111 } // namespace art 112 113 #endif // ART_RUNTIME_GC_SPACE_ROSALLOC_SPACE_INL_H_ 114