1 /* 2 * Copyright (C) 2012 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_VERIFIER_DEX_GC_MAP_H_ 18 #define ART_RUNTIME_VERIFIER_DEX_GC_MAP_H_ 19 20 #include <stdint.h> 21 22 #include "base/logging.h" 23 #include "base/macros.h" 24 25 namespace art { 26 namespace verifier { 27 28 /* 29 * Format enumeration for RegisterMap data area. 30 */ 31 enum RegisterMapFormat { 32 kRegMapFormatUnknown = 0, 33 kRegMapFormatNone = 1, // Indicates no map data follows. 34 kRegMapFormatCompact8 = 2, // Compact layout, 8-bit addresses. 35 kRegMapFormatCompact16 = 3, // Compact layout, 16-bit addresses. 36 }; 37 38 // Lightweight wrapper for Dex PC to reference bit maps. 39 class DexPcToReferenceMap { 40 public: 41 explicit DexPcToReferenceMap(const uint8_t* data) : data_(data) { 42 CHECK(data_ != NULL); 43 } 44 45 // The total size of the reference bit map including header. 46 size_t RawSize() const { 47 return EntryWidth() * NumEntries() + 4u /* header */; 48 } 49 50 // The number of entries in the table 51 size_t NumEntries() const { 52 return GetData()[2] | (GetData()[3] << 8); 53 } 54 55 // Get the Dex PC at the given index 56 uint16_t GetDexPc(size_t index) const { 57 size_t entry_offset = index * EntryWidth(); 58 if (DexPcWidth() == 1) { 59 return Table()[entry_offset]; 60 } else { 61 return Table()[entry_offset] | (Table()[entry_offset + 1] << 8); 62 } 63 } 64 65 // Return address of bitmap encoding what are live references 66 const uint8_t* GetBitMap(size_t index) const { 67 size_t entry_offset = index * EntryWidth(); 68 return &Table()[entry_offset + DexPcWidth()]; 69 } 70 71 // Find the bitmap associated with the given dex pc 72 const uint8_t* FindBitMap(uint16_t dex_pc, bool error_if_not_present = true) const; 73 74 // The number of bytes used to encode registers 75 size_t RegWidth() const { 76 return GetData()[1] | ((GetData()[0] & ~kRegMapFormatMask) << kRegMapFormatShift); 77 } 78 79 private: 80 // Table of num_entries * (dex pc, bitmap) 81 const uint8_t* Table() const { 82 return GetData() + 4; 83 } 84 85 // The format of the table of the PCs for the table 86 RegisterMapFormat Format() const { 87 return static_cast<RegisterMapFormat>(GetData()[0] & kRegMapFormatMask); 88 } 89 90 // Number of bytes used to encode a dex pc 91 size_t DexPcWidth() const { 92 RegisterMapFormat format = Format(); 93 switch (format) { 94 case kRegMapFormatCompact8: 95 return 1; 96 case kRegMapFormatCompact16: 97 return 2; 98 default: 99 LOG(FATAL) << "Invalid format " << static_cast<int>(format); 100 return -1; 101 } 102 } 103 104 // The width of an entry in the table 105 size_t EntryWidth() const { 106 return DexPcWidth() + RegWidth(); 107 } 108 109 const uint8_t* GetData() const { 110 return data_; 111 } 112 113 static const int kRegMapFormatShift = 5; 114 static const uint8_t kRegMapFormatMask = 0x7; 115 116 const uint8_t* const data_; // The header and table data 117 }; 118 119 } // namespace verifier 120 } // namespace art 121 122 #endif // ART_RUNTIME_VERIFIER_DEX_GC_MAP_H_ 123