Mercurial > hg > truffle
annotate src/cpu/zero/vm/methodHandles_zero.cpp @ 7411:8580f22db905
Merge
author | coleenp |
---|---|
date | Fri, 14 Dec 2012 16:43:37 -0800 |
parents | a3e2f723f2a5 |
children |
rev | line source |
---|---|
1010 | 1 /* |
1972 | 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. |
2480 | 3 * Copyright 2009, 2010, 2011 Red Hat, Inc. |
1010 | 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
5 * | |
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 | |
8 * published by the Free Software Foundation. | |
9 * | |
10 * This code is distributed in the hope that it will be useful, but WITHOUT | |
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
13 * version 2 for more details (a copy is included in the LICENSE file that | |
14 * accompanied this code). | |
15 * | |
16 * You should have received a copy of the GNU General Public License version | |
17 * 2 along with this work; if not, write to the Free Software Foundation, | |
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
19 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1510
diff
changeset
|
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1510
diff
changeset
|
21 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1510
diff
changeset
|
22 * questions. |
1010 | 23 * |
24 */ | |
25 | |
1972 | 26 #include "precompiled.hpp" |
6926 | 27 #include "interpreter/interpreterGenerator.hpp" |
1972 | 28 #include "interpreter/interpreter.hpp" |
29 #include "memory/allocation.inline.hpp" | |
30 #include "prims/methodHandles.hpp" | |
1346 | 31 |
6926 | 32 void MethodHandles::invoke_target(Method* method, TRAPS) { |
33 | |
34 JavaThread *thread = (JavaThread *) THREAD; | |
35 ZeroStack *stack = thread->zero_stack(); | |
36 InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); | |
37 interpreterState istate = frame->interpreter_state(); | |
38 | |
39 // Trim back the stack to put the parameters at the top | |
40 stack->set_sp(istate->stack() + 1); | |
41 | |
42 Interpreter::invoke_method(method, method->from_interpreted_entry(), THREAD); | |
43 | |
44 // Convert the result | |
45 istate->set_stack(stack->sp() - 1); | |
46 | |
47 } | |
48 | |
49 oop MethodHandles::popFromStack(TRAPS) { | |
50 | |
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 | |
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; | |
1510 | 94 } |
95 | |
6926 | 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; | |
1346 | 127 } |
6926 | 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 } |