1 /* 2 * Copyright (C) 2015 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_UTILS_DEX_CACHE_ARRAYS_LAYOUT_INL_H_ 18 #define ART_RUNTIME_UTILS_DEX_CACHE_ARRAYS_LAYOUT_INL_H_ 19 20 #include "dex_cache_arrays_layout.h" 21 22 #include "base/bit_utils.h" 23 #include "base/logging.h" 24 #include "gc_root.h" 25 #include "globals.h" 26 #include "primitive.h" 27 28 namespace art { 29 30 inline DexCacheArraysLayout::DexCacheArraysLayout(size_t pointer_size, 31 const DexFile::Header& header) 32 : pointer_size_(pointer_size), 33 /* types_offset_ is always 0u, so it's constexpr */ 34 methods_offset_( 35 RoundUp(types_offset_ + TypesSize(header.type_ids_size_), MethodsAlignment())), 36 strings_offset_( 37 RoundUp(methods_offset_ + MethodsSize(header.method_ids_size_), StringsAlignment())), 38 fields_offset_( 39 RoundUp(strings_offset_ + StringsSize(header.string_ids_size_), FieldsAlignment())), 40 size_( 41 RoundUp(fields_offset_ + FieldsSize(header.field_ids_size_), Alignment())) { 42 DCHECK(ValidPointerSize(pointer_size)) << pointer_size; 43 } 44 45 inline DexCacheArraysLayout::DexCacheArraysLayout(size_t pointer_size, const DexFile* dex_file) 46 : DexCacheArraysLayout(pointer_size, dex_file->GetHeader()) { 47 } 48 49 inline size_t DexCacheArraysLayout::Alignment() const { 50 // GcRoot<> alignment is 4, i.e. lower than or equal to the pointer alignment. 51 static_assert(alignof(GcRoot<mirror::Class>) == 4, "Expecting alignof(GcRoot<>) == 4"); 52 static_assert(alignof(GcRoot<mirror::String>) == 4, "Expecting alignof(GcRoot<>) == 4"); 53 DCHECK(pointer_size_ == 4u || pointer_size_ == 8u); 54 // Pointer alignment is the same as pointer size. 55 return pointer_size_; 56 } 57 58 inline size_t DexCacheArraysLayout::TypeOffset(uint32_t type_idx) const { 59 return types_offset_ + ElementOffset(sizeof(GcRoot<mirror::Class>), type_idx); 60 } 61 62 inline size_t DexCacheArraysLayout::TypesSize(size_t num_elements) const { 63 // App image patching relies on having enough room for a forwarding pointer in the types array. 64 // See FixupArtMethodArrayVisitor and ClassLinker::AddImageSpace. 65 return std::max(ArraySize(sizeof(GcRoot<mirror::Class>), num_elements), pointer_size_); 66 } 67 68 inline size_t DexCacheArraysLayout::TypesAlignment() const { 69 return alignof(GcRoot<mirror::Class>); 70 } 71 72 inline size_t DexCacheArraysLayout::MethodOffset(uint32_t method_idx) const { 73 return methods_offset_ + ElementOffset(pointer_size_, method_idx); 74 } 75 76 inline size_t DexCacheArraysLayout::MethodsSize(size_t num_elements) const { 77 // App image patching relies on having enough room for a forwarding pointer in the methods array. 78 return std::max(ArraySize(pointer_size_, num_elements), pointer_size_); 79 } 80 81 inline size_t DexCacheArraysLayout::MethodsAlignment() const { 82 return pointer_size_; 83 } 84 85 inline size_t DexCacheArraysLayout::StringOffset(uint32_t string_idx) const { 86 return strings_offset_ + ElementOffset(sizeof(GcRoot<mirror::String>), string_idx); 87 } 88 89 inline size_t DexCacheArraysLayout::StringsSize(size_t num_elements) const { 90 return ArraySize(sizeof(GcRoot<mirror::String>), num_elements); 91 } 92 93 inline size_t DexCacheArraysLayout::StringsAlignment() const { 94 return alignof(GcRoot<mirror::String>); 95 } 96 97 inline size_t DexCacheArraysLayout::FieldOffset(uint32_t field_idx) const { 98 return fields_offset_ + ElementOffset(pointer_size_, field_idx); 99 } 100 101 inline size_t DexCacheArraysLayout::FieldsSize(size_t num_elements) const { 102 return ArraySize(pointer_size_, num_elements); 103 } 104 105 inline size_t DexCacheArraysLayout::FieldsAlignment() const { 106 return pointer_size_; 107 } 108 109 inline size_t DexCacheArraysLayout::ElementOffset(size_t element_size, uint32_t idx) { 110 return element_size * idx; 111 } 112 113 inline size_t DexCacheArraysLayout::ArraySize(size_t element_size, uint32_t num_elements) { 114 return element_size * num_elements; 115 } 116 117 } // namespace art 118 119 #endif // ART_RUNTIME_UTILS_DEX_CACHE_ARRAYS_LAYOUT_INL_H_ 120