comparison src/cpu/x86/vm/interpreter_x86_64.cpp @ 304:dc7f315e41f7

5108146: Merge i486 and amd64 cpu directories 6459804: Want client (c1) compiler for x86_64 (amd64) for faster start-up Reviewed-by: kvn
author never
date Wed, 27 Aug 2008 00:21:55 -0700
parents d1605aabd0a1
children e5b0439ef4ae
comparison
equal deleted inserted replaced
303:fa4d1d240383 304:dc7f315e41f7
33 address entry = __ pc(); 33 address entry = __ pc();
34 34
35 // rbx: method 35 // rbx: method
36 // r14: pointer to locals 36 // r14: pointer to locals
37 // c_rarg3: first stack arg - wordSize 37 // c_rarg3: first stack arg - wordSize
38 __ movq(c_rarg3, rsp); 38 __ mov(c_rarg3, rsp);
39 // adjust rsp 39 // adjust rsp
40 __ subq(rsp, 4 * wordSize); 40 __ subptr(rsp, 4 * wordSize);
41 __ call_VM(noreg, 41 __ call_VM(noreg,
42 CAST_FROM_FN_PTR(address, 42 CAST_FROM_FN_PTR(address,
43 InterpreterRuntime::slow_signature_handler), 43 InterpreterRuntime::slow_signature_handler),
44 rbx, r14, c_rarg3); 44 rbx, r14, c_rarg3);
45 45
68 // Do Int register here 68 // Do Int register here
69 switch ( i ) { 69 switch ( i ) {
70 case 0: 70 case 0:
71 __ movl(rscratch1, Address(rbx, methodOopDesc::access_flags_offset())); 71 __ movl(rscratch1, Address(rbx, methodOopDesc::access_flags_offset()));
72 __ testl(rscratch1, JVM_ACC_STATIC); 72 __ testl(rscratch1, JVM_ACC_STATIC);
73 __ cmovq(Assembler::zero, c_rarg1, Address(rsp, 0)); 73 __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0));
74 break; 74 break;
75 case 1: 75 case 1:
76 __ movq(c_rarg2, Address(rsp, wordSize)); 76 __ movptr(c_rarg2, Address(rsp, wordSize));
77 break; 77 break;
78 case 2: 78 case 2:
79 __ movq(c_rarg3, Address(rsp, 2 * wordSize)); 79 __ movptr(c_rarg3, Address(rsp, 2 * wordSize));
80 break; 80 break;
81 default: 81 default:
82 break; 82 break;
83 } 83 }
84 84
99 __ bind(next); 99 __ bind(next);
100 } 100 }
101 101
102 102
103 // restore rsp 103 // restore rsp
104 __ addq(rsp, 4 * wordSize); 104 __ addptr(rsp, 4 * wordSize);
105 105
106 __ ret(0); 106 __ ret(0);
107 107
108 return entry; 108 return entry;
109 } 109 }
112 address entry = __ pc(); 112 address entry = __ pc();
113 113
114 // rbx: method 114 // rbx: method
115 // r14: pointer to locals 115 // r14: pointer to locals
116 // c_rarg3: first stack arg - wordSize 116 // c_rarg3: first stack arg - wordSize
117 __ movq(c_rarg3, rsp); 117 __ mov(c_rarg3, rsp);
118 // adjust rsp 118 // adjust rsp
119 __ subq(rsp, 14 * wordSize); 119 __ subptr(rsp, 14 * wordSize);
120 __ call_VM(noreg, 120 __ call_VM(noreg,
121 CAST_FROM_FN_PTR(address, 121 CAST_FROM_FN_PTR(address,
122 InterpreterRuntime::slow_signature_handler), 122 InterpreterRuntime::slow_signature_handler),
123 rbx, r14, c_rarg3); 123 rbx, r14, c_rarg3);
124 124
153 } 153 }
154 154
155 // Now handle integrals. Only do c_rarg1 if not static. 155 // Now handle integrals. Only do c_rarg1 if not static.
156 __ movl(c_rarg3, Address(rbx, methodOopDesc::access_flags_offset())); 156 __ movl(c_rarg3, Address(rbx, methodOopDesc::access_flags_offset()));
157 __ testl(c_rarg3, JVM_ACC_STATIC); 157 __ testl(c_rarg3, JVM_ACC_STATIC);
158 __ cmovq(Assembler::zero, c_rarg1, Address(rsp, 0)); 158 __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0));
159 159
160 __ movq(c_rarg2, Address(rsp, wordSize)); 160 __ movptr(c_rarg2, Address(rsp, wordSize));
161 __ movq(c_rarg3, Address(rsp, 2 * wordSize)); 161 __ movptr(c_rarg3, Address(rsp, 2 * wordSize));
162 __ movq(c_rarg4, Address(rsp, 3 * wordSize)); 162 __ movptr(c_rarg4, Address(rsp, 3 * wordSize));
163 __ movq(c_rarg5, Address(rsp, 4 * wordSize)); 163 __ movptr(c_rarg5, Address(rsp, 4 * wordSize));
164 164
165 // restore rsp 165 // restore rsp
166 __ addq(rsp, 14 * wordSize); 166 __ addptr(rsp, 14 * wordSize);
167 167
168 __ ret(0); 168 __ ret(0);
169 169
170 return entry; 170 return entry;
171 } 171 }
174 174
175 // 175 //
176 // Various method entries 176 // Various method entries
177 // 177 //
178 178
179 address InterpreterGenerator::generate_math_entry( 179 address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
180 AbstractInterpreter::MethodKind kind) { 180
181 // rbx: methodOop 181 // rbx,: methodOop
182 // rcx: scratrch
183 // r13: sender sp
182 184
183 if (!InlineIntrinsics) return NULL; // Generate a vanilla entry 185 if (!InlineIntrinsics) return NULL; // Generate a vanilla entry
184
185 assert(kind == Interpreter::java_lang_math_sqrt,
186 "Other intrinsics are not special");
187 186
188 address entry_point = __ pc(); 187 address entry_point = __ pc();
189 188
190 // These don't need a safepoint check because they aren't virtually 189 // These don't need a safepoint check because they aren't virtually
191 // callable. We won't enter these intrinsics from compiled code. 190 // callable. We won't enter these intrinsics from compiled code.
195 // mathematical functions inlined by compiler 194 // mathematical functions inlined by compiler
196 // (interpreter must provide identical implementation 195 // (interpreter must provide identical implementation
197 // in order to avoid monotonicity bugs when switching 196 // in order to avoid monotonicity bugs when switching
198 // from interpreter to compiler in the middle of some 197 // from interpreter to compiler in the middle of some
199 // computation) 198 // computation)
199 //
200 // stack: [ ret adr ] <-- rsp
201 // [ lo(arg) ]
202 // [ hi(arg) ]
203 //
200 204
201 // Note: For JDK 1.2 StrictMath doesn't exist and Math.sin/cos/sqrt are 205 // Note: For JDK 1.2 StrictMath doesn't exist and Math.sin/cos/sqrt are
202 // native methods. Interpreter::method_kind(...) does a check for 206 // native methods. Interpreter::method_kind(...) does a check for
203 // native methods first before checking for intrinsic methods and 207 // native methods first before checking for intrinsic methods and
204 // thus will never select this entry point. Make sure it is not 208 // thus will never select this entry point. Make sure it is not
216 // JDK version is only determined when universe2_init() is called. 220 // JDK version is only determined when universe2_init() is called.
217 221
218 // Note: For JDK 1.3 StrictMath exists and Math.sin/cos/sqrt are 222 // Note: For JDK 1.3 StrictMath exists and Math.sin/cos/sqrt are
219 // java methods. Interpreter::method_kind(...) will select 223 // java methods. Interpreter::method_kind(...) will select
220 // this entry point for the corresponding methods in JDK 1.3. 224 // this entry point for the corresponding methods in JDK 1.3.
221 __ sqrtsd(xmm0, Address(rsp, wordSize)); 225 // get argument
222 226
223 __ popq(rax); 227 if (kind == Interpreter::java_lang_math_sqrt) {
224 __ movq(rsp, r13); 228 __ sqrtsd(xmm0, Address(rsp, wordSize));
229 } else {
230 __ fld_d(Address(rsp, wordSize));
231 switch (kind) {
232 case Interpreter::java_lang_math_sin :
233 __ trigfunc('s');
234 break;
235 case Interpreter::java_lang_math_cos :
236 __ trigfunc('c');
237 break;
238 case Interpreter::java_lang_math_tan :
239 __ trigfunc('t');
240 break;
241 case Interpreter::java_lang_math_abs:
242 __ fabs();
243 break;
244 case Interpreter::java_lang_math_log:
245 __ flog();
246 break;
247 case Interpreter::java_lang_math_log10:
248 __ flog10();
249 break;
250 default :
251 ShouldNotReachHere();
252 }
253
254 // return double result in xmm0 for interpreter and compilers.
255 __ subptr(rsp, 2*wordSize);
256 // Round to 64bit precision
257 __ fstp_d(Address(rsp, 0));
258 __ movdbl(xmm0, Address(rsp, 0));
259 __ addptr(rsp, 2*wordSize);
260 }
261
262
263 __ pop(rax);
264 __ mov(rsp, r13);
225 __ jmp(rax); 265 __ jmp(rax);
226 266
227 return entry_point; 267 return entry_point;
228 } 268 }
229 269
237 address entry_point = __ pc(); 277 address entry_point = __ pc();
238 278
239 // abstract method entry 279 // abstract method entry
240 // remove return address. Not really needed, since exception 280 // remove return address. Not really needed, since exception
241 // handling throws away expression stack 281 // handling throws away expression stack
242 __ popq(rbx); 282 __ pop(rbx);
243 283
244 // adjust stack to what a normal return would do 284 // adjust stack to what a normal return would do
245 __ movq(rsp, r13); 285 __ mov(rsp, r13);
246 286
247 // throw exception 287 // throw exception
248 __ call_VM(noreg, CAST_FROM_FN_PTR(address, 288 __ call_VM(noreg, CAST_FROM_FN_PTR(address,
249 InterpreterRuntime::throw_AbstractMethodError)); 289 InterpreterRuntime::throw_AbstractMethodError));
250 // the call_VM checks for exception, so we should never return here. 290 // the call_VM checks for exception, so we should never return here.
274 314
275 // do nothing for empty methods (do not even increment invocation counter) 315 // do nothing for empty methods (do not even increment invocation counter)
276 // Code: _return 316 // Code: _return
277 // _return 317 // _return
278 // return w/o popping parameters 318 // return w/o popping parameters
279 __ popq(rax); 319 __ pop(rax);
280 __ movq(rsp, r13); 320 __ mov(rsp, r13);
281 __ jmp(rax); 321 __ jmp(rax);
282 322
283 __ bind(slow_path); 323 __ bind(slow_path);
284 (void) generate_normal_entry(false); 324 (void) generate_normal_entry(false);
285 return entry_point; 325 return entry_point;
286 326
287 }
288
289 // Call an accessor method (assuming it is resolved, otherwise drop
290 // into vanilla (slow path) entry
291 address InterpreterGenerator::generate_accessor_entry(void) {
292 // rbx: methodOop
293
294 // r13: senderSP must preserver for slow path, set SP to it on fast path
295
296 address entry_point = __ pc();
297 Label xreturn_path;
298
299 // do fastpath for resolved accessor methods
300 if (UseFastAccessorMethods) {
301 // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites
302 // thereof; parameter size = 1
303 // Note: We can only use this code if the getfield has been resolved
304 // and if we don't have a null-pointer exception => check for
305 // these conditions first and use slow path if necessary.
306 Label slow_path;
307 // If we need a safepoint check, generate full interpreter entry.
308 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
309 SafepointSynchronize::_not_synchronized);
310
311 __ jcc(Assembler::notEqual, slow_path);
312 // rbx: method
313 __ movq(rax, Address(rsp, wordSize));
314
315 // check if local 0 != NULL and read field
316 __ testq(rax, rax);
317 __ jcc(Assembler::zero, slow_path);
318
319 __ movq(rdi, Address(rbx, methodOopDesc::constants_offset()));
320 // read first instruction word and extract bytecode @ 1 and index @ 2
321 __ movq(rdx, Address(rbx, methodOopDesc::const_offset()));
322 __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset()));
323 // Shift codes right to get the index on the right.
324 // The bytecode fetched looks like <index><0xb4><0x2a>
325 __ shrl(rdx, 2 * BitsPerByte);
326 __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size())));
327 __ movq(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes()));
328
329 // rax: local 0
330 // rbx: method
331 // rdx: constant pool cache index
332 // rdi: constant pool cache
333
334 // check if getfield has been resolved and read constant pool cache entry
335 // check the validity of the cache entry by testing whether _indices field
336 // contains Bytecode::_getfield in b1 byte.
337 assert(in_words(ConstantPoolCacheEntry::size()) == 4,
338 "adjust shift below");
339 __ movl(rcx,
340 Address(rdi,
341 rdx,
342 Address::times_8,
343 constantPoolCacheOopDesc::base_offset() +
344 ConstantPoolCacheEntry::indices_offset()));
345 __ shrl(rcx, 2 * BitsPerByte);
346 __ andl(rcx, 0xFF);
347 __ cmpl(rcx, Bytecodes::_getfield);
348 __ jcc(Assembler::notEqual, slow_path);
349
350 // Note: constant pool entry is not valid before bytecode is resolved
351 __ movq(rcx,
352 Address(rdi,
353 rdx,
354 Address::times_8,
355 constantPoolCacheOopDesc::base_offset() +
356 ConstantPoolCacheEntry::f2_offset()));
357 // edx: flags
358 __ movl(rdx,
359 Address(rdi,
360 rdx,
361 Address::times_8,
362 constantPoolCacheOopDesc::base_offset() +
363 ConstantPoolCacheEntry::flags_offset()));
364
365 Label notObj, notInt, notByte, notShort;
366 const Address field_address(rax, rcx, Address::times_1);
367
368 // Need to differentiate between igetfield, agetfield, bgetfield etc.
369 // because they are different sizes.
370 // Use the type from the constant pool cache
371 __ shrl(rdx, ConstantPoolCacheEntry::tosBits);
372 // Make sure we don't need to mask edx for tosBits after the above shift
373 ConstantPoolCacheEntry::verify_tosBits();
374
375 __ cmpl(rdx, atos);
376 __ jcc(Assembler::notEqual, notObj);
377 // atos
378 __ load_heap_oop(rax, field_address);
379 __ jmp(xreturn_path);
380
381 __ bind(notObj);
382 __ cmpl(rdx, itos);
383 __ jcc(Assembler::notEqual, notInt);
384 // itos
385 __ movl(rax, field_address);
386 __ jmp(xreturn_path);
387
388 __ bind(notInt);
389 __ cmpl(rdx, btos);
390 __ jcc(Assembler::notEqual, notByte);
391 // btos
392 __ load_signed_byte(rax, field_address);
393 __ jmp(xreturn_path);
394
395 __ bind(notByte);
396 __ cmpl(rdx, stos);
397 __ jcc(Assembler::notEqual, notShort);
398 // stos
399 __ load_signed_word(rax, field_address);
400 __ jmp(xreturn_path);
401
402 __ bind(notShort);
403 #ifdef ASSERT
404 Label okay;
405 __ cmpl(rdx, ctos);
406 __ jcc(Assembler::equal, okay);
407 __ stop("what type is this?");
408 __ bind(okay);
409 #endif
410 // ctos
411 __ load_unsigned_word(rax, field_address);
412
413 __ bind(xreturn_path);
414
415 // _ireturn/_areturn
416 __ popq(rdi);
417 __ movq(rsp, r13);
418 __ jmp(rdi);
419 __ ret(0);
420
421 // generate a vanilla interpreter entry as the slow path
422 __ bind(slow_path);
423 (void) generate_normal_entry(false);
424 } else {
425 (void) generate_normal_entry(false);
426 }
427
428 return entry_point;
429 } 327 }
430 328
431 // This method tells the deoptimizer how big an interpreted frame must be: 329 // This method tells the deoptimizer how big an interpreted frame must be:
432 int AbstractInterpreter::size_activation(methodOop method, 330 int AbstractInterpreter::size_activation(methodOop method,
433 int tempcount, 331 int tempcount,