Mercurial > hg > graal-jvmci-8
comparison src/cpu/zero/vm/methodHandles_zero.cpp @ 6926:a3e2f723f2a5
8000780: make Zero build and run with JDK8
Reviewed-by: coleenp, dholmes, twisti
Contributed-by: Roman Kennke <rkennke@redhat.com>
author | twisti |
---|---|
date | Mon, 29 Oct 2012 11:08:48 -0700 |
parents | 4b95bbb36464 |
children |
comparison
equal
deleted
inserted
replaced
6915:a516debe2cee | 6926:a3e2f723f2a5 |
---|---|
22 * questions. | 22 * questions. |
23 * | 23 * |
24 */ | 24 */ |
25 | 25 |
26 #include "precompiled.hpp" | 26 #include "precompiled.hpp" |
27 #include "interpreter/interpreterGenerator.hpp" | |
27 #include "interpreter/interpreter.hpp" | 28 #include "interpreter/interpreter.hpp" |
28 #include "memory/allocation.inline.hpp" | 29 #include "memory/allocation.inline.hpp" |
29 #include "prims/methodHandles.hpp" | 30 #include "prims/methodHandles.hpp" |
30 | 31 |
31 int MethodHandles::adapter_conversion_ops_supported_mask() { | 32 void MethodHandles::invoke_target(Method* method, TRAPS) { |
32 return ((1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY) | 33 |
33 |(1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW) | 34 JavaThread *thread = (JavaThread *) THREAD; |
34 |(1<<java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST) | 35 ZeroStack *stack = thread->zero_stack(); |
35 |(1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM) | 36 InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); |
36 |(1<<java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM) | 37 interpreterState istate = frame->interpreter_state(); |
37 |(1<<java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS) | 38 |
38 |(1<<java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS) | 39 // Trim back the stack to put the parameters at the top |
39 |(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS) | 40 stack->set_sp(istate->stack() + 1); |
40 |(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS) | 41 |
41 //|(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG! | 42 Interpreter::invoke_method(method, method->from_interpreted_entry(), THREAD); |
42 ); | 43 |
43 // FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS. | 44 // Convert the result |
45 istate->set_stack(stack->sp() - 1); | |
46 | |
44 } | 47 } |
45 | 48 |
46 void MethodHandles::generate_method_handle_stub(MacroAssembler* masm, | 49 oop MethodHandles::popFromStack(TRAPS) { |
47 MethodHandles::EntryKind ek) { | 50 |
48 init_entry(ek, (MethodHandleEntry *) ek); | 51 JavaThread *thread = (JavaThread *) THREAD; |
52 InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); | |
53 interpreterState istate = frame->interpreter_state(); | |
54 intptr_t* topOfStack = istate->stack(); | |
55 | |
56 oop top = STACK_OBJECT(-1); | |
57 MORE_STACK(-1); | |
58 istate->set_stack(topOfStack); | |
59 | |
60 return top; | |
61 | |
49 } | 62 } |
63 | |
64 int MethodHandles::method_handle_entry_invokeBasic(Method* method, intptr_t UNUSED, TRAPS) { | |
65 | |
66 JavaThread *thread = (JavaThread *) THREAD; | |
67 InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); | |
68 interpreterState istate = frame->interpreter_state(); | |
69 intptr_t* topOfStack = istate->stack(); | |
70 | |
71 // 'this' is a MethodHandle. We resolve the target method by accessing this.form.vmentry.vmtarget. | |
72 int numArgs = method->size_of_parameters(); | |
73 oop lform1 = java_lang_invoke_MethodHandle::form(STACK_OBJECT(-numArgs)); // this.form | |
74 oop vmEntry1 = java_lang_invoke_LambdaForm::vmentry(lform1); | |
75 Method* vmtarget = (Method*) java_lang_invoke_MemberName::vmtarget(vmEntry1); | |
76 | |
77 invoke_target(vmtarget, THREAD); | |
78 | |
79 // No deoptimized frames on the stack | |
80 return 0; | |
81 } | |
82 | |
83 int MethodHandles::method_handle_entry_linkToStaticOrSpecial(Method* method, intptr_t UNUSED, TRAPS) { | |
84 | |
85 // Pop appendix argument from stack. This is a MemberName which we resolve to the | |
86 // target method. | |
87 oop vmentry = popFromStack(THREAD); | |
88 | |
89 Method* vmtarget = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry); | |
90 | |
91 invoke_target(vmtarget, THREAD); | |
92 | |
93 return 0; | |
94 } | |
95 | |
96 int MethodHandles::method_handle_entry_linkToInterface(Method* method, intptr_t UNUSED, TRAPS) { | |
97 JavaThread *thread = (JavaThread *) THREAD; | |
98 InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); | |
99 interpreterState istate = frame->interpreter_state(); | |
100 | |
101 // Pop appendix argument from stack. This is a MemberName which we resolve to the | |
102 // target method. | |
103 oop vmentry = popFromStack(THREAD); | |
104 intptr_t* topOfStack = istate->stack(); | |
105 | |
106 // Resolve target method by looking up in the receiver object's itable. | |
107 Klass* clazz = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(vmentry)); | |
108 intptr_t vmindex = java_lang_invoke_MemberName::vmindex(vmentry); | |
109 Method* target = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry); | |
110 | |
111 int numArgs = target->size_of_parameters(); | |
112 oop recv = STACK_OBJECT(-numArgs); | |
113 | |
114 InstanceKlass* klass_part = InstanceKlass::cast(recv->klass()); | |
115 itableOffsetEntry* ki = (itableOffsetEntry*) klass_part->start_of_itable(); | |
116 int i; | |
117 for ( i = 0 ; i < klass_part->itable_length() ; i++, ki++ ) { | |
118 if (ki->interface_klass() == clazz) break; | |
119 } | |
120 | |
121 itableMethodEntry* im = ki->first_method_entry(recv->klass()); | |
122 Method* vmtarget = im[vmindex].method(); | |
123 | |
124 invoke_target(vmtarget, THREAD); | |
125 | |
126 return 0; | |
127 } | |
128 | |
129 int MethodHandles::method_handle_entry_linkToVirtual(Method* method, intptr_t UNUSED, TRAPS) { | |
130 JavaThread *thread = (JavaThread *) THREAD; | |
131 | |
132 InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); | |
133 interpreterState istate = frame->interpreter_state(); | |
134 | |
135 // Pop appendix argument from stack. This is a MemberName which we resolve to the | |
136 // target method. | |
137 oop vmentry = popFromStack(THREAD); | |
138 intptr_t* topOfStack = istate->stack(); | |
139 | |
140 // Resolve target method by looking up in the receiver object's vtable. | |
141 intptr_t vmindex = java_lang_invoke_MemberName::vmindex(vmentry); | |
142 Method* target = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry); | |
143 int numArgs = target->size_of_parameters(); | |
144 oop recv = STACK_OBJECT(-numArgs); | |
145 Klass* clazz = recv->klass(); | |
146 Klass* klass_part = InstanceKlass::cast(clazz); | |
147 klassVtable* vtable = klass_part->vtable(); | |
148 Method* vmtarget = vtable->method_at(vmindex); | |
149 | |
150 invoke_target(vmtarget, THREAD); | |
151 | |
152 return 0; | |
153 } | |
154 | |
155 int MethodHandles::method_handle_entry_invalid(Method* method, intptr_t UNUSED, TRAPS) { | |
156 ShouldNotReachHere(); | |
157 return 0; | |
158 } | |
159 | |
160 address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* masm, | |
161 vmIntrinsics::ID iid) { | |
162 switch (iid) { | |
163 case vmIntrinsics::_invokeGeneric: | |
164 case vmIntrinsics::_compiledLambdaForm: | |
165 // Perhaps surprisingly, the symbolic references visible to Java are not directly used. | |
166 // They are linked to Java-generated adapters via MethodHandleNatives.linkMethod. | |
167 // They all allow an appendix argument. | |
168 return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_invalid); | |
169 case vmIntrinsics::_invokeBasic: | |
170 return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_invokeBasic); | |
171 case vmIntrinsics::_linkToStatic: | |
172 case vmIntrinsics::_linkToSpecial: | |
173 return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_linkToStaticOrSpecial); | |
174 case vmIntrinsics::_linkToInterface: | |
175 return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_linkToInterface); | |
176 case vmIntrinsics::_linkToVirtual: | |
177 return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_linkToVirtual); | |
178 default: | |
179 ShouldNotReachHere(); | |
180 return NULL; | |
181 } | |
182 } |