Mercurial > hg > graal-jvmci-8
comparison src/cpu/zero/vm/cppInterpreter_zero.cpp @ 2480:4b95bbb36464
7035870: JSR 292: Zero support
Summary: This adds support for JSR 292 to Zero.
Reviewed-by: twisti
Contributed-by: Gary Benson <gbenson@redhat.com>
author | twisti |
---|---|
date | Tue, 12 Apr 2011 02:40:23 -0700 |
parents | c7f3d0b4570f |
children | 732454aaf5cb |
comparison
equal
deleted
inserted
replaced
2479:15c9a0e16269 | 2480: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 |