comparison src/share/vm/interpreter/rewriter.cpp @ 6266:1d7922586cf6

7023639: JSR 292 method handle invocation needs a fast path for compiled code 6984705: JSR 292 method handle creation should not go through JNI Summary: remove assembly code for JDK 7 chained method handles Reviewed-by: jrose, twisti, kvn, mhaupt Contributed-by: John Rose <john.r.rose@oracle.com>, Christian Thalinger <christian.thalinger@oracle.com>, Michael Haupt <michael.haupt@oracle.com>
author twisti
date Tue, 24 Jul 2012 10:51:00 -0700
parents d3b9f2be46ab
children 957c266d8bc5 da91efe96a93
comparison
equal deleted inserted replaced
6241:aba91a731143 6266:1d7922586cf6
31 #include "memory/resourceArea.hpp" 31 #include "memory/resourceArea.hpp"
32 #include "oops/generateOopMap.hpp" 32 #include "oops/generateOopMap.hpp"
33 #include "oops/objArrayOop.hpp" 33 #include "oops/objArrayOop.hpp"
34 #include "oops/oop.inline.hpp" 34 #include "oops/oop.inline.hpp"
35 #include "prims/methodComparator.hpp" 35 #include "prims/methodComparator.hpp"
36 #include "prims/methodHandles.hpp"
36 37
37 // Computes a CPC map (new_index -> original_index) for constant pool entries 38 // Computes a CPC map (new_index -> original_index) for constant pool entries
38 // that are referred to by the interpreter at runtime via the constant pool cache. 39 // that are referred to by the interpreter at runtime via the constant pool cache.
39 // Also computes a CP map (original_index -> new_index). 40 // Also computes a CP map (original_index -> new_index).
40 // Marks entries in CP which require additional processing. 41 // Marks entries in CP which require additional processing.
41 void Rewriter::compute_index_maps() { 42 void Rewriter::compute_index_maps() {
42 const int length = _pool->length(); 43 const int length = _pool->length();
43 init_cp_map(length); 44 init_cp_map(length);
44 jint tag_mask = 0; 45 bool saw_mh_symbol = false;
45 for (int i = 0; i < length; i++) { 46 for (int i = 0; i < length; i++) {
46 int tag = _pool->tag_at(i).value(); 47 int tag = _pool->tag_at(i).value();
47 tag_mask |= (1 << tag);
48 switch (tag) { 48 switch (tag) {
49 case JVM_CONSTANT_InterfaceMethodref: 49 case JVM_CONSTANT_InterfaceMethodref:
50 case JVM_CONSTANT_Fieldref : // fall through 50 case JVM_CONSTANT_Fieldref : // fall through
51 case JVM_CONSTANT_Methodref : // fall through 51 case JVM_CONSTANT_Methodref : // fall through
52 case JVM_CONSTANT_MethodHandle : // fall through 52 case JVM_CONSTANT_MethodHandle : // fall through
53 case JVM_CONSTANT_MethodType : // fall through 53 case JVM_CONSTANT_MethodType : // fall through
54 case JVM_CONSTANT_InvokeDynamic : // fall through 54 case JVM_CONSTANT_InvokeDynamic : // fall through
55 add_cp_cache_entry(i); 55 add_cp_cache_entry(i);
56 break; 56 break;
57 case JVM_CONSTANT_Utf8:
58 if (_pool->symbol_at(i) == vmSymbols::java_lang_invoke_MethodHandle())
59 saw_mh_symbol = true;
60 break;
57 } 61 }
58 } 62 }
59 63
60 guarantee((int)_cp_cache_map.length()-1 <= (int)((u2)-1), 64 guarantee((int)_cp_cache_map.length()-1 <= (int)((u2)-1),
61 "all cp cache indexes fit in a u2"); 65 "all cp cache indexes fit in a u2");
62 66
63 _have_invoke_dynamic = ((tag_mask & (1 << JVM_CONSTANT_InvokeDynamic)) != 0); 67 if (saw_mh_symbol)
68 _method_handle_invokers.initialize(length, (int)0);
64 } 69 }
65 70
66 // Unrewrite the bytecodes if an error occurs. 71 // Unrewrite the bytecodes if an error occurs.
67 void Rewriter::restore_bytecodes() { 72 void Rewriter::restore_bytecodes() {
68 int len = _methods->length(); 73 int len = _methods->length();
78 const int length = _cp_cache_map.length(); 83 const int length = _cp_cache_map.length();
79 constantPoolCacheOop cache = 84 constantPoolCacheOop cache =
80 oopFactory::new_constantPoolCache(length, CHECK); 85 oopFactory::new_constantPoolCache(length, CHECK);
81 No_Safepoint_Verifier nsv; 86 No_Safepoint_Verifier nsv;
82 cache->initialize(_cp_cache_map); 87 cache->initialize(_cp_cache_map);
83
84 // Don't bother with the next pass if there is no JVM_CONSTANT_InvokeDynamic.
85 if (_have_invoke_dynamic) {
86 for (int i = 0; i < length; i++) {
87 int pool_index = cp_cache_entry_pool_index(i);
88 if (pool_index >= 0 &&
89 _pool->tag_at(pool_index).is_invoke_dynamic()) {
90 int bsm_index = _pool->invoke_dynamic_bootstrap_method_ref_index_at(pool_index);
91 assert(_pool->tag_at(bsm_index).is_method_handle(), "must be a MH constant");
92 // There is a CP cache entry holding the BSM for these calls.
93 int bsm_cache_index = cp_entry_to_cp_cache(bsm_index);
94 cache->entry_at(i)->initialize_bootstrap_method_index_in_cache(bsm_cache_index);
95 }
96 }
97 }
98
99 _pool->set_cache(cache); 88 _pool->set_cache(cache);
100 cache->set_constant_pool(_pool()); 89 cache->set_constant_pool(_pool());
101 } 90 }
102 91
103 92
146 address p = bcp + offset; 135 address p = bcp + offset;
147 if (!reverse) { 136 if (!reverse) {
148 int cp_index = Bytes::get_Java_u2(p); 137 int cp_index = Bytes::get_Java_u2(p);
149 int cache_index = cp_entry_to_cp_cache(cp_index); 138 int cache_index = cp_entry_to_cp_cache(cp_index);
150 Bytes::put_native_u2(p, cache_index); 139 Bytes::put_native_u2(p, cache_index);
140 if (!_method_handle_invokers.is_empty())
141 maybe_rewrite_invokehandle(p - 1, cp_index, reverse);
151 } else { 142 } else {
152 int cache_index = Bytes::get_native_u2(p); 143 int cache_index = Bytes::get_native_u2(p);
153 int pool_index = cp_cache_entry_pool_index(cache_index); 144 int pool_index = cp_cache_entry_pool_index(cache_index);
154 Bytes::put_Java_u2(p, pool_index); 145 Bytes::put_Java_u2(p, pool_index);
146 if (!_method_handle_invokers.is_empty())
147 maybe_rewrite_invokehandle(p - 1, pool_index, reverse);
148 }
149 }
150
151
152 // Adjust the invocation bytecode for a signature-polymorphic method (MethodHandle.invoke, etc.)
153 void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, bool reverse) {
154 if (!reverse) {
155 if ((*opc) == (u1)Bytecodes::_invokevirtual ||
156 // allow invokespecial as an alias, although it would be very odd:
157 (*opc) == (u1)Bytecodes::_invokespecial) {
158 assert(_pool->tag_at(cp_index).is_method(), "wrong index");
159 // Determine whether this is a signature-polymorphic method.
160 if (cp_index >= _method_handle_invokers.length()) return;
161 int status = _method_handle_invokers[cp_index];
162 assert(status >= -1 && status <= 1, "oob tri-state");
163 if (status == 0) {
164 if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_MethodHandle() &&
165 MethodHandles::is_signature_polymorphic_name(SystemDictionary::MethodHandle_klass(),
166 _pool->name_ref_at(cp_index)))
167 status = +1;
168 else
169 status = -1;
170 _method_handle_invokers[cp_index] = status;
171 }
172 // We use a special internal bytecode for such methods (if non-static).
173 // The basic reason for this is that such methods need an extra "appendix" argument
174 // to transmit the call site's intended call type.
175 if (status > 0) {
176 (*opc) = (u1)Bytecodes::_invokehandle;
177 }
178 }
179 } else {
180 // Do not need to look at cp_index.
181 if ((*opc) == (u1)Bytecodes::_invokehandle) {
182 (*opc) = (u1)Bytecodes::_invokevirtual;
183 // Ignore corner case of original _invokespecial instruction.
184 // This is safe because (a) the signature polymorphic method was final, and
185 // (b) the implementation of MethodHandle will not call invokespecial on it.
186 }
155 } 187 }
156 } 188 }
157 189
158 190
159 void Rewriter::rewrite_invokedynamic(address bcp, int offset, bool reverse) { 191 void Rewriter::rewrite_invokedynamic(address bcp, int offset, bool reverse) {
295 case Bytecodes::_putfield : // fall through 327 case Bytecodes::_putfield : // fall through
296 case Bytecodes::_invokevirtual : // fall through 328 case Bytecodes::_invokevirtual : // fall through
297 case Bytecodes::_invokespecial : // fall through 329 case Bytecodes::_invokespecial : // fall through
298 case Bytecodes::_invokestatic : 330 case Bytecodes::_invokestatic :
299 case Bytecodes::_invokeinterface: 331 case Bytecodes::_invokeinterface:
332 case Bytecodes::_invokehandle : // if reverse=true
300 rewrite_member_reference(bcp, prefix_length+1, reverse); 333 rewrite_member_reference(bcp, prefix_length+1, reverse);
301 break; 334 break;
302 case Bytecodes::_invokedynamic: 335 case Bytecodes::_invokedynamic:
303 rewrite_invokedynamic(bcp, prefix_length+1, reverse); 336 rewrite_invokedynamic(bcp, prefix_length+1, reverse);
304 break; 337 break;
305 case Bytecodes::_ldc: 338 case Bytecodes::_ldc:
306 case Bytecodes::_fast_aldc: 339 case Bytecodes::_fast_aldc: // if reverse=true
307 maybe_rewrite_ldc(bcp, prefix_length+1, false, reverse); 340 maybe_rewrite_ldc(bcp, prefix_length+1, false, reverse);
308 break; 341 break;
309 case Bytecodes::_ldc_w: 342 case Bytecodes::_ldc_w:
310 case Bytecodes::_fast_aldc_w: 343 case Bytecodes::_fast_aldc_w: // if reverse=true
311 maybe_rewrite_ldc(bcp, prefix_length+1, true, reverse); 344 maybe_rewrite_ldc(bcp, prefix_length+1, true, reverse);
312 break; 345 break;
313 case Bytecodes::_jsr : // fall through 346 case Bytecodes::_jsr : // fall through
314 case Bytecodes::_jsr_w : nof_jsrs++; break; 347 case Bytecodes::_jsr_w : nof_jsrs++; break;
315 case Bytecodes::_monitorenter : // fall through 348 case Bytecodes::_monitorenter : // fall through