604 stack->set_sp(stack->sp() + method->size_of_parameters()); |
626 stack->set_sp(stack->sp() + method->size_of_parameters()); |
605 |
627 |
606 // No deoptimized frames on the stack |
628 // No deoptimized frames on the stack |
607 return 0; |
629 return 0; |
608 } |
630 } |
|
631 |
|
632 int CppInterpreter::method_handle_entry(methodOop method, |
|
633 intptr_t UNUSED, TRAPS) { |
|
634 JavaThread *thread = (JavaThread *) THREAD; |
|
635 ZeroStack *stack = thread->zero_stack(); |
|
636 int argument_slots = method->size_of_parameters(); |
|
637 int result_slots = type2size[result_type_of(method)]; |
|
638 intptr_t *vmslots = stack->sp(); |
|
639 intptr_t *unwind_sp = vmslots + argument_slots; |
|
640 |
|
641 // Find the MethodType |
|
642 address p = (address) method; |
|
643 for (jint* pc = method->method_type_offsets_chain(); (*pc) != -1; pc++) { |
|
644 p = *(address*)(p + (*pc)); |
|
645 } |
|
646 oop method_type = (oop) p; |
|
647 |
|
648 // The MethodHandle is in the slot after the arguments |
|
649 oop form = java_lang_invoke_MethodType::form(method_type); |
|
650 int num_vmslots = java_lang_invoke_MethodTypeForm::vmslots(form); |
|
651 assert(argument_slots == num_vmslots + 1, "should be"); |
|
652 oop method_handle = VMSLOTS_OBJECT(num_vmslots); |
|
653 |
|
654 // InvokeGeneric requires some extra shuffling |
|
655 oop mhtype = java_lang_invoke_MethodHandle::type(method_handle); |
|
656 bool is_exact = mhtype == method_type; |
|
657 if (!is_exact) { |
|
658 if (method->intrinsic_id() == vmIntrinsics::_invokeExact) { |
|
659 CALL_VM_NOCHECK_NOFIX( |
|
660 InterpreterRuntime::throw_WrongMethodTypeException( |
|
661 thread, method_type, mhtype)); |
|
662 // NB all oops trashed! |
|
663 assert(HAS_PENDING_EXCEPTION, "should do"); |
|
664 stack->set_sp(unwind_sp); |
|
665 return 0; |
|
666 } |
|
667 assert(method->intrinsic_id() == vmIntrinsics::_invokeGeneric, "should be"); |
|
668 |
|
669 // Load up an adapter from the calling type |
|
670 // NB the x86 code for this (in methodHandles_x86.cpp, search for |
|
671 // "genericInvoker") is really really odd. I'm hoping it's trying |
|
672 // to accomodate odd VM/class library combinations I can ignore. |
|
673 oop adapter = java_lang_invoke_MethodTypeForm::genericInvoker(form); |
|
674 if (adapter == NULL) { |
|
675 CALL_VM_NOCHECK_NOFIX( |
|
676 InterpreterRuntime::throw_WrongMethodTypeException( |
|
677 thread, method_type, mhtype)); |
|
678 // NB all oops trashed! |
|
679 assert(HAS_PENDING_EXCEPTION, "should do"); |
|
680 stack->set_sp(unwind_sp); |
|
681 return 0; |
|
682 } |
|
683 |
|
684 // Adapters are shared among form-families of method-type. The |
|
685 // type being called is passed as a trusted first argument so that |
|
686 // the adapter knows the actual types of its arguments and return |
|
687 // values. |
|
688 insert_vmslots(num_vmslots + 1, 1, THREAD); |
|
689 if (HAS_PENDING_EXCEPTION) { |
|
690 // NB all oops trashed! |
|
691 stack->set_sp(unwind_sp); |
|
692 return 0; |
|
693 } |
|
694 |
|
695 vmslots = stack->sp(); |
|
696 num_vmslots++; |
|
697 SET_VMSLOTS_OBJECT(method_type, num_vmslots); |
|
698 |
|
699 method_handle = adapter; |
|
700 } |
|
701 |
|
702 // Start processing |
|
703 process_method_handle(method_handle, THREAD); |
|
704 if (HAS_PENDING_EXCEPTION) |
|
705 result_slots = 0; |
|
706 |
|
707 // If this is an invokeExact then the eventual callee will not |
|
708 // have unwound the method handle argument so we have to do it. |
|
709 // If a result is being returned the it will be above the method |
|
710 // handle argument we're unwinding. |
|
711 if (is_exact) { |
|
712 intptr_t result[2]; |
|
713 for (int i = 0; i < result_slots; i++) |
|
714 result[i] = stack->pop(); |
|
715 stack->pop(); |
|
716 for (int i = result_slots - 1; i >= 0; i--) |
|
717 stack->push(result[i]); |
|
718 } |
|
719 |
|
720 // Check |
|
721 assert(stack->sp() == unwind_sp - result_slots, "should be"); |
|
722 |
|
723 // No deoptimized frames on the stack |
|
724 return 0; |
|
725 } |
|
726 |
|
727 void CppInterpreter::process_method_handle(oop method_handle, TRAPS) { |
|
728 JavaThread *thread = (JavaThread *) THREAD; |
|
729 ZeroStack *stack = thread->zero_stack(); |
|
730 intptr_t *vmslots = stack->sp(); |
|
731 |
|
732 bool direct_to_method = false; |
|
733 BasicType src_rtype = T_ILLEGAL; |
|
734 BasicType dst_rtype = T_ILLEGAL; |
|
735 |
|
736 MethodHandleEntry *entry = |
|
737 java_lang_invoke_MethodHandle::vmentry(method_handle); |
|
738 MethodHandles::EntryKind entry_kind = |
|
739 (MethodHandles::EntryKind) (((intptr_t) entry) & 0xffffffff); |
|
740 |
|
741 methodOop method = NULL; |
|
742 switch (entry_kind) { |
|
743 case MethodHandles::_invokestatic_mh: |
|
744 direct_to_method = true; |
|
745 break; |
|
746 |
|
747 case MethodHandles::_invokespecial_mh: |
|
748 case MethodHandles::_invokevirtual_mh: |
|
749 case MethodHandles::_invokeinterface_mh: |
|
750 { |
|
751 oop receiver = |
|
752 VMSLOTS_OBJECT( |
|
753 java_lang_invoke_MethodHandle::vmslots(method_handle) - 1); |
|
754 if (receiver == NULL) { |
|
755 stack->set_sp(calculate_unwind_sp(stack, method_handle)); |
|
756 CALL_VM_NOCHECK_NOFIX( |
|
757 throw_exception( |
|
758 thread, vmSymbols::java_lang_NullPointerException())); |
|
759 // NB all oops trashed! |
|
760 assert(HAS_PENDING_EXCEPTION, "should do"); |
|
761 return; |
|
762 } |
|
763 if (entry_kind != MethodHandles::_invokespecial_mh) { |
|
764 int index = java_lang_invoke_DirectMethodHandle::vmindex(method_handle); |
|
765 instanceKlass* rcvrKlass = |
|
766 (instanceKlass *) receiver->klass()->klass_part(); |
|
767 if (entry_kind == MethodHandles::_invokevirtual_mh) { |
|
768 method = (methodOop) rcvrKlass->start_of_vtable()[index]; |
|
769 } |
|
770 else { |
|
771 oop iclass = java_lang_invoke_MethodHandle::vmtarget(method_handle); |
|
772 itableOffsetEntry* ki = |
|
773 (itableOffsetEntry *) rcvrKlass->start_of_itable(); |
|
774 int i, length = rcvrKlass->itable_length(); |
|
775 for (i = 0; i < length; i++, ki++ ) { |
|
776 if (ki->interface_klass() == iclass) |
|
777 break; |
|
778 } |
|
779 if (i == length) { |
|
780 stack->set_sp(calculate_unwind_sp(stack, method_handle)); |
|
781 CALL_VM_NOCHECK_NOFIX( |
|
782 throw_exception( |
|
783 thread, vmSymbols::java_lang_IncompatibleClassChangeError())); |
|
784 // NB all oops trashed! |
|
785 assert(HAS_PENDING_EXCEPTION, "should do"); |
|
786 return; |
|
787 } |
|
788 itableMethodEntry* im = ki->first_method_entry(receiver->klass()); |
|
789 method = im[index].method(); |
|
790 if (method == NULL) { |
|
791 stack->set_sp(calculate_unwind_sp(stack, method_handle)); |
|
792 CALL_VM_NOCHECK_NOFIX( |
|
793 throw_exception( |
|
794 thread, vmSymbols::java_lang_AbstractMethodError())); |
|
795 // NB all oops trashed! |
|
796 assert(HAS_PENDING_EXCEPTION, "should do"); |
|
797 return; |
|
798 } |
|
799 } |
|
800 } |
|
801 } |
|
802 direct_to_method = true; |
|
803 break; |
|
804 |
|
805 case MethodHandles::_bound_ref_direct_mh: |
|
806 case MethodHandles::_bound_int_direct_mh: |
|
807 case MethodHandles::_bound_long_direct_mh: |
|
808 direct_to_method = true; |
|
809 // fall through |
|
810 case MethodHandles::_bound_ref_mh: |
|
811 case MethodHandles::_bound_int_mh: |
|
812 case MethodHandles::_bound_long_mh: |
|
813 { |
|
814 BasicType arg_type = T_ILLEGAL; |
|
815 int arg_mask = -1; |
|
816 int arg_slots = -1; |
|
817 MethodHandles::get_ek_bound_mh_info( |
|
818 entry_kind, arg_type, arg_mask, arg_slots); |
|
819 int arg_slot = |
|
820 java_lang_invoke_BoundMethodHandle::vmargslot(method_handle); |
|
821 |
|
822 // Create the new slot(s) |
|
823 intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle); |
|
824 insert_vmslots(arg_slot, arg_slots, THREAD); |
|
825 if (HAS_PENDING_EXCEPTION) { |
|
826 // all oops trashed |
|
827 stack->set_sp(unwind_sp); |
|
828 return; |
|
829 } |
|
830 vmslots = stack->sp(); |
|
831 |
|
832 // Store bound argument into new stack slot |
|
833 oop arg = java_lang_invoke_BoundMethodHandle::argument(method_handle); |
|
834 if (arg_type == T_OBJECT) { |
|
835 assert(arg_slots == 1, "should be"); |
|
836 SET_VMSLOTS_OBJECT(arg, arg_slot); |
|
837 } |
|
838 else { |
|
839 jvalue arg_value; |
|
840 arg_type = java_lang_boxing_object::get_value(arg, &arg_value); |
|
841 switch (arg_type) { |
|
842 case T_BOOLEAN: |
|
843 SET_VMSLOTS_INT(arg_value.z, arg_slot); |
|
844 break; |
|
845 case T_CHAR: |
|
846 SET_VMSLOTS_INT(arg_value.c, arg_slot); |
|
847 break; |
|
848 case T_BYTE: |
|
849 SET_VMSLOTS_INT(arg_value.b, arg_slot); |
|
850 break; |
|
851 case T_SHORT: |
|
852 SET_VMSLOTS_INT(arg_value.s, arg_slot); |
|
853 break; |
|
854 case T_INT: |
|
855 SET_VMSLOTS_INT(arg_value.i, arg_slot); |
|
856 break; |
|
857 case T_FLOAT: |
|
858 SET_VMSLOTS_FLOAT(arg_value.f, arg_slot); |
|
859 break; |
|
860 case T_LONG: |
|
861 SET_VMSLOTS_LONG(arg_value.j, arg_slot + 1); |
|
862 break; |
|
863 case T_DOUBLE: |
|
864 SET_VMSLOTS_DOUBLE(arg_value.d, arg_slot + 1); |
|
865 break; |
|
866 default: |
|
867 tty->print_cr("unhandled type %s", type2name(arg_type)); |
|
868 ShouldNotReachHere(); |
|
869 } |
|
870 } |
|
871 } |
|
872 break; |
|
873 |
|
874 case MethodHandles::_adapter_retype_only: |
|
875 case MethodHandles::_adapter_retype_raw: |
|
876 src_rtype = result_type_of_handle( |
|
877 java_lang_invoke_MethodHandle::vmtarget(method_handle)); |
|
878 dst_rtype = result_type_of_handle(method_handle); |
|
879 break; |
|
880 |
|
881 case MethodHandles::_adapter_check_cast: |
|
882 { |
|
883 int arg_slot = |
|
884 java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); |
|
885 oop arg = VMSLOTS_OBJECT(arg_slot); |
|
886 if (arg != NULL) { |
|
887 klassOop objKlassOop = arg->klass(); |
|
888 klassOop klassOf = java_lang_Class::as_klassOop( |
|
889 java_lang_invoke_AdapterMethodHandle::argument(method_handle)); |
|
890 |
|
891 if (objKlassOop != klassOf && |
|
892 !objKlassOop->klass_part()->is_subtype_of(klassOf)) { |
|
893 ResourceMark rm(THREAD); |
|
894 const char* objName = Klass::cast(objKlassOop)->external_name(); |
|
895 const char* klassName = Klass::cast(klassOf)->external_name(); |
|
896 char* message = SharedRuntime::generate_class_cast_message( |
|
897 objName, klassName); |
|
898 |
|
899 stack->set_sp(calculate_unwind_sp(stack, method_handle)); |
|
900 CALL_VM_NOCHECK_NOFIX( |
|
901 throw_exception( |
|
902 thread, vmSymbols::java_lang_ClassCastException(), message)); |
|
903 // NB all oops trashed! |
|
904 assert(HAS_PENDING_EXCEPTION, "should do"); |
|
905 return; |
|
906 } |
|
907 } |
|
908 } |
|
909 break; |
|
910 |
|
911 case MethodHandles::_adapter_dup_args: |
|
912 { |
|
913 int arg_slot = |
|
914 java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); |
|
915 int conv = |
|
916 java_lang_invoke_AdapterMethodHandle::conversion(method_handle); |
|
917 int num_slots = -MethodHandles::adapter_conversion_stack_move(conv); |
|
918 assert(num_slots > 0, "should be"); |
|
919 |
|
920 // Create the new slot(s) |
|
921 intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle); |
|
922 stack->overflow_check(num_slots, THREAD); |
|
923 if (HAS_PENDING_EXCEPTION) { |
|
924 // all oops trashed |
|
925 stack->set_sp(unwind_sp); |
|
926 return; |
|
927 } |
|
928 |
|
929 // Duplicate the arguments |
|
930 for (int i = num_slots - 1; i >= 0; i--) |
|
931 stack->push(*VMSLOTS_SLOT(arg_slot + i)); |
|
932 |
|
933 vmslots = stack->sp(); // unused, but let the compiler figure that out |
|
934 } |
|
935 break; |
|
936 |
|
937 case MethodHandles::_adapter_drop_args: |
|
938 { |
|
939 int arg_slot = |
|
940 java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); |
|
941 int conv = |
|
942 java_lang_invoke_AdapterMethodHandle::conversion(method_handle); |
|
943 int num_slots = MethodHandles::adapter_conversion_stack_move(conv); |
|
944 assert(num_slots > 0, "should be"); |
|
945 |
|
946 remove_vmslots(arg_slot, num_slots, THREAD); // doesn't trap |
|
947 vmslots = stack->sp(); // unused, but let the compiler figure that out |
|
948 } |
|
949 break; |
|
950 |
|
951 case MethodHandles::_adapter_opt_swap_1: |
|
952 case MethodHandles::_adapter_opt_swap_2: |
|
953 case MethodHandles::_adapter_opt_rot_1_up: |
|
954 case MethodHandles::_adapter_opt_rot_1_down: |
|
955 case MethodHandles::_adapter_opt_rot_2_up: |
|
956 case MethodHandles::_adapter_opt_rot_2_down: |
|
957 { |
|
958 int arg1 = |
|
959 java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); |
|
960 int conv = |
|
961 java_lang_invoke_AdapterMethodHandle::conversion(method_handle); |
|
962 int arg2 = MethodHandles::adapter_conversion_vminfo(conv); |
|
963 |
|
964 int swap_bytes = 0, rotate = 0; |
|
965 MethodHandles::get_ek_adapter_opt_swap_rot_info( |
|
966 entry_kind, swap_bytes, rotate); |
|
967 int swap_slots = swap_bytes >> LogBytesPerWord; |
|
968 |
|
969 intptr_t tmp; |
|
970 switch (rotate) { |
|
971 case 0: // swap |
|
972 for (int i = 0; i < swap_slots; i++) { |
|
973 tmp = *VMSLOTS_SLOT(arg1 + i); |
|
974 SET_VMSLOTS_SLOT(VMSLOTS_SLOT(arg2 + i), arg1 + i); |
|
975 SET_VMSLOTS_SLOT(&tmp, arg2 + i); |
|
976 } |
|
977 break; |
|
978 |
|
979 case 1: // up |
|
980 assert(arg1 - swap_slots > arg2, "should be"); |
|
981 |
|
982 tmp = *VMSLOTS_SLOT(arg1); |
|
983 for (int i = arg1 - swap_slots; i >= arg2; i--) |
|
984 SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i), i + swap_slots); |
|
985 SET_VMSLOTS_SLOT(&tmp, arg2); |
|
986 |
|
987 break; |
|
988 |
|
989 case -1: // down |
|
990 assert(arg2 - swap_slots > arg1, "should be"); |
|
991 |
|
992 tmp = *VMSLOTS_SLOT(arg1); |
|
993 for (int i = arg1 + swap_slots; i <= arg2; i++) |
|
994 SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i), i - swap_slots); |
|
995 SET_VMSLOTS_SLOT(&tmp, arg2); |
|
996 break; |
|
997 |
|
998 default: |
|
999 ShouldNotReachHere(); |
|
1000 } |
|
1001 } |
|
1002 break; |
|
1003 |
|
1004 case MethodHandles::_adapter_opt_i2l: |
|
1005 { |
|
1006 int arg_slot = |
|
1007 java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); |
|
1008 int arg = VMSLOTS_INT(arg_slot); |
|
1009 intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle); |
|
1010 insert_vmslots(arg_slot, 1, THREAD); |
|
1011 if (HAS_PENDING_EXCEPTION) { |
|
1012 // all oops trashed |
|
1013 stack->set_sp(unwind_sp); |
|
1014 return; |
|
1015 } |
|
1016 vmslots = stack->sp(); |
|
1017 arg_slot++; |
|
1018 SET_VMSLOTS_LONG(arg, arg_slot); |
|
1019 } |
|
1020 break; |
|
1021 |
|
1022 case MethodHandles::_adapter_opt_unboxi: |
|
1023 case MethodHandles::_adapter_opt_unboxl: |
|
1024 { |
|
1025 int arg_slot = |
|
1026 java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle); |
|
1027 oop arg = VMSLOTS_OBJECT(arg_slot); |
|
1028 jvalue arg_value; |
|
1029 BasicType arg_type = java_lang_boxing_object::get_value(arg, &arg_value); |
|
1030 if (arg_type == T_LONG || arg_type == T_DOUBLE) { |
|
1031 intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle); |
|
1032 insert_vmslots(arg_slot, 1, THREAD); |
|
1033 if (HAS_PENDING_EXCEPTION) { |
|
1034 // all oops trashed |
|
1035 stack->set_sp(unwind_sp); |
|
1036 return; |
|
1037 } |
|
1038 vmslots = stack->sp(); |
|
1039 arg_slot++; |
|
1040 } |
|
1041 switch (arg_type) { |
|
1042 case T_BOOLEAN: |
|
1043 SET_VMSLOTS_INT(arg_value.z, arg_slot); |
|
1044 break; |
|
1045 case T_CHAR: |
|
1046 SET_VMSLOTS_INT(arg_value.c, arg_slot); |
|
1047 break; |
|
1048 case T_BYTE: |
|
1049 SET_VMSLOTS_INT(arg_value.b, arg_slot); |
|
1050 break; |
|
1051 case T_SHORT: |
|
1052 SET_VMSLOTS_INT(arg_value.s, arg_slot); |
|
1053 break; |
|
1054 case T_INT: |
|
1055 SET_VMSLOTS_INT(arg_value.i, arg_slot); |
|
1056 break; |
|
1057 case T_FLOAT: |
|
1058 SET_VMSLOTS_FLOAT(arg_value.f, arg_slot); |
|
1059 break; |
|
1060 case T_LONG: |
|
1061 SET_VMSLOTS_LONG(arg_value.j, arg_slot); |
|
1062 break; |
|
1063 case T_DOUBLE: |
|
1064 SET_VMSLOTS_DOUBLE(arg_value.d, arg_slot); |
|
1065 break; |
|
1066 default: |
|
1067 tty->print_cr("unhandled type %s", type2name(arg_type)); |
|
1068 ShouldNotReachHere(); |
|
1069 } |
|
1070 } |
|
1071 break; |
|
1072 |
|
1073 default: |
|
1074 tty->print_cr("unhandled entry_kind %s", |
|
1075 MethodHandles::entry_name(entry_kind)); |
|
1076 ShouldNotReachHere(); |
|
1077 } |
|
1078 |
|
1079 // Continue along the chain |
|
1080 if (direct_to_method) { |
|
1081 if (method == NULL) { |
|
1082 method = |
|
1083 (methodOop) java_lang_invoke_MethodHandle::vmtarget(method_handle); |
|
1084 } |
|
1085 address entry_point = method->from_interpreted_entry(); |
|
1086 Interpreter::invoke_method(method, entry_point, THREAD); |
|
1087 } |
|
1088 else { |
|
1089 process_method_handle( |
|
1090 java_lang_invoke_MethodHandle::vmtarget(method_handle), THREAD); |
|
1091 } |
|
1092 // NB all oops now trashed |
|
1093 |
|
1094 // Adapt the result type, if necessary |
|
1095 if (src_rtype != dst_rtype && !HAS_PENDING_EXCEPTION) { |
|
1096 switch (dst_rtype) { |
|
1097 case T_VOID: |
|
1098 for (int i = 0; i < type2size[src_rtype]; i++) |
|
1099 stack->pop(); |
|
1100 return; |
|
1101 |
|
1102 case T_INT: |
|
1103 switch (src_rtype) { |
|
1104 case T_VOID: |
|
1105 stack->overflow_check(1, CHECK); |
|
1106 stack->push(0); |
|
1107 return; |
|
1108 |
|
1109 case T_BOOLEAN: |
|
1110 case T_CHAR: |
|
1111 case T_BYTE: |
|
1112 case T_SHORT: |
|
1113 return; |
|
1114 } |
|
1115 } |
|
1116 |
|
1117 tty->print_cr("unhandled conversion:"); |
|
1118 tty->print_cr("src_rtype = %s", type2name(src_rtype)); |
|
1119 tty->print_cr("dst_rtype = %s", type2name(dst_rtype)); |
|
1120 ShouldNotReachHere(); |
|
1121 } |
|
1122 } |
|
1123 |
|
1124 // The new slots will be inserted before slot insert_before. |
|
1125 // Slots < insert_before will have the same slot number after the insert. |
|
1126 // Slots >= insert_before will become old_slot + num_slots. |
|
1127 void CppInterpreter::insert_vmslots(int insert_before, int num_slots, TRAPS) { |
|
1128 JavaThread *thread = (JavaThread *) THREAD; |
|
1129 ZeroStack *stack = thread->zero_stack(); |
|
1130 |
|
1131 // Allocate the space |
|
1132 stack->overflow_check(num_slots, CHECK); |
|
1133 stack->alloc(num_slots * wordSize); |
|
1134 intptr_t *vmslots = stack->sp(); |
|
1135 |
|
1136 // Shuffle everything up |
|
1137 for (int i = 0; i < insert_before; i++) |
|
1138 SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i + num_slots), i); |
|
1139 } |
|
1140 |
|
1141 void CppInterpreter::remove_vmslots(int first_slot, int num_slots, TRAPS) { |
|
1142 JavaThread *thread = (JavaThread *) THREAD; |
|
1143 ZeroStack *stack = thread->zero_stack(); |
|
1144 intptr_t *vmslots = stack->sp(); |
|
1145 |
|
1146 // Move everything down |
|
1147 for (int i = first_slot - 1; i >= 0; i--) |
|
1148 SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i), i + num_slots); |
|
1149 |
|
1150 // Deallocate the space |
|
1151 stack->set_sp(stack->sp() + num_slots); |
|
1152 } |
|
1153 |
|
1154 BasicType CppInterpreter::result_type_of_handle(oop method_handle) { |
|
1155 oop method_type = java_lang_invoke_MethodHandle::type(method_handle); |
|
1156 oop return_type = java_lang_invoke_MethodType::rtype(method_type); |
|
1157 return java_lang_Class::as_BasicType(return_type, (klassOop *) NULL); |
|
1158 } |
|
1159 |
|
1160 intptr_t* CppInterpreter::calculate_unwind_sp(ZeroStack* stack, |
|
1161 oop method_handle) { |
|
1162 oop method_type = java_lang_invoke_MethodHandle::type(method_handle); |
|
1163 oop form = java_lang_invoke_MethodType::form(method_type); |
|
1164 int argument_slots = java_lang_invoke_MethodTypeForm::vmslots(form); |
|
1165 |
|
1166 return stack->sp() + argument_slots; |
|
1167 } |
|
1168 |
|
1169 IRT_ENTRY(void, CppInterpreter::throw_exception(JavaThread* thread, |
|
1170 Symbol* name, |
|
1171 char* message)) |
|
1172 THROW_MSG(name, message); |
|
1173 IRT_END |
609 |
1174 |
610 InterpreterFrame *InterpreterFrame::build(const methodOop method, TRAPS) { |
1175 InterpreterFrame *InterpreterFrame::build(const methodOop method, TRAPS) { |
611 JavaThread *thread = (JavaThread *) THREAD; |
1176 JavaThread *thread = (JavaThread *) THREAD; |
612 ZeroStack *stack = thread->zero_stack(); |
1177 ZeroStack *stack = thread->zero_stack(); |
613 |
1178 |