src/cpu/zero/vm/cppInterpreter_zero.cpp

changeset 2762
4b95bbb36464
parent 2658
c7f3d0b4570f
child 2793
732454aaf5cb
equal deleted inserted replaced
2761:15c9a0e16269 2762:4b95bbb36464
1 /* 1 /*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc. 3 * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * 5 *
6 * This code is free software; you can redistribute it and/or modify it 6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as 7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
54 #ifdef CC_INTERP 54 #ifdef CC_INTERP
55 55
56 #define fixup_after_potential_safepoint() \ 56 #define fixup_after_potential_safepoint() \
57 method = istate->method() 57 method = istate->method()
58 58
59 #define CALL_VM_NOCHECK(func) \ 59 #define CALL_VM_NOCHECK_NOFIX(func) \
60 thread->set_last_Java_frame(); \ 60 thread->set_last_Java_frame(); \
61 func; \ 61 func; \
62 thread->reset_last_Java_frame(); \ 62 thread->reset_last_Java_frame();
63
64 #define CALL_VM_NOCHECK(func) \
65 CALL_VM_NOCHECK_NOFIX(func) \
63 fixup_after_potential_safepoint() 66 fixup_after_potential_safepoint()
64 67
65 int CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) { 68 int CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) {
66 JavaThread *thread = (JavaThread *) THREAD; 69 JavaThread *thread = (JavaThread *) THREAD;
67 70
174 177
175 // Jump into the OSR method 178 // Jump into the OSR method
176 Interpreter::invoke_osr( 179 Interpreter::invoke_osr(
177 method, istate->osr_entry(), istate->osr_buf(), THREAD); 180 method, istate->osr_entry(), istate->osr_buf(), THREAD);
178 return; 181 return;
182 }
183 else if (istate->msg() == BytecodeInterpreter::call_method_handle) {
184 oop method_handle = istate->callee();
185
186 // Trim back the stack to put the parameters at the top
187 stack->set_sp(istate->stack() + 1);
188
189 // Make the call
190 process_method_handle(method_handle, THREAD);
191 fixup_after_potential_safepoint();
192
193 // Convert the result
194 istate->set_stack(stack->sp() - 1);
195
196 // Restore the stack
197 stack->set_sp(istate->stack_limit() + 1);
198
199 // Resume the interpreter
200 istate->set_msg(BytecodeInterpreter::method_resume);
179 } 201 }
180 else { 202 else {
181 ShouldNotReachHere(); 203 ShouldNotReachHere();
182 } 204 }
183 } 205 }
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

mercurial