blob: 07f63179340b6c426bd0de701483bfb7a653460b [file] [log] [blame]
Ian Rogers776ac1f2012-04-13 23:36:36 -07001/*
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_SRC_VERIFIER_GC_MAP_H_
18#define ART_SRC_VERIFIER_GC_MAP_H_
19
20#include "logging.h"
21#include "macros.h"
22#include <stdint.h>
23
24namespace art {
25namespace verifier {
26
27/*
28 * Format enumeration for RegisterMap data area.
29 */
30enum RegisterMapFormat {
31 kRegMapFormatUnknown = 0,
32 kRegMapFormatNone = 1, // Indicates no map data follows.
33 kRegMapFormatCompact8 = 2, // Compact layout, 8-bit addresses.
34 kRegMapFormatCompact16 = 3, // Compact layout, 16-bit addresses.
35};
36
37// Lightweight wrapper for PC to reference bit maps.
38class PcToReferenceMap {
39 public:
40 PcToReferenceMap(const uint8_t* data, size_t data_length) {
41 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
49 size_t NumEntries() const {
50 return GetData()[2] | (GetData()[3] << 8);
51 }
52
53 // Get the PC at the given index
54 uint16_t GetPC(size_t index) const {
55 size_t entry_offset = index * EntryWidth();
56 if (PcWidth() == 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
64 const uint8_t* GetBitMap(size_t index) const {
65 size_t entry_offset = index * EntryWidth();
66 return &Table()[entry_offset + PcWidth()];
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
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)
79 const uint8_t* Table() const {
80 return GetData() + 4;
81 }
82
83 // The format of the table of the PCs for the table
84 RegisterMapFormat Format() const {
85 return static_cast<RegisterMapFormat>(GetData()[0] & kRegMapFormatMask);
86 }
87
88 // Number of bytes used to encode a dex pc
89 size_t PcWidth() 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
103 size_t EntryWidth() const {
104 return PcWidth() + RegWidth();
105 }
106
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* data_; // The header and table data
117};
118
119} // namespace verifier
120} // namespace art
121
122#endif // ART_SRC_VERIFIER_GC_MAP_H_