244 |
244 |
245 |
245 |
246 // The invokedynamic points at a CP cache entry. This entry points back |
246 // The invokedynamic points at a CP cache entry. This entry points back |
247 // at the original CP entry (CONSTANT_InvokeDynamic) and also (via f2) at an entry |
247 // at the original CP entry (CONSTANT_InvokeDynamic) and also (via f2) at an entry |
248 // in the resolved_references array (which provides the appendix argument). |
248 // in the resolved_references array (which provides the appendix argument). |
249 int invokedynamic_cp_cache_index(int index) const { |
249 int invokedynamic_cp_cache_index(int indy_index) const { |
250 assert (is_invokedynamic_index(index), "should be a invokedynamic index"); |
250 assert(is_invokedynamic_index(indy_index), "should be a invokedynamic index"); |
251 int cache_index = decode_invokedynamic_index(index); |
251 int cache_index = decode_invokedynamic_index(indy_index); |
252 return cache_index; |
252 return cache_index; |
253 } |
253 } |
254 ConstantPoolCacheEntry* invokedynamic_cp_cache_entry_at(int index) const { |
254 ConstantPoolCacheEntry* invokedynamic_cp_cache_entry_at(int indy_index) const { |
255 // decode index that invokedynamic points to. |
255 // decode index that invokedynamic points to. |
256 int cp_cache_index = invokedynamic_cp_cache_index(index); |
256 int cp_cache_index = invokedynamic_cp_cache_index(indy_index); |
257 return cache()->entry_at(cp_cache_index); |
257 return cache()->entry_at(cp_cache_index); |
|
258 } |
|
259 // Given the per-instruction index of an indy instruction, report the |
|
260 // main constant pool entry for its bootstrap specifier. |
|
261 // From there, uncached_name/signature_ref_at will get the name/type. |
|
262 int invokedynamic_bootstrap_ref_index_at(int indy_index) const { |
|
263 return invokedynamic_cp_cache_entry_at(indy_index)->constant_pool_index(); |
258 } |
264 } |
259 |
265 |
260 // Assembly code support |
266 // Assembly code support |
261 static int tags_offset_in_bytes() { return offset_of(ConstantPool, _tags); } |
267 static int tags_offset_in_bytes() { return offset_of(ConstantPool, _tags); } |
262 static int cache_offset_in_bytes() { return offset_of(ConstantPool, _cache); } |
268 static int cache_offset_in_bytes() { return offset_of(ConstantPool, _cache); } |
292 void method_type_index_at_put(int which, int ref_index) { |
298 void method_type_index_at_put(int which, int ref_index) { |
293 tag_at_put(which, JVM_CONSTANT_MethodType); |
299 tag_at_put(which, JVM_CONSTANT_MethodType); |
294 *int_at_addr(which) = ref_index; |
300 *int_at_addr(which) = ref_index; |
295 } |
301 } |
296 |
302 |
297 void dynamic_constant_at_put(int which, int bootstrap_specifier_index, int name_and_type_index) { |
303 void dynamic_constant_at_put(int which, int bsms_attribute_index, int name_and_type_index) { |
298 tag_at_put(which, JVM_CONSTANT_Dynamic); |
304 tag_at_put(which, JVM_CONSTANT_Dynamic); |
299 *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_specifier_index; |
305 *int_at_addr(which) = ((jint) name_and_type_index<<16) | bsms_attribute_index; |
300 } |
306 } |
301 |
307 |
302 void invoke_dynamic_at_put(int which, int bootstrap_specifier_index, int name_and_type_index) { |
308 void invoke_dynamic_at_put(int which, int bsms_attribute_index, int name_and_type_index) { |
303 tag_at_put(which, JVM_CONSTANT_InvokeDynamic); |
309 tag_at_put(which, JVM_CONSTANT_InvokeDynamic); |
304 *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_specifier_index; |
310 *int_at_addr(which) = ((jint) name_and_type_index<<16) | bsms_attribute_index; |
305 } |
311 } |
306 |
312 |
307 void unresolved_string_at_put(int which, Symbol* s) { |
313 void unresolved_string_at_put(int which, Symbol* s) { |
308 release_tag_at_put(which, JVM_CONSTANT_String); |
314 release_tag_at_put(which, JVM_CONSTANT_String); |
309 slot_at_put(which, CPSlot(s)); |
315 slot_at_put(which, CPSlot(s)); |
532 Symbol* method_type_signature_at(int which) { |
538 Symbol* method_type_signature_at(int which) { |
533 int sym = method_type_index_at(which); |
539 int sym = method_type_index_at(which); |
534 return symbol_at(sym); |
540 return symbol_at(sym); |
535 } |
541 } |
536 |
542 |
537 int invoke_dynamic_name_and_type_ref_index_at(int which) { |
543 int bootstrap_name_and_type_ref_index_at(int which) { |
538 assert(tag_at(which).is_invoke_dynamic() || |
544 assert(tag_at(which).has_bootstrap(), "Corrupted constant pool"); |
539 tag_at(which).is_dynamic_constant() || |
|
540 tag_at(which).is_dynamic_constant_in_error(), "Corrupted constant pool"); |
|
541 return extract_high_short_from_int(*int_at_addr(which)); |
545 return extract_high_short_from_int(*int_at_addr(which)); |
542 } |
546 } |
543 int invoke_dynamic_bootstrap_specifier_index(int which) { |
547 int bootstrap_methods_attribute_index(int which) { |
544 assert(tag_at(which).is_invoke_dynamic() || |
548 assert(tag_at(which).has_bootstrap(), "Corrupted constant pool"); |
545 tag_at(which).is_dynamic_constant() || |
|
546 tag_at(which).is_dynamic_constant_in_error(), "Corrupted constant pool"); |
|
547 return extract_low_short_from_int(*int_at_addr(which)); |
549 return extract_low_short_from_int(*int_at_addr(which)); |
548 } |
550 } |
549 int invoke_dynamic_operand_base(int which) { |
551 int bootstrap_operand_base(int which) { |
550 int bootstrap_specifier_index = invoke_dynamic_bootstrap_specifier_index(which); |
552 int bsms_attribute_index = bootstrap_methods_attribute_index(which); |
551 return operand_offset_at(operands(), bootstrap_specifier_index); |
553 return operand_offset_at(operands(), bsms_attribute_index); |
552 } |
554 } |
553 // The first part of the operands array consists of an index into the second part. |
555 // The first part of the operands array consists of an index into the second part. |
554 // Extract a 32-bit index value from the first part. |
556 // Extract a 32-bit index value from the first part. |
555 static int operand_offset_at(Array<u2>* operands, int bootstrap_specifier_index) { |
557 static int operand_offset_at(Array<u2>* operands, int bsms_attribute_index) { |
556 int n = (bootstrap_specifier_index * 2); |
558 int n = (bsms_attribute_index * 2); |
557 assert(n >= 0 && n+2 <= operands->length(), "oob"); |
559 assert(n >= 0 && n+2 <= operands->length(), "oob"); |
558 // The first 32-bit index points to the beginning of the second part |
560 // The first 32-bit index points to the beginning of the second part |
559 // of the operands array. Make sure this index is in the first part. |
561 // of the operands array. Make sure this index is in the first part. |
560 DEBUG_ONLY(int second_part = build_int_from_shorts(operands->at(0), |
562 DEBUG_ONLY(int second_part = build_int_from_shorts(operands->at(0), |
561 operands->at(1))); |
563 operands->at(1))); |
578 return (second_part / 2); |
580 return (second_part / 2); |
579 } |
581 } |
580 |
582 |
581 #ifdef ASSERT |
583 #ifdef ASSERT |
582 // operand tuples fit together exactly, end to end |
584 // operand tuples fit together exactly, end to end |
583 static int operand_limit_at(Array<u2>* operands, int bootstrap_specifier_index) { |
585 static int operand_limit_at(Array<u2>* operands, int bsms_attribute_index) { |
584 int nextidx = bootstrap_specifier_index + 1; |
586 int nextidx = bsms_attribute_index + 1; |
585 if (nextidx == operand_array_length(operands)) |
587 if (nextidx == operand_array_length(operands)) |
586 return operands->length(); |
588 return operands->length(); |
587 else |
589 else |
588 return operand_offset_at(operands, nextidx); |
590 return operand_offset_at(operands, nextidx); |
589 } |
591 } |
590 int invoke_dynamic_operand_limit(int which) { |
592 int bootstrap_operand_limit(int which) { |
591 int bootstrap_specifier_index = invoke_dynamic_bootstrap_specifier_index(which); |
593 int bsms_attribute_index = bootstrap_methods_attribute_index(which); |
592 return operand_limit_at(operands(), bootstrap_specifier_index); |
594 return operand_limit_at(operands(), bsms_attribute_index); |
593 } |
595 } |
594 #endif //ASSERT |
596 #endif //ASSERT |
595 |
597 |
596 // layout of InvokeDynamic and Dynamic bootstrap method specifier (in second part of operands array): |
598 // Layout of InvokeDynamic and Dynamic bootstrap method specifier |
|
599 // data in second part of operands array. This encodes one record in |
|
600 // the BootstrapMethods attribute. The whole specifier also includes |
|
601 // the name and type information from the main constant pool entry. |
597 enum { |
602 enum { |
598 _indy_bsm_offset = 0, // CONSTANT_MethodHandle bsm |
603 _indy_bsm_offset = 0, // CONSTANT_MethodHandle bsm |
599 _indy_argc_offset = 1, // u2 argc |
604 _indy_argc_offset = 1, // u2 argc |
600 _indy_argv_offset = 2 // u2 argv[argc] |
605 _indy_argv_offset = 2 // u2 argv[argc] |
601 }; |
606 }; |
602 |
607 |
603 // These functions are used in RedefineClasses for CP merge |
608 // These functions are used in RedefineClasses for CP merge |
604 |
609 |
605 int operand_offset_at(int bootstrap_specifier_index) { |
610 int operand_offset_at(int bsms_attribute_index) { |
606 assert(0 <= bootstrap_specifier_index && |
611 assert(0 <= bsms_attribute_index && |
607 bootstrap_specifier_index < operand_array_length(operands()), |
612 bsms_attribute_index < operand_array_length(operands()), |
608 "Corrupted CP operands"); |
613 "Corrupted CP operands"); |
609 return operand_offset_at(operands(), bootstrap_specifier_index); |
614 return operand_offset_at(operands(), bsms_attribute_index); |
610 } |
615 } |
611 int operand_bootstrap_method_ref_index_at(int bootstrap_specifier_index) { |
616 int operand_bootstrap_method_ref_index_at(int bsms_attribute_index) { |
612 int offset = operand_offset_at(bootstrap_specifier_index); |
617 int offset = operand_offset_at(bsms_attribute_index); |
613 return operands()->at(offset + _indy_bsm_offset); |
618 return operands()->at(offset + _indy_bsm_offset); |
614 } |
619 } |
615 int operand_argument_count_at(int bootstrap_specifier_index) { |
620 int operand_argument_count_at(int bsms_attribute_index) { |
616 int offset = operand_offset_at(bootstrap_specifier_index); |
621 int offset = operand_offset_at(bsms_attribute_index); |
617 int argc = operands()->at(offset + _indy_argc_offset); |
622 int argc = operands()->at(offset + _indy_argc_offset); |
618 return argc; |
623 return argc; |
619 } |
624 } |
620 int operand_argument_index_at(int bootstrap_specifier_index, int j) { |
625 int operand_argument_index_at(int bsms_attribute_index, int j) { |
621 int offset = operand_offset_at(bootstrap_specifier_index); |
626 int offset = operand_offset_at(bsms_attribute_index); |
622 return operands()->at(offset + _indy_argv_offset + j); |
627 return operands()->at(offset + _indy_argv_offset + j); |
623 } |
628 } |
624 int operand_next_offset_at(int bootstrap_specifier_index) { |
629 int operand_next_offset_at(int bsms_attribute_index) { |
625 int offset = operand_offset_at(bootstrap_specifier_index) + _indy_argv_offset |
630 int offset = operand_offset_at(bsms_attribute_index) + _indy_argv_offset |
626 + operand_argument_count_at(bootstrap_specifier_index); |
631 + operand_argument_count_at(bsms_attribute_index); |
627 return offset; |
632 return offset; |
628 } |
633 } |
629 // Compare a bootsrap specifier in the operands arrays |
634 // Compare a bootstrap specifier data in the operands arrays |
630 bool compare_operand_to(int bootstrap_specifier_index1, const constantPoolHandle& cp2, |
635 bool compare_operand_to(int bsms_attribute_index1, const constantPoolHandle& cp2, |
631 int bootstrap_specifier_index2, TRAPS); |
636 int bsms_attribute_index2, TRAPS); |
632 // Find a bootsrap specifier in the operands array |
637 // Find a bootstrap specifier data in the operands array |
633 int find_matching_operand(int bootstrap_specifier_index, const constantPoolHandle& search_cp, |
638 int find_matching_operand(int bsms_attribute_index, const constantPoolHandle& search_cp, |
634 int operands_cur_len, TRAPS); |
639 int operands_cur_len, TRAPS); |
635 // Resize the operands array with delta_len and delta_size |
640 // Resize the operands array with delta_len and delta_size |
636 void resize_operands(int delta_len, int delta_size, TRAPS); |
641 void resize_operands(int delta_len, int delta_size, TRAPS); |
637 // Extend the operands array with the length and size of the ext_cp operands |
642 // Extend the operands array with the length and size of the ext_cp operands |
638 void extend_operands(const constantPoolHandle& ext_cp, TRAPS); |
643 void extend_operands(const constantPoolHandle& ext_cp, TRAPS); |
639 // Shrink the operands array to a smaller array with new_len length |
644 // Shrink the operands array to a smaller array with new_len length |
640 void shrink_operands(int new_len, TRAPS); |
645 void shrink_operands(int new_len, TRAPS); |
641 |
646 |
642 int invoke_dynamic_bootstrap_method_ref_index_at(int which) { |
647 int bootstrap_method_ref_index_at(int which) { |
643 assert(tag_at(which).is_invoke_dynamic() || |
648 assert(tag_at(which).has_bootstrap(), "Corrupted constant pool"); |
644 tag_at(which).is_dynamic_constant() || |
649 int op_base = bootstrap_operand_base(which); |
645 tag_at(which).is_dynamic_constant_in_error(), "Corrupted constant pool"); |
|
646 int op_base = invoke_dynamic_operand_base(which); |
|
647 return operands()->at(op_base + _indy_bsm_offset); |
650 return operands()->at(op_base + _indy_bsm_offset); |
648 } |
651 } |
649 int invoke_dynamic_argument_count_at(int which) { |
652 int bootstrap_argument_count_at(int which) { |
650 assert(tag_at(which).is_invoke_dynamic() || |
653 assert(tag_at(which).has_bootstrap(), "Corrupted constant pool"); |
651 tag_at(which).is_dynamic_constant() || |
654 int op_base = bootstrap_operand_base(which); |
652 tag_at(which).is_dynamic_constant_in_error(), "Corrupted constant pool"); |
|
653 int op_base = invoke_dynamic_operand_base(which); |
|
654 int argc = operands()->at(op_base + _indy_argc_offset); |
655 int argc = operands()->at(op_base + _indy_argc_offset); |
655 DEBUG_ONLY(int end_offset = op_base + _indy_argv_offset + argc; |
656 DEBUG_ONLY(int end_offset = op_base + _indy_argv_offset + argc; |
656 int next_offset = invoke_dynamic_operand_limit(which)); |
657 int next_offset = bootstrap_operand_limit(which)); |
657 assert(end_offset == next_offset, "matched ending"); |
658 assert(end_offset == next_offset, "matched ending"); |
658 return argc; |
659 return argc; |
659 } |
660 } |
660 int invoke_dynamic_argument_index_at(int which, int j) { |
661 int bootstrap_argument_index_at(int which, int j) { |
661 int op_base = invoke_dynamic_operand_base(which); |
662 int op_base = bootstrap_operand_base(which); |
662 DEBUG_ONLY(int argc = operands()->at(op_base + _indy_argc_offset)); |
663 DEBUG_ONLY(int argc = operands()->at(op_base + _indy_argc_offset)); |
663 assert((uint)j < (uint)argc, "oob"); |
664 assert((uint)j < (uint)argc, "oob"); |
664 return operands()->at(op_base + _indy_argv_offset + j); |
665 return operands()->at(op_base + _indy_argv_offset + j); |
665 } |
666 } |
666 |
667 |