Mercurial > hg > graal-jvmci-8
comparison src/share/vm/oops/constantPoolOop.hpp @ 2011:dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
Reviewed-by: twisti
author | jrose |
---|---|
date | Fri, 03 Dec 2010 15:53:57 -0800 |
parents | f95d63e2154a |
children | 3582bf76420e |
comparison
equal
deleted
inserted
replaced
2010:7601ab0e1e33 | 2011:dad31fc330cd |
---|---|
177 void method_type_index_at_put(int which, int ref_index) { | 177 void method_type_index_at_put(int which, int ref_index) { |
178 tag_at_put(which, JVM_CONSTANT_MethodType); | 178 tag_at_put(which, JVM_CONSTANT_MethodType); |
179 *int_at_addr(which) = ref_index; | 179 *int_at_addr(which) = ref_index; |
180 } | 180 } |
181 | 181 |
182 void invoke_dynamic_at_put(int which, int operand_base, int operand_count) { | 182 void invoke_dynamic_at_put(int which, int bootstrap_specifier_index, int name_and_type_index) { |
183 tag_at_put(which, JVM_CONSTANT_InvokeDynamic); | 183 tag_at_put(which, JVM_CONSTANT_InvokeDynamic); |
184 *int_at_addr(which) = operand_base; // this is the real information | 184 *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_specifier_index; |
185 } | 185 } |
186 #ifdef ASSERT | 186 |
187 bool check_invoke_dynamic_at(int which, | 187 void invoke_dynamic_trans_at_put(int which, int bootstrap_method_index, int name_and_type_index) { |
188 int bootstrap_method_index, | 188 tag_at_put(which, JVM_CONSTANT_InvokeDynamicTrans); |
189 int name_and_type_index, | 189 *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_method_index; |
190 int argument_count) { | 190 assert(AllowTransitionalJSR292, ""); |
191 assert(invoke_dynamic_bootstrap_method_ref_index_at(which) == bootstrap_method_index, | 191 } |
192 "already stored by caller"); | |
193 assert(invoke_dynamic_name_and_type_ref_index_at(which) == name_and_type_index, | |
194 "already stored by caller"); | |
195 assert(invoke_dynamic_argument_count_at(which) == argument_count, | |
196 "consistent argument count"); | |
197 if (argument_count != 0) { | |
198 invoke_dynamic_argument_index_at(which, 0); | |
199 invoke_dynamic_argument_index_at(which, argument_count - 1); | |
200 } | |
201 return true; | |
202 } | |
203 #endif //ASSERT | |
204 | 192 |
205 // Temporary until actual use | 193 // Temporary until actual use |
206 void unresolved_string_at_put(int which, symbolOop s) { | 194 void unresolved_string_at_put(int which, symbolOop s) { |
207 *obj_at_addr(which) = NULL; | 195 *obj_at_addr(which) = NULL; |
208 release_tag_at_put(which, JVM_CONSTANT_UnresolvedString); | 196 release_tag_at_put(which, JVM_CONSTANT_UnresolvedString); |
441 symbolOop method_type_signature_at(int which) { | 429 symbolOop method_type_signature_at(int which) { |
442 int sym = method_type_index_at(which); | 430 int sym = method_type_index_at(which); |
443 return symbol_at(sym); | 431 return symbol_at(sym); |
444 } | 432 } |
445 | 433 |
446 private: | 434 int invoke_dynamic_name_and_type_ref_index_at(int which) { |
447 // some nodes (InvokeDynamic) have a variable number of operands, each a u2 value | |
448 enum { _multi_operand_count_offset = -1, | |
449 _multi_operand_base_offset = 0, | |
450 _multi_operand_buffer_fill_pointer_offset = 0 // shared at front of operands array | |
451 }; | |
452 int multi_operand_buffer_length() { | |
453 return operands() == NULL ? 0 : operands()->length(); | |
454 } | |
455 int multi_operand_buffer_fill_pointer() { | |
456 return operands() == NULL | |
457 ? _multi_operand_buffer_fill_pointer_offset + 1 | |
458 : operands()->int_at(_multi_operand_buffer_fill_pointer_offset); | |
459 } | |
460 void multi_operand_buffer_grow(int min_length, TRAPS); | |
461 void set_multi_operand_buffer_fill_pointer(int fillp) { | |
462 assert(operands() != NULL, ""); | |
463 operands()->int_at_put(_multi_operand_buffer_fill_pointer_offset, fillp); | |
464 } | |
465 int multi_operand_base_at(int which) { | |
466 assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); | 435 assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); |
467 int op_base = *int_at_addr(which); | 436 return extract_high_short_from_int(*int_at_addr(which)); |
468 assert(op_base > _multi_operand_buffer_fill_pointer_offset, "Corrupted operand base"); | 437 } |
469 return op_base; | 438 int invoke_dynamic_bootstrap_specifier_index(int which) { |
470 } | 439 assert(tag_at(which).value() == JVM_CONSTANT_InvokeDynamic, "Corrupted constant pool"); |
471 int multi_operand_count_at(int which) { | 440 return extract_low_short_from_int(*int_at_addr(which)); |
472 int op_base = multi_operand_base_at(which); | 441 } |
473 assert((uint)(op_base + _multi_operand_count_offset) < (uint)operands()->length(), "oob"); | 442 int invoke_dynamic_operand_base(int which) { |
474 int count = operands()->int_at(op_base + _multi_operand_count_offset); | 443 int bootstrap_specifier_index = invoke_dynamic_bootstrap_specifier_index(which); |
475 return count; | 444 return operand_offset_at(operands(), bootstrap_specifier_index); |
476 } | 445 } |
477 int multi_operand_ref_at(int which, int i) { | 446 // The first part of the operands array consists of an index into the second part. |
478 int op_base = multi_operand_base_at(which); | 447 // Extract a 32-bit index value from the first part. |
479 assert((uint)i < (uint)multi_operand_count_at(which), "oob"); | 448 static int operand_offset_at(typeArrayOop operands, int bootstrap_specifier_index) { |
480 assert((uint)(op_base + _multi_operand_base_offset + i) < (uint)operands()->length(), "oob"); | 449 int n = (bootstrap_specifier_index * 2); |
481 return operands()->int_at(op_base + _multi_operand_base_offset + i); | 450 assert(n >= 0 && n+2 <= operands->length(), "oob"); |
482 } | 451 // The first 32-bit index points to the beginning of the second part |
483 void set_multi_operand_ref_at(int which, int i, int ref) { | 452 // of the operands array. Make sure this index is in the first part. |
484 DEBUG_ONLY(multi_operand_ref_at(which, i)); // trigger asserts | 453 DEBUG_ONLY(int second_part = build_int_from_shorts(operands->short_at(0), |
485 int op_base = multi_operand_base_at(which); | 454 operands->short_at(1))); |
486 operands()->int_at_put(op_base + _multi_operand_base_offset + i, ref); | 455 assert(second_part == 0 || n+2 <= second_part, "oob (2)"); |
487 } | 456 int offset = build_int_from_shorts(operands->short_at(n+0), |
488 | 457 operands->short_at(n+1)); |
489 public: | 458 // The offset itself must point into the second part of the array. |
490 // layout of InvokeDynamic: | 459 assert(offset == 0 || offset >= second_part && offset <= operands->length(), "oob (3)"); |
460 return offset; | |
461 } | |
462 static void operand_offset_at_put(typeArrayOop operands, int bootstrap_specifier_index, int offset) { | |
463 int n = bootstrap_specifier_index * 2; | |
464 assert(n >= 0 && n+2 <= operands->length(), "oob"); | |
465 operands->short_at_put(n+0, extract_low_short_from_int(offset)); | |
466 operands->short_at_put(n+1, extract_high_short_from_int(offset)); | |
467 } | |
468 static int operand_array_length(typeArrayOop operands) { | |
469 if (operands == NULL || operands->length() == 0) return 0; | |
470 int second_part = operand_offset_at(operands, 0); | |
471 return (second_part / 2); | |
472 } | |
473 | |
474 #ifdef ASSERT | |
475 // operand tuples fit together exactly, end to end | |
476 static int operand_limit_at(typeArrayOop operands, int bootstrap_specifier_index) { | |
477 int nextidx = bootstrap_specifier_index + 1; | |
478 if (nextidx == operand_array_length(operands)) | |
479 return operands->length(); | |
480 else | |
481 return operand_offset_at(operands, nextidx); | |
482 } | |
483 int invoke_dynamic_operand_limit(int which) { | |
484 int bootstrap_specifier_index = invoke_dynamic_bootstrap_specifier_index(which); | |
485 return operand_limit_at(operands(), bootstrap_specifier_index); | |
486 } | |
487 #endif //ASSERT | |
488 | |
489 // layout of InvokeDynamic bootstrap method specifier (in second part of operands array): | |
491 enum { | 490 enum { |
492 _indy_bsm_offset = 0, // CONSTANT_MethodHandle bsm | 491 _indy_bsm_offset = 0, // CONSTANT_MethodHandle bsm |
493 _indy_nt_offset = 1, // CONSTANT_NameAndType descr | 492 _indy_argc_offset = 1, // u2 argc |
494 _indy_argc_offset = 2, // u2 argc | 493 _indy_argv_offset = 2 // u2 argv[argc] |
495 _indy_argv_offset = 3 // u2 argv[argc] | |
496 }; | 494 }; |
497 int invoke_dynamic_bootstrap_method_ref_index_at(int which) { | 495 int invoke_dynamic_bootstrap_method_ref_index_at(int which) { |
498 assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); | 496 assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); |
499 return multi_operand_ref_at(which, _indy_bsm_offset); | 497 if (tag_at(which).value() == JVM_CONSTANT_InvokeDynamicTrans) |
500 } | 498 return extract_low_short_from_int(*int_at_addr(which)); |
501 int invoke_dynamic_name_and_type_ref_index_at(int which) { | 499 int op_base = invoke_dynamic_operand_base(which); |
502 assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); | 500 return operands()->short_at(op_base + _indy_bsm_offset); |
503 return multi_operand_ref_at(which, _indy_nt_offset); | |
504 } | 501 } |
505 int invoke_dynamic_argument_count_at(int which) { | 502 int invoke_dynamic_argument_count_at(int which) { |
506 assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); | 503 assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); |
507 int argc = multi_operand_ref_at(which, _indy_argc_offset); | 504 if (tag_at(which).value() == JVM_CONSTANT_InvokeDynamicTrans) |
508 DEBUG_ONLY(int op_count = multi_operand_count_at(which)); | 505 return 0; |
509 assert(_indy_argv_offset + argc == op_count, "consistent inner and outer counts"); | 506 int op_base = invoke_dynamic_operand_base(which); |
507 int argc = operands()->short_at(op_base + _indy_argc_offset); | |
508 DEBUG_ONLY(int end_offset = op_base + _indy_argv_offset + argc; | |
509 int next_offset = invoke_dynamic_operand_limit(which)); | |
510 assert(end_offset == next_offset, "matched ending"); | |
510 return argc; | 511 return argc; |
511 } | 512 } |
512 int invoke_dynamic_argument_index_at(int which, int j) { | 513 int invoke_dynamic_argument_index_at(int which, int j) { |
513 assert((uint)j < (uint)invoke_dynamic_argument_count_at(which), "oob"); | 514 int op_base = invoke_dynamic_operand_base(which); |
514 return multi_operand_ref_at(which, _indy_argv_offset + j); | 515 DEBUG_ONLY(int argc = operands()->short_at(op_base + _indy_argc_offset)); |
516 assert((uint)j < (uint)argc, "oob"); | |
517 return operands()->short_at(op_base + _indy_argv_offset + j); | |
515 } | 518 } |
516 | 519 |
517 // The following methods (name/signature/klass_ref_at, klass_ref_at_noresolve, | 520 // The following methods (name/signature/klass_ref_at, klass_ref_at_noresolve, |
518 // name_and_type_ref_index_at) all expect to be passed indices obtained | 521 // name_and_type_ref_index_at) all expect to be passed indices obtained |
519 // directly from the bytecode. | 522 // directly from the bytecode. |
657 static oop resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS); | 660 static oop resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS); |
658 | 661 |
659 public: | 662 public: |
660 // Merging constantPoolOop support: | 663 // Merging constantPoolOop support: |
661 bool compare_entry_to(int index1, constantPoolHandle cp2, int index2, TRAPS); | 664 bool compare_entry_to(int index1, constantPoolHandle cp2, int index2, TRAPS); |
662 void copy_cp_to(int start_i, int end_i, constantPoolHandle to_cp, int to_i, | 665 void copy_cp_to(int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS) { |
663 TRAPS); | 666 constantPoolHandle h_this(THREAD, this); |
664 void copy_entry_to(int from_i, constantPoolHandle to_cp, int to_i, TRAPS); | 667 copy_cp_to_impl(h_this, start_i, end_i, to_cp, to_i, THREAD); |
668 } | |
669 static void copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS); | |
670 static void copy_entry_to(constantPoolHandle from_cp, int from_i, constantPoolHandle to_cp, int to_i, TRAPS); | |
665 int find_matching_entry(int pattern_i, constantPoolHandle search_cp, TRAPS); | 671 int find_matching_entry(int pattern_i, constantPoolHandle search_cp, TRAPS); |
666 int orig_length() const { return _orig_length; } | 672 int orig_length() const { return _orig_length; } |
667 void set_orig_length(int orig_length) { _orig_length = orig_length; } | 673 void set_orig_length(int orig_length) { _orig_length = orig_length; } |
668 | 674 |
669 | 675 |