blob: c19ccf97a41cb7d9080c971fef5e63c4168ffbbc [file] [log] [blame]
Shih-wei Liao63433ba2011-10-15 18:40:39 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#include <stdio.h>
4
5#include "UniquePtr.h"
6#include "class_linker.h"
7#include "dex_verifier.h"
8#include "object.h"
9#include "jni.h"
10
11namespace art {
12
13#define REG(method, reg_vector, reg) \
14 ( ((reg) < (method)->NumRegisters()) && \
15 (( *((reg_vector) + (reg)/8) >> ((reg) % 8) ) & 0x01) )
16
17#define CHECK_REGS(...) do { \
18 int t[] = {__VA_ARGS__}; \
19 int t_size = sizeof(t) / sizeof(*t); \
20 for (int i = 0; i < t_size; ++i) \
21 EXPECT_TRUE(REG(m, reg_vector, t[i])) << "Error: Reg " << i << " is not in RegisterMap"; \
22 } while(false)
23
24// << "Error: Reg " << i << " is not in RegisterMap";
25
26struct ReferenceMap2Visitor : public Thread::StackVisitor {
27 ReferenceMap2Visitor() {
28 }
29
30 void VisitFrame(const Frame& frame, uintptr_t pc) {
31 Method* m = frame.GetMethod();
32 if (!m ||m->IsNative()) {
33 return;
34 }
35 LOG(INFO) << "At " << PrettyMethod(m, false);
36
37 art::DexVerifier::RegisterMap* map = new art::DexVerifier::RegisterMap(
38 m->GetRegisterMapHeader(),
39 m->GetRegisterMapData());
40
41 if (!pc) {
42 // pc == NULL: m is either a native method or a phony method
43 return;
44 }
45 if (m->IsCalleeSaveMethod()) {
46 LOG(WARNING) << "no PC for " << PrettyMethod(m);
47 return;
48 }
49
50 const uint8_t* reg_vector = NULL;
51 std::string m_name = m->GetName()->ToModifiedUtf8();
52
53 // Given the method name and the number of times the method has been called,
54 // we know the Dex registers with live reference values. Assert that what we
55 // find is what is expected.
56 if (m_name.compare("f") == 0) {
57 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x01U);
58 if (reg_vector) {
59 LOG(WARNING) << "Reg1: " << *reg_vector << *(reg_vector+1);
60 CHECK_REGS(7); //v7: this
61 }
62
63 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x02U);
64 if (reg_vector) {
65 LOG(WARNING) << "Reg2: " << *reg_vector << *(reg_vector+1);
66 CHECK_REGS(7); //v7: this
67 }
68
69 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x03U);
70 if (reg_vector) {
71 LOG(WARNING) << "Reg3: " << std::hex << reg_vector[0] << reg_vector[1];
72 CHECK_REGS(7); //v7: this
73 }
74
75 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x05U);
76 if (reg_vector) {
77 LOG(WARNING) << "Reg4: " << std::hex << *reg_vector << *(reg_vector+1);
78 CHECK_REGS(0, 7); //v0: x, v7: this
79 }
80
81 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x06U);
82 if (reg_vector) {
83 LOG(WARNING) << "Reg5: " << std::hex << reg_vector[0] << reg_vector[1];
84 CHECK_REGS(0, 7); //v0: x, v7: this
85 }
86
87 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x08U);
88 if (reg_vector) {
89 LOG(WARNING) << "Reg6: " << std::hex << *reg_vector << *(reg_vector+1);
90 CHECK_REGS(0, 2, 7); //v0: x, v2: y, v7: this
91 }
92
93 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x0bU);
94 if (reg_vector) {
95 LOG(WARNING) << "Reg7: " << std::hex << *reg_vector << *(reg_vector+1);
96 CHECK_REGS(0, 2, 7); //v0: x, v2: y, v7: this
97 }
98
99 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x0cU);
100 if (reg_vector) {
101 LOG(WARNING) << "Reg8: " << std::hex << *reg_vector << *(reg_vector+1);
102 CHECK_REGS(0, 2, 7); //v0: x, v2: y, v7: this
103 }
104
105 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x38U);
106 if (reg_vector) {
107 LOG(WARNING) << "Reg9: " << std::hex << *reg_vector << *(reg_vector+1);
108 CHECK_REGS(0, 2, 7); //v0: x, v2: y, v7: this
109 }
110
111 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x39U);
112 if (reg_vector) {
113 LOG(WARNING) << "Reg10: " << std::hex << *reg_vector << *(reg_vector+1);
114 CHECK_REGS(0, 2, 7, 1); //v0: x, v2: y, v7: this, v1: ex
115 }
116
117 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x3aU);
118 if (reg_vector) {
119 LOG(WARNING) << "Reg11: " << std::hex << *reg_vector << *(reg_vector+1);
120 CHECK_REGS(0, 2, 7, 1); //v0: x, v2: y, v7: this, v1: y
121 }
122
123 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x16U);
124 if (reg_vector) {
125 LOG(WARNING) << "Reg12: " << std::hex << *reg_vector << *(reg_vector+1);
126 CHECK_REGS(0, 7, 1); //v0: x, v7: this, v1: y
127 }
128
129 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x20U);
130 if (reg_vector) {
131 LOG(WARNING) << "Reg13: " << std::hex << *reg_vector << *(reg_vector+1);
132 CHECK_REGS(0, 7, 1); //v0: x, v7: this, v1: y
133 }
134
135 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x22U);
136 if (reg_vector) {
137 LOG(WARNING) << "Reg14: " << std::hex << *reg_vector << *(reg_vector+1);
138 CHECK_REGS(0, 7, 1); //v0: x, v7: this, v1: y
139 }
140
141 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x25U);
142 if (reg_vector) {
143 LOG(WARNING) << "Reg15: " << std::hex << *reg_vector << *(reg_vector+1);
144 CHECK_REGS(0); //v0: x, v7: this, v1: y
145 }
146
147 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x26U);
148 if (reg_vector) {
149 LOG(WARNING) << "Reg16: " << std::hex << *reg_vector << *(reg_vector+1);
150 CHECK_REGS(0, 7, 1); //v0: y, v7: this, v1: y
151 }
152
153 reg_vector = art::DexVerifier::RegisterMapGetLine(map, 0x14U);
154 if (reg_vector) {
155 LOG(WARNING) << "Reg17: " << std::hex << *reg_vector << *(reg_vector+1);
156 CHECK_REGS(0, 7); //v0: y, v7: this
157 }
158 }
159
160 }
161};
162
163extern "C"
164JNIEXPORT jint JNICALL Java_ReferenceMap_refmap(JNIEnv* env, jobject thisObj, jint count) {
165 // Visitor
166 ReferenceMap2Visitor mapper;
167 Thread::Current()->WalkStack(&mapper);
168
169 return count + 1;
170}
171
172}