comparison src/share/vm/ci/ciStreams.cpp @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children be93aad57795
comparison
equal deleted inserted replaced
-1:000000000000 0:a61af66fc99e
1 /*
2 * Copyright 1999-2005 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/_ciStreams.cpp.incl"
27
28 // ciExceptionHandlerStream
29 //
30 // Walk over some selected set of a methods exception handlers.
31
32 // ------------------------------------------------------------------
33 // ciExceptionHandlerStream::count
34 //
35 // How many exception handlers are there in this stream?
36 //
37 // Implementation note: Compiler2 needs this functionality, so I had
38 int ciExceptionHandlerStream::count() {
39 int save_pos = _pos;
40 int save_end = _end;
41
42 int count = 0;
43
44 _pos = -1;
45 _end = _method->_handler_count;
46
47
48 next();
49 while (!is_done()) {
50 count++;
51 next();
52 }
53
54 _pos = save_pos;
55 _end = save_end;
56
57 return count;
58 }
59
60 int ciExceptionHandlerStream::count_remaining() {
61 int save_pos = _pos;
62 int save_end = _end;
63
64 int count = 0;
65
66 while (!is_done()) {
67 count++;
68 next();
69 }
70
71 _pos = save_pos;
72 _end = save_end;
73
74 return count;
75 }
76
77 // ciBytecodeStream
78 //
79 // The class is used to iterate over the bytecodes of a method.
80 // It hides the details of constant pool structure/access by
81 // providing accessors for constant pool items.
82
83 // ------------------------------------------------------------------
84 // ciBytecodeStream::wide
85 //
86 // Special handling for the wide bytcode
87 Bytecodes::Code ciBytecodeStream::wide()
88 {
89 // Get following bytecode; do not return wide
90 Bytecodes::Code bc = (Bytecodes::Code)_pc[1];
91 _pc += 2; // Skip both bytecodes
92 _pc += 2; // Skip index always
93 if( bc == Bytecodes::_iinc )
94 _pc += 2; // Skip optional constant
95 _was_wide = _pc; // Flag last wide bytecode found
96 return bc;
97 }
98
99 // ------------------------------------------------------------------
100 // ciBytecodeStream::table
101 //
102 // Special handling for switch ops
103 Bytecodes::Code ciBytecodeStream::table( Bytecodes::Code bc ) {
104 switch( bc ) { // Check for special bytecode handling
105
106 case Bytecodes::_lookupswitch:
107 _pc++; // Skip wide bytecode
108 _pc += (_start-_pc)&3; // Word align
109 _table_base = (jint*)_pc; // Capture for later usage
110 // table_base[0] is default far_dest
111 // Table has 2 lead elements (default, length), then pairs of u4 values.
112 // So load table length, and compute address at end of table
113 _pc = (address)&_table_base[2+ 2*Bytes::get_Java_u4((address)&_table_base[1])];
114 break;
115
116 case Bytecodes::_tableswitch: {
117 _pc++; // Skip wide bytecode
118 _pc += (_start-_pc)&3; // Word align
119 _table_base = (jint*)_pc; // Capture for later usage
120 // table_base[0] is default far_dest
121 int lo = Bytes::get_Java_u4((address)&_table_base[1]);// Low bound
122 int hi = Bytes::get_Java_u4((address)&_table_base[2]);// High bound
123 int len = hi - lo + 1; // Dense table size
124 _pc = (address)&_table_base[3+len]; // Skip past table
125 break;
126 }
127
128 default:
129 fatal("unhandled bytecode");
130 }
131 return bc;
132 }
133
134 // ------------------------------------------------------------------
135 // ciBytecodeStream::reset_to_bci
136 void ciBytecodeStream::reset_to_bci( int bci ) {
137 _bc_start=_was_wide=0;
138 _pc = _start+bci;
139 }
140
141 // ------------------------------------------------------------------
142 // ciBytecodeStream::force_bci
143 void ciBytecodeStream::force_bci(int bci) {
144 if (bci < 0) {
145 reset_to_bci(0);
146 _bc_start = _start + bci;
147 _bc = EOBC();
148 } else {
149 reset_to_bci(bci);
150 next();
151 }
152 }
153
154
155 // ------------------------------------------------------------------
156 // Constant pool access
157 // ------------------------------------------------------------------
158
159 // ------------------------------------------------------------------
160 // ciBytecodeStream::get_klass_index
161 //
162 // If this bytecodes references a klass, return the index of the
163 // referenced klass.
164 int ciBytecodeStream::get_klass_index() const {
165 switch(cur_bc()) {
166 case Bytecodes::_ldc:
167 return get_index();
168 case Bytecodes::_ldc_w:
169 case Bytecodes::_ldc2_w:
170 case Bytecodes::_checkcast:
171 case Bytecodes::_instanceof:
172 case Bytecodes::_anewarray:
173 case Bytecodes::_multianewarray:
174 case Bytecodes::_new:
175 case Bytecodes::_newarray:
176 return get_index_big();
177 default:
178 ShouldNotReachHere();
179 return 0;
180 }
181 }
182
183 // ------------------------------------------------------------------
184 // ciBytecodeStream::get_klass
185 //
186 // If this bytecode is a new, newarray, multianewarray, instanceof,
187 // or checkcast, get the referenced klass.
188 ciKlass* ciBytecodeStream::get_klass(bool& will_link) {
189 return CURRENT_ENV->get_klass_by_index(_holder, get_klass_index(),
190 will_link);
191 }
192
193 // ------------------------------------------------------------------
194 // ciBytecodeStream::get_constant_index
195 //
196 // If this bytecode is one of the ldc variants, get the index of the
197 // referenced constant.
198 int ciBytecodeStream::get_constant_index() const {
199 switch(cur_bc()) {
200 case Bytecodes::_ldc:
201 return get_index();
202 case Bytecodes::_ldc_w:
203 case Bytecodes::_ldc2_w:
204 return get_index_big();
205 default:
206 ShouldNotReachHere();
207 return 0;
208 }
209 }
210 // ------------------------------------------------------------------
211 // ciBytecodeStream::get_constant
212 //
213 // If this bytecode is one of the ldc variants, get the referenced
214 // constant.
215 ciConstant ciBytecodeStream::get_constant() {
216 return CURRENT_ENV->get_constant_by_index(_holder, get_constant_index());
217 }
218
219 // ------------------------------------------------------------------
220 bool ciBytecodeStream::is_unresolved_string() const {
221 return CURRENT_ENV->is_unresolved_string(_holder, get_constant_index());
222 }
223
224 // ------------------------------------------------------------------
225 bool ciBytecodeStream::is_unresolved_klass() const {
226 return CURRENT_ENV->is_unresolved_klass(_holder, get_klass_index());
227 }
228
229 // ------------------------------------------------------------------
230 // ciBytecodeStream::get_field_index
231 //
232 // If this is a field access bytecode, get the constant pool
233 // index of the referenced field.
234 int ciBytecodeStream::get_field_index() {
235 assert(cur_bc() == Bytecodes::_getfield ||
236 cur_bc() == Bytecodes::_putfield ||
237 cur_bc() == Bytecodes::_getstatic ||
238 cur_bc() == Bytecodes::_putstatic, "wrong bc");
239 return get_index_big();
240 }
241
242
243 // ------------------------------------------------------------------
244 // ciBytecodeStream::get_field
245 //
246 // If this bytecode is one of get_field, get_static, put_field,
247 // or put_static, get the referenced field.
248 ciField* ciBytecodeStream::get_field(bool& will_link) {
249 ciField* f = CURRENT_ENV->get_field_by_index(_holder, get_field_index());
250 will_link = f->will_link(_holder, _bc);
251 return f;
252 }
253
254
255 // ------------------------------------------------------------------
256 // ciBytecodeStream::get_declared_field_holder
257 //
258 // Get the declared holder of the currently referenced field.
259 //
260 // Usage note: the holder() of a ciField class returns the canonical
261 // holder of the field, rather than the holder declared in the
262 // bytecodes.
263 //
264 // There is no "will_link" result passed back. The user is responsible
265 // for checking linkability when retrieving the associated field.
266 ciInstanceKlass* ciBytecodeStream::get_declared_field_holder() {
267 int holder_index = get_field_holder_index();
268 bool ignore;
269 return CURRENT_ENV->get_klass_by_index(_holder, holder_index, ignore)
270 ->as_instance_klass();
271 }
272
273 // ------------------------------------------------------------------
274 // ciBytecodeStream::get_field_holder_index
275 //
276 // Get the constant pool index of the declared holder of the field
277 // referenced by the current bytecode. Used for generating
278 // deoptimization information.
279 int ciBytecodeStream::get_field_holder_index() {
280 VM_ENTRY_MARK;
281 constantPoolOop cpool = _holder->get_instanceKlass()->constants();
282 return cpool->klass_ref_index_at(get_field_index());
283 }
284
285 // ------------------------------------------------------------------
286 // ciBytecodeStream::get_field_signature_index
287 //
288 // Get the constant pool index of the signature of the field
289 // referenced by the current bytecode. Used for generating
290 // deoptimization information.
291 int ciBytecodeStream::get_field_signature_index() {
292 VM_ENTRY_MARK;
293 constantPoolOop cpool = _holder->get_instanceKlass()->constants();
294 int nt_index = cpool->name_and_type_ref_index_at(get_field_index());
295 return cpool->signature_ref_index_at(nt_index);
296 }
297
298 // ------------------------------------------------------------------
299 // ciBytecodeStream::get_method_index
300 //
301 // If this is a method invocation bytecode, get the constant pool
302 // index of the invoked method.
303 int ciBytecodeStream::get_method_index() {
304 switch (cur_bc()) {
305 case Bytecodes::_invokeinterface:
306 return Bytes::get_Java_u2(_pc-4);
307 case Bytecodes::_invokevirtual:
308 case Bytecodes::_invokespecial:
309 case Bytecodes::_invokestatic:
310 return get_index_big();
311 default:
312 ShouldNotReachHere();
313 return 0;
314 }
315 }
316
317 // ------------------------------------------------------------------
318 // ciBytecodeStream::get_method
319 //
320 // If this is a method invocation bytecode, get the invoked method.
321 ciMethod* ciBytecodeStream::get_method(bool& will_link) {
322 ciMethod* m = CURRENT_ENV->get_method_by_index(_holder, get_method_index(),cur_bc());
323 will_link = m->is_loaded();
324 return m;
325 }
326
327 // ------------------------------------------------------------------
328 // ciBytecodeStream::get_declared_method_holder
329 //
330 // Get the declared holder of the currently referenced method.
331 //
332 // Usage note: the holder() of a ciMethod class returns the canonical
333 // holder of the method, rather than the holder declared in the
334 // bytecodes.
335 //
336 // There is no "will_link" result passed back. The user is responsible
337 // for checking linkability when retrieving the associated method.
338 ciKlass* ciBytecodeStream::get_declared_method_holder() {
339 bool ignore;
340 return CURRENT_ENV->get_klass_by_index(_holder, get_method_holder_index(), ignore);
341 }
342
343 // ------------------------------------------------------------------
344 // ciBytecodeStream::get_method_holder_index
345 //
346 // Get the constant pool index of the declared holder of the method
347 // referenced by the current bytecode. Used for generating
348 // deoptimization information.
349 int ciBytecodeStream::get_method_holder_index() {
350 VM_ENTRY_MARK;
351 constantPoolOop cpool = _holder->get_instanceKlass()->constants();
352 return cpool->klass_ref_index_at(get_method_index());
353 }
354
355 // ------------------------------------------------------------------
356 // ciBytecodeStream::get_method_signature_index
357 //
358 // Get the constant pool index of the signature of the method
359 // referenced by the current bytecode. Used for generating
360 // deoptimization information.
361 int ciBytecodeStream::get_method_signature_index() {
362 VM_ENTRY_MARK;
363 constantPoolOop cpool = _holder->get_instanceKlass()->constants();
364 int method_index = get_method_index();
365 int name_and_type_index = cpool->name_and_type_ref_index_at(method_index);
366 return cpool->signature_ref_index_at(name_and_type_index);
367 }