Mercurial > hg > truffle
annotate src/cpu/x86/vm/methodHandles_x86.cpp @ 3101:6ccb95c97e6d
IdealGraphVisualizer: Work around a problem with JSplitPane and the NetBeans editor: setDividerLocation() doesn't work when the split pane has not been layouted and painted yet. JSplitPane then initially uses a tiny width for the left editor component, which causes the editor to calculate invalid offsets and constantly throw exceptions, particularly on mouse events. Thus, defer adding the two components and setting the divider's location.
author | Peter Hofer <peter.hofer@jku.at> |
---|---|
date | Thu, 30 Jun 2011 12:17:27 +0200 |
parents | 8033953d67ff |
children | 2e038ad0c1d0 |
rev | line source |
---|---|
710 | 1 /* |
2116
d810e9a3fc33
7010180: JSR 292 InvokeDynamicPrintArgs fails with: assert(_adapter == NULL) failed: init'd to NULL
twisti
parents:
2088
diff
changeset
|
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
710 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1507
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1507
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1507
diff
changeset
|
21 * questions. |
710 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "interpreter/interpreter.hpp" | |
27 #include "memory/allocation.inline.hpp" | |
28 #include "prims/methodHandles.hpp" | |
710 | 29 |
30 #define __ _masm-> | |
31 | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
32 #ifdef PRODUCT |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
33 #define BLOCK_COMMENT(str) /* nothing */ |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
34 #else |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
35 #define BLOCK_COMMENT(str) __ block_comment(str) |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
36 #endif |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
37 |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
38 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":") |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
39 |
710 | 40 address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm, |
41 address interpreted_entry) { | |
42 // Just before the actual machine code entry point, allocate space | |
43 // for a MethodHandleEntry::Data record, so that we can manage everything | |
44 // from one base pointer. | |
45 __ align(wordSize); | |
46 address target = __ pc() + sizeof(Data); | |
47 while (__ pc() < target) { | |
48 __ nop(); | |
49 __ align(wordSize); | |
50 } | |
51 | |
52 MethodHandleEntry* me = (MethodHandleEntry*) __ pc(); | |
53 me->set_end_address(__ pc()); // set a temporary end_address | |
54 me->set_from_interpreted_entry(interpreted_entry); | |
55 me->set_type_checking_entry(NULL); | |
56 | |
57 return (address) me; | |
58 } | |
59 | |
60 MethodHandleEntry* MethodHandleEntry::finish_compiled_entry(MacroAssembler* _masm, | |
61 address start_addr) { | |
62 MethodHandleEntry* me = (MethodHandleEntry*) start_addr; | |
63 assert(me->end_address() == start_addr, "valid ME"); | |
64 | |
65 // Fill in the real end_address: | |
66 __ align(wordSize); | |
67 me->set_end_address(__ pc()); | |
68 | |
69 return me; | |
70 } | |
71 | |
72 #ifdef ASSERT | |
1304 | 73 static void verify_argslot(MacroAssembler* _masm, Register argslot_reg, |
710 | 74 const char* error_message) { |
75 // Verify that argslot lies within (rsp, rbp]. | |
76 Label L_ok, L_bad; | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
77 BLOCK_COMMENT("{ verify_argslot"); |
1304 | 78 __ cmpptr(argslot_reg, rbp); |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
79 __ jccb(Assembler::above, L_bad); |
1304 | 80 __ cmpptr(rsp, argslot_reg); |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
81 __ jccb(Assembler::below, L_ok); |
710 | 82 __ bind(L_bad); |
83 __ stop(error_message); | |
84 __ bind(L_ok); | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
85 BLOCK_COMMENT("} verify_argslot"); |
710 | 86 } |
87 #endif | |
88 | |
89 | |
90 // Code generation | |
91 address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm) { | |
92 // rbx: methodOop | |
93 // rcx: receiver method handle (must load from sp[MethodTypeForm.vmslots]) | |
94 // rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted) | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
95 // rdx, rdi: garbage temp, blown away |
710 | 96 |
97 Register rbx_method = rbx; | |
98 Register rcx_recv = rcx; | |
99 Register rax_mtype = rax; | |
100 Register rdx_temp = rdx; | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
101 Register rdi_temp = rdi; |
710 | 102 |
103 // emit WrongMethodType path first, to enable jccb back-branch from main path | |
104 Label wrong_method_type; | |
105 __ bind(wrong_method_type); | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
106 Label invoke_generic_slow_path; |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
107 assert(methodOopDesc::intrinsic_id_size_in_bytes() == sizeof(u1), "");; |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
108 __ cmpb(Address(rbx_method, methodOopDesc::intrinsic_id_offset_in_bytes()), (int) vmIntrinsics::_invokeExact); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
109 __ jcc(Assembler::notEqual, invoke_generic_slow_path); |
710 | 110 __ push(rax_mtype); // required mtype |
111 __ push(rcx_recv); // bad mh (1st stacked argument) | |
112 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); | |
113 | |
114 // here's where control starts out: | |
115 __ align(CodeEntryAlignment); | |
116 address entry_point = __ pc(); | |
117 | |
118 // fetch the MethodType from the method handle into rax (the 'check' register) | |
119 { | |
120 Register tem = rbx_method; | |
121 for (jint* pchase = methodOopDesc::method_type_offsets_chain(); (*pchase) != -1; pchase++) { | |
122 __ movptr(rax_mtype, Address(tem, *pchase)); | |
123 tem = rax_mtype; // in case there is another indirection | |
124 } | |
125 } | |
126 | |
127 // given the MethodType, find out where the MH argument is buried | |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
128 __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, rdi_temp))); |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
129 Register rdx_vmslots = rdx_temp; |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
130 __ movl(rdx_vmslots, Address(rdx_temp, __ delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp))); |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
131 __ movptr(rcx_recv, __ argument_address(rdx_vmslots)); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
132 |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
133 trace_method_handle(_masm, "invokeExact"); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
134 |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
135 __ check_method_handle_type(rax_mtype, rcx_recv, rdi_temp, wrong_method_type); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
136 __ jump_to_method_handle_entry(rcx_recv, rdi_temp); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
137 |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
138 // for invokeGeneric (only), apply argument and result conversions on the fly |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
139 __ bind(invoke_generic_slow_path); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
140 #ifdef ASSERT |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
141 { Label L; |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
142 __ cmpb(Address(rbx_method, methodOopDesc::intrinsic_id_offset_in_bytes()), (int) vmIntrinsics::_invokeGeneric); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
143 __ jcc(Assembler::equal, L); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
144 __ stop("bad methodOop::intrinsic_id"); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
145 __ bind(L); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
146 } |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
147 #endif //ASSERT |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
148 Register rbx_temp = rbx_method; // don't need it now |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
149 |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
150 // make room on the stack for another pointer: |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
151 Register rcx_argslot = rcx_recv; |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
152 __ lea(rcx_argslot, __ argument_address(rdx_vmslots, 1)); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
153 insert_arg_slots(_masm, 2 * stack_move_unit(), _INSERT_REF_MASK, |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
154 rcx_argslot, rbx_temp, rdx_temp); |
710 | 155 |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
156 // load up an adapter from the calling type (Java weaves this) |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
157 __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, rdi_temp))); |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
158 Register rdx_adapter = rdx_temp; |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
159 // __ load_heap_oop(rdx_adapter, Address(rdx_temp, java_lang_invoke_MethodTypeForm::genericInvoker_offset_in_bytes())); |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
160 // deal with old JDK versions: |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
161 __ lea(rdi_temp, Address(rdx_temp, __ delayed_value(java_lang_invoke_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp))); |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
162 __ cmpptr(rdi_temp, rdx_temp); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
163 Label sorry_no_invoke_generic; |
1846 | 164 __ jcc(Assembler::below, sorry_no_invoke_generic); |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
165 |
1846 | 166 __ load_heap_oop(rdx_adapter, Address(rdi_temp, 0)); |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
167 __ testptr(rdx_adapter, rdx_adapter); |
1846 | 168 __ jcc(Assembler::zero, sorry_no_invoke_generic); |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
169 __ movptr(Address(rcx_argslot, 1 * Interpreter::stackElementSize), rdx_adapter); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
170 // As a trusted first argument, pass the type being called, so the adapter knows |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
171 // the actual types of the arguments and return values. |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
172 // (Generic invokers are shared among form-families of method-type.) |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
173 __ movptr(Address(rcx_argslot, 0 * Interpreter::stackElementSize), rax_mtype); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
174 // FIXME: assert that rdx_adapter is of the right method-type. |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
175 __ mov(rcx, rdx_adapter); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
176 trace_method_handle(_masm, "invokeGeneric"); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
177 __ jump_to_method_handle_entry(rcx, rdi_temp); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
178 |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
179 __ bind(sorry_no_invoke_generic); // no invokeGeneric implementation available! |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
180 __ movptr(rcx_recv, Address(rcx_argslot, -1 * Interpreter::stackElementSize)); // recover original MH |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
181 __ push(rax_mtype); // required mtype |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
182 __ push(rcx_recv); // bad mh (1st stacked argument) |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
183 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); |
710 | 184 |
185 return entry_point; | |
186 } | |
187 | |
188 // Helper to insert argument slots into the stack. | |
189 // arg_slots must be a multiple of stack_move_unit() and <= 0 | |
190 void MethodHandles::insert_arg_slots(MacroAssembler* _masm, | |
191 RegisterOrConstant arg_slots, | |
192 int arg_mask, | |
193 Register rax_argslot, | |
1503 | 194 Register rbx_temp, Register rdx_temp, Register temp3_reg) { |
195 assert(temp3_reg == noreg, "temp3 not required"); | |
710 | 196 assert_different_registers(rax_argslot, rbx_temp, rdx_temp, |
197 (!arg_slots.is_register() ? rsp : arg_slots.as_register())); | |
198 | |
199 #ifdef ASSERT | |
200 verify_argslot(_masm, rax_argslot, "insertion point must fall within current frame"); | |
201 if (arg_slots.is_register()) { | |
202 Label L_ok, L_bad; | |
203 __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD); | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
204 __ jccb(Assembler::greater, L_bad); |
710 | 205 __ testl(arg_slots.as_register(), -stack_move_unit() - 1); |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
206 __ jccb(Assembler::zero, L_ok); |
710 | 207 __ bind(L_bad); |
208 __ stop("assert arg_slots <= 0 and clear low bits"); | |
209 __ bind(L_ok); | |
210 } else { | |
211 assert(arg_slots.as_constant() <= 0, ""); | |
212 assert(arg_slots.as_constant() % -stack_move_unit() == 0, ""); | |
213 } | |
214 #endif //ASSERT | |
215 | |
216 #ifdef _LP64 | |
217 if (arg_slots.is_register()) { | |
218 // clean high bits of stack motion register (was loaded as an int) | |
219 __ movslq(arg_slots.as_register(), arg_slots.as_register()); | |
220 } | |
221 #endif | |
222 | |
223 // Make space on the stack for the inserted argument(s). | |
224 // Then pull down everything shallower than rax_argslot. | |
225 // The stacked return address gets pulled down with everything else. | |
226 // That is, copy [rsp, argslot) downward by -size words. In pseudo-code: | |
227 // rsp -= size; | |
228 // for (rdx = rsp + size; rdx < argslot; rdx++) | |
229 // rdx[-size] = rdx[0] | |
230 // argslot -= size; | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
231 BLOCK_COMMENT("insert_arg_slots {"); |
710 | 232 __ mov(rdx_temp, rsp); // source pointer for copy |
233 __ lea(rsp, Address(rsp, arg_slots, Address::times_ptr)); | |
234 { | |
235 Label loop; | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
236 __ BIND(loop); |
710 | 237 // pull one word down each time through the loop |
238 __ movptr(rbx_temp, Address(rdx_temp, 0)); | |
239 __ movptr(Address(rdx_temp, arg_slots, Address::times_ptr), rbx_temp); | |
240 __ addptr(rdx_temp, wordSize); | |
241 __ cmpptr(rdx_temp, rax_argslot); | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
242 __ jccb(Assembler::less, loop); |
710 | 243 } |
244 | |
245 // Now move the argslot down, to point to the opened-up space. | |
246 __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr)); | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
247 BLOCK_COMMENT("} insert_arg_slots"); |
710 | 248 } |
249 | |
250 // Helper to remove argument slots from the stack. | |
251 // arg_slots must be a multiple of stack_move_unit() and >= 0 | |
252 void MethodHandles::remove_arg_slots(MacroAssembler* _masm, | |
253 RegisterOrConstant arg_slots, | |
254 Register rax_argslot, | |
1503 | 255 Register rbx_temp, Register rdx_temp, Register temp3_reg) { |
256 assert(temp3_reg == noreg, "temp3 not required"); | |
710 | 257 assert_different_registers(rax_argslot, rbx_temp, rdx_temp, |
258 (!arg_slots.is_register() ? rsp : arg_slots.as_register())); | |
259 | |
260 #ifdef ASSERT | |
1304 | 261 // Verify that [argslot..argslot+size) lies within (rsp, rbp). |
262 __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr)); | |
263 verify_argslot(_masm, rbx_temp, "deleted argument(s) must fall within current frame"); | |
710 | 264 if (arg_slots.is_register()) { |
265 Label L_ok, L_bad; | |
266 __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD); | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
267 __ jccb(Assembler::less, L_bad); |
710 | 268 __ testl(arg_slots.as_register(), -stack_move_unit() - 1); |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
269 __ jccb(Assembler::zero, L_ok); |
710 | 270 __ bind(L_bad); |
271 __ stop("assert arg_slots >= 0 and clear low bits"); | |
272 __ bind(L_ok); | |
273 } else { | |
274 assert(arg_slots.as_constant() >= 0, ""); | |
275 assert(arg_slots.as_constant() % -stack_move_unit() == 0, ""); | |
276 } | |
277 #endif //ASSERT | |
278 | |
279 #ifdef _LP64 | |
280 if (false) { // not needed, since register is positive | |
281 // clean high bits of stack motion register (was loaded as an int) | |
282 if (arg_slots.is_register()) | |
283 __ movslq(arg_slots.as_register(), arg_slots.as_register()); | |
284 } | |
285 #endif | |
286 | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
287 BLOCK_COMMENT("remove_arg_slots {"); |
710 | 288 // Pull up everything shallower than rax_argslot. |
289 // Then remove the excess space on the stack. | |
290 // The stacked return address gets pulled up with everything else. | |
291 // That is, copy [rsp, argslot) upward by size words. In pseudo-code: | |
292 // for (rdx = argslot-1; rdx >= rsp; --rdx) | |
293 // rdx[size] = rdx[0] | |
294 // argslot += size; | |
295 // rsp += size; | |
296 __ lea(rdx_temp, Address(rax_argslot, -wordSize)); // source pointer for copy | |
297 { | |
298 Label loop; | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
299 __ BIND(loop); |
710 | 300 // pull one word up each time through the loop |
301 __ movptr(rbx_temp, Address(rdx_temp, 0)); | |
302 __ movptr(Address(rdx_temp, arg_slots, Address::times_ptr), rbx_temp); | |
303 __ addptr(rdx_temp, -wordSize); | |
304 __ cmpptr(rdx_temp, rsp); | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
305 __ jccb(Assembler::greaterEqual, loop); |
710 | 306 } |
307 | |
308 // Now move the argslot up, to point to the just-copied block. | |
309 __ lea(rsp, Address(rsp, arg_slots, Address::times_ptr)); | |
310 // And adjust the argslot address to point at the deletion point. | |
311 __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr)); | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
312 BLOCK_COMMENT("} remove_arg_slots"); |
710 | 313 } |
314 | |
315 #ifndef PRODUCT | |
1133
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1108
diff
changeset
|
316 extern "C" void print_method_handle(oop mh); |
710 | 317 void trace_method_handle_stub(const char* adaptername, |
1133
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1108
diff
changeset
|
318 oop mh, |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
319 intptr_t* saved_regs, |
710 | 320 intptr_t* entry_sp, |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
321 intptr_t* saved_sp, |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
322 intptr_t* saved_bp) { |
710 | 323 // called as a leaf from native code: do not block the JVM! |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
324 intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset]; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
325 intptr_t* base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset]; |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
326 printf("MH %s mh="INTPTR_FORMAT" sp=("INTPTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="INTPTR_FORMAT"\n", |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
327 adaptername, (intptr_t)mh, (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp); |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
328 if (last_sp != saved_sp && last_sp != NULL) |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
329 printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp); |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
330 if (Verbose) { |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
331 printf(" reg dump: "); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
332 int saved_regs_count = (entry_sp-1) - saved_regs; |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
333 // 32 bit: rdi rsi rbp rsp; rbx rdx rcx (*) rax |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
334 int i; |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
335 for (i = 0; i <= saved_regs_count; i++) { |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
336 if (i > 0 && i % 4 == 0 && i != saved_regs_count) |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
337 printf("\n + dump: "); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
338 printf(" %d: "INTPTR_FORMAT, i, saved_regs[i]); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
339 } |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
340 printf("\n"); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
341 int stack_dump_count = 16; |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
342 if (stack_dump_count < (int)(saved_bp + 2 - saved_sp)) |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
343 stack_dump_count = (int)(saved_bp + 2 - saved_sp); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
344 if (stack_dump_count > 64) stack_dump_count = 48; |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
345 for (i = 0; i < stack_dump_count; i += 4) { |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
346 printf(" dump at SP[%d] "INTPTR_FORMAT": "INTPTR_FORMAT" "INTPTR_FORMAT" "INTPTR_FORMAT" "INTPTR_FORMAT"\n", |
1818
c93c652551b5
6986944: JSR 292 assert(caller_nm->is_method_handle_return(caller_frame.pc())) failed: must be MH call site
twisti
parents:
1793
diff
changeset
|
347 i, (intptr_t) &entry_sp[i+0], entry_sp[i+0], entry_sp[i+1], entry_sp[i+2], entry_sp[i+3]); |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
348 } |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
349 print_method_handle(mh); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
350 } |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
351 } |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
352 void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
353 if (!TraceMethodHandles) return; |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
354 BLOCK_COMMENT("trace_method_handle {"); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
355 __ push(rax); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
356 __ lea(rax, Address(rsp, wordSize*6)); // entry_sp |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
357 __ pusha(); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
358 // arguments: |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
359 __ push(rbp); // interpreter frame pointer |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
360 __ push(rsi); // saved_sp |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
361 __ push(rax); // entry_sp |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
362 __ push(rcx); // mh |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
363 __ push(rcx); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
364 __ movptr(Address(rsp, 0), (intptr_t) adaptername); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
365 __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), 5); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
366 __ popa(); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
367 __ pop(rax); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
368 BLOCK_COMMENT("} trace_method_handle"); |
710 | 369 } |
370 #endif //PRODUCT | |
371 | |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
372 // which conversion op types are implemented here? |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
373 int MethodHandles::adapter_conversion_ops_supported_mask() { |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
374 return ((1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY) |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
375 |(1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW) |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
376 |(1<<java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST) |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
377 |(1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM) |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
378 |(1<<java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM) |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
379 |(1<<java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS) |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
380 |(1<<java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS) |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
381 |(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS) |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
382 |(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS) |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
383 //|(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG! |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
384 ); |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
385 // FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS. |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
386 } |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
387 |
2088
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
388 //------------------------------------------------------------------------------ |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
389 // MethodHandles::generate_method_handle_stub |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
390 // |
710 | 391 // Generate an "entry" field for a method handle. |
392 // This determines how the method handle will respond to calls. | |
2116
d810e9a3fc33
7010180: JSR 292 InvokeDynamicPrintArgs fails with: assert(_adapter == NULL) failed: init'd to NULL
twisti
parents:
2088
diff
changeset
|
393 void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) { |
710 | 394 // Here is the register state during an interpreted call, |
395 // as set up by generate_method_handle_interpreter_entry(): | |
396 // - rbx: garbage temp (was MethodHandle.invoke methodOop, unused) | |
397 // - rcx: receiver method handle | |
398 // - rax: method handle type (only used by the check_mtype entry point) | |
399 // - rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted) | |
400 // - rdx: garbage temp, can blow away | |
401 | |
2088
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
402 const Register rcx_recv = rcx; |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
403 const Register rax_argslot = rax; |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
404 const Register rbx_temp = rbx; |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
405 const Register rdx_temp = rdx; |
710 | 406 |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
407 // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls) |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
408 // and gen_c2i_adapter (from compiled calls): |
2088
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
409 const Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi); |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
410 |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
411 // Argument registers for _raise_exception. |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
412 // 32-bit: Pass first two oop/int args in registers ECX and EDX. |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
413 const Register rarg0_code = LP64_ONLY(j_rarg0) NOT_LP64(rcx); |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
414 const Register rarg1_actual = LP64_ONLY(j_rarg1) NOT_LP64(rdx); |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
415 const Register rarg2_required = LP64_ONLY(j_rarg2) NOT_LP64(rdi); |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
416 assert_different_registers(rarg0_code, rarg1_actual, rarg2_required, saved_last_sp); |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
417 |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
418 guarantee(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets"); |
710 | 419 |
420 // some handy addresses | |
421 Address rbx_method_fie( rbx, methodOopDesc::from_interpreted_offset() ); | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2258
diff
changeset
|
422 Address rbx_method_fce( rbx, methodOopDesc::from_compiled_offset() ); |
710 | 423 |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
424 Address rcx_mh_vmtarget( rcx_recv, java_lang_invoke_MethodHandle::vmtarget_offset_in_bytes() ); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
425 Address rcx_dmh_vmindex( rcx_recv, java_lang_invoke_DirectMethodHandle::vmindex_offset_in_bytes() ); |
710 | 426 |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
427 Address rcx_bmh_vmargslot( rcx_recv, java_lang_invoke_BoundMethodHandle::vmargslot_offset_in_bytes() ); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
428 Address rcx_bmh_argument( rcx_recv, java_lang_invoke_BoundMethodHandle::argument_offset_in_bytes() ); |
710 | 429 |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
430 Address rcx_amh_vmargslot( rcx_recv, java_lang_invoke_AdapterMethodHandle::vmargslot_offset_in_bytes() ); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
431 Address rcx_amh_argument( rcx_recv, java_lang_invoke_AdapterMethodHandle::argument_offset_in_bytes() ); |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
432 Address rcx_amh_conversion( rcx_recv, java_lang_invoke_AdapterMethodHandle::conversion_offset_in_bytes() ); |
710 | 433 Address vmarg; // __ argument_address(vmargslot) |
434 | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
435 const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
436 |
710 | 437 if (have_entry(ek)) { |
438 __ nop(); // empty stubs make SG sick | |
439 return; | |
440 } | |
441 | |
442 address interp_entry = __ pc(); | |
443 | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
444 trace_method_handle(_masm, entry_name(ek)); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
445 |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1552
diff
changeset
|
446 BLOCK_COMMENT(entry_name(ek)); |
710 | 447 |
448 switch ((int) ek) { | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
449 case _raise_exception: |
710 | 450 { |
2088
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
451 // Not a real MH entry, but rather shared code for raising an |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2258
diff
changeset
|
452 // exception. Since we use the compiled entry, arguments are |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2258
diff
changeset
|
453 // expected in compiler argument registers. |
2116
d810e9a3fc33
7010180: JSR 292 InvokeDynamicPrintArgs fails with: assert(_adapter == NULL) failed: init'd to NULL
twisti
parents:
2088
diff
changeset
|
454 assert(raise_exception_method(), "must be set"); |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2258
diff
changeset
|
455 assert(raise_exception_method()->from_compiled_entry(), "method must be linked"); |
710 | 456 |
2088
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
457 const Register rdi_pc = rax; |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
458 __ pop(rdi_pc); // caller PC |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
459 __ mov(rsp, saved_last_sp); // cut the stack back to where the caller started |
710 | 460 |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
461 Register rbx_method = rbx_temp; |
2088
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
462 Label L_no_method; |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2321
diff
changeset
|
463 // FIXME: fill in _raise_exception_method with a suitable java.lang.invoke method |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
464 __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method)); |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
465 __ testptr(rbx_method, rbx_method); |
2088
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
466 __ jccb(Assembler::zero, L_no_method); |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
467 |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
468 const int jobject_oop_offset = 0; |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
469 __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
470 __ testptr(rbx_method, rbx_method); |
2088
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
471 __ jccb(Assembler::zero, L_no_method); |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
472 __ verify_oop(rbx_method); |
2088
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
473 |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
474 NOT_LP64(__ push(rarg2_required)); |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2258
diff
changeset
|
475 __ push(rdi_pc); // restore caller PC |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2258
diff
changeset
|
476 __ jmp(rbx_method_fce); // jump to compiled entry |
2088
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
477 |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
478 // Do something that is at least causes a valid throw from the interpreter. |
2088
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
479 __ bind(L_no_method); |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
480 __ push(rarg2_required); |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
481 __ push(rarg1_actual); |
710 | 482 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); |
483 } | |
484 break; | |
485 | |
486 case _invokestatic_mh: | |
487 case _invokespecial_mh: | |
488 { | |
489 Register rbx_method = rbx_temp; | |
1846 | 490 __ load_heap_oop(rbx_method, rcx_mh_vmtarget); // target is a methodOop |
710 | 491 __ verify_oop(rbx_method); |
492 // same as TemplateTable::invokestatic or invokespecial, | |
493 // minus the CP setup and profiling: | |
494 if (ek == _invokespecial_mh) { | |
495 // Must load & check the first argument before entering the target method. | |
496 __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp); | |
497 __ movptr(rcx_recv, __ argument_address(rax_argslot, -1)); | |
498 __ null_check(rcx_recv); | |
499 __ verify_oop(rcx_recv); | |
500 } | |
501 __ jmp(rbx_method_fie); | |
502 } | |
503 break; | |
504 | |
505 case _invokevirtual_mh: | |
506 { | |
507 // same as TemplateTable::invokevirtual, | |
508 // minus the CP setup and profiling: | |
509 | |
510 // pick out the vtable index and receiver offset from the MH, | |
511 // and then we can discard it: | |
512 __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp); | |
513 Register rbx_index = rbx_temp; | |
514 __ movl(rbx_index, rcx_dmh_vmindex); | |
515 // Note: The verifier allows us to ignore rcx_mh_vmtarget. | |
516 __ movptr(rcx_recv, __ argument_address(rax_argslot, -1)); | |
517 __ null_check(rcx_recv, oopDesc::klass_offset_in_bytes()); | |
518 | |
519 // get receiver klass | |
520 Register rax_klass = rax_argslot; | |
521 __ load_klass(rax_klass, rcx_recv); | |
522 __ verify_oop(rax_klass); | |
523 | |
524 // get target methodOop & entry point | |
525 const int base = instanceKlass::vtable_start_offset() * wordSize; | |
526 assert(vtableEntry::size() * wordSize == wordSize, "adjust the scaling in the code below"); | |
527 Address vtable_entry_addr(rax_klass, | |
528 rbx_index, Address::times_ptr, | |
529 base + vtableEntry::method_offset_in_bytes()); | |
530 Register rbx_method = rbx_temp; | |
1108 | 531 __ movptr(rbx_method, vtable_entry_addr); |
710 | 532 |
533 __ verify_oop(rbx_method); | |
534 __ jmp(rbx_method_fie); | |
535 } | |
536 break; | |
537 | |
538 case _invokeinterface_mh: | |
539 { | |
540 // same as TemplateTable::invokeinterface, | |
541 // minus the CP setup and profiling: | |
542 | |
543 // pick out the interface and itable index from the MH. | |
544 __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp); | |
545 Register rdx_intf = rdx_temp; | |
546 Register rbx_index = rbx_temp; | |
1846 | 547 __ load_heap_oop(rdx_intf, rcx_mh_vmtarget); |
548 __ movl(rbx_index, rcx_dmh_vmindex); | |
710 | 549 __ movptr(rcx_recv, __ argument_address(rax_argslot, -1)); |
550 __ null_check(rcx_recv, oopDesc::klass_offset_in_bytes()); | |
551 | |
552 // get receiver klass | |
553 Register rax_klass = rax_argslot; | |
554 __ load_klass(rax_klass, rcx_recv); | |
555 __ verify_oop(rax_klass); | |
556 | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
557 Register rdi_temp = rdi; |
710 | 558 Register rbx_method = rbx_index; |
559 | |
560 // get interface klass | |
561 Label no_such_interface; | |
562 __ verify_oop(rdx_intf); | |
563 __ lookup_interface_method(rax_klass, rdx_intf, | |
564 // note: next two args must be the same: | |
565 rbx_index, rbx_method, | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
566 rdi_temp, |
710 | 567 no_such_interface); |
568 | |
569 __ verify_oop(rbx_method); | |
570 __ jmp(rbx_method_fie); | |
571 __ hlt(); | |
572 | |
573 __ bind(no_such_interface); | |
574 // Throw an exception. | |
575 // For historical reasons, it will be IncompatibleClassChangeError. | |
2088
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
576 __ mov(rbx_temp, rcx_recv); // rarg2_required might be RCX |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
577 assert_different_registers(rarg2_required, rbx_temp); |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
578 __ movptr(rarg2_required, Address(rdx_intf, java_mirror_offset)); // required interface |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
579 __ mov( rarg1_actual, rbx_temp); // bad receiver |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
580 __ movl( rarg0_code, (int) Bytecodes::_invokeinterface); // who is complaining? |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
581 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); |
710 | 582 } |
583 break; | |
584 | |
585 case _bound_ref_mh: | |
586 case _bound_int_mh: | |
587 case _bound_long_mh: | |
588 case _bound_ref_direct_mh: | |
589 case _bound_int_direct_mh: | |
590 case _bound_long_direct_mh: | |
591 { | |
592 bool direct_to_method = (ek >= _bound_ref_direct_mh); | |
1304 | 593 BasicType arg_type = T_ILLEGAL; |
594 int arg_mask = _INSERT_NO_MASK; | |
595 int arg_slots = -1; | |
596 get_ek_bound_mh_info(ek, arg_type, arg_mask, arg_slots); | |
710 | 597 |
598 // make room for the new argument: | |
599 __ movl(rax_argslot, rcx_bmh_vmargslot); | |
600 __ lea(rax_argslot, __ argument_address(rax_argslot)); | |
2258
28bf941f445e
7018378: JSR 292: _bound_int_mh produces wrong result on 64-bit SPARC
twisti
parents:
2116
diff
changeset
|
601 |
28bf941f445e
7018378: JSR 292: _bound_int_mh produces wrong result on 64-bit SPARC
twisti
parents:
2116
diff
changeset
|
602 insert_arg_slots(_masm, arg_slots * stack_move_unit(), arg_mask, rax_argslot, rbx_temp, rdx_temp); |
710 | 603 |
604 // store bound argument into the new stack slot: | |
1846 | 605 __ load_heap_oop(rbx_temp, rcx_bmh_argument); |
710 | 606 if (arg_type == T_OBJECT) { |
607 __ movptr(Address(rax_argslot, 0), rbx_temp); | |
608 } else { | |
2258
28bf941f445e
7018378: JSR 292: _bound_int_mh produces wrong result on 64-bit SPARC
twisti
parents:
2116
diff
changeset
|
609 Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type)); |
28bf941f445e
7018378: JSR 292: _bound_int_mh produces wrong result on 64-bit SPARC
twisti
parents:
2116
diff
changeset
|
610 const int arg_size = type2aelembytes(arg_type); |
28bf941f445e
7018378: JSR 292: _bound_int_mh produces wrong result on 64-bit SPARC
twisti
parents:
2116
diff
changeset
|
611 __ load_sized_value(rdx_temp, prim_value_addr, arg_size, is_signed_subword_type(arg_type), rbx_temp); |
28bf941f445e
7018378: JSR 292: _bound_int_mh produces wrong result on 64-bit SPARC
twisti
parents:
2116
diff
changeset
|
612 __ store_sized_value(Address(rax_argslot, 0), rdx_temp, arg_size, rbx_temp); |
710 | 613 } |
614 | |
615 if (direct_to_method) { | |
616 Register rbx_method = rbx_temp; | |
1846 | 617 __ load_heap_oop(rbx_method, rcx_mh_vmtarget); |
710 | 618 __ verify_oop(rbx_method); |
619 __ jmp(rbx_method_fie); | |
620 } else { | |
1846 | 621 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); |
710 | 622 __ verify_oop(rcx_recv); |
623 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); | |
624 } | |
625 } | |
626 break; | |
627 | |
628 case _adapter_retype_only: | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
629 case _adapter_retype_raw: |
710 | 630 // immediately jump to the next MH layer: |
1846 | 631 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); |
710 | 632 __ verify_oop(rcx_recv); |
633 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); | |
634 // This is OK when all parameter types widen. | |
635 // It is also OK when a return type narrows. | |
636 break; | |
637 | |
638 case _adapter_check_cast: | |
639 { | |
640 // temps: | |
641 Register rbx_klass = rbx_temp; // interesting AMH data | |
642 | |
643 // check a reference argument before jumping to the next layer of MH: | |
644 __ movl(rax_argslot, rcx_amh_vmargslot); | |
645 vmarg = __ argument_address(rax_argslot); | |
646 | |
647 // What class are we casting to? | |
1846 | 648 __ load_heap_oop(rbx_klass, rcx_amh_argument); // this is a Class object! |
649 __ load_heap_oop(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes())); | |
710 | 650 |
651 Label done; | |
652 __ movptr(rdx_temp, vmarg); | |
1277 | 653 __ testptr(rdx_temp, rdx_temp); |
1846 | 654 __ jcc(Assembler::zero, done); // no cast if null |
710 | 655 __ load_klass(rdx_temp, rdx_temp); |
656 | |
657 // live at this point: | |
658 // - rbx_klass: klass required by the target method | |
659 // - rdx_temp: argument klass to test | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
660 // - rcx_recv: adapter method handle |
710 | 661 __ check_klass_subtype(rdx_temp, rbx_klass, rax_argslot, done); |
662 | |
663 // If we get here, the type check failed! | |
664 // Call the wrong_method_type stub, passing the failing argument type in rax. | |
665 Register rax_mtype = rax_argslot; | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
666 __ movl(rax_argslot, rcx_amh_vmargslot); // reload argslot field |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
667 __ movptr(rdx_temp, vmarg); |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
668 |
2088
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
669 assert_different_registers(rarg2_required, rdx_temp); |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
670 __ load_heap_oop(rarg2_required, rcx_amh_argument); // required class |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
671 __ mov( rarg1_actual, rdx_temp); // bad object |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
672 __ movl( rarg0_code, (int) Bytecodes::_checkcast); // who is complaining? |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
673 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); |
710 | 674 |
675 __ bind(done); | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
676 // get the new MH: |
1846 | 677 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); |
710 | 678 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); |
679 } | |
680 break; | |
681 | |
682 case _adapter_prim_to_prim: | |
683 case _adapter_ref_to_prim: | |
684 // handled completely by optimized cases | |
685 __ stop("init_AdapterMethodHandle should not issue this"); | |
686 break; | |
687 | |
688 case _adapter_opt_i2i: // optimized subcase of adapt_prim_to_prim | |
689 //case _adapter_opt_f2i: // optimized subcase of adapt_prim_to_prim | |
690 case _adapter_opt_l2i: // optimized subcase of adapt_prim_to_prim | |
691 case _adapter_opt_unboxi: // optimized subcase of adapt_ref_to_prim | |
692 { | |
693 // perform an in-place conversion to int or an int subword | |
694 __ movl(rax_argslot, rcx_amh_vmargslot); | |
695 vmarg = __ argument_address(rax_argslot); | |
696 | |
697 switch (ek) { | |
698 case _adapter_opt_i2i: | |
699 __ movl(rdx_temp, vmarg); | |
700 break; | |
701 case _adapter_opt_l2i: | |
702 { | |
703 // just delete the extra slot; on a little-endian machine we keep the first | |
704 __ lea(rax_argslot, __ argument_address(rax_argslot, 1)); | |
705 remove_arg_slots(_masm, -stack_move_unit(), | |
706 rax_argslot, rbx_temp, rdx_temp); | |
1506 | 707 vmarg = Address(rax_argslot, -Interpreter::stackElementSize); |
710 | 708 __ movl(rdx_temp, vmarg); |
709 } | |
710 break; | |
711 case _adapter_opt_unboxi: | |
712 { | |
713 // Load the value up from the heap. | |
714 __ movptr(rdx_temp, vmarg); | |
715 int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT); | |
716 #ifdef ASSERT | |
717 for (int bt = T_BOOLEAN; bt < T_INT; bt++) { | |
718 if (is_subword_type(BasicType(bt))) | |
719 assert(value_offset == java_lang_boxing_object::value_offset_in_bytes(BasicType(bt)), ""); | |
720 } | |
721 #endif | |
722 __ null_check(rdx_temp, value_offset); | |
723 __ movl(rdx_temp, Address(rdx_temp, value_offset)); | |
724 // We load this as a word. Because we are little-endian, | |
725 // the low bits will be correct, but the high bits may need cleaning. | |
726 // The vminfo will guide us to clean those bits. | |
727 } | |
728 break; | |
729 default: | |
1304 | 730 ShouldNotReachHere(); |
710 | 731 } |
732 | |
1304 | 733 // Do the requested conversion and store the value. |
710 | 734 Register rbx_vminfo = rbx_temp; |
735 __ movl(rbx_vminfo, rcx_amh_conversion); | |
736 assert(CONV_VMINFO_SHIFT == 0, "preshifted"); | |
737 | |
738 // get the new MH: | |
1846 | 739 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); |
710 | 740 // (now we are done with the old MH) |
741 | |
742 // original 32-bit vmdata word must be of this form: | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
743 // | MBZ:6 | signBitCount:8 | srcDstTypes:8 | conversionOp:8 | |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
744 __ xchgptr(rcx, rbx_vminfo); // free rcx for shifts |
710 | 745 __ shll(rdx_temp /*, rcx*/); |
746 Label zero_extend, done; | |
747 __ testl(rcx, CONV_VMINFO_SIGN_FLAG); | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
748 __ jccb(Assembler::zero, zero_extend); |
710 | 749 |
750 // this path is taken for int->byte, int->short | |
751 __ sarl(rdx_temp /*, rcx*/); | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
752 __ jmpb(done); |
710 | 753 |
754 __ bind(zero_extend); | |
755 // this is taken for int->char | |
756 __ shrl(rdx_temp /*, rcx*/); | |
757 | |
758 __ bind(done); | |
1304 | 759 __ movl(vmarg, rdx_temp); // Store the value. |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
760 __ xchgptr(rcx, rbx_vminfo); // restore rcx_recv |
710 | 761 |
762 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); | |
763 } | |
764 break; | |
765 | |
766 case _adapter_opt_i2l: // optimized subcase of adapt_prim_to_prim | |
767 case _adapter_opt_unboxl: // optimized subcase of adapt_ref_to_prim | |
768 { | |
769 // perform an in-place int-to-long or ref-to-long conversion | |
770 __ movl(rax_argslot, rcx_amh_vmargslot); | |
771 | |
772 // on a little-endian machine we keep the first slot and add another after | |
773 __ lea(rax_argslot, __ argument_address(rax_argslot, 1)); | |
774 insert_arg_slots(_masm, stack_move_unit(), _INSERT_INT_MASK, | |
775 rax_argslot, rbx_temp, rdx_temp); | |
1506 | 776 Address vmarg1(rax_argslot, -Interpreter::stackElementSize); |
777 Address vmarg2 = vmarg1.plus_disp(Interpreter::stackElementSize); | |
710 | 778 |
779 switch (ek) { | |
780 case _adapter_opt_i2l: | |
781 { | |
1293
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
782 #ifdef _LP64 |
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
783 __ movslq(rdx_temp, vmarg1); // Load sign-extended |
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
784 __ movq(vmarg1, rdx_temp); // Store into first slot |
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
785 #else |
710 | 786 __ movl(rdx_temp, vmarg1); |
1293
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
787 __ sarl(rdx_temp, BitsPerInt - 1); // __ extend_sign() |
710 | 788 __ movl(vmarg2, rdx_temp); // store second word |
1293
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
789 #endif |
710 | 790 } |
791 break; | |
792 case _adapter_opt_unboxl: | |
793 { | |
794 // Load the value up from the heap. | |
795 __ movptr(rdx_temp, vmarg1); | |
796 int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_LONG); | |
797 assert(value_offset == java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE), ""); | |
798 __ null_check(rdx_temp, value_offset); | |
1293
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
799 #ifdef _LP64 |
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
800 __ movq(rbx_temp, Address(rdx_temp, value_offset)); |
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
801 __ movq(vmarg1, rbx_temp); |
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
802 #else |
710 | 803 __ movl(rbx_temp, Address(rdx_temp, value_offset + 0*BytesPerInt)); |
804 __ movl(rdx_temp, Address(rdx_temp, value_offset + 1*BytesPerInt)); | |
805 __ movl(vmarg1, rbx_temp); | |
806 __ movl(vmarg2, rdx_temp); | |
1293
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
807 #endif |
710 | 808 } |
809 break; | |
810 default: | |
1304 | 811 ShouldNotReachHere(); |
710 | 812 } |
813 | |
1846 | 814 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); |
710 | 815 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); |
816 } | |
817 break; | |
818 | |
819 case _adapter_opt_f2d: // optimized subcase of adapt_prim_to_prim | |
820 case _adapter_opt_d2f: // optimized subcase of adapt_prim_to_prim | |
821 { | |
822 // perform an in-place floating primitive conversion | |
823 __ movl(rax_argslot, rcx_amh_vmargslot); | |
824 __ lea(rax_argslot, __ argument_address(rax_argslot, 1)); | |
825 if (ek == _adapter_opt_f2d) { | |
826 insert_arg_slots(_masm, stack_move_unit(), _INSERT_INT_MASK, | |
827 rax_argslot, rbx_temp, rdx_temp); | |
828 } | |
1506 | 829 Address vmarg(rax_argslot, -Interpreter::stackElementSize); |
710 | 830 |
831 #ifdef _LP64 | |
832 if (ek == _adapter_opt_f2d) { | |
833 __ movflt(xmm0, vmarg); | |
834 __ cvtss2sd(xmm0, xmm0); | |
835 __ movdbl(vmarg, xmm0); | |
836 } else { | |
837 __ movdbl(xmm0, vmarg); | |
838 __ cvtsd2ss(xmm0, xmm0); | |
839 __ movflt(vmarg, xmm0); | |
840 } | |
841 #else //_LP64 | |
842 if (ek == _adapter_opt_f2d) { | |
843 __ fld_s(vmarg); // load float to ST0 | |
844 __ fstp_s(vmarg); // store single | |
1304 | 845 } else { |
710 | 846 __ fld_d(vmarg); // load double to ST0 |
847 __ fstp_s(vmarg); // store single | |
848 } | |
849 #endif //_LP64 | |
850 | |
851 if (ek == _adapter_opt_d2f) { | |
852 remove_arg_slots(_masm, -stack_move_unit(), | |
853 rax_argslot, rbx_temp, rdx_temp); | |
854 } | |
855 | |
1846 | 856 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); |
710 | 857 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); |
858 } | |
859 break; | |
860 | |
861 case _adapter_prim_to_ref: | |
862 __ unimplemented(entry_name(ek)); // %%% FIXME: NYI | |
863 break; | |
864 | |
865 case _adapter_swap_args: | |
866 case _adapter_rot_args: | |
867 // handled completely by optimized cases | |
868 __ stop("init_AdapterMethodHandle should not issue this"); | |
869 break; | |
870 | |
871 case _adapter_opt_swap_1: | |
872 case _adapter_opt_swap_2: | |
873 case _adapter_opt_rot_1_up: | |
874 case _adapter_opt_rot_1_down: | |
875 case _adapter_opt_rot_2_up: | |
876 case _adapter_opt_rot_2_down: | |
877 { | |
1304 | 878 int swap_bytes = 0, rotate = 0; |
879 get_ek_adapter_opt_swap_rot_info(ek, swap_bytes, rotate); | |
710 | 880 |
881 // 'argslot' is the position of the first argument to swap | |
882 __ movl(rax_argslot, rcx_amh_vmargslot); | |
883 __ lea(rax_argslot, __ argument_address(rax_argslot)); | |
884 | |
885 // 'vminfo' is the second | |
886 Register rbx_destslot = rbx_temp; | |
887 __ movl(rbx_destslot, rcx_amh_conversion); | |
888 assert(CONV_VMINFO_SHIFT == 0, "preshifted"); | |
889 __ andl(rbx_destslot, CONV_VMINFO_MASK); | |
890 __ lea(rbx_destslot, __ argument_address(rbx_destslot)); | |
891 DEBUG_ONLY(verify_argslot(_masm, rbx_destslot, "swap point must fall within current frame")); | |
892 | |
893 if (!rotate) { | |
894 for (int i = 0; i < swap_bytes; i += wordSize) { | |
895 __ movptr(rdx_temp, Address(rax_argslot , i)); | |
896 __ push(rdx_temp); | |
897 __ movptr(rdx_temp, Address(rbx_destslot, i)); | |
898 __ movptr(Address(rax_argslot, i), rdx_temp); | |
899 __ pop(rdx_temp); | |
900 __ movptr(Address(rbx_destslot, i), rdx_temp); | |
901 } | |
902 } else { | |
903 // push the first chunk, which is going to get overwritten | |
904 for (int i = swap_bytes; (i -= wordSize) >= 0; ) { | |
905 __ movptr(rdx_temp, Address(rax_argslot, i)); | |
906 __ push(rdx_temp); | |
907 } | |
908 | |
909 if (rotate > 0) { | |
910 // rotate upward | |
911 __ subptr(rax_argslot, swap_bytes); | |
912 #ifdef ASSERT | |
913 { | |
914 // Verify that argslot > destslot, by at least swap_bytes. | |
915 Label L_ok; | |
916 __ cmpptr(rax_argslot, rbx_destslot); | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
917 __ jccb(Assembler::aboveEqual, L_ok); |
710 | 918 __ stop("source must be above destination (upward rotation)"); |
919 __ bind(L_ok); | |
920 } | |
921 #endif | |
922 // work argslot down to destslot, copying contiguous data upwards | |
923 // pseudo-code: | |
924 // rax = src_addr - swap_bytes | |
925 // rbx = dest_addr | |
926 // while (rax >= rbx) *(rax + swap_bytes) = *(rax + 0), rax--; | |
927 Label loop; | |
928 __ bind(loop); | |
929 __ movptr(rdx_temp, Address(rax_argslot, 0)); | |
930 __ movptr(Address(rax_argslot, swap_bytes), rdx_temp); | |
931 __ addptr(rax_argslot, -wordSize); | |
932 __ cmpptr(rax_argslot, rbx_destslot); | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
933 __ jccb(Assembler::aboveEqual, loop); |
710 | 934 } else { |
935 __ addptr(rax_argslot, swap_bytes); | |
936 #ifdef ASSERT | |
937 { | |
938 // Verify that argslot < destslot, by at least swap_bytes. | |
939 Label L_ok; | |
940 __ cmpptr(rax_argslot, rbx_destslot); | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
941 __ jccb(Assembler::belowEqual, L_ok); |
710 | 942 __ stop("source must be below destination (downward rotation)"); |
943 __ bind(L_ok); | |
944 } | |
945 #endif | |
946 // work argslot up to destslot, copying contiguous data downwards | |
947 // pseudo-code: | |
948 // rax = src_addr + swap_bytes | |
949 // rbx = dest_addr | |
950 // while (rax <= rbx) *(rax - swap_bytes) = *(rax + 0), rax++; | |
951 Label loop; | |
952 __ bind(loop); | |
953 __ movptr(rdx_temp, Address(rax_argslot, 0)); | |
954 __ movptr(Address(rax_argslot, -swap_bytes), rdx_temp); | |
955 __ addptr(rax_argslot, wordSize); | |
956 __ cmpptr(rax_argslot, rbx_destslot); | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
957 __ jccb(Assembler::belowEqual, loop); |
710 | 958 } |
959 | |
960 // pop the original first chunk into the destination slot, now free | |
961 for (int i = 0; i < swap_bytes; i += wordSize) { | |
962 __ pop(rdx_temp); | |
963 __ movptr(Address(rbx_destslot, i), rdx_temp); | |
964 } | |
965 } | |
966 | |
1846 | 967 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); |
710 | 968 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); |
969 } | |
970 break; | |
971 | |
972 case _adapter_dup_args: | |
973 { | |
974 // 'argslot' is the position of the first argument to duplicate | |
975 __ movl(rax_argslot, rcx_amh_vmargslot); | |
976 __ lea(rax_argslot, __ argument_address(rax_argslot)); | |
977 | |
978 // 'stack_move' is negative number of words to duplicate | |
979 Register rdx_stack_move = rdx_temp; | |
1293
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
980 __ movl2ptr(rdx_stack_move, rcx_amh_conversion); |
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
981 __ sarptr(rdx_stack_move, CONV_STACK_MOVE_SHIFT); |
710 | 982 |
983 int argslot0_num = 0; | |
984 Address argslot0 = __ argument_address(RegisterOrConstant(argslot0_num)); | |
985 assert(argslot0.base() == rsp, ""); | |
986 int pre_arg_size = argslot0.disp(); | |
987 assert(pre_arg_size % wordSize == 0, ""); | |
988 assert(pre_arg_size > 0, "must include PC"); | |
989 | |
990 // remember the old rsp+1 (argslot[0]) | |
991 Register rbx_oldarg = rbx_temp; | |
992 __ lea(rbx_oldarg, argslot0); | |
993 | |
994 // move rsp down to make room for dups | |
995 __ lea(rsp, Address(rsp, rdx_stack_move, Address::times_ptr)); | |
996 | |
997 // compute the new rsp+1 (argslot[0]) | |
998 Register rdx_newarg = rdx_temp; | |
999 __ lea(rdx_newarg, argslot0); | |
1000 | |
1001 __ push(rdi); // need a temp | |
1002 // (preceding push must be done after arg addresses are taken!) | |
1003 | |
1004 // pull down the pre_arg_size data (PC) | |
1005 for (int i = -pre_arg_size; i < 0; i += wordSize) { | |
1006 __ movptr(rdi, Address(rbx_oldarg, i)); | |
1007 __ movptr(Address(rdx_newarg, i), rdi); | |
1008 } | |
1009 | |
1010 // copy from rax_argslot[0...] down to new_rsp[1...] | |
1011 // pseudo-code: | |
1012 // rbx = old_rsp+1 | |
1013 // rdx = new_rsp+1 | |
1014 // rax = argslot | |
1015 // while (rdx < rbx) *rdx++ = *rax++ | |
1016 Label loop; | |
1017 __ bind(loop); | |
1018 __ movptr(rdi, Address(rax_argslot, 0)); | |
1019 __ movptr(Address(rdx_newarg, 0), rdi); | |
1020 __ addptr(rax_argslot, wordSize); | |
1021 __ addptr(rdx_newarg, wordSize); | |
1022 __ cmpptr(rdx_newarg, rbx_oldarg); | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
1023 __ jccb(Assembler::less, loop); |
710 | 1024 |
1025 __ pop(rdi); // restore temp | |
1026 | |
1846 | 1027 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); |
710 | 1028 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); |
1029 } | |
1030 break; | |
1031 | |
1032 case _adapter_drop_args: | |
1033 { | |
1034 // 'argslot' is the position of the first argument to nuke | |
1035 __ movl(rax_argslot, rcx_amh_vmargslot); | |
1036 __ lea(rax_argslot, __ argument_address(rax_argslot)); | |
1037 | |
1038 __ push(rdi); // need a temp | |
1039 // (must do previous push after argslot address is taken) | |
1040 | |
1041 // 'stack_move' is number of words to drop | |
1042 Register rdi_stack_move = rdi; | |
1293
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
1043 __ movl2ptr(rdi_stack_move, rcx_amh_conversion); |
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
1044 __ sarptr(rdi_stack_move, CONV_STACK_MOVE_SHIFT); |
710 | 1045 remove_arg_slots(_masm, rdi_stack_move, |
1046 rax_argslot, rbx_temp, rdx_temp); | |
1047 | |
1048 __ pop(rdi); // restore temp | |
1049 | |
1846 | 1050 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); |
710 | 1051 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); |
1052 } | |
1053 break; | |
1054 | |
1055 case _adapter_collect_args: | |
1056 __ unimplemented(entry_name(ek)); // %%% FIXME: NYI | |
1057 break; | |
1058 | |
1059 case _adapter_spread_args: | |
1060 // handled completely by optimized cases | |
1061 __ stop("init_AdapterMethodHandle should not issue this"); | |
1062 break; | |
1063 | |
1064 case _adapter_opt_spread_0: | |
1065 case _adapter_opt_spread_1: | |
1066 case _adapter_opt_spread_more: | |
1067 { | |
1068 // spread an array out into a group of arguments | |
1304 | 1069 int length_constant = get_ek_adapter_opt_spread_info(ek); |
710 | 1070 |
1071 // find the address of the array argument | |
1072 __ movl(rax_argslot, rcx_amh_vmargslot); | |
1073 __ lea(rax_argslot, __ argument_address(rax_argslot)); | |
1074 | |
1075 // grab some temps | |
1076 { __ push(rsi); __ push(rdi); } | |
1077 // (preceding pushes must be done after argslot address is taken!) | |
1078 #define UNPUSH_RSI_RDI \ | |
1079 { __ pop(rdi); __ pop(rsi); } | |
1080 | |
1081 // arx_argslot points both to the array and to the first output arg | |
1082 vmarg = Address(rax_argslot, 0); | |
1083 | |
1084 // Get the array value. | |
1085 Register rsi_array = rsi; | |
1086 Register rdx_array_klass = rdx_temp; | |
1087 BasicType elem_type = T_OBJECT; | |
1088 int length_offset = arrayOopDesc::length_offset_in_bytes(); | |
1089 int elem0_offset = arrayOopDesc::base_offset_in_bytes(elem_type); | |
1090 __ movptr(rsi_array, vmarg); | |
1091 Label skip_array_check; | |
1092 if (length_constant == 0) { | |
1093 __ testptr(rsi_array, rsi_array); | |
1094 __ jcc(Assembler::zero, skip_array_check); | |
1095 } | |
1096 __ null_check(rsi_array, oopDesc::klass_offset_in_bytes()); | |
1097 __ load_klass(rdx_array_klass, rsi_array); | |
1098 | |
1099 // Check the array type. | |
1100 Register rbx_klass = rbx_temp; | |
1846 | 1101 __ load_heap_oop(rbx_klass, rcx_amh_argument); // this is a Class object! |
1102 __ load_heap_oop(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes())); | |
710 | 1103 |
1104 Label ok_array_klass, bad_array_klass, bad_array_length; | |
1105 __ check_klass_subtype(rdx_array_klass, rbx_klass, rdi, ok_array_klass); | |
1106 // If we get here, the type check failed! | |
1107 __ jmp(bad_array_klass); | |
1108 __ bind(ok_array_klass); | |
1109 | |
1110 // Check length. | |
1111 if (length_constant >= 0) { | |
1112 __ cmpl(Address(rsi_array, length_offset), length_constant); | |
1113 } else { | |
1114 Register rbx_vminfo = rbx_temp; | |
1115 __ movl(rbx_vminfo, rcx_amh_conversion); | |
1116 assert(CONV_VMINFO_SHIFT == 0, "preshifted"); | |
1117 __ andl(rbx_vminfo, CONV_VMINFO_MASK); | |
1118 __ cmpl(rbx_vminfo, Address(rsi_array, length_offset)); | |
1119 } | |
1120 __ jcc(Assembler::notEqual, bad_array_length); | |
1121 | |
1122 Register rdx_argslot_limit = rdx_temp; | |
1123 | |
1124 // Array length checks out. Now insert any required stack slots. | |
1125 if (length_constant == -1) { | |
1126 // Form a pointer to the end of the affected region. | |
1506 | 1127 __ lea(rdx_argslot_limit, Address(rax_argslot, Interpreter::stackElementSize)); |
710 | 1128 // 'stack_move' is negative number of words to insert |
1129 Register rdi_stack_move = rdi; | |
1293
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
1130 __ movl2ptr(rdi_stack_move, rcx_amh_conversion); |
51db1e4b379d
6932536: JSR 292 modified JDK MethodHandlesTest fails on x86_64
twisti
parents:
1277
diff
changeset
|
1131 __ sarptr(rdi_stack_move, CONV_STACK_MOVE_SHIFT); |
710 | 1132 Register rsi_temp = rsi_array; // spill this |
1133 insert_arg_slots(_masm, rdi_stack_move, -1, | |
1134 rax_argslot, rbx_temp, rsi_temp); | |
1135 // reload the array (since rsi was killed) | |
1136 __ movptr(rsi_array, vmarg); | |
1137 } else if (length_constant > 1) { | |
1138 int arg_mask = 0; | |
1139 int new_slots = (length_constant - 1); | |
1140 for (int i = 0; i < new_slots; i++) { | |
1141 arg_mask <<= 1; | |
1142 arg_mask |= _INSERT_REF_MASK; | |
1143 } | |
1144 insert_arg_slots(_masm, new_slots * stack_move_unit(), arg_mask, | |
1145 rax_argslot, rbx_temp, rdx_temp); | |
1146 } else if (length_constant == 1) { | |
1147 // no stack resizing required | |
1148 } else if (length_constant == 0) { | |
1149 remove_arg_slots(_masm, -stack_move_unit(), | |
1150 rax_argslot, rbx_temp, rdx_temp); | |
1151 } | |
1152 | |
1153 // Copy from the array to the new slots. | |
1154 // Note: Stack change code preserves integrity of rax_argslot pointer. | |
1155 // So even after slot insertions, rax_argslot still points to first argument. | |
1156 if (length_constant == -1) { | |
1157 // [rax_argslot, rdx_argslot_limit) is the area we are inserting into. | |
1158 Register rsi_source = rsi_array; | |
1159 __ lea(rsi_source, Address(rsi_array, elem0_offset)); | |
1160 Label loop; | |
1161 __ bind(loop); | |
1162 __ movptr(rbx_temp, Address(rsi_source, 0)); | |
1163 __ movptr(Address(rax_argslot, 0), rbx_temp); | |
1164 __ addptr(rsi_source, type2aelembytes(elem_type)); | |
1506 | 1165 __ addptr(rax_argslot, Interpreter::stackElementSize); |
710 | 1166 __ cmpptr(rax_argslot, rdx_argslot_limit); |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1133
diff
changeset
|
1167 __ jccb(Assembler::less, loop); |
710 | 1168 } else if (length_constant == 0) { |
1169 __ bind(skip_array_check); | |
1170 // nothing to copy | |
1171 } else { | |
1172 int elem_offset = elem0_offset; | |
1173 int slot_offset = 0; | |
1174 for (int index = 0; index < length_constant; index++) { | |
1175 __ movptr(rbx_temp, Address(rsi_array, elem_offset)); | |
1176 __ movptr(Address(rax_argslot, slot_offset), rbx_temp); | |
1177 elem_offset += type2aelembytes(elem_type); | |
1506 | 1178 slot_offset += Interpreter::stackElementSize; |
710 | 1179 } |
1180 } | |
1181 | |
1182 // Arguments are spread. Move to next method handle. | |
1183 UNPUSH_RSI_RDI; | |
1846 | 1184 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); |
710 | 1185 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); |
1186 | |
1187 __ bind(bad_array_klass); | |
1188 UNPUSH_RSI_RDI; | |
2088
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
1189 assert(!vmarg.uses(rarg2_required), "must be different registers"); |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
1190 __ movptr(rarg2_required, Address(rdx_array_klass, java_mirror_offset)); // required type |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
1191 __ movptr(rarg1_actual, vmarg); // bad array |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
1192 __ movl( rarg0_code, (int) Bytecodes::_aaload); // who is complaining? |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
1193 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); |
710 | 1194 |
1195 __ bind(bad_array_length); | |
1196 UNPUSH_RSI_RDI; | |
2088
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
1197 assert(!vmarg.uses(rarg2_required), "must be different registers"); |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
1198 __ mov (rarg2_required, rcx_recv); // AMH requiring a certain length |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
1199 __ movptr(rarg1_actual, vmarg); // bad array |
8d0b933dda2d
7007377: JSR 292 MethodHandlesTest.testCastFailure fails on SPARC with -Xcomp +DeoptimizeALot
twisti
parents:
1972
diff
changeset
|
1200 __ movl( rarg0_code, (int) Bytecodes::_arraylength); // who is complaining? |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
845
diff
changeset
|
1201 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); |
710 | 1202 |
1203 #undef UNPUSH_RSI_RDI | |
1204 } | |
1205 break; | |
1206 | |
1207 case _adapter_flyby: | |
1208 case _adapter_ricochet: | |
1209 __ unimplemented(entry_name(ek)); // %%% FIXME: NYI | |
1210 break; | |
1211 | |
1212 default: ShouldNotReachHere(); | |
1213 } | |
1214 __ hlt(); | |
1215 | |
1216 address me_cookie = MethodHandleEntry::start_compiled_entry(_masm, interp_entry); | |
1217 __ unimplemented(entry_name(ek)); // %%% FIXME: NYI | |
1218 | |
1219 init_entry(ek, MethodHandleEntry::finish_compiled_entry(_masm, me_cookie)); | |
1220 } |