Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/templateTable_x86_32.cpp @ 3852:fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
Reviewed-by: kvn, never, bdelsart
author | twisti |
---|---|
date | Tue, 16 Aug 2011 04:14:05 -0700 |
parents | ddd894528dbc |
children | 52b5d32fbfaf 069ab3f976d3 |
comparison
equal
deleted
inserted
replaced
3851:95134e034042 | 3852:fdb992d83a87 |
---|---|
200 assert(_desc->uses_bcp(), "inconsistent uses_bcp information"); | 200 assert(_desc->uses_bcp(), "inconsistent uses_bcp information"); |
201 return Address(rsi, offset); | 201 return Address(rsi, offset); |
202 } | 202 } |
203 | 203 |
204 | 204 |
205 void TemplateTable::patch_bytecode(Bytecodes::Code bytecode, Register bc, | 205 void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg, |
206 Register scratch, | 206 Register temp_reg, bool load_bc_into_bc_reg/*=true*/, |
207 bool load_bc_into_scratch/*=true*/) { | 207 int byte_no) { |
208 | 208 if (!RewriteBytecodes) return; |
209 if (!RewriteBytecodes) return; | 209 Label L_patch_done; |
210 // the pair bytecodes have already done the load. | 210 |
211 if (load_bc_into_scratch) { | 211 switch (bc) { |
212 __ movl(bc, bytecode); | 212 case Bytecodes::_fast_aputfield: |
213 } | 213 case Bytecodes::_fast_bputfield: |
214 Label patch_done; | 214 case Bytecodes::_fast_cputfield: |
215 case Bytecodes::_fast_dputfield: | |
216 case Bytecodes::_fast_fputfield: | |
217 case Bytecodes::_fast_iputfield: | |
218 case Bytecodes::_fast_lputfield: | |
219 case Bytecodes::_fast_sputfield: | |
220 { | |
221 // We skip bytecode quickening for putfield instructions when | |
222 // the put_code written to the constant pool cache is zero. | |
223 // This is required so that every execution of this instruction | |
224 // calls out to InterpreterRuntime::resolve_get_put to do | |
225 // additional, required work. | |
226 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); | |
227 assert(load_bc_into_bc_reg, "we use bc_reg as temp"); | |
228 __ get_cache_and_index_and_bytecode_at_bcp(bc_reg, temp_reg, temp_reg, byte_no, 1); | |
229 __ movl(bc_reg, bc); | |
230 __ cmpl(temp_reg, (int) 0); | |
231 __ jcc(Assembler::zero, L_patch_done); // don't patch | |
232 } | |
233 break; | |
234 default: | |
235 assert(byte_no == -1, "sanity"); | |
236 // the pair bytecodes have already done the load. | |
237 if (load_bc_into_bc_reg) { | |
238 __ movl(bc_reg, bc); | |
239 } | |
240 } | |
241 | |
215 if (JvmtiExport::can_post_breakpoint()) { | 242 if (JvmtiExport::can_post_breakpoint()) { |
216 Label fast_patch; | 243 Label L_fast_patch; |
217 // if a breakpoint is present we can't rewrite the stream directly | 244 // if a breakpoint is present we can't rewrite the stream directly |
218 __ movzbl(scratch, at_bcp(0)); | 245 __ movzbl(temp_reg, at_bcp(0)); |
219 __ cmpl(scratch, Bytecodes::_breakpoint); | 246 __ cmpl(temp_reg, Bytecodes::_breakpoint); |
220 __ jcc(Assembler::notEqual, fast_patch); | 247 __ jcc(Assembler::notEqual, L_fast_patch); |
221 __ get_method(scratch); | 248 __ get_method(temp_reg); |
222 // Let breakpoint table handling rewrite to quicker bytecode | 249 // Let breakpoint table handling rewrite to quicker bytecode |
223 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, rsi, bc); | 250 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), temp_reg, rsi, bc_reg); |
224 #ifndef ASSERT | 251 #ifndef ASSERT |
225 __ jmpb(patch_done); | 252 __ jmpb(L_patch_done); |
226 #else | 253 #else |
227 __ jmp(patch_done); | 254 __ jmp(L_patch_done); |
228 #endif | 255 #endif |
229 __ bind(fast_patch); | 256 __ bind(L_fast_patch); |
230 } | 257 } |
258 | |
231 #ifdef ASSERT | 259 #ifdef ASSERT |
232 Label okay; | 260 Label L_okay; |
233 __ load_unsigned_byte(scratch, at_bcp(0)); | 261 __ load_unsigned_byte(temp_reg, at_bcp(0)); |
234 __ cmpl(scratch, (int)Bytecodes::java_code(bytecode)); | 262 __ cmpl(temp_reg, (int)Bytecodes::java_code(bc)); |
235 __ jccb(Assembler::equal, okay); | 263 __ jccb(Assembler::equal, L_okay); |
236 __ cmpl(scratch, bc); | 264 __ cmpl(temp_reg, bc_reg); |
237 __ jcc(Assembler::equal, okay); | 265 __ jcc(Assembler::equal, L_okay); |
238 __ stop("patching the wrong bytecode"); | 266 __ stop("patching the wrong bytecode"); |
239 __ bind(okay); | 267 __ bind(L_okay); |
240 #endif | 268 #endif |
269 | |
241 // patch bytecode | 270 // patch bytecode |
242 __ movb(at_bcp(0), bc); | 271 __ movb(at_bcp(0), bc_reg); |
243 __ bind(patch_done); | 272 __ bind(L_patch_done); |
244 } | 273 } |
245 | 274 |
246 //---------------------------------------------------------------------------------------------------- | 275 //---------------------------------------------------------------------------------------------------- |
247 // Individual instructions | 276 // Individual instructions |
248 | 277 |
2058 Register temp = rbx; | 2087 Register temp = rbx; |
2059 | 2088 |
2060 assert_different_registers(result, Rcache, index, temp); | 2089 assert_different_registers(result, Rcache, index, temp); |
2061 | 2090 |
2062 Label resolved; | 2091 Label resolved; |
2063 __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); | |
2064 if (byte_no == f1_oop) { | 2092 if (byte_no == f1_oop) { |
2065 // We are resolved if the f1 field contains a non-null object (CallSite, etc.) | 2093 // We are resolved if the f1 field contains a non-null object (CallSite, etc.) |
2066 // This kind of CP cache entry does not need to match the flags byte, because | 2094 // This kind of CP cache entry does not need to match the flags byte, because |
2067 // there is a 1-1 relation between bytecode type and CP entry type. | 2095 // there is a 1-1 relation between bytecode type and CP entry type. |
2068 assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD) | 2096 assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD) |
2097 __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); | |
2069 __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset())); | 2098 __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset())); |
2070 __ testptr(result, result); | 2099 __ testptr(result, result); |
2071 __ jcc(Assembler::notEqual, resolved); | 2100 __ jcc(Assembler::notEqual, resolved); |
2072 } else { | 2101 } else { |
2073 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); | 2102 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); |
2074 assert(result == noreg, ""); //else change code for setting result | 2103 assert(result == noreg, ""); //else change code for setting result |
2075 const int shift_count = (1 + byte_no)*BitsPerByte; | 2104 __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size); |
2076 __ movl(temp, Address(Rcache, index, Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); | 2105 __ cmpl(temp, (int) bytecode()); // have we resolved this bytecode? |
2077 __ shrl(temp, shift_count); | |
2078 // have we resolved this bytecode? | |
2079 __ andl(temp, 0xFF); | |
2080 __ cmpl(temp, (int)bytecode()); | |
2081 __ jcc(Assembler::equal, resolved); | 2106 __ jcc(Assembler::equal, resolved); |
2082 } | 2107 } |
2083 | 2108 |
2084 // resolve first time through | 2109 // resolve first time through |
2085 address entry; | 2110 address entry; |
2451 | 2476 |
2452 Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble; | 2477 Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble; |
2453 | 2478 |
2454 __ shrl(flags, ConstantPoolCacheEntry::tosBits); | 2479 __ shrl(flags, ConstantPoolCacheEntry::tosBits); |
2455 assert(btos == 0, "change code, btos != 0"); | 2480 assert(btos == 0, "change code, btos != 0"); |
2456 // btos | |
2457 __ andl(flags, 0x0f); | 2481 __ andl(flags, 0x0f); |
2458 __ jcc(Assembler::notZero, notByte); | 2482 __ jcc(Assembler::notZero, notByte); |
2459 | 2483 |
2460 __ pop(btos); | 2484 // btos |
2461 if (!is_static) pop_and_check_object(obj); | 2485 { |
2462 __ movb(lo, rax ); | 2486 __ pop(btos); |
2463 if (!is_static) { | 2487 if (!is_static) pop_and_check_object(obj); |
2464 patch_bytecode(Bytecodes::_fast_bputfield, rcx, rbx); | 2488 __ movb(lo, rax); |
2465 } | 2489 if (!is_static) { |
2466 __ jmp(Done); | 2490 patch_bytecode(Bytecodes::_fast_bputfield, rcx, rbx, true, byte_no); |
2491 } | |
2492 __ jmp(Done); | |
2493 } | |
2467 | 2494 |
2468 __ bind(notByte); | 2495 __ bind(notByte); |
2496 __ cmpl(flags, itos); | |
2497 __ jcc(Assembler::notEqual, notInt); | |
2498 | |
2469 // itos | 2499 // itos |
2470 __ cmpl(flags, itos ); | 2500 { |
2471 __ jcc(Assembler::notEqual, notInt); | 2501 __ pop(itos); |
2472 | 2502 if (!is_static) pop_and_check_object(obj); |
2473 __ pop(itos); | 2503 __ movl(lo, rax); |
2474 if (!is_static) pop_and_check_object(obj); | 2504 if (!is_static) { |
2475 | 2505 patch_bytecode(Bytecodes::_fast_iputfield, rcx, rbx, true, byte_no); |
2476 __ movl(lo, rax ); | 2506 } |
2477 if (!is_static) { | 2507 __ jmp(Done); |
2478 patch_bytecode(Bytecodes::_fast_iputfield, rcx, rbx); | 2508 } |
2479 } | |
2480 __ jmp(Done); | |
2481 | 2509 |
2482 __ bind(notInt); | 2510 __ bind(notInt); |
2511 __ cmpl(flags, atos); | |
2512 __ jcc(Assembler::notEqual, notObj); | |
2513 | |
2483 // atos | 2514 // atos |
2484 __ cmpl(flags, atos ); | 2515 { |
2485 __ jcc(Assembler::notEqual, notObj); | 2516 __ pop(atos); |
2486 | 2517 if (!is_static) pop_and_check_object(obj); |
2487 __ pop(atos); | 2518 do_oop_store(_masm, lo, rax, _bs->kind(), false); |
2488 if (!is_static) pop_and_check_object(obj); | 2519 if (!is_static) { |
2489 | 2520 patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx, true, byte_no); |
2490 do_oop_store(_masm, lo, rax, _bs->kind(), false); | 2521 } |
2491 | 2522 __ jmp(Done); |
2492 if (!is_static) { | 2523 } |
2493 patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx); | |
2494 } | |
2495 | |
2496 __ jmp(Done); | |
2497 | 2524 |
2498 __ bind(notObj); | 2525 __ bind(notObj); |
2526 __ cmpl(flags, ctos); | |
2527 __ jcc(Assembler::notEqual, notChar); | |
2528 | |
2499 // ctos | 2529 // ctos |
2500 __ cmpl(flags, ctos ); | 2530 { |
2501 __ jcc(Assembler::notEqual, notChar); | 2531 __ pop(ctos); |
2502 | 2532 if (!is_static) pop_and_check_object(obj); |
2503 __ pop(ctos); | 2533 __ movw(lo, rax); |
2504 if (!is_static) pop_and_check_object(obj); | 2534 if (!is_static) { |
2505 __ movw(lo, rax ); | 2535 patch_bytecode(Bytecodes::_fast_cputfield, rcx, rbx, true, byte_no); |
2506 if (!is_static) { | 2536 } |
2507 patch_bytecode(Bytecodes::_fast_cputfield, rcx, rbx); | 2537 __ jmp(Done); |
2508 } | 2538 } |
2509 __ jmp(Done); | |
2510 | 2539 |
2511 __ bind(notChar); | 2540 __ bind(notChar); |
2541 __ cmpl(flags, stos); | |
2542 __ jcc(Assembler::notEqual, notShort); | |
2543 | |
2512 // stos | 2544 // stos |
2513 __ cmpl(flags, stos ); | 2545 { |
2514 __ jcc(Assembler::notEqual, notShort); | 2546 __ pop(stos); |
2515 | 2547 if (!is_static) pop_and_check_object(obj); |
2516 __ pop(stos); | 2548 __ movw(lo, rax); |
2517 if (!is_static) pop_and_check_object(obj); | 2549 if (!is_static) { |
2518 __ movw(lo, rax ); | 2550 patch_bytecode(Bytecodes::_fast_sputfield, rcx, rbx, true, byte_no); |
2519 if (!is_static) { | 2551 } |
2520 patch_bytecode(Bytecodes::_fast_sputfield, rcx, rbx); | 2552 __ jmp(Done); |
2521 } | 2553 } |
2522 __ jmp(Done); | |
2523 | 2554 |
2524 __ bind(notShort); | 2555 __ bind(notShort); |
2556 __ cmpl(flags, ltos); | |
2557 __ jcc(Assembler::notEqual, notLong); | |
2558 | |
2525 // ltos | 2559 // ltos |
2526 __ cmpl(flags, ltos ); | 2560 { |
2527 __ jcc(Assembler::notEqual, notLong); | 2561 Label notVolatileLong; |
2528 | 2562 __ testl(rdx, rdx); |
2529 Label notVolatileLong; | 2563 __ jcc(Assembler::zero, notVolatileLong); |
2530 __ testl(rdx, rdx); | 2564 |
2531 __ jcc(Assembler::zero, notVolatileLong); | 2565 __ pop(ltos); // overwrites rdx, do this after testing volatile. |
2532 | 2566 if (!is_static) pop_and_check_object(obj); |
2533 __ pop(ltos); // overwrites rdx, do this after testing volatile. | 2567 |
2534 if (!is_static) pop_and_check_object(obj); | 2568 // Replace with real volatile test |
2535 | 2569 __ push(rdx); |
2536 // Replace with real volatile test | 2570 __ push(rax); // Must update atomically with FIST |
2537 __ push(rdx); | 2571 __ fild_d(Address(rsp,0)); // So load into FPU register |
2538 __ push(rax); // Must update atomically with FIST | 2572 __ fistp_d(lo); // and put into memory atomically |
2539 __ fild_d(Address(rsp,0)); // So load into FPU register | 2573 __ addptr(rsp, 2*wordSize); |
2540 __ fistp_d(lo); // and put into memory atomically | 2574 // volatile_barrier(); |
2541 __ addptr(rsp, 2*wordSize); | 2575 volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | |
2542 // volatile_barrier(); | 2576 Assembler::StoreStore)); |
2543 volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | | 2577 // Don't rewrite volatile version |
2544 Assembler::StoreStore)); | 2578 __ jmp(notVolatile); |
2545 // Don't rewrite volatile version | 2579 |
2546 __ jmp(notVolatile); | 2580 __ bind(notVolatileLong); |
2547 | 2581 |
2548 __ bind(notVolatileLong); | 2582 __ pop(ltos); // overwrites rdx |
2549 | 2583 if (!is_static) pop_and_check_object(obj); |
2550 __ pop(ltos); // overwrites rdx | 2584 NOT_LP64(__ movptr(hi, rdx)); |
2551 if (!is_static) pop_and_check_object(obj); | 2585 __ movptr(lo, rax); |
2552 NOT_LP64(__ movptr(hi, rdx)); | 2586 if (!is_static) { |
2553 __ movptr(lo, rax); | 2587 patch_bytecode(Bytecodes::_fast_lputfield, rcx, rbx, true, byte_no); |
2554 if (!is_static) { | 2588 } |
2555 patch_bytecode(Bytecodes::_fast_lputfield, rcx, rbx); | 2589 __ jmp(notVolatile); |
2556 } | 2590 } |
2557 __ jmp(notVolatile); | |
2558 | 2591 |
2559 __ bind(notLong); | 2592 __ bind(notLong); |
2593 __ cmpl(flags, ftos); | |
2594 __ jcc(Assembler::notEqual, notFloat); | |
2595 | |
2560 // ftos | 2596 // ftos |
2561 __ cmpl(flags, ftos ); | 2597 { |
2562 __ jcc(Assembler::notEqual, notFloat); | 2598 __ pop(ftos); |
2563 | 2599 if (!is_static) pop_and_check_object(obj); |
2564 __ pop(ftos); | 2600 __ fstp_s(lo); |
2565 if (!is_static) pop_and_check_object(obj); | 2601 if (!is_static) { |
2566 __ fstp_s(lo); | 2602 patch_bytecode(Bytecodes::_fast_fputfield, rcx, rbx, true, byte_no); |
2567 if (!is_static) { | 2603 } |
2568 patch_bytecode(Bytecodes::_fast_fputfield, rcx, rbx); | 2604 __ jmp(Done); |
2569 } | 2605 } |
2570 __ jmp(Done); | |
2571 | 2606 |
2572 __ bind(notFloat); | 2607 __ bind(notFloat); |
2608 #ifdef ASSERT | |
2609 __ cmpl(flags, dtos); | |
2610 __ jcc(Assembler::notEqual, notDouble); | |
2611 #endif | |
2612 | |
2573 // dtos | 2613 // dtos |
2574 __ cmpl(flags, dtos ); | 2614 { |
2575 __ jcc(Assembler::notEqual, notDouble); | 2615 __ pop(dtos); |
2576 | 2616 if (!is_static) pop_and_check_object(obj); |
2577 __ pop(dtos); | 2617 __ fstp_d(lo); |
2578 if (!is_static) pop_and_check_object(obj); | 2618 if (!is_static) { |
2579 __ fstp_d(lo); | 2619 patch_bytecode(Bytecodes::_fast_dputfield, rcx, rbx, true, byte_no); |
2580 if (!is_static) { | 2620 } |
2581 patch_bytecode(Bytecodes::_fast_dputfield, rcx, rbx); | 2621 __ jmp(Done); |
2582 } | 2622 } |
2583 __ jmp(Done); | 2623 |
2584 | 2624 #ifdef ASSERT |
2585 __ bind(notDouble); | 2625 __ bind(notDouble); |
2586 | |
2587 __ stop("Bad state"); | 2626 __ stop("Bad state"); |
2627 #endif | |
2588 | 2628 |
2589 __ bind(Done); | 2629 __ bind(Done); |
2590 | 2630 |
2591 // Check for volatile store | 2631 // Check for volatile store |
2592 __ testl(rdx, rdx); | 2632 __ testl(rdx, rdx); |