annotate src/share/vm/interpreter/bytecodeTracer.cpp @ 452:00b023ae2d78

6722113: CMS: Incorrect overflow handling during precleaning of Reference lists Summary: When we encounter marking stack overflow during precleaning of Reference lists, we were using the overflow list mechanism, which can cause problems on account of mutating the mark word of the header because of conflicts with mutator accesses and updates of that field. Instead we should use the usual mechanism for overflow handling in concurrent phases, namely dirtying of the card on which the overflowed object lies. Since precleaning effectively does a form of discovered list processing, albeit with discovery enabled, we needed to adjust some code to be correct in the face of interleaved processing and discovery. Reviewed-by: apetrusenko, jcoomes
author ysr
date Thu, 20 Nov 2008 12:27:41 -0800
parents a61af66fc99e
children be93aad57795
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "incls/_bytecodeTracer.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // Standard closure for BytecodeTracer: prints the current bytecode
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // and its attributes using bytecode-specific information.
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34 class BytecodePrinter: public BytecodeClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
35 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // %%% This field is not GC-ed, and so can contain garbage
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // between critical sections. Use only pointer-comparison
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // operations on the pointer, except within a critical section.
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // (Also, ensure that occasional false positives are benign.)
a61af66fc99e Initial load
duke
parents:
diff changeset
40 methodOop _current_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 bool _is_wide;
a61af66fc99e Initial load
duke
parents:
diff changeset
42 address _next_pc; // current decoding position
a61af66fc99e Initial load
duke
parents:
diff changeset
43
a61af66fc99e Initial load
duke
parents:
diff changeset
44 void align() { _next_pc = (address)round_to((intptr_t)_next_pc, sizeof(jint)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
45 int get_byte() { return *(jbyte*) _next_pc++; } // signed
a61af66fc99e Initial load
duke
parents:
diff changeset
46 short get_short() { short i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; }
a61af66fc99e Initial load
duke
parents:
diff changeset
47 int get_int() { int i=Bytes::get_Java_u4(_next_pc); _next_pc+=4; return i; }
a61af66fc99e Initial load
duke
parents:
diff changeset
48
a61af66fc99e Initial load
duke
parents:
diff changeset
49 int get_index() { return *(address)_next_pc++; }
a61af66fc99e Initial load
duke
parents:
diff changeset
50 int get_big_index() { int i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; }
a61af66fc99e Initial load
duke
parents:
diff changeset
51 int get_index_special() { return (is_wide()) ? get_big_index() : get_index(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
52 methodOop method() { return _current_method; }
a61af66fc99e Initial load
duke
parents:
diff changeset
53 bool is_wide() { return _is_wide; }
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55
a61af66fc99e Initial load
duke
parents:
diff changeset
56 void print_constant(int i, outputStream* st = tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
57 void print_attributes(Bytecodes::Code code, int bci, outputStream* st = tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
58 void bytecode_epilog(int bci, outputStream* st = tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
59
a61af66fc99e Initial load
duke
parents:
diff changeset
60 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
61 BytecodePrinter() {
a61af66fc99e Initial load
duke
parents:
diff changeset
62 _is_wide = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
63 }
a61af66fc99e Initial load
duke
parents:
diff changeset
64
a61af66fc99e Initial load
duke
parents:
diff changeset
65 // This method is called while executing the raw bytecodes, so none of
a61af66fc99e Initial load
duke
parents:
diff changeset
66 // the adjustments that BytecodeStream performs applies.
a61af66fc99e Initial load
duke
parents:
diff changeset
67 void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
69 if (_current_method != method()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // Note 1: This code will not work as expected with true MT/MP.
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // Need an explicit lock or a different solution.
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // It is possible for this block to be skipped, if a garbage
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // _current_method pointer happens to have the same bits as
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // the incoming method. We could lose a line of trace output.
a61af66fc99e Initial load
duke
parents:
diff changeset
75 // This is acceptable in a debug-only feature.
a61af66fc99e Initial load
duke
parents:
diff changeset
76 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
77 st->print("[%d] ", (int) Thread::current()->osthread()->thread_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
78 method->print_name(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
79 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
80 _current_method = method();
a61af66fc99e Initial load
duke
parents:
diff changeset
81 }
a61af66fc99e Initial load
duke
parents:
diff changeset
82 Bytecodes::Code code;
a61af66fc99e Initial load
duke
parents:
diff changeset
83 if (is_wide()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // bcp wasn't advanced if previous bytecode was _wide.
a61af66fc99e Initial load
duke
parents:
diff changeset
85 code = Bytecodes::code_at(bcp+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
86 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
87 code = Bytecodes::code_at(bcp);
a61af66fc99e Initial load
duke
parents:
diff changeset
88 }
a61af66fc99e Initial load
duke
parents:
diff changeset
89 int bci = bcp - method->code_base();
a61af66fc99e Initial load
duke
parents:
diff changeset
90 st->print("[%d] ", (int) Thread::current()->osthread()->thread_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
91 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
92 st->print("%8d %4d " INTPTR_FORMAT " " INTPTR_FORMAT " %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
93 BytecodeCounter::counter_value(), bci, tos, tos2, Bytecodes::name(code));
a61af66fc99e Initial load
duke
parents:
diff changeset
94 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 st->print("%8d %4d %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
96 BytecodeCounter::counter_value(), bci, Bytecodes::name(code));
a61af66fc99e Initial load
duke
parents:
diff changeset
97 }
a61af66fc99e Initial load
duke
parents:
diff changeset
98 _next_pc = is_wide() ? bcp+2 : bcp+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
99 print_attributes(code, bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // Set is_wide for the next one, since the caller of this doesn't skip
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // the next bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
102 _is_wide = (code == Bytecodes::_wide);
a61af66fc99e Initial load
duke
parents:
diff changeset
103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
104
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // Used for methodOop::print_codes(). The input bcp comes from
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // BytecodeStream, which will skip wide bytecodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
107 void trace(methodHandle method, address bcp, outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 _current_method = method();
a61af66fc99e Initial load
duke
parents:
diff changeset
109 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
110 Bytecodes::Code code = Bytecodes::code_at(bcp);
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // Set is_wide
a61af66fc99e Initial load
duke
parents:
diff changeset
112 _is_wide = (code == Bytecodes::_wide);
a61af66fc99e Initial load
duke
parents:
diff changeset
113 if (is_wide()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
114 code = Bytecodes::code_at(bcp+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
116 int bci = bcp - method->code_base();
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // Print bytecode index and name
a61af66fc99e Initial load
duke
parents:
diff changeset
118 if (is_wide()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
119 st->print("%d %s_w", bci, Bytecodes::name(code));
a61af66fc99e Initial load
duke
parents:
diff changeset
120 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
121 st->print("%d %s", bci, Bytecodes::name(code));
a61af66fc99e Initial load
duke
parents:
diff changeset
122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
123 _next_pc = is_wide() ? bcp+2 : bcp+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
124 print_attributes(code, bci, st);
a61af66fc99e Initial load
duke
parents:
diff changeset
125 bytecode_epilog(bci, st);
a61af66fc99e Initial load
duke
parents:
diff changeset
126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
127 };
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // Implementation of BytecodeTracer
a61af66fc99e Initial load
duke
parents:
diff changeset
131
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // %%% This set_closure thing seems overly general, given that
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // nobody uses it. Also, if BytecodePrinter weren't hidden
a61af66fc99e Initial load
duke
parents:
diff changeset
134 // then methodOop could use instances of it directly and it
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // would be easier to remove races on _current_method and bcp.
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // Since this is not product functionality, we can defer cleanup.
a61af66fc99e Initial load
duke
parents:
diff changeset
137
a61af66fc99e Initial load
duke
parents:
diff changeset
138 BytecodeClosure* BytecodeTracer::_closure = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
139
a61af66fc99e Initial load
duke
parents:
diff changeset
140 static BytecodePrinter std_closure;
a61af66fc99e Initial load
duke
parents:
diff changeset
141 BytecodeClosure* BytecodeTracer::std_closure() {
a61af66fc99e Initial load
duke
parents:
diff changeset
142 return &::std_closure;
a61af66fc99e Initial load
duke
parents:
diff changeset
143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145
a61af66fc99e Initial load
duke
parents:
diff changeset
146 void BytecodeTracer::trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
147 if (TraceBytecodes && BytecodeCounter::counter_value() >= TraceBytecodesAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
148 ttyLocker ttyl; // 5065316: keep the following output coherent
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // The ttyLocker also prevents races between two threads
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // trying to use the single instance of BytecodePrinter.
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // Using the ttyLocker prevents the system from coming to
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // a safepoint within this code, which is sensitive to methodOop
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // movement.
a61af66fc99e Initial load
duke
parents:
diff changeset
154 //
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // There used to be a leaf mutex here, but the ttyLocker will
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // work just as well, as long as the printing operations never block.
a61af66fc99e Initial load
duke
parents:
diff changeset
157 //
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // We put the locker on the static trace method, not the
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // virtual one, because the clients of this module go through
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // the static method.
a61af66fc99e Initial load
duke
parents:
diff changeset
161 _closure->trace(method, bcp, tos, tos2, st);
a61af66fc99e Initial load
duke
parents:
diff changeset
162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 void BytecodeTracer::trace(methodHandle method, address bcp, outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
166 ttyLocker ttyl; // 5065316: keep the following output coherent
a61af66fc99e Initial load
duke
parents:
diff changeset
167 _closure->trace(method, bcp, st);
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 void print_oop(oop value, outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 if (value == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 st->print_cr(" NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
173 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
174 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
175 Handle h_value (THREAD, value);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 symbolHandle sym = java_lang_String::as_symbol(h_value, CATCH);
a61af66fc99e Initial load
duke
parents:
diff changeset
177 if (sym->utf8_length() > 32) {
a61af66fc99e Initial load
duke
parents:
diff changeset
178 st->print_cr(" ....");
a61af66fc99e Initial load
duke
parents:
diff changeset
179 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
180 sym->print_on(st); st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183 }
a61af66fc99e Initial load
duke
parents:
diff changeset
184
a61af66fc99e Initial load
duke
parents:
diff changeset
185 void BytecodePrinter::print_constant(int i, outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
186 constantPoolOop constants = method()->constants();
a61af66fc99e Initial load
duke
parents:
diff changeset
187 constantTag tag = constants->tag_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 if (tag.is_int()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
190 st->print_cr(" " INT32_FORMAT, constants->int_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
191 } else if (tag.is_long()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
192 st->print_cr(" " INT64_FORMAT, constants->long_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
193 } else if (tag.is_float()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
194 st->print_cr(" %f", constants->float_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
195 } else if (tag.is_double()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 st->print_cr(" %f", constants->double_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
197 } else if (tag.is_string()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
198 oop string = constants->resolved_string_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
199 print_oop(string, st);
a61af66fc99e Initial load
duke
parents:
diff changeset
200 } else if (tag.is_unresolved_string()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
201 st->print_cr(" <unresolved string at %d>", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
202 } else if (tag.is_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
203 st->print_cr(" %s", constants->resolved_klass_at(i)->klass_part()->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
204 } else if (tag.is_unresolved_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
205 st->print_cr(" <unresolved klass at %d>", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
206 } else ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209
a61af66fc99e Initial load
duke
parents:
diff changeset
210 void BytecodePrinter::print_attributes(Bytecodes::Code code, int bci, outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // Show attributes of pre-rewritten codes
a61af66fc99e Initial load
duke
parents:
diff changeset
212 code = Bytecodes::java_code(code);
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // If the code doesn't have any fields there's nothing to print.
a61af66fc99e Initial load
duke
parents:
diff changeset
214 // note this is ==1 because the tableswitch and lookupswitch are
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // zero size (for some reason) and we want to print stuff out for them.
a61af66fc99e Initial load
duke
parents:
diff changeset
216 if (Bytecodes::length_for(code) == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
217 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
218 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221 switch(code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
222 // Java specific bytecodes only matter.
a61af66fc99e Initial load
duke
parents:
diff changeset
223 case Bytecodes::_bipush:
a61af66fc99e Initial load
duke
parents:
diff changeset
224 st->print_cr(" " INT32_FORMAT, get_byte());
a61af66fc99e Initial load
duke
parents:
diff changeset
225 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
226 case Bytecodes::_sipush:
a61af66fc99e Initial load
duke
parents:
diff changeset
227 st->print_cr(" " INT32_FORMAT, get_short());
a61af66fc99e Initial load
duke
parents:
diff changeset
228 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
229 case Bytecodes::_ldc:
a61af66fc99e Initial load
duke
parents:
diff changeset
230 print_constant(get_index(), st);
a61af66fc99e Initial load
duke
parents:
diff changeset
231 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 case Bytecodes::_ldc_w:
a61af66fc99e Initial load
duke
parents:
diff changeset
234 case Bytecodes::_ldc2_w:
a61af66fc99e Initial load
duke
parents:
diff changeset
235 print_constant(get_big_index(), st);
a61af66fc99e Initial load
duke
parents:
diff changeset
236 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
237
a61af66fc99e Initial load
duke
parents:
diff changeset
238 case Bytecodes::_iload:
a61af66fc99e Initial load
duke
parents:
diff changeset
239 case Bytecodes::_lload:
a61af66fc99e Initial load
duke
parents:
diff changeset
240 case Bytecodes::_fload:
a61af66fc99e Initial load
duke
parents:
diff changeset
241 case Bytecodes::_dload:
a61af66fc99e Initial load
duke
parents:
diff changeset
242 case Bytecodes::_aload:
a61af66fc99e Initial load
duke
parents:
diff changeset
243 case Bytecodes::_istore:
a61af66fc99e Initial load
duke
parents:
diff changeset
244 case Bytecodes::_lstore:
a61af66fc99e Initial load
duke
parents:
diff changeset
245 case Bytecodes::_fstore:
a61af66fc99e Initial load
duke
parents:
diff changeset
246 case Bytecodes::_dstore:
a61af66fc99e Initial load
duke
parents:
diff changeset
247 case Bytecodes::_astore:
a61af66fc99e Initial load
duke
parents:
diff changeset
248 st->print_cr(" #%d", get_index_special());
a61af66fc99e Initial load
duke
parents:
diff changeset
249 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
250
a61af66fc99e Initial load
duke
parents:
diff changeset
251 case Bytecodes::_iinc:
a61af66fc99e Initial load
duke
parents:
diff changeset
252 { int index = get_index_special();
a61af66fc99e Initial load
duke
parents:
diff changeset
253 jint offset = is_wide() ? get_short(): get_byte();
a61af66fc99e Initial load
duke
parents:
diff changeset
254 st->print_cr(" #%d " INT32_FORMAT, index, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
256 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
257
a61af66fc99e Initial load
duke
parents:
diff changeset
258 case Bytecodes::_newarray: {
a61af66fc99e Initial load
duke
parents:
diff changeset
259 BasicType atype = (BasicType)get_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
260 const char* str = type2name(atype);
a61af66fc99e Initial load
duke
parents:
diff changeset
261 if (str == NULL || atype == T_OBJECT || atype == T_ARRAY) {
a61af66fc99e Initial load
duke
parents:
diff changeset
262 assert(false, "Unidentified basic type");
a61af66fc99e Initial load
duke
parents:
diff changeset
263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
264 st->print_cr(" %s", str);
a61af66fc99e Initial load
duke
parents:
diff changeset
265 }
a61af66fc99e Initial load
duke
parents:
diff changeset
266 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
267 case Bytecodes::_anewarray: {
a61af66fc99e Initial load
duke
parents:
diff changeset
268 int klass_index = get_big_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
269 constantPoolOop constants = method()->constants();
a61af66fc99e Initial load
duke
parents:
diff changeset
270 symbolOop name = constants->klass_name_at(klass_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
271 st->print_cr(" %s ", name->as_C_string());
a61af66fc99e Initial load
duke
parents:
diff changeset
272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
273 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
274 case Bytecodes::_multianewarray: {
a61af66fc99e Initial load
duke
parents:
diff changeset
275 int klass_index = get_big_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
276 int nof_dims = get_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
277 constantPoolOop constants = method()->constants();
a61af66fc99e Initial load
duke
parents:
diff changeset
278 symbolOop name = constants->klass_name_at(klass_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
279 st->print_cr(" %s %d", name->as_C_string(), nof_dims);
a61af66fc99e Initial load
duke
parents:
diff changeset
280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
281 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
282
a61af66fc99e Initial load
duke
parents:
diff changeset
283 case Bytecodes::_ifeq:
a61af66fc99e Initial load
duke
parents:
diff changeset
284 case Bytecodes::_ifnull:
a61af66fc99e Initial load
duke
parents:
diff changeset
285 case Bytecodes::_iflt:
a61af66fc99e Initial load
duke
parents:
diff changeset
286 case Bytecodes::_ifle:
a61af66fc99e Initial load
duke
parents:
diff changeset
287 case Bytecodes::_ifne:
a61af66fc99e Initial load
duke
parents:
diff changeset
288 case Bytecodes::_ifnonnull:
a61af66fc99e Initial load
duke
parents:
diff changeset
289 case Bytecodes::_ifgt:
a61af66fc99e Initial load
duke
parents:
diff changeset
290 case Bytecodes::_ifge:
a61af66fc99e Initial load
duke
parents:
diff changeset
291 case Bytecodes::_if_icmpeq:
a61af66fc99e Initial load
duke
parents:
diff changeset
292 case Bytecodes::_if_icmpne:
a61af66fc99e Initial load
duke
parents:
diff changeset
293 case Bytecodes::_if_icmplt:
a61af66fc99e Initial load
duke
parents:
diff changeset
294 case Bytecodes::_if_icmpgt:
a61af66fc99e Initial load
duke
parents:
diff changeset
295 case Bytecodes::_if_icmple:
a61af66fc99e Initial load
duke
parents:
diff changeset
296 case Bytecodes::_if_icmpge:
a61af66fc99e Initial load
duke
parents:
diff changeset
297 case Bytecodes::_if_acmpeq:
a61af66fc99e Initial load
duke
parents:
diff changeset
298 case Bytecodes::_if_acmpne:
a61af66fc99e Initial load
duke
parents:
diff changeset
299 case Bytecodes::_goto:
a61af66fc99e Initial load
duke
parents:
diff changeset
300 case Bytecodes::_jsr:
a61af66fc99e Initial load
duke
parents:
diff changeset
301 st->print_cr(" %d", bci + get_short());
a61af66fc99e Initial load
duke
parents:
diff changeset
302 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
303
a61af66fc99e Initial load
duke
parents:
diff changeset
304 case Bytecodes::_goto_w:
a61af66fc99e Initial load
duke
parents:
diff changeset
305 case Bytecodes::_jsr_w:
a61af66fc99e Initial load
duke
parents:
diff changeset
306 st->print_cr(" %d", bci + get_int());
a61af66fc99e Initial load
duke
parents:
diff changeset
307 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
308
a61af66fc99e Initial load
duke
parents:
diff changeset
309 case Bytecodes::_ret: st->print_cr(" %d", get_index_special()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
310
a61af66fc99e Initial load
duke
parents:
diff changeset
311 case Bytecodes::_tableswitch:
a61af66fc99e Initial load
duke
parents:
diff changeset
312 { align();
a61af66fc99e Initial load
duke
parents:
diff changeset
313 int default_dest = bci + get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
314 int lo = get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
315 int hi = get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
316 int len = hi - lo + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
317 jint* dest = NEW_RESOURCE_ARRAY(jint, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
318 for (int i = 0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
319 dest[i] = bci + get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
321 st->print(" %d " INT32_FORMAT " " INT32_FORMAT " ",
a61af66fc99e Initial load
duke
parents:
diff changeset
322 default_dest, lo, hi);
a61af66fc99e Initial load
duke
parents:
diff changeset
323 int first = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
324 for (int ll = lo; ll <= hi; ll++, first = false) {
a61af66fc99e Initial load
duke
parents:
diff changeset
325 int idx = ll - lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
326 const char *format = first ? " %d:" INT32_FORMAT " (delta: %d)" :
a61af66fc99e Initial load
duke
parents:
diff changeset
327 ", %d:" INT32_FORMAT " (delta: %d)";
a61af66fc99e Initial load
duke
parents:
diff changeset
328 st->print(format, ll, dest[idx], dest[idx]-bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
329 }
a61af66fc99e Initial load
duke
parents:
diff changeset
330 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
332 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
333 case Bytecodes::_lookupswitch:
a61af66fc99e Initial load
duke
parents:
diff changeset
334 { align();
a61af66fc99e Initial load
duke
parents:
diff changeset
335 int default_dest = bci + get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
336 int len = get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
337 jint* key = NEW_RESOURCE_ARRAY(jint, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
338 jint* dest = NEW_RESOURCE_ARRAY(jint, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
339 for (int i = 0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
340 key [i] = get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
341 dest[i] = bci + get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
342 };
a61af66fc99e Initial load
duke
parents:
diff changeset
343 st->print(" %d %d ", default_dest, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
344 bool first = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
345 for (int ll = 0; ll < len; ll++, first = false) {
a61af66fc99e Initial load
duke
parents:
diff changeset
346 const char *format = first ? " " INT32_FORMAT ":" INT32_FORMAT :
a61af66fc99e Initial load
duke
parents:
diff changeset
347 ", " INT32_FORMAT ":" INT32_FORMAT ;
a61af66fc99e Initial load
duke
parents:
diff changeset
348 st->print(format, key[ll], dest[ll]);
a61af66fc99e Initial load
duke
parents:
diff changeset
349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
350 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
352 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
353
a61af66fc99e Initial load
duke
parents:
diff changeset
354 case Bytecodes::_putstatic:
a61af66fc99e Initial load
duke
parents:
diff changeset
355 case Bytecodes::_getstatic:
a61af66fc99e Initial load
duke
parents:
diff changeset
356 case Bytecodes::_putfield:
a61af66fc99e Initial load
duke
parents:
diff changeset
357 case Bytecodes::_getfield: {
a61af66fc99e Initial load
duke
parents:
diff changeset
358 int i = get_big_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
359 constantPoolOop constants = method()->constants();
a61af66fc99e Initial load
duke
parents:
diff changeset
360 symbolOop field = constants->name_ref_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
361 st->print_cr(" %d <%s>", i, field->as_C_string());
a61af66fc99e Initial load
duke
parents:
diff changeset
362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
363 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
364
a61af66fc99e Initial load
duke
parents:
diff changeset
365 case Bytecodes::_invokevirtual:
a61af66fc99e Initial load
duke
parents:
diff changeset
366 case Bytecodes::_invokespecial:
a61af66fc99e Initial load
duke
parents:
diff changeset
367 case Bytecodes::_invokestatic:
a61af66fc99e Initial load
duke
parents:
diff changeset
368 { int i = get_big_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
369 constantPoolOop constants = method()->constants();
a61af66fc99e Initial load
duke
parents:
diff changeset
370 symbolOop name = constants->name_ref_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
371 symbolOop signature = constants->signature_ref_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
372 st->print_cr(" %d <%s> <%s> ", i, name->as_C_string(), signature->as_C_string());
a61af66fc99e Initial load
duke
parents:
diff changeset
373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
374 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 case Bytecodes::_invokeinterface:
a61af66fc99e Initial load
duke
parents:
diff changeset
377 { int i = get_big_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
378 int n = get_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
379 get_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
380 constantPoolOop constants = method()->constants();
a61af66fc99e Initial load
duke
parents:
diff changeset
381 symbolOop name = constants->name_ref_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
382 symbolOop signature = constants->signature_ref_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
383 st->print_cr(" %d <%s> <%s> %d", i, name->as_C_string(), signature->as_C_string(), n);
a61af66fc99e Initial load
duke
parents:
diff changeset
384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
385 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
386
a61af66fc99e Initial load
duke
parents:
diff changeset
387 case Bytecodes::_new:
a61af66fc99e Initial load
duke
parents:
diff changeset
388 case Bytecodes::_checkcast:
a61af66fc99e Initial load
duke
parents:
diff changeset
389 case Bytecodes::_instanceof:
a61af66fc99e Initial load
duke
parents:
diff changeset
390 { int i = get_big_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
391 constantPoolOop constants = method()->constants();
a61af66fc99e Initial load
duke
parents:
diff changeset
392 symbolOop name = constants->klass_name_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
393 st->print_cr(" %d <%s>", i, name->as_C_string());
a61af66fc99e Initial load
duke
parents:
diff changeset
394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
395 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 case Bytecodes::_wide:
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // length is zero not one, but printed with no more info.
a61af66fc99e Initial load
duke
parents:
diff changeset
399 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
400
a61af66fc99e Initial load
duke
parents:
diff changeset
401 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
402 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
403 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
406
a61af66fc99e Initial load
duke
parents:
diff changeset
407
a61af66fc99e Initial load
duke
parents:
diff changeset
408 void BytecodePrinter::bytecode_epilog(int bci, outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
409 methodDataOop mdo = method()->method_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
410 if (mdo != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
411 ProfileData* data = mdo->bci_to_data(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
412 if (data != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
413 st->print(" %d", mdo->dp_to_di(data->dp()));
a61af66fc99e Initial load
duke
parents:
diff changeset
414 st->fill_to(6);
a61af66fc99e Initial load
duke
parents:
diff changeset
415 data->print_data_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
419 #endif // PRODUCT