1 /* 2 * Copyright (C) 2014 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_COMPILER_GC_MAP_BUILDER_H_ 18 #define ART_COMPILER_GC_MAP_BUILDER_H_ 19 20 #include <vector> 21 22 #include "base/bit_utils.h" 23 #include "gc_map.h" 24 25 namespace art { 26 27 class GcMapBuilder { 28 public: 29 template <typename Alloc> GcMapBuilder(std::vector<uint8_t,Alloc> * table,size_t entries,uint32_t max_native_offset,size_t references_width)30 GcMapBuilder(std::vector<uint8_t, Alloc>* table, size_t entries, uint32_t max_native_offset, 31 size_t references_width) 32 : entries_(entries), references_width_(entries != 0u ? references_width : 0u), 33 native_offset_width_(entries != 0 && max_native_offset != 0 34 ? sizeof(max_native_offset) - CLZ(max_native_offset) / 8u 35 : 0u), 36 in_use_(entries) { 37 // Resize table and set up header. 38 table->resize((EntryWidth() * entries) + sizeof(uint32_t)); 39 table_ = table->data(); 40 CHECK_LT(native_offset_width_, 1U << 3); 41 (*table)[0] = native_offset_width_ & 7; 42 CHECK_LT(references_width_, 1U << 13); 43 (*table)[0] |= (references_width_ << 3) & 0xFF; 44 (*table)[1] = (references_width_ >> 5) & 0xFF; 45 CHECK_LT(entries, 1U << 16); 46 (*table)[2] = entries & 0xFF; 47 (*table)[3] = (entries >> 8) & 0xFF; 48 } 49 AddEntry(uint32_t native_offset,const uint8_t * references)50 void AddEntry(uint32_t native_offset, const uint8_t* references) { 51 size_t table_index = TableIndex(native_offset); 52 while (in_use_[table_index]) { 53 table_index = (table_index + 1) % entries_; 54 } 55 in_use_[table_index] = true; 56 SetCodeOffset(table_index, native_offset); 57 DCHECK_EQ(native_offset, GetCodeOffset(table_index)); 58 SetReferences(table_index, references); 59 } 60 61 private: TableIndex(uint32_t native_offset)62 size_t TableIndex(uint32_t native_offset) { 63 return NativePcOffsetToReferenceMap::Hash(native_offset) % entries_; 64 } 65 GetCodeOffset(size_t table_index)66 uint32_t GetCodeOffset(size_t table_index) { 67 uint32_t native_offset = 0; 68 size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t); 69 for (size_t i = 0; i < native_offset_width_; i++) { 70 native_offset |= table_[table_offset + i] << (i * 8); 71 } 72 return native_offset; 73 } 74 SetCodeOffset(size_t table_index,uint32_t native_offset)75 void SetCodeOffset(size_t table_index, uint32_t native_offset) { 76 size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t); 77 for (size_t i = 0; i < native_offset_width_; i++) { 78 table_[table_offset + i] = (native_offset >> (i * 8)) & 0xFF; 79 } 80 } 81 SetReferences(size_t table_index,const uint8_t * references)82 void SetReferences(size_t table_index, const uint8_t* references) { 83 size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t); 84 memcpy(&table_[table_offset + native_offset_width_], references, references_width_); 85 } 86 EntryWidth()87 size_t EntryWidth() const { 88 return native_offset_width_ + references_width_; 89 } 90 91 // Number of entries in the table. 92 const size_t entries_; 93 // Number of bytes used to encode the reference bitmap. 94 const size_t references_width_; 95 // Number of bytes used to encode a native offset. 96 const size_t native_offset_width_; 97 // Entries that are in use. 98 std::vector<bool> in_use_; 99 // The table we're building. 100 uint8_t* table_; 101 }; 102 103 } // namespace art 104 105 #endif // ART_COMPILER_GC_MAP_BUILDER_H_ 106