Mercurial > hg > truffle
comparison src/share/vm/oops/cpCacheOop.cpp @ 1660:083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
Summary: Add JVM_CONSTANT_InvokeDynamic records to constant pool to determine per-instruction BSMs.
Reviewed-by: twisti
author | jrose |
---|---|
date | Thu, 15 Jul 2010 18:40:45 -0700 |
parents | c18cbe5936b8 |
children | e0ba4e04c839 |
comparison
equal
deleted
inserted
replaced
1649:a528509c992b | 1660:083fde3b838e |
---|---|
132 } | 132 } |
133 | 133 |
134 void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, | 134 void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, |
135 methodHandle method, | 135 methodHandle method, |
136 int vtable_index) { | 136 int vtable_index) { |
137 | 137 assert(!is_secondary_entry(), ""); |
138 assert(method->interpreter_entry() != NULL, "should have been set at this point"); | 138 assert(method->interpreter_entry() != NULL, "should have been set at this point"); |
139 assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache"); | 139 assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache"); |
140 bool change_to_virtual = (invoke_code == Bytecodes::_invokeinterface); | 140 bool change_to_virtual = (invoke_code == Bytecodes::_invokeinterface); |
141 | 141 |
142 int byte_no = -1; | 142 int byte_no = -1; |
143 bool needs_vfinal_flag = false; | 143 bool needs_vfinal_flag = false; |
144 switch (invoke_code) { | 144 switch (invoke_code) { |
145 case Bytecodes::_invokedynamic: | |
146 case Bytecodes::_invokevirtual: | 145 case Bytecodes::_invokevirtual: |
147 case Bytecodes::_invokeinterface: { | 146 case Bytecodes::_invokeinterface: { |
148 if (method->can_be_statically_bound()) { | 147 if (method->can_be_statically_bound()) { |
149 set_f2((intptr_t)method()); | 148 set_f2((intptr_t)method()); |
150 needs_vfinal_flag = true; | 149 needs_vfinal_flag = true; |
153 set_f2(vtable_index); | 152 set_f2(vtable_index); |
154 } | 153 } |
155 byte_no = 2; | 154 byte_no = 2; |
156 break; | 155 break; |
157 } | 156 } |
157 | |
158 case Bytecodes::_invokedynamic: // similar to _invokevirtual | |
159 if (TraceInvokeDynamic) { | |
160 tty->print_cr("InvokeDynamic set_method%s method="PTR_FORMAT" index=%d", | |
161 (is_secondary_entry() ? " secondary" : ""), | |
162 (intptr_t)method(), vtable_index); | |
163 method->print(); | |
164 this->print(tty, 0); | |
165 } | |
166 assert(method->can_be_statically_bound(), "must be a MH invoker method"); | |
167 assert(AllowTransitionalJSR292 || _f2 >= constantPoolOopDesc::CPCACHE_INDEX_TAG, "BSM index initialized"); | |
168 set_f1(method()); | |
169 needs_vfinal_flag = false; // _f2 is not an oop | |
170 assert(!is_vfinal(), "f2 not an oop"); | |
171 byte_no = 1; // just a formality | |
172 break; | |
173 | |
158 case Bytecodes::_invokespecial: | 174 case Bytecodes::_invokespecial: |
159 // Preserve the value of the vfinal flag on invokevirtual bytecode | 175 // Preserve the value of the vfinal flag on invokevirtual bytecode |
160 // which may be shared with this constant pool cache entry. | 176 // which may be shared with this constant pool cache entry. |
161 needs_vfinal_flag = is_resolved(Bytecodes::_invokevirtual) && is_vfinal(); | 177 needs_vfinal_flag = is_resolved(Bytecodes::_invokevirtual) && is_vfinal(); |
162 // fall through | 178 // fall through |
207 NOT_PRODUCT(verify(tty)); | 223 NOT_PRODUCT(verify(tty)); |
208 } | 224 } |
209 | 225 |
210 | 226 |
211 void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index) { | 227 void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index) { |
228 assert(!is_secondary_entry(), ""); | |
212 klassOop interf = method->method_holder(); | 229 klassOop interf = method->method_holder(); |
213 assert(instanceKlass::cast(interf)->is_interface(), "must be an interface"); | 230 assert(instanceKlass::cast(interf)->is_interface(), "must be an interface"); |
214 set_f1(interf); | 231 set_f1(interf); |
215 set_f2(index); | 232 set_f2(index); |
216 set_flags(as_flags(as_TosState(method->result_type()), method->is_final_method(), false, false, false, true) | method()->size_of_parameters()); | 233 set_flags(as_flags(as_TosState(method->result_type()), method->is_final_method(), false, false, false, true) | method()->size_of_parameters()); |
217 set_bytecode_1(Bytecodes::_invokeinterface); | 234 set_bytecode_1(Bytecodes::_invokeinterface); |
218 } | 235 } |
219 | 236 |
220 | 237 |
238 void ConstantPoolCacheEntry::initialize_bootstrap_method_index_in_cache(int bsm_cache_index) { | |
239 assert(!is_secondary_entry(), "only for JVM_CONSTANT_InvokeDynamic main entry"); | |
240 assert(_f2 == 0, "initialize once"); | |
241 assert(bsm_cache_index == (int)(u2)bsm_cache_index, "oob"); | |
242 set_f2(bsm_cache_index + constantPoolOopDesc::CPCACHE_INDEX_TAG); | |
243 } | |
244 | |
245 int ConstantPoolCacheEntry::bootstrap_method_index_in_cache() { | |
246 assert(!is_secondary_entry(), "only for JVM_CONSTANT_InvokeDynamic main entry"); | |
247 intptr_t bsm_cache_index = (intptr_t) _f2 - constantPoolOopDesc::CPCACHE_INDEX_TAG; | |
248 assert(bsm_cache_index == (intptr_t)(u2)bsm_cache_index, "oob"); | |
249 return (int) bsm_cache_index; | |
250 } | |
251 | |
221 void ConstantPoolCacheEntry::set_dynamic_call(Handle call_site, | 252 void ConstantPoolCacheEntry::set_dynamic_call(Handle call_site, |
222 methodHandle signature_invoker) { | 253 methodHandle signature_invoker) { |
254 assert(is_secondary_entry(), ""); | |
223 int param_size = signature_invoker->size_of_parameters(); | 255 int param_size = signature_invoker->size_of_parameters(); |
224 assert(param_size >= 1, "method argument size must include MH.this"); | 256 assert(param_size >= 1, "method argument size must include MH.this"); |
225 param_size -= 1; // do not count MH.this; it is not stacked for invokedynamic | 257 param_size -= 1; // do not count MH.this; it is not stacked for invokedynamic |
226 if (Atomic::cmpxchg_ptr(call_site(), &_f1, NULL) == NULL) { | 258 if (Atomic::cmpxchg_ptr(call_site(), &_f1, NULL) == NULL) { |
227 // racing threads might be trying to install their own favorites | 259 // racing threads might be trying to install their own favorites |
228 set_f1(call_site()); | 260 set_f1(call_site()); |
229 } | 261 } |
230 //set_f2(0); | |
231 bool is_final = true; | 262 bool is_final = true; |
232 assert(signature_invoker->is_final_method(), "is_final"); | 263 assert(signature_invoker->is_final_method(), "is_final"); |
233 set_flags(as_flags(as_TosState(signature_invoker->result_type()), is_final, false, false, false, true) | param_size); | 264 set_flags(as_flags(as_TosState(signature_invoker->result_type()), is_final, false, false, false, true) | param_size); |
234 // do not do set_bytecode on a secondary CP cache entry | 265 // do not do set_bytecode on a secondary CP cache entry |
235 //set_bytecode_1(Bytecodes::_invokedynamic); | 266 //set_bytecode_1(Bytecodes::_invokedynamic); |
415 | 446 |
416 void ConstantPoolCacheEntry::print(outputStream* st, int index) const { | 447 void ConstantPoolCacheEntry::print(outputStream* st, int index) const { |
417 // print separator | 448 // print separator |
418 if (index == 0) tty->print_cr(" -------------"); | 449 if (index == 0) tty->print_cr(" -------------"); |
419 // print entry | 450 // print entry |
420 tty->print_cr("%3d (%08x) ", index, this); | 451 tty->print("%3d ("PTR_FORMAT") ", index, (intptr_t)this); |
421 if (is_secondary_entry()) | 452 if (is_secondary_entry()) |
422 tty->print_cr("[%5d|secondary]", main_entry_index()); | 453 tty->print_cr("[%5d|secondary]", main_entry_index()); |
423 else | 454 else |
424 tty->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(), constant_pool_index()); | 455 tty->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(), constant_pool_index()); |
425 tty->print_cr(" [ %08x]", (address)(oop)_f1); | 456 tty->print_cr(" [ "PTR_FORMAT"]", (intptr_t)(oop)_f1); |
426 tty->print_cr(" [ %08x]", _f2); | 457 tty->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_f2); |
427 tty->print_cr(" [ %08x]", _flags); | 458 tty->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_flags); |
428 tty->print_cr(" -------------"); | 459 tty->print_cr(" -------------"); |
429 } | 460 } |
430 | 461 |
431 void ConstantPoolCacheEntry::verify(outputStream* st) const { | 462 void ConstantPoolCacheEntry::verify(outputStream* st) const { |
432 // not implemented yet | 463 // not implemented yet |