Tue, 05 Jan 2010 15:21:25 +0100
6893268: additional dynamic language related optimizations in C2
Summary: C2 needs some additional optimizations to be able to handle MethodHandle invokes and invokedynamic instructions at the best performance.
Reviewed-by: kvn, never
1 /*
2 * Copyright 1999-2009 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 */
25 #include "incls/_precompiled.incl"
26 #include "incls/_ciStreams.cpp.incl"
28 // ciExceptionHandlerStream
29 //
30 // Walk over some selected set of a methods exception handlers.
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;
42 int count = 0;
44 _pos = -1;
45 _end = _method->_handler_count;
48 next();
49 while (!is_done()) {
50 count++;
51 next();
52 }
54 _pos = save_pos;
55 _end = save_end;
57 return count;
58 }
60 int ciExceptionHandlerStream::count_remaining() {
61 int save_pos = _pos;
62 int save_end = _end;
64 int count = 0;
66 while (!is_done()) {
67 count++;
68 next();
69 }
71 _pos = save_pos;
72 _end = save_end;
74 return count;
75 }
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.
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 }
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
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;
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 }
128 default:
129 fatal("unhandled bytecode");
130 }
131 return bc;
132 }
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 }
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 }
155 // ------------------------------------------------------------------
156 // Constant pool access
157 // ------------------------------------------------------------------
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 }
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 VM_ENTRY_MARK;
190 constantPoolHandle cpool(_method->get_methodOop()->constants());
191 return CURRENT_ENV->get_klass_by_index(cpool, get_klass_index(), will_link, _holder);
192 }
194 // ------------------------------------------------------------------
195 // ciBytecodeStream::get_constant_index
196 //
197 // If this bytecode is one of the ldc variants, get the index of the
198 // referenced constant.
199 int ciBytecodeStream::get_constant_index() const {
200 switch(cur_bc()) {
201 case Bytecodes::_ldc:
202 return get_index();
203 case Bytecodes::_ldc_w:
204 case Bytecodes::_ldc2_w:
205 return get_index_big();
206 default:
207 ShouldNotReachHere();
208 return 0;
209 }
210 }
211 // ------------------------------------------------------------------
212 // ciBytecodeStream::get_constant
213 //
214 // If this bytecode is one of the ldc variants, get the referenced
215 // constant.
216 ciConstant ciBytecodeStream::get_constant() {
217 VM_ENTRY_MARK;
218 constantPoolHandle cpool(_method->get_methodOop()->constants());
219 return CURRENT_ENV->get_constant_by_index(cpool, get_constant_index(), _holder);
220 }
222 // ------------------------------------------------------------------
223 bool ciBytecodeStream::is_unresolved_string() const {
224 return CURRENT_ENV->is_unresolved_string(_holder, get_constant_index());
225 }
227 // ------------------------------------------------------------------
228 bool ciBytecodeStream::is_unresolved_klass() const {
229 return CURRENT_ENV->is_unresolved_klass(_holder, get_klass_index());
230 }
232 // ------------------------------------------------------------------
233 // ciBytecodeStream::get_field_index
234 //
235 // If this is a field access bytecode, get the constant pool
236 // index of the referenced field.
237 int ciBytecodeStream::get_field_index() {
238 assert(cur_bc() == Bytecodes::_getfield ||
239 cur_bc() == Bytecodes::_putfield ||
240 cur_bc() == Bytecodes::_getstatic ||
241 cur_bc() == Bytecodes::_putstatic, "wrong bc");
242 return get_index_big();
243 }
246 // ------------------------------------------------------------------
247 // ciBytecodeStream::get_field
248 //
249 // If this bytecode is one of get_field, get_static, put_field,
250 // or put_static, get the referenced field.
251 ciField* ciBytecodeStream::get_field(bool& will_link) {
252 ciField* f = CURRENT_ENV->get_field_by_index(_holder, get_field_index());
253 will_link = f->will_link(_holder, _bc);
254 return f;
255 }
258 // ------------------------------------------------------------------
259 // ciBytecodeStream::get_declared_field_holder
260 //
261 // Get the declared holder of the currently referenced field.
262 //
263 // Usage note: the holder() of a ciField class returns the canonical
264 // holder of the field, rather than the holder declared in the
265 // bytecodes.
266 //
267 // There is no "will_link" result passed back. The user is responsible
268 // for checking linkability when retrieving the associated field.
269 ciInstanceKlass* ciBytecodeStream::get_declared_field_holder() {
270 VM_ENTRY_MARK;
271 constantPoolHandle cpool(_method->get_methodOop()->constants());
272 int holder_index = get_field_holder_index();
273 bool ignore;
274 return CURRENT_ENV->get_klass_by_index(cpool, holder_index, ignore, _holder)
275 ->as_instance_klass();
276 }
278 // ------------------------------------------------------------------
279 // ciBytecodeStream::get_field_holder_index
280 //
281 // Get the constant pool index of the declared holder of the field
282 // referenced by the current bytecode. Used for generating
283 // deoptimization information.
284 int ciBytecodeStream::get_field_holder_index() {
285 GUARDED_VM_ENTRY(
286 constantPoolOop cpool = _holder->get_instanceKlass()->constants();
287 return cpool->klass_ref_index_at(get_field_index());
288 )
289 }
291 // ------------------------------------------------------------------
292 // ciBytecodeStream::get_field_signature_index
293 //
294 // Get the constant pool index of the signature of the field
295 // referenced by the current bytecode. Used for generating
296 // deoptimization information.
297 int ciBytecodeStream::get_field_signature_index() {
298 VM_ENTRY_MARK;
299 constantPoolOop cpool = _holder->get_instanceKlass()->constants();
300 int nt_index = cpool->name_and_type_ref_index_at(get_field_index());
301 return cpool->signature_ref_index_at(nt_index);
302 }
304 // ------------------------------------------------------------------
305 // ciBytecodeStream::get_method_index
306 //
307 // If this is a method invocation bytecode, get the constant pool
308 // index of the invoked method.
309 int ciBytecodeStream::get_method_index() {
310 #ifdef ASSERT
311 switch (cur_bc()) {
312 case Bytecodes::_invokeinterface:
313 case Bytecodes::_invokevirtual:
314 case Bytecodes::_invokespecial:
315 case Bytecodes::_invokestatic:
316 case Bytecodes::_invokedynamic:
317 break;
318 default:
319 ShouldNotReachHere();
320 }
321 #endif
322 return get_index_int();
323 }
325 // ------------------------------------------------------------------
326 // ciBytecodeStream::get_method
327 //
328 // If this is a method invocation bytecode, get the invoked method.
329 ciMethod* ciBytecodeStream::get_method(bool& will_link) {
330 VM_ENTRY_MARK;
331 constantPoolHandle cpool(_method->get_methodOop()->constants());
332 ciMethod* m = CURRENT_ENV->get_method_by_index(cpool, get_method_index(), cur_bc(), _holder);
333 will_link = m->is_loaded();
334 return m;
335 }
337 // ------------------------------------------------------------------
338 // ciBytecodeStream::get_declared_method_holder
339 //
340 // Get the declared holder of the currently referenced method.
341 //
342 // Usage note: the holder() of a ciMethod class returns the canonical
343 // holder of the method, rather than the holder declared in the
344 // bytecodes.
345 //
346 // There is no "will_link" result passed back. The user is responsible
347 // for checking linkability when retrieving the associated method.
348 ciKlass* ciBytecodeStream::get_declared_method_holder() {
349 VM_ENTRY_MARK;
350 constantPoolHandle cpool(_method->get_methodOop()->constants());
351 bool ignore;
352 // report as InvokeDynamic for invokedynamic, which is syntactically classless
353 if (cur_bc() == Bytecodes::_invokedynamic)
354 return CURRENT_ENV->get_klass_by_name(_holder, ciSymbol::java_dyn_InvokeDynamic(), false);
355 return CURRENT_ENV->get_klass_by_index(cpool, get_method_holder_index(), ignore, _holder);
356 }
358 // ------------------------------------------------------------------
359 // ciBytecodeStream::get_method_holder_index
360 //
361 // Get the constant pool index of the declared holder of the method
362 // referenced by the current bytecode. Used for generating
363 // deoptimization information.
364 int ciBytecodeStream::get_method_holder_index() {
365 constantPoolOop cpool = _method->get_methodOop()->constants();
366 return cpool->klass_ref_index_at(get_method_index());
367 }
369 // ------------------------------------------------------------------
370 // ciBytecodeStream::get_method_signature_index
371 //
372 // Get the constant pool index of the signature of the method
373 // referenced by the current bytecode. Used for generating
374 // deoptimization information.
375 int ciBytecodeStream::get_method_signature_index() {
376 VM_ENTRY_MARK;
377 constantPoolOop cpool = _holder->get_instanceKlass()->constants();
378 int method_index = get_method_index();
379 int name_and_type_index = cpool->name_and_type_ref_index_at(method_index);
380 return cpool->signature_ref_index_at(name_and_type_index);
381 }
383 // ------------------------------------------------------------------
384 // ciBytecodeStream::get_cpcache
385 ciCPCache* ciBytecodeStream::get_cpcache() {
386 VM_ENTRY_MARK;
387 // Get the constant pool.
388 constantPoolOop cpool = _holder->get_instanceKlass()->constants();
389 constantPoolCacheOop cpcache = cpool->cache();
391 return CURRENT_ENV->get_object(cpcache)->as_cpcache();
392 }
394 // ------------------------------------------------------------------
395 // ciBytecodeStream::get_call_site
396 ciCallSite* ciBytecodeStream::get_call_site() {
397 VM_ENTRY_MARK;
398 // Get the constant pool.
399 constantPoolOop cpool = _holder->get_instanceKlass()->constants();
400 constantPoolCacheOop cpcache = cpool->cache();
402 // Get the CallSite from the constant pool cache.
403 int method_index = get_method_index();
404 ConstantPoolCacheEntry* cpcache_entry = cpcache->secondary_entry_at(method_index);
405 oop call_site_oop = cpcache_entry->f1();
407 // Create a CallSite object and return it.
408 return CURRENT_ENV->get_object(call_site_oop)->as_call_site();
409 }