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