Mercurial > hg > truffle
comparison src/cpu/x86/vm/disassembler_x86.cpp @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a61af66fc99e |
---|---|
1 /* | |
2 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_disassembler_x86.cpp.incl" | |
27 | |
28 #ifndef PRODUCT | |
29 | |
30 void* Disassembler::_library = NULL; | |
31 Disassembler::decode_func Disassembler::_decode_instruction = NULL; | |
32 | |
33 bool Disassembler::load_library() { | |
34 if (_library == NULL) { | |
35 char buf[1024]; | |
36 char ebuf[1024]; | |
37 sprintf(buf, "disassembler%s", os::dll_file_extension()); | |
38 _library = hpi::dll_load(buf, ebuf, sizeof ebuf); | |
39 if (_library != NULL) { | |
40 tty->print_cr("Loaded disassembler"); | |
41 _decode_instruction = CAST_TO_FN_PTR(Disassembler::decode_func, hpi::dll_lookup(_library, "decode_instruction")); | |
42 } | |
43 } | |
44 return (_library != NULL) && (_decode_instruction != NULL); | |
45 } | |
46 | |
47 class x86_env : public DisassemblerEnv { | |
48 private: | |
49 nmethod* code; | |
50 outputStream* output; | |
51 public: | |
52 x86_env(nmethod* rcode, outputStream* routput) { | |
53 code = rcode; | |
54 output = routput; | |
55 } | |
56 void print_label(intptr_t value); | |
57 void print_raw(char* str) { output->print_raw(str); } | |
58 void print(char* format, ...); | |
59 char* string_for_offset(intptr_t value); | |
60 char* string_for_constant(unsigned char* pc, intptr_t value, int is_decimal); | |
61 }; | |
62 | |
63 | |
64 void x86_env::print_label(intptr_t value) { | |
65 if (!Universe::is_fully_initialized()) { | |
66 output->print(INTPTR_FORMAT, value); | |
67 return; | |
68 } | |
69 address adr = (address) value; | |
70 if (StubRoutines::contains(adr)) { | |
71 StubCodeDesc* desc = StubCodeDesc::desc_for(adr); | |
72 const char * desc_name = "unknown stub"; | |
73 if (desc != NULL) { | |
74 desc_name = desc->name(); | |
75 } | |
76 output->print("Stub::%s", desc_name); | |
77 if (WizardMode) output->print(" " INTPTR_FORMAT, value); | |
78 } else { | |
79 output->print(INTPTR_FORMAT, value); | |
80 } | |
81 } | |
82 | |
83 void x86_env::print(char* format, ...) { | |
84 va_list ap; | |
85 va_start(ap, format); | |
86 output->vprint(format, ap); | |
87 va_end(ap); | |
88 } | |
89 | |
90 char* x86_env::string_for_offset(intptr_t value) { | |
91 stringStream st; | |
92 if (!Universe::is_fully_initialized()) { | |
93 st.print(INTX_FORMAT, value); | |
94 return st.as_string(); | |
95 } | |
96 BarrierSet* bs = Universe::heap()->barrier_set(); | |
97 BarrierSet::Name bsn = bs->kind(); | |
98 if (bs->kind() == BarrierSet::CardTableModRef && | |
99 (jbyte*) value == ((CardTableModRefBS*)(bs))->byte_map_base) { | |
100 st.print("word_map_base"); | |
101 } else { | |
102 st.print(INTX_FORMAT, value); | |
103 } | |
104 return st.as_string(); | |
105 } | |
106 | |
107 char* x86_env::string_for_constant(unsigned char* pc, intptr_t value, int is_decimal) { | |
108 stringStream st; | |
109 oop obj = NULL; | |
110 if (code && ((obj = code->embeddedOop_at(pc)) != NULL)) { | |
111 obj->print_value_on(&st); | |
112 } else { | |
113 if (is_decimal == 1) { | |
114 st.print(INTX_FORMAT, value); | |
115 } else { | |
116 st.print(INTPTR_FORMAT, value); | |
117 } | |
118 } | |
119 return st.as_string(); | |
120 } | |
121 | |
122 | |
123 | |
124 address Disassembler::decode_instruction(address start, DisassemblerEnv* env) { | |
125 return ((decode_func) _decode_instruction)(start, env); | |
126 } | |
127 | |
128 | |
129 void Disassembler::decode(CodeBlob* cb, outputStream* st) { | |
130 st = st ? st : tty; | |
131 st->print_cr("Decoding CodeBlob " INTPTR_FORMAT, cb); | |
132 decode(cb->instructions_begin(), cb->instructions_end(), st); | |
133 } | |
134 | |
135 | |
136 void Disassembler::decode(u_char* begin, u_char* end, outputStream* st) { | |
137 st = st ? st : tty; | |
138 | |
139 const int show_bytes = false; // for disassembler debugging | |
140 | |
141 if (!load_library()) { | |
142 st->print_cr("Could not load disassembler"); | |
143 return; | |
144 } | |
145 | |
146 x86_env env(NULL, st); | |
147 unsigned char* p = (unsigned char*) begin; | |
148 CodeBlob* cb = CodeCache::find_blob_unsafe(begin); | |
149 while (p < (unsigned char*) end) { | |
150 if (cb != NULL) { | |
151 cb->print_block_comment(st, (intptr_t)(p - cb->instructions_begin())); | |
152 } | |
153 | |
154 unsigned char* p0 = p; | |
155 st->print(" " INTPTR_FORMAT ": ", p); | |
156 p = decode_instruction(p, &env); | |
157 if (show_bytes) { | |
158 st->print("\t\t\t"); | |
159 while (p0 < p) st->print("%x ", *p0++); | |
160 } | |
161 st->cr(); | |
162 } | |
163 } | |
164 | |
165 | |
166 void Disassembler::decode(nmethod* nm, outputStream* st) { | |
167 st = st ? st : tty; | |
168 | |
169 st->print_cr("Decoding compiled method " INTPTR_FORMAT ":", nm); | |
170 st->print("Code:"); | |
171 st->cr(); | |
172 | |
173 if (!load_library()) { | |
174 st->print_cr("Could not load disassembler"); | |
175 return; | |
176 } | |
177 x86_env env(nm, st); | |
178 unsigned char* p = nm->instructions_begin(); | |
179 unsigned char* end = nm->instructions_end(); | |
180 while (p < end) { | |
181 if (p == nm->entry_point()) st->print_cr("[Entry Point]"); | |
182 if (p == nm->verified_entry_point()) st->print_cr("[Verified Entry Point]"); | |
183 if (p == nm->exception_begin()) st->print_cr("[Exception Handler]"); | |
184 if (p == nm->stub_begin()) st->print_cr("[Stub Code]"); | |
185 if (p == nm->consts_begin()) st->print_cr("[Constants]"); | |
186 nm->print_block_comment(st, (intptr_t)(p - nm->instructions_begin())); | |
187 unsigned char* p0 = p; | |
188 st->print(" " INTPTR_FORMAT ": ", p); | |
189 p = decode_instruction(p, &env); | |
190 nm->print_code_comment_on(st, 40, p0, p); | |
191 st->cr(); | |
192 // Output pc bucket ticks if we have any | |
193 address bucket_pc = FlatProfiler::bucket_start_for(p); | |
194 if (bucket_pc != NULL && bucket_pc > p0 && bucket_pc <= p) { | |
195 int bucket_count = FlatProfiler::bucket_count_for(bucket_pc); | |
196 tty->print_cr("[%d]", bucket_count); | |
197 } | |
198 } | |
199 } | |
200 | |
201 #endif // PRODUCT |