blob: 2566f052d7cd94195535d7b9601b8a5435cf821f [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
Shih-wei Liao39723d32011-10-24 02:20:31 -070013#define IS_IN_REF_BITMAP(method, ref_bitmap, reg) \
Shih-wei Liao63433ba2011-10-15 18:40:39 -070014 ( ((reg) < (method)->NumRegisters()) && \
Shih-wei Liao39723d32011-10-24 02:20:31 -070015 (( *((ref_bitmap) + (reg)/8) >> ((reg) % 8) ) & 0x01) )
Shih-wei Liao63433ba2011-10-15 18:40:39 -070016
Shih-wei Liao39723d32011-10-24 02:20:31 -070017#define CHECK_REGS_CONTAIN_REFS(...) \
18 do { \
Shih-wei Liao63433ba2011-10-15 18:40:39 -070019 int t[] = {__VA_ARGS__}; \
20 int t_size = sizeof(t) / sizeof(*t); \
21 for (int i = 0; i < t_size; ++i) \
Shih-wei Liao39723d32011-10-24 02:20:31 -070022 CHECK(IS_IN_REF_BITMAP(m, ref_bitmap, t[i])) \
23 << "Error: Reg @ " << i << "-th argument is not in GC map"; \
Shih-wei Liao63433ba2011-10-15 18:40:39 -070024 } while(false)
25
Shih-wei Liao63433ba2011-10-15 18:40:39 -070026struct ReferenceMap2Visitor : public Thread::StackVisitor {
27 ReferenceMap2Visitor() {
28 }
29
30 void VisitFrame(const Frame& frame, uintptr_t pc) {
31 Method* m = frame.GetMethod();
Brian Carlstrom40381fb2011-10-19 14:13:40 -070032 if (!m || m->IsNative()) {
Shih-wei Liao63433ba2011-10-15 18:40:39 -070033 return;
34 }
35 LOG(INFO) << "At " << PrettyMethod(m, false);
36
Ian Rogersd81871c2011-10-03 13:57:23 -070037 verifier::PcToReferenceMap map(m);
Shih-wei Liao63433ba2011-10-15 18:40:39 -070038
39 if (!pc) {
40 // pc == NULL: m is either a native method or a phony method
41 return;
42 }
43 if (m->IsCalleeSaveMethod()) {
44 LOG(WARNING) << "no PC for " << PrettyMethod(m);
45 return;
46 }
47
Shih-wei Liao39723d32011-10-24 02:20:31 -070048 const uint8_t* ref_bitmap = NULL;
Shih-wei Liao63433ba2011-10-15 18:40:39 -070049 std::string m_name = m->GetName()->ToModifiedUtf8();
50
51 // Given the method name and the number of times the method has been called,
52 // we know the Dex registers with live reference values. Assert that what we
53 // find is what is expected.
54 if (m_name.compare("f") == 0) {
Shih-wei Liao39723d32011-10-24 02:20:31 -070055 ref_bitmap = map.FindBitMap(0x03U);
56 CHECK(ref_bitmap);
57 CHECK_REGS_CONTAIN_REFS(8); // v8: this
Shih-wei Liao63433ba2011-10-15 18:40:39 -070058
Shih-wei Liao39723d32011-10-24 02:20:31 -070059 ref_bitmap = map.FindBitMap(0x06U);
60 CHECK(ref_bitmap);
61 CHECK_REGS_CONTAIN_REFS(8, 1); // v7: this, v2: x
Shih-wei Liao63433ba2011-10-15 18:40:39 -070062
Shih-wei Liao39723d32011-10-24 02:20:31 -070063 ref_bitmap = map.FindBitMap(0x08U);
64 CHECK(ref_bitmap);
65 CHECK_REGS_CONTAIN_REFS(8, 3, 1); // v7: this, v2: x, v0: y
Shih-wei Liao63433ba2011-10-15 18:40:39 -070066
Shih-wei Liao39723d32011-10-24 02:20:31 -070067 ref_bitmap = map.FindBitMap(0x0cU);
68 CHECK(ref_bitmap);
69 CHECK_REGS_CONTAIN_REFS(8, 3, 1); // v7: this, v2: x, v0: y
Shih-wei Liao63433ba2011-10-15 18:40:39 -070070
Shih-wei Liao39723d32011-10-24 02:20:31 -070071 ref_bitmap = map.FindBitMap(0x0eU);
72 CHECK(ref_bitmap);
73 CHECK_REGS_CONTAIN_REFS(8, 3, 1); // v7: this, v2: x, v0: y
Shih-wei Liao63433ba2011-10-15 18:40:39 -070074
Shih-wei Liao39723d32011-10-24 02:20:31 -070075 ref_bitmap = map.FindBitMap(0x10U);
76 CHECK(ref_bitmap);
77 CHECK_REGS_CONTAIN_REFS(8, 3, 1); // v7: this, v2: x, v0: y
Shih-wei Liao63433ba2011-10-15 18:40:39 -070078
Shih-wei Liao39723d32011-10-24 02:20:31 -070079 ref_bitmap = map.FindBitMap(0x13U);
80 CHECK(ref_bitmap);
81 CHECK_REGS_CONTAIN_REFS(8, 3, 2, 1); // v7: this, v2: x, v0: y
Shih-wei Liao63433ba2011-10-15 18:40:39 -070082
Shih-wei Liao39723d32011-10-24 02:20:31 -070083 ref_bitmap = map.FindBitMap(0x15U);
84 CHECK(ref_bitmap);
85 // FIXME: v1?
86 CHECK_REGS_CONTAIN_REFS(8, 2, 1, 0); // v7: this, v2: x, v0: y, v1: y or ex.
Shih-wei Liao63433ba2011-10-15 18:40:39 -070087
Shih-wei Liao39723d32011-10-24 02:20:31 -070088 ref_bitmap = map.FindBitMap(0x18U);
89 CHECK(ref_bitmap);
90 CHECK_REGS_CONTAIN_REFS(8, 2, 1, 0); // v7: this, v2: x, v0: y
Shih-wei Liao63433ba2011-10-15 18:40:39 -070091
Shih-wei Liao39723d32011-10-24 02:20:31 -070092 ref_bitmap = map.FindBitMap(0x1aU);
93 CHECK(ref_bitmap);
94 CHECK_REGS_CONTAIN_REFS(8, 5, 2, 1, 0); // v7: this, v2: x, v0: y, v3: x[1]
Shih-wei Liao63433ba2011-10-15 18:40:39 -070095
Shih-wei Liao39723d32011-10-24 02:20:31 -070096 ref_bitmap = map.FindBitMap(0x1dU);
97 CHECK(ref_bitmap);
98 CHECK_REGS_CONTAIN_REFS(8, 5, 2, 1, 0); // v7: this, v2: x, v0: y, v3: x[1]
Shih-wei Liao63433ba2011-10-15 18:40:39 -070099
Shih-wei Liao39723d32011-10-24 02:20:31 -0700100 ref_bitmap = map.FindBitMap(0x1fU);
101 CHECK(ref_bitmap);
102 CHECK_REGS_CONTAIN_REFS(8, 2, 1, 0); // v7: this, v2: x, v0: y
Shih-wei Liao63433ba2011-10-15 18:40:39 -0700103
Shih-wei Liao39723d32011-10-24 02:20:31 -0700104 ref_bitmap = map.FindBitMap(0x21U);
105 CHECK(ref_bitmap);
106 CHECK_REGS_CONTAIN_REFS(8, 2, 1, 0); // v7: this, v2: x, v0: y
Shih-wei Liao63433ba2011-10-15 18:40:39 -0700107
Shih-wei Liao39723d32011-10-24 02:20:31 -0700108 ref_bitmap = map.FindBitMap(0x25U);
109 CHECK(ref_bitmap);
110 CHECK_REGS_CONTAIN_REFS(8, 3, 2, 1, 0); // v7: this, v2: x, v0: y
Shih-wei Liao63433ba2011-10-15 18:40:39 -0700111
Shih-wei Liao39723d32011-10-24 02:20:31 -0700112 ref_bitmap = map.FindBitMap(0x27U);
113 CHECK(ref_bitmap);
114 CHECK_REGS_CONTAIN_REFS(8, 4, 2, 1); // v7: this, v2: x, v0: ex, v1: y
Shih-wei Liao63433ba2011-10-15 18:40:39 -0700115
Shih-wei Liao39723d32011-10-24 02:20:31 -0700116 ref_bitmap = map.FindBitMap(0x29U);
117 CHECK(ref_bitmap);
118 CHECK_REGS_CONTAIN_REFS(8, 4, 2, 1); // v7: this, v2: x, v0: ex, v1: y
Shih-wei Liao63433ba2011-10-15 18:40:39 -0700119
Shih-wei Liao39723d32011-10-24 02:20:31 -0700120 ref_bitmap = map.FindBitMap(0x2cU);
121 CHECK(ref_bitmap);
122 CHECK_REGS_CONTAIN_REFS(8, 4, 2, 1); // v7: this, v2: x, v0: ex, v1: y
123
124 ref_bitmap = map.FindBitMap(0x2fU);
125 CHECK(ref_bitmap);
126 CHECK_REGS_CONTAIN_REFS(8, 4, 3, 2, 1); // v7: this, v2: x, v0: ex, v1: y, v6: ex
127
128 ref_bitmap = map.FindBitMap(0x32U);
129 CHECK(ref_bitmap);
130 CHECK_REGS_CONTAIN_REFS(8, 3, 2, 1, 0); // v7: this, v2: x, v0: ex, v1: y
Shih-wei Liao63433ba2011-10-15 18:40:39 -0700131 }
132
133 }
134};
135
136extern "C"
137JNIEXPORT jint JNICALL Java_ReferenceMap_refmap(JNIEnv* env, jobject thisObj, jint count) {
138 // Visitor
139 ReferenceMap2Visitor mapper;
140 Thread::Current()->WalkStack(&mapper);
141
142 return count + 1;
143}
144
145}