Mercurial > hg > truffle
comparison src/share/vm/oops/constantPoolOop.cpp @ 1913:3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
Summary: Allow CONSTANT_InvokeDynamic nodes to have any number of extra operands.
Reviewed-by: twisti
author | jrose |
---|---|
date | Sat, 30 Oct 2010 13:08:23 -0700 |
parents | d1896d1dda3e |
children | f95d63e2154a |
comparison
equal
deleted
inserted
replaced
1912:8213b0f5c92d | 1913:3b2dea75431e |
---|---|
265 int i = which; | 265 int i = which; |
266 if (!uncached && cache() != NULL) { | 266 if (!uncached && cache() != NULL) { |
267 if (constantPoolCacheOopDesc::is_secondary_index(which)) { | 267 if (constantPoolCacheOopDesc::is_secondary_index(which)) { |
268 // Invokedynamic index. | 268 // Invokedynamic index. |
269 int pool_index = cache()->main_entry_at(which)->constant_pool_index(); | 269 int pool_index = cache()->main_entry_at(which)->constant_pool_index(); |
270 if (tag_at(pool_index).is_invoke_dynamic()) | 270 if (!AllowTransitionalJSR292 || tag_at(pool_index).is_invoke_dynamic()) |
271 pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index); | 271 pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index); |
272 assert(tag_at(pool_index).is_name_and_type(), ""); | 272 assert(tag_at(pool_index).is_name_and_type(), ""); |
273 return pool_index; | 273 return pool_index; |
274 } | 274 } |
275 // change byte-ordering and go via cache | 275 // change byte-ordering and go via cache |
276 i = remap_instruction_operand_from_cache(which); | 276 i = remap_instruction_operand_from_cache(which); |
277 } else { | 277 } else { |
278 if (tag_at(which).is_name_and_type()) | 278 if (AllowTransitionalJSR292 && tag_at(which).is_name_and_type()) |
279 // invokedynamic index is a simple name-and-type | 279 // invokedynamic index is a simple name-and-type |
280 return which; | 280 return which; |
281 if (tag_at(which).is_invoke_dynamic()) { | |
282 int pool_index = invoke_dynamic_name_and_type_ref_index_at(which); | |
283 assert(tag_at(pool_index).is_name_and_type(), ""); | |
284 return pool_index; | |
285 } | |
281 } | 286 } |
282 assert(tag_at(i).is_field_or_method(), "Corrupted constant pool"); | 287 assert(tag_at(i).is_field_or_method(), "Corrupted constant pool"); |
288 assert(!tag_at(i).is_invoke_dynamic(), "Must be handled above"); | |
283 jint ref_index = *int_at_addr(i); | 289 jint ref_index = *int_at_addr(i); |
284 return extract_high_short_from_int(ref_index); | 290 return extract_high_short_from_int(ref_index); |
285 } | 291 } |
286 | 292 |
287 | 293 |
391 this_oop->string_at(index, CHECK); | 397 this_oop->string_at(index, CHECK); |
392 } | 398 } |
393 } | 399 } |
394 } | 400 } |
395 | 401 |
402 // A resolved constant value in the CP cache is represented as a non-null | |
403 // value. As a special case, this value can be a 'systemObjArray' | |
404 // which masks an exception object to throw. | |
405 // This allows a MethodHandle constant reference to throw a consistent | |
406 // exception every time, if it fails to resolve. | |
407 static oop decode_exception_from_f1(oop result_oop, TRAPS) { | |
408 if (result_oop->klass() != Universe::systemObjArrayKlassObj()) | |
409 return result_oop; | |
410 | |
411 // Special cases here: Masked null, saved exception. | |
412 objArrayOop sys_array = (objArrayOop) result_oop; | |
413 assert(sys_array->length() == 1, "bad system array"); | |
414 if (sys_array->length() == 1) { | |
415 THROW_OOP_(sys_array->obj_at(0), NULL); | |
416 } | |
417 return NULL; | |
418 } | |
419 | |
396 oop constantPoolOopDesc::resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS) { | 420 oop constantPoolOopDesc::resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS) { |
397 oop result_oop = NULL; | 421 oop result_oop = NULL; |
422 Handle throw_exception; | |
423 | |
424 if (cache_index == _possible_index_sentinel) { | |
425 // It is possible that this constant is one which is cached in the CP cache. | |
426 // We'll do a linear search. This should be OK because this usage is rare. | |
427 assert(index > 0, "valid index"); | |
428 constantPoolCacheOop cache = this_oop()->cache(); | |
429 for (int i = 0, len = cache->length(); i < len; i++) { | |
430 ConstantPoolCacheEntry* cpc_entry = cache->entry_at(i); | |
431 if (!cpc_entry->is_secondary_entry() && cpc_entry->constant_pool_index() == index) { | |
432 // Switch the query to use this CPC entry. | |
433 cache_index = i; | |
434 index = _no_index_sentinel; | |
435 break; | |
436 } | |
437 } | |
438 if (cache_index == _possible_index_sentinel) | |
439 cache_index = _no_index_sentinel; // not found | |
440 } | |
441 assert(cache_index == _no_index_sentinel || cache_index >= 0, ""); | |
442 assert(index == _no_index_sentinel || index >= 0, ""); | |
443 | |
398 if (cache_index >= 0) { | 444 if (cache_index >= 0) { |
399 assert(index < 0, "only one kind of index at a time"); | 445 assert(index == _no_index_sentinel, "only one kind of index at a time"); |
400 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); | 446 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); |
401 result_oop = cpc_entry->f1(); | 447 result_oop = cpc_entry->f1(); |
402 if (result_oop != NULL) { | 448 if (result_oop != NULL) { |
403 return result_oop; // that was easy... | 449 return decode_exception_from_f1(result_oop, THREAD); |
450 // That was easy... | |
404 } | 451 } |
405 index = cpc_entry->constant_pool_index(); | 452 index = cpc_entry->constant_pool_index(); |
406 } | 453 } |
454 | |
455 jvalue prim_value; // temp used only in a few cases below | |
407 | 456 |
408 int tag_value = this_oop->tag_at(index).value(); | 457 int tag_value = this_oop->tag_at(index).value(); |
409 switch (tag_value) { | 458 switch (tag_value) { |
410 | 459 |
411 case JVM_CONSTANT_UnresolvedClass: | 460 case JVM_CONSTANT_UnresolvedClass: |
446 callee = KlassHandle(THREAD, k); | 495 callee = KlassHandle(THREAD, k); |
447 } | 496 } |
448 KlassHandle klass(THREAD, this_oop->pool_holder()); | 497 KlassHandle klass(THREAD, this_oop->pool_holder()); |
449 Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind, | 498 Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind, |
450 callee, name, signature, | 499 callee, name, signature, |
451 CHECK_NULL); | 500 THREAD); |
501 if (HAS_PENDING_EXCEPTION) { | |
502 throw_exception = Handle(THREAD, PENDING_EXCEPTION); | |
503 CLEAR_PENDING_EXCEPTION; | |
504 break; | |
505 } | |
452 result_oop = value(); | 506 result_oop = value(); |
453 // FIXME: Uniquify errors, using SystemDictionary::find_resolution_error. | 507 assert(result_oop != NULL, ""); |
454 break; | 508 break; |
455 } | 509 } |
456 | 510 |
457 case JVM_CONSTANT_MethodType: | 511 case JVM_CONSTANT_MethodType: |
458 { | 512 { |
465 bool ignore_is_on_bcp = false; | 519 bool ignore_is_on_bcp = false; |
466 Handle value = SystemDictionary::find_method_handle_type(signature, | 520 Handle value = SystemDictionary::find_method_handle_type(signature, |
467 klass, | 521 klass, |
468 false, | 522 false, |
469 ignore_is_on_bcp, | 523 ignore_is_on_bcp, |
470 CHECK_NULL); | 524 THREAD); |
525 if (HAS_PENDING_EXCEPTION) { | |
526 throw_exception = Handle(THREAD, PENDING_EXCEPTION); | |
527 CLEAR_PENDING_EXCEPTION; | |
528 break; | |
529 } | |
471 result_oop = value(); | 530 result_oop = value(); |
472 // FIXME: Uniquify errors, using SystemDictionary::find_resolution_error. | 531 assert(result_oop != NULL, ""); |
473 break; | 532 break; |
474 } | 533 } |
475 | 534 |
476 /* maybe some day | |
477 case JVM_CONSTANT_Integer: | 535 case JVM_CONSTANT_Integer: |
536 prim_value.i = this_oop->int_at(index); | |
537 result_oop = java_lang_boxing_object::create(T_INT, &prim_value, CHECK_NULL); | |
538 break; | |
539 | |
478 case JVM_CONSTANT_Float: | 540 case JVM_CONSTANT_Float: |
541 prim_value.f = this_oop->float_at(index); | |
542 result_oop = java_lang_boxing_object::create(T_FLOAT, &prim_value, CHECK_NULL); | |
543 break; | |
544 | |
479 case JVM_CONSTANT_Long: | 545 case JVM_CONSTANT_Long: |
546 prim_value.j = this_oop->long_at(index); | |
547 result_oop = java_lang_boxing_object::create(T_LONG, &prim_value, CHECK_NULL); | |
548 break; | |
549 | |
480 case JVM_CONSTANT_Double: | 550 case JVM_CONSTANT_Double: |
481 result_oop = java_lang_boxing_object::create(...); | 551 prim_value.d = this_oop->double_at(index); |
552 result_oop = java_lang_boxing_object::create(T_DOUBLE, &prim_value, CHECK_NULL); | |
482 break; | 553 break; |
483 */ | |
484 | 554 |
485 default: | 555 default: |
486 DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d", | 556 DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d", |
487 this_oop(), index, cache_index, tag_value) ); | 557 this_oop(), index, cache_index, tag_value) ); |
488 assert(false, "unexpected constant tag"); | 558 assert(false, "unexpected constant tag"); |
489 break; | 559 break; |
490 } | 560 } |
491 | 561 |
492 if (cache_index >= 0) { | 562 if (cache_index >= 0) { |
493 // Cache the oop here also. | 563 // Cache the oop here also. |
494 Handle result(THREAD, result_oop); | 564 if (throw_exception.not_null()) { |
565 objArrayOop sys_array = oopFactory::new_system_objArray(1, CHECK_NULL); | |
566 sys_array->obj_at_put(0, throw_exception()); | |
567 result_oop = sys_array; | |
568 throw_exception = Handle(); // be tidy | |
569 } | |
570 Handle result_handle(THREAD, result_oop); | |
495 result_oop = NULL; // safety | 571 result_oop = NULL; // safety |
496 ObjectLocker ol(this_oop, THREAD); | 572 ObjectLocker ol(this_oop, THREAD); |
497 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); | 573 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); |
498 oop result_oop2 = cpc_entry->f1(); | 574 result_oop = cpc_entry->f1(); |
499 if (result_oop2 != NULL) { | 575 // Benign race condition: f1 may already be filled in while we were trying to lock. |
500 // Race condition: May already be filled in while we were trying to lock. | 576 // The important thing here is that all threads pick up the same result. |
501 return result_oop2; | 577 // It doesn't matter which racing thread wins, as long as only one |
502 } | 578 // result is used by all threads, and all future queries. |
503 cpc_entry->set_f1(result()); | 579 // That result may be either a resolved constant or a failure exception. |
504 return result(); | 580 if (result_oop == NULL) { |
581 result_oop = result_handle(); | |
582 cpc_entry->set_f1(result_oop); | |
583 } | |
584 return decode_exception_from_f1(result_oop, THREAD); | |
505 } else { | 585 } else { |
586 if (throw_exception.not_null()) { | |
587 THROW_HANDLE_(throw_exception, NULL); | |
588 } | |
506 return result_oop; | 589 return result_oop; |
507 } | 590 } |
508 } | 591 } |
509 | 592 |
510 oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) { | 593 oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) { |
618 // Iterate over the [one] tags array (in preparation for writing to the | 701 // Iterate over the [one] tags array (in preparation for writing to the |
619 // shared archive). | 702 // shared archive). |
620 | 703 |
621 void constantPoolOopDesc::shared_tags_iterate(OopClosure* closure) { | 704 void constantPoolOopDesc::shared_tags_iterate(OopClosure* closure) { |
622 closure->do_oop(tags_addr()); | 705 closure->do_oop(tags_addr()); |
706 closure->do_oop(operands_addr()); | |
623 } | 707 } |
624 | 708 |
625 | 709 |
626 // Iterate over String objects (in preparation for writing to the shared | 710 // Iterate over String objects (in preparation for writing to the shared |
627 // archive). | 711 // archive). |
835 } | 919 } |
836 } break; | 920 } break; |
837 | 921 |
838 case JVM_CONSTANT_InvokeDynamic: | 922 case JVM_CONSTANT_InvokeDynamic: |
839 { | 923 { |
840 int k1 = invoke_dynamic_bootstrap_method_ref_index_at(index1); | 924 int op_count = multi_operand_count_at(index1); |
841 int k2 = cp2->invoke_dynamic_bootstrap_method_ref_index_at(index2); | 925 if (op_count == cp2->multi_operand_count_at(index2)) { |
842 if (k1 == k2) { | 926 bool all_equal = true; |
843 int i1 = invoke_dynamic_name_and_type_ref_index_at(index1); | 927 for (int op_i = 0; op_i < op_count; op_i++) { |
844 int i2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2); | 928 int k1 = multi_operand_ref_at(index1, op_i); |
845 if (i1 == i2) { | 929 int k2 = cp2->multi_operand_ref_at(index2, op_i); |
846 return true; | 930 if (k1 != k2) { |
931 all_equal = false; | |
932 break; | |
933 } | |
934 } | |
935 if (all_equal) { | |
936 return true; // got through loop; all elements equal | |
847 } | 937 } |
848 } | 938 } |
849 } break; | 939 } break; |
850 | 940 |
851 case JVM_CONSTANT_UnresolvedString: | 941 case JVM_CONSTANT_UnresolvedString: |
876 break; | 966 break; |
877 } | 967 } |
878 | 968 |
879 return false; | 969 return false; |
880 } // end compare_entry_to() | 970 } // end compare_entry_to() |
971 | |
972 | |
973 // Grow this->operands() to the indicated length, unless it is already at least that long. | |
974 void constantPoolOopDesc::multi_operand_buffer_grow(int min_length, TRAPS) { | |
975 int old_length = multi_operand_buffer_fill_pointer(); | |
976 if (old_length >= min_length) return; | |
977 int new_length = min_length; | |
978 assert(new_length > _multi_operand_buffer_fill_pointer_offset, ""); | |
979 typeArrayHandle new_operands = oopFactory::new_permanent_intArray(new_length, CHECK); | |
980 if (operands() == NULL) { | |
981 new_operands->int_at_put(_multi_operand_buffer_fill_pointer_offset, old_length); | |
982 } else { | |
983 // copy fill pointer and everything else | |
984 for (int i = 0; i < old_length; i++) { | |
985 new_operands->int_at_put(i, operands()->int_at(i)); | |
986 } | |
987 } | |
988 set_operands(new_operands()); | |
989 } | |
881 | 990 |
882 | 991 |
883 // Copy this constant pool's entries at start_i to end_i (inclusive) | 992 // Copy this constant pool's entries at start_i to end_i (inclusive) |
884 // to the constant pool to_cp's entries starting at to_i. A total of | 993 // to the constant pool to_cp's entries starting at to_i. A total of |
885 // (end_i - start_i) + 1 entries are copied. | 994 // (end_i - start_i) + 1 entries are copied. |
886 void constantPoolOopDesc::copy_cp_to(int start_i, int end_i, | 995 void constantPoolOopDesc::copy_cp_to(int start_i, int end_i, |
887 constantPoolHandle to_cp, int to_i, TRAPS) { | 996 constantPoolHandle to_cp, int to_i, TRAPS) { |
888 | 997 |
889 int dest_i = to_i; // leave original alone for debug purposes | 998 int dest_i = to_i; // leave original alone for debug purposes |
999 | |
1000 if (operands() != NULL) { | |
1001 // pre-grow the target CP's operand buffer | |
1002 int nops = this->multi_operand_buffer_fill_pointer(); | |
1003 nops += to_cp->multi_operand_buffer_fill_pointer(); | |
1004 to_cp->multi_operand_buffer_grow(nops, CHECK); | |
1005 } | |
890 | 1006 |
891 for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) { | 1007 for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) { |
892 copy_entry_to(src_i, to_cp, dest_i, CHECK); | 1008 copy_entry_to(src_i, to_cp, dest_i, CHECK); |
893 | 1009 |
894 switch (tag_at(src_i).value()) { | 1010 switch (tag_at(src_i).value()) { |
1034 to_cp->method_handle_index_at_put(to_i, k1, k2); | 1150 to_cp->method_handle_index_at_put(to_i, k1, k2); |
1035 } break; | 1151 } break; |
1036 | 1152 |
1037 case JVM_CONSTANT_InvokeDynamic: | 1153 case JVM_CONSTANT_InvokeDynamic: |
1038 { | 1154 { |
1155 int op_count = multi_operand_count_at(from_i); | |
1156 int fillp = to_cp->multi_operand_buffer_fill_pointer(); | |
1157 int to_op_base = fillp - _multi_operand_count_offset; // fillp is count offset; get to base | |
1158 to_cp->multi_operand_buffer_grow(to_op_base + op_count, CHECK); | |
1159 to_cp->operands()->int_at_put(fillp++, op_count); | |
1160 assert(fillp == to_op_base + _multi_operand_base_offset, "just wrote count, will now write args"); | |
1161 for (int op_i = 0; op_i < op_count; op_i++) { | |
1162 int op = multi_operand_ref_at(from_i, op_i); | |
1163 to_cp->operands()->int_at_put(fillp++, op); | |
1164 } | |
1165 assert(fillp <= to_cp->operands()->length(), "oob"); | |
1166 to_cp->set_multi_operand_buffer_fill_pointer(fillp); | |
1167 to_cp->invoke_dynamic_at_put(to_i, to_op_base, op_count); | |
1168 #ifdef ASSERT | |
1039 int k1 = invoke_dynamic_bootstrap_method_ref_index_at(from_i); | 1169 int k1 = invoke_dynamic_bootstrap_method_ref_index_at(from_i); |
1040 int k2 = invoke_dynamic_name_and_type_ref_index_at(from_i); | 1170 int k2 = invoke_dynamic_name_and_type_ref_index_at(from_i); |
1041 to_cp->invoke_dynamic_at_put(to_i, k1, k2); | 1171 int k3 = invoke_dynamic_argument_count_at(from_i); |
1172 assert(to_cp->check_invoke_dynamic_at(to_i, k1, k2, k3), | |
1173 "indy structure is OK"); | |
1174 #endif //ASSERT | |
1042 } break; | 1175 } break; |
1043 | 1176 |
1044 // Invalid is used as the tag for the second constant pool entry | 1177 // Invalid is used as the tag for the second constant pool entry |
1045 // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should | 1178 // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should |
1046 // not be seen by itself. | 1179 // not be seen by itself. |
1254 case JVM_CONSTANT_Float: | 1387 case JVM_CONSTANT_Float: |
1255 case JVM_CONSTANT_Fieldref: | 1388 case JVM_CONSTANT_Fieldref: |
1256 case JVM_CONSTANT_Methodref: | 1389 case JVM_CONSTANT_Methodref: |
1257 case JVM_CONSTANT_InterfaceMethodref: | 1390 case JVM_CONSTANT_InterfaceMethodref: |
1258 case JVM_CONSTANT_NameAndType: | 1391 case JVM_CONSTANT_NameAndType: |
1392 return 5; | |
1393 | |
1259 case JVM_CONSTANT_InvokeDynamic: | 1394 case JVM_CONSTANT_InvokeDynamic: |
1260 return 5; | 1395 // u1 tag, u2 bsm, u2 nt, u2 argc, u2 argv[argc] |
1396 return 7 + 2 * invoke_dynamic_argument_count_at(idx); | |
1261 | 1397 |
1262 case JVM_CONSTANT_Long: | 1398 case JVM_CONSTANT_Long: |
1263 case JVM_CONSTANT_Double: | 1399 case JVM_CONSTANT_Double: |
1264 return 9; | 1400 return 9; |
1265 } | 1401 } |
1472 } | 1608 } |
1473 case JVM_CONSTANT_InvokeDynamic: { | 1609 case JVM_CONSTANT_InvokeDynamic: { |
1474 *bytes = JVM_CONSTANT_InvokeDynamic; | 1610 *bytes = JVM_CONSTANT_InvokeDynamic; |
1475 idx1 = invoke_dynamic_bootstrap_method_ref_index_at(idx); | 1611 idx1 = invoke_dynamic_bootstrap_method_ref_index_at(idx); |
1476 idx2 = invoke_dynamic_name_and_type_ref_index_at(idx); | 1612 idx2 = invoke_dynamic_name_and_type_ref_index_at(idx); |
1613 int argc = invoke_dynamic_argument_count_at(idx); | |
1477 Bytes::put_Java_u2((address) (bytes+1), idx1); | 1614 Bytes::put_Java_u2((address) (bytes+1), idx1); |
1478 Bytes::put_Java_u2((address) (bytes+3), idx2); | 1615 Bytes::put_Java_u2((address) (bytes+3), idx2); |
1479 DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd", idx1, idx2)); | 1616 Bytes::put_Java_u2((address) (bytes+5), argc); |
1617 for (int arg_i = 0; arg_i < argc; arg_i++) { | |
1618 int arg = invoke_dynamic_argument_index_at(idx, arg_i); | |
1619 Bytes::put_Java_u2((address) (bytes+7+2*arg_i), arg); | |
1620 } | |
1621 DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd [%d]", idx1, idx2, argc)); | |
1480 break; | 1622 break; |
1481 } | 1623 } |
1482 } | 1624 } |
1483 DBG(printf("\n")); | 1625 DBG(printf("\n")); |
1484 bytes += ent_size; | 1626 bytes += ent_size; |