• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
DexPcToReferenceMap(const uint8_t * data,size_t data_length)41   DexPcToReferenceMap(const uint8_t* data, size_t data_length) : data_(data) {
42     CHECK(data_ != NULL);
43     // Check the size of the table agrees with the number of entries
44     size_t data_size = data_length - 4;
45     DCHECK_EQ(EntryWidth() * NumEntries(), data_size);
46   }
47 
48   // The number of entries in the table
NumEntries()49   size_t NumEntries() const {
50     return GetData()[2] | (GetData()[3] << 8);
51   }
52 
53   // Get the Dex PC at the given index
GetDexPc(size_t index)54   uint16_t GetDexPc(size_t index) const {
55     size_t entry_offset = index * EntryWidth();
56     if (DexPcWidth() == 1) {
57       return Table()[entry_offset];
58     } else {
59       return Table()[entry_offset] | (Table()[entry_offset + 1] << 8);
60     }
61   }
62 
63   // Return address of bitmap encoding what are live references
GetBitMap(size_t index)64   const uint8_t* GetBitMap(size_t index) const {
65     size_t entry_offset = index * EntryWidth();
66     return &Table()[entry_offset + DexPcWidth()];
67   }
68 
69   // Find the bitmap associated with the given dex pc
70   const uint8_t* FindBitMap(uint16_t dex_pc, bool error_if_not_present = true) const;
71 
72   // The number of bytes used to encode registers
RegWidth()73   size_t RegWidth() const {
74     return GetData()[1] | ((GetData()[0] & ~kRegMapFormatMask) << kRegMapFormatShift);
75   }
76 
77  private:
78   // Table of num_entries * (dex pc, bitmap)
Table()79   const uint8_t* Table() const {
80     return GetData() + 4;
81   }
82 
83   // The format of the table of the PCs for the table
Format()84   RegisterMapFormat Format() const {
85     return static_cast<RegisterMapFormat>(GetData()[0] & kRegMapFormatMask);
86   }
87 
88   // Number of bytes used to encode a dex pc
DexPcWidth()89   size_t DexPcWidth() const {
90     RegisterMapFormat format = Format();
91     switch (format) {
92       case kRegMapFormatCompact8:
93         return 1;
94       case kRegMapFormatCompact16:
95         return 2;
96       default:
97         LOG(FATAL) << "Invalid format " << static_cast<int>(format);
98         return -1;
99     }
100   }
101 
102   // The width of an entry in the table
EntryWidth()103   size_t EntryWidth() const {
104     return DexPcWidth() + RegWidth();
105   }
106 
GetData()107   const uint8_t* GetData() const {
108     return data_;
109   }
110 
111   friend class MethodVerifier;
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