blob: d588cfd388e36b923561475b19d10a4e476d845f [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
Ian Rogers0c7abda2012-09-19 13:33:42 -070017#ifndef ART_SRC_VERIFIER_DEX_GC_MAP_H_
18#define ART_SRC_VERIFIER_DEX_GC_MAP_H_
Ian Rogers776ac1f2012-04-13 23:36:36 -070019
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
Ian Rogers46c6bb22012-09-18 13:47:36 -070037// Lightweight wrapper for Dex PC to reference bit maps.
38class DexPcToReferenceMap {
Ian Rogers776ac1f2012-04-13 23:36:36 -070039 public:
Ian Rogers0c7abda2012-09-19 13:33:42 -070040 DexPcToReferenceMap(const uint8_t* data, size_t data_length) : data_(data) {
Ian Rogers776ac1f2012-04-13 23:36:36 -070041 CHECK(data_ != NULL);
42 // Check the size of the table agrees with the number of entries
43 size_t data_size = data_length - 4;
44 DCHECK_EQ(EntryWidth() * NumEntries(), data_size);
45 }
46
47 // The number of entries in the table
48 size_t NumEntries() const {
49 return GetData()[2] | (GetData()[3] << 8);
50 }
51
Ian Rogers46c6bb22012-09-18 13:47:36 -070052 // Get the Dex PC at the given index
53 uint16_t GetDexPc(size_t index) const {
Ian Rogers776ac1f2012-04-13 23:36:36 -070054 size_t entry_offset = index * EntryWidth();
Ian Rogers0c7abda2012-09-19 13:33:42 -070055 if (DexPcWidth() == 1) {
Ian Rogers776ac1f2012-04-13 23:36:36 -070056 return Table()[entry_offset];
57 } else {
58 return Table()[entry_offset] | (Table()[entry_offset + 1] << 8);
59 }
60 }
61
62 // Return address of bitmap encoding what are live references
63 const uint8_t* GetBitMap(size_t index) const {
64 size_t entry_offset = index * EntryWidth();
Ian Rogers0c7abda2012-09-19 13:33:42 -070065 return &Table()[entry_offset + DexPcWidth()];
Ian Rogers776ac1f2012-04-13 23:36:36 -070066 }
67
68 // Find the bitmap associated with the given dex pc
69 const uint8_t* FindBitMap(uint16_t dex_pc, bool error_if_not_present = true) const;
70
71 // The number of bytes used to encode registers
72 size_t RegWidth() const {
73 return GetData()[1] | ((GetData()[0] & ~kRegMapFormatMask) << kRegMapFormatShift);
74 }
75
76 private:
77 // Table of num_entries * (dex pc, bitmap)
78 const uint8_t* Table() const {
79 return GetData() + 4;
80 }
81
82 // The format of the table of the PCs for the table
83 RegisterMapFormat Format() const {
84 return static_cast<RegisterMapFormat>(GetData()[0] & kRegMapFormatMask);
85 }
86
87 // Number of bytes used to encode a dex pc
Ian Rogers0c7abda2012-09-19 13:33:42 -070088 size_t DexPcWidth() const {
Ian Rogers776ac1f2012-04-13 23:36:36 -070089 RegisterMapFormat format = Format();
90 switch (format) {
91 case kRegMapFormatCompact8:
92 return 1;
93 case kRegMapFormatCompact16:
94 return 2;
95 default:
96 LOG(FATAL) << "Invalid format " << static_cast<int>(format);
97 return -1;
98 }
99 }
100
101 // The width of an entry in the table
102 size_t EntryWidth() const {
Ian Rogers0c7abda2012-09-19 13:33:42 -0700103 return DexPcWidth() + RegWidth();
Ian Rogers776ac1f2012-04-13 23:36:36 -0700104 }
105
106 const uint8_t* GetData() const {
107 return data_;
108 }
109
110 friend class MethodVerifier;
111
112 static const int kRegMapFormatShift = 5;
113 static const uint8_t kRegMapFormatMask = 0x7;
114
Ian Rogers0c7abda2012-09-19 13:33:42 -0700115 const uint8_t* const data_; // The header and table data
Ian Rogers776ac1f2012-04-13 23:36:36 -0700116};
117
118} // namespace verifier
119} // namespace art
120
Ian Rogers0c7abda2012-09-19 13:33:42 -0700121#endif // ART_SRC_VERIFIER_DEX_GC_MAP_H_