Mercurial > hg > truffle
annotate src/cpu/x86/vm/interpreter_x86_64.cpp @ 2013:ec8c74742417
7005241: C1: SEGV in java.util.concurrent.LinkedTransferQueue.xfer() with compressed oops
Summary: Implementation of the CAS primitive for x64 compressed oops was incorrect. It kills rscratch2 register (r11), which is allocatable in C1. Also, we don't need to restore cmpval as it's never used after that, so we need only one temporary register, which can be scratch1.
Reviewed-by: kvn, never
author | iveresov |
---|---|
date | Wed, 08 Dec 2010 02:36:36 -0800 |
parents | f95d63e2154a |
children | 8033953d67ff |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 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:
1108
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1108
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:
1108
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "asm/assembler.hpp" | |
27 #include "interpreter/bytecodeHistogram.hpp" | |
28 #include "interpreter/interpreter.hpp" | |
29 #include "interpreter/interpreterGenerator.hpp" | |
30 #include "interpreter/interpreterRuntime.hpp" | |
31 #include "interpreter/templateTable.hpp" | |
32 #include "oops/arrayOop.hpp" | |
33 #include "oops/methodDataOop.hpp" | |
34 #include "oops/methodOop.hpp" | |
35 #include "oops/oop.inline.hpp" | |
36 #include "prims/jvmtiExport.hpp" | |
37 #include "prims/jvmtiThreadState.hpp" | |
38 #include "prims/methodHandles.hpp" | |
39 #include "runtime/arguments.hpp" | |
40 #include "runtime/deoptimization.hpp" | |
41 #include "runtime/frame.inline.hpp" | |
42 #include "runtime/sharedRuntime.hpp" | |
43 #include "runtime/stubRoutines.hpp" | |
44 #include "runtime/synchronizer.hpp" | |
45 #include "runtime/timer.hpp" | |
46 #include "runtime/vframeArray.hpp" | |
47 #include "utilities/debug.hpp" | |
48 #ifdef COMPILER1 | |
49 #include "c1/c1_Runtime1.hpp" | |
50 #endif | |
0 | 51 |
52 #define __ _masm-> | |
53 | |
54 | |
55 #ifdef _WIN64 | |
56 address AbstractInterpreterGenerator::generate_slow_signature_handler() { | |
57 address entry = __ pc(); | |
58 | |
59 // rbx: method | |
60 // r14: pointer to locals | |
61 // c_rarg3: first stack arg - wordSize | |
304 | 62 __ mov(c_rarg3, rsp); |
0 | 63 // adjust rsp |
304 | 64 __ subptr(rsp, 4 * wordSize); |
0 | 65 __ call_VM(noreg, |
66 CAST_FROM_FN_PTR(address, | |
67 InterpreterRuntime::slow_signature_handler), | |
68 rbx, r14, c_rarg3); | |
69 | |
70 // rax: result handler | |
71 | |
72 // Stack layout: | |
73 // rsp: 3 integer or float args (if static first is unused) | |
74 // 1 float/double identifiers | |
75 // return address | |
76 // stack args | |
77 // garbage | |
78 // expression stack bottom | |
79 // bcp (NULL) | |
80 // ... | |
81 | |
82 // Do FP first so we can use c_rarg3 as temp | |
83 __ movl(c_rarg3, Address(rsp, 3 * wordSize)); // float/double identifiers | |
84 | |
85 for ( int i= 0; i < Argument::n_int_register_parameters_c-1; i++ ) { | |
86 XMMRegister floatreg = as_XMMRegister(i+1); | |
87 Label isfloatordouble, isdouble, next; | |
88 | |
89 __ testl(c_rarg3, 1 << (i*2)); // Float or Double? | |
90 __ jcc(Assembler::notZero, isfloatordouble); | |
91 | |
92 // Do Int register here | |
93 switch ( i ) { | |
94 case 0: | |
95 __ movl(rscratch1, Address(rbx, methodOopDesc::access_flags_offset())); | |
96 __ testl(rscratch1, JVM_ACC_STATIC); | |
304 | 97 __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); |
0 | 98 break; |
99 case 1: | |
304 | 100 __ movptr(c_rarg2, Address(rsp, wordSize)); |
0 | 101 break; |
102 case 2: | |
304 | 103 __ movptr(c_rarg3, Address(rsp, 2 * wordSize)); |
0 | 104 break; |
105 default: | |
106 break; | |
107 } | |
108 | |
109 __ jmp (next); | |
110 | |
111 __ bind(isfloatordouble); | |
112 __ testl(c_rarg3, 1 << ((i*2)+1)); // Double? | |
113 __ jcc(Assembler::notZero, isdouble); | |
114 | |
115 // Do Float Here | |
116 __ movflt(floatreg, Address(rsp, i * wordSize)); | |
117 __ jmp(next); | |
118 | |
119 // Do Double here | |
120 __ bind(isdouble); | |
121 __ movdbl(floatreg, Address(rsp, i * wordSize)); | |
122 | |
123 __ bind(next); | |
124 } | |
125 | |
126 | |
127 // restore rsp | |
304 | 128 __ addptr(rsp, 4 * wordSize); |
0 | 129 |
130 __ ret(0); | |
131 | |
132 return entry; | |
133 } | |
134 #else | |
135 address AbstractInterpreterGenerator::generate_slow_signature_handler() { | |
136 address entry = __ pc(); | |
137 | |
138 // rbx: method | |
139 // r14: pointer to locals | |
140 // c_rarg3: first stack arg - wordSize | |
304 | 141 __ mov(c_rarg3, rsp); |
0 | 142 // adjust rsp |
304 | 143 __ subptr(rsp, 14 * wordSize); |
0 | 144 __ call_VM(noreg, |
145 CAST_FROM_FN_PTR(address, | |
146 InterpreterRuntime::slow_signature_handler), | |
147 rbx, r14, c_rarg3); | |
148 | |
149 // rax: result handler | |
150 | |
151 // Stack layout: | |
152 // rsp: 5 integer args (if static first is unused) | |
153 // 1 float/double identifiers | |
154 // 8 double args | |
155 // return address | |
156 // stack args | |
157 // garbage | |
158 // expression stack bottom | |
159 // bcp (NULL) | |
160 // ... | |
161 | |
162 // Do FP first so we can use c_rarg3 as temp | |
163 __ movl(c_rarg3, Address(rsp, 5 * wordSize)); // float/double identifiers | |
164 | |
165 for (int i = 0; i < Argument::n_float_register_parameters_c; i++) { | |
166 const XMMRegister r = as_XMMRegister(i); | |
167 | |
168 Label d, done; | |
169 | |
170 __ testl(c_rarg3, 1 << i); | |
171 __ jcc(Assembler::notZero, d); | |
172 __ movflt(r, Address(rsp, (6 + i) * wordSize)); | |
173 __ jmp(done); | |
174 __ bind(d); | |
175 __ movdbl(r, Address(rsp, (6 + i) * wordSize)); | |
176 __ bind(done); | |
177 } | |
178 | |
179 // Now handle integrals. Only do c_rarg1 if not static. | |
180 __ movl(c_rarg3, Address(rbx, methodOopDesc::access_flags_offset())); | |
181 __ testl(c_rarg3, JVM_ACC_STATIC); | |
304 | 182 __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); |
0 | 183 |
304 | 184 __ movptr(c_rarg2, Address(rsp, wordSize)); |
185 __ movptr(c_rarg3, Address(rsp, 2 * wordSize)); | |
186 __ movptr(c_rarg4, Address(rsp, 3 * wordSize)); | |
187 __ movptr(c_rarg5, Address(rsp, 4 * wordSize)); | |
0 | 188 |
189 // restore rsp | |
304 | 190 __ addptr(rsp, 14 * wordSize); |
0 | 191 |
192 __ ret(0); | |
193 | |
194 return entry; | |
195 } | |
196 #endif | |
197 | |
198 | |
199 // | |
200 // Various method entries | |
201 // | |
202 | |
304 | 203 address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) { |
204 | |
205 // rbx,: methodOop | |
206 // rcx: scratrch | |
207 // r13: sender sp | |
0 | 208 |
209 if (!InlineIntrinsics) return NULL; // Generate a vanilla entry | |
210 | |
211 address entry_point = __ pc(); | |
212 | |
213 // These don't need a safepoint check because they aren't virtually | |
214 // callable. We won't enter these intrinsics from compiled code. | |
215 // If in the future we added an intrinsic which was virtually callable | |
216 // we'd have to worry about how to safepoint so that this code is used. | |
217 | |
218 // mathematical functions inlined by compiler | |
219 // (interpreter must provide identical implementation | |
220 // in order to avoid monotonicity bugs when switching | |
221 // from interpreter to compiler in the middle of some | |
222 // computation) | |
304 | 223 // |
224 // stack: [ ret adr ] <-- rsp | |
225 // [ lo(arg) ] | |
226 // [ hi(arg) ] | |
227 // | |
0 | 228 |
229 // Note: For JDK 1.2 StrictMath doesn't exist and Math.sin/cos/sqrt are | |
230 // native methods. Interpreter::method_kind(...) does a check for | |
231 // native methods first before checking for intrinsic methods and | |
232 // thus will never select this entry point. Make sure it is not | |
233 // called accidentally since the SharedRuntime entry points will | |
234 // not work for JDK 1.2. | |
235 // | |
236 // We no longer need to check for JDK 1.2 since it's EOL'ed. | |
237 // The following check existed in pre 1.6 implementation, | |
238 // if (Universe::is_jdk12x_version()) { | |
239 // __ should_not_reach_here(); | |
240 // } | |
241 // Universe::is_jdk12x_version() always returns false since | |
242 // the JDK version is not yet determined when this method is called. | |
243 // This method is called during interpreter_init() whereas | |
244 // JDK version is only determined when universe2_init() is called. | |
245 | |
246 // Note: For JDK 1.3 StrictMath exists and Math.sin/cos/sqrt are | |
247 // java methods. Interpreter::method_kind(...) will select | |
248 // this entry point for the corresponding methods in JDK 1.3. | |
304 | 249 // get argument |
0 | 250 |
304 | 251 if (kind == Interpreter::java_lang_math_sqrt) { |
252 __ sqrtsd(xmm0, Address(rsp, wordSize)); | |
253 } else { | |
254 __ fld_d(Address(rsp, wordSize)); | |
255 switch (kind) { | |
256 case Interpreter::java_lang_math_sin : | |
257 __ trigfunc('s'); | |
258 break; | |
259 case Interpreter::java_lang_math_cos : | |
260 __ trigfunc('c'); | |
261 break; | |
262 case Interpreter::java_lang_math_tan : | |
263 __ trigfunc('t'); | |
264 break; | |
265 case Interpreter::java_lang_math_abs: | |
266 __ fabs(); | |
267 break; | |
268 case Interpreter::java_lang_math_log: | |
269 __ flog(); | |
270 break; | |
271 case Interpreter::java_lang_math_log10: | |
272 __ flog10(); | |
273 break; | |
274 default : | |
275 ShouldNotReachHere(); | |
276 } | |
277 | |
278 // return double result in xmm0 for interpreter and compilers. | |
279 __ subptr(rsp, 2*wordSize); | |
280 // Round to 64bit precision | |
281 __ fstp_d(Address(rsp, 0)); | |
282 __ movdbl(xmm0, Address(rsp, 0)); | |
283 __ addptr(rsp, 2*wordSize); | |
284 } | |
285 | |
286 | |
287 __ pop(rax); | |
288 __ mov(rsp, r13); | |
0 | 289 __ jmp(rax); |
290 | |
291 return entry_point; | |
292 } | |
293 | |
294 | |
295 // Abstract method entry | |
296 // Attempt to execute abstract method. Throw exception | |
297 address InterpreterGenerator::generate_abstract_entry(void) { | |
298 // rbx: methodOop | |
299 // r13: sender SP | |
300 | |
301 address entry_point = __ pc(); | |
302 | |
303 // abstract method entry | |
304 | |
1108 | 305 // pop return address, reset last_sp to NULL |
306 __ empty_expression_stack(); | |
307 __ restore_bcp(); // rsi must be correct for exception handler (was destroyed) | |
308 __ restore_locals(); // make sure locals pointer is correct as well (was destroyed) | |
0 | 309 |
310 // throw exception | |
311 __ call_VM(noreg, CAST_FROM_FN_PTR(address, | |
312 InterpreterRuntime::throw_AbstractMethodError)); | |
313 // the call_VM checks for exception, so we should never return here. | |
314 __ should_not_reach_here(); | |
315 | |
316 return entry_point; | |
317 } | |
318 | |
319 | |
710 | 320 // Method handle invoker |
321 // Dispatch a method of the form java.dyn.MethodHandles::invoke(...) | |
322 address InterpreterGenerator::generate_method_handle_entry(void) { | |
323 if (!EnableMethodHandles) { | |
324 return generate_abstract_entry(); | |
325 } | |
1108 | 326 |
327 address entry_point = MethodHandles::generate_method_handle_interpreter_entry(_masm); | |
328 | |
329 return entry_point; | |
710 | 330 } |
331 | |
332 | |
0 | 333 // Empty method, generate a very fast return. |
334 | |
335 address InterpreterGenerator::generate_empty_entry(void) { | |
336 // rbx: methodOop | |
337 // r13: sender sp must set sp to this value on return | |
338 | |
339 if (!UseFastEmptyMethods) { | |
340 return NULL; | |
341 } | |
342 | |
343 address entry_point = __ pc(); | |
344 | |
345 // If we need a safepoint check, generate full interpreter entry. | |
346 Label slow_path; | |
347 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), | |
348 SafepointSynchronize::_not_synchronized); | |
349 __ jcc(Assembler::notEqual, slow_path); | |
350 | |
351 // do nothing for empty methods (do not even increment invocation counter) | |
352 // Code: _return | |
353 // _return | |
354 // return w/o popping parameters | |
304 | 355 __ pop(rax); |
356 __ mov(rsp, r13); | |
0 | 357 __ jmp(rax); |
358 | |
359 __ bind(slow_path); | |
360 (void) generate_normal_entry(false); | |
361 return entry_point; | |
362 | |
363 } | |
364 | |
365 // This method tells the deoptimizer how big an interpreted frame must be: | |
366 int AbstractInterpreter::size_activation(methodOop method, | |
367 int tempcount, | |
368 int popframe_extra_args, | |
369 int moncount, | |
370 int callee_param_count, | |
371 int callee_locals, | |
372 bool is_top_frame) { | |
373 return layout_activation(method, | |
374 tempcount, popframe_extra_args, moncount, | |
375 callee_param_count, callee_locals, | |
376 (frame*) NULL, (frame*) NULL, is_top_frame); | |
377 } | |
378 | |
379 void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) { | |
380 | |
381 // This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in | |
382 // the days we had adapter frames. When we deoptimize a situation where a | |
383 // compiled caller calls a compiled caller will have registers it expects | |
384 // to survive the call to the callee. If we deoptimize the callee the only | |
385 // way we can restore these registers is to have the oldest interpreter | |
386 // frame that we create restore these values. That is what this routine | |
387 // will accomplish. | |
388 | |
389 // At the moment we have modified c2 to not have any callee save registers | |
390 // so this problem does not exist and this routine is just a place holder. | |
391 | |
392 assert(f->is_interpreted_frame(), "must be interpreted"); | |
393 } |