Mercurial > hg > truffle
comparison src/cpu/x86/vm/x86_32.ad @ 420:a1980da045cc
6462850: generate biased locking code in C2 ideal graph
Summary: Inline biased locking code in C2 ideal graph during macro nodes expansion
Reviewed-by: never
author | kvn |
---|---|
date | Fri, 07 Nov 2008 09:29:38 -0800 |
parents | 4d9884b01ba6 |
children | db4caa99ef11 3b5ac9e7e6ea |
comparison
equal
deleted
inserted
replaced
419:0bf25c4807f9 | 420:a1980da045cc |
---|---|
3311 // TODO: optimize away redundant LDs of obj->mark and improve the markword triage | 3311 // TODO: optimize away redundant LDs of obj->mark and improve the markword triage |
3312 // order to reduce the number of conditional branches in the most common cases. | 3312 // order to reduce the number of conditional branches in the most common cases. |
3313 // Beware -- there's a subtle invariant that fetch of the markword | 3313 // Beware -- there's a subtle invariant that fetch of the markword |
3314 // at [FETCH], below, will never observe a biased encoding (*101b). | 3314 // at [FETCH], below, will never observe a biased encoding (*101b). |
3315 // If this invariant is not held we risk exclusion (safety) failure. | 3315 // If this invariant is not held we risk exclusion (safety) failure. |
3316 if (UseBiasedLocking) { | 3316 if (UseBiasedLocking && !UseOptoBiasInlining) { |
3317 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); | 3317 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); |
3318 } | 3318 } |
3319 | 3319 |
3320 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] | 3320 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] |
3321 masm.testptr(tmpReg, 0x02) ; // Inflated v (Stack-locked or neutral) | 3321 masm.testptr(tmpReg, 0x02) ; // Inflated v (Stack-locked or neutral) |
3532 } else { | 3532 } else { |
3533 Label DONE_LABEL, Stacked, CheckSucc, Inflated ; | 3533 Label DONE_LABEL, Stacked, CheckSucc, Inflated ; |
3534 | 3534 |
3535 // Critically, the biased locking test must have precedence over | 3535 // Critically, the biased locking test must have precedence over |
3536 // and appear before the (box->dhw == 0) recursive stack-lock test. | 3536 // and appear before the (box->dhw == 0) recursive stack-lock test. |
3537 if (UseBiasedLocking) { | 3537 if (UseBiasedLocking && !UseOptoBiasInlining) { |
3538 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); | 3538 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); |
3539 } | 3539 } |
3540 | 3540 |
3541 masm.cmpptr(Address(boxReg, 0), 0) ; // Examine the displaced header | 3541 masm.cmpptr(Address(boxReg, 0), 0) ; // Examine the displaced header |
3542 masm.movptr(tmpReg, Address(objReg, 0)) ; // Examine the object's markword | 3542 masm.movptr(tmpReg, Address(objReg, 0)) ; // Examine the object's markword |
7928 format %{ "CMPXCHG $heap_top_ptr,$newval\t# If EAX==$heap_top_ptr Then store $newval into $heap_top_ptr" %} | 7928 format %{ "CMPXCHG $heap_top_ptr,$newval\t# If EAX==$heap_top_ptr Then store $newval into $heap_top_ptr" %} |
7929 ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval,heap_top_ptr) ); | 7929 ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval,heap_top_ptr) ); |
7930 ins_pipe( pipe_cmpxchg ); | 7930 ins_pipe( pipe_cmpxchg ); |
7931 %} | 7931 %} |
7932 | 7932 |
7933 // Conditional-store of a long value | 7933 // Conditional-store of an int value. |
7934 // Returns a boolean value (0/1) on success. Implemented with a CMPXCHG8 on Intel. | 7934 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel. |
7935 // mem_ptr can actually be in either ESI or EDI | 7935 instruct storeIConditional( memory mem, eAXRegI oldval, eRegI newval, eFlagsReg cr ) %{ |
7936 instruct storeLConditional( eRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{ | 7936 match(Set cr (StoreIConditional mem (Binary oldval newval))); |
7937 match(Set res (StoreLConditional mem_ptr (Binary oldval newval))); | 7937 effect(KILL oldval); |
7938 effect(KILL cr); | 7938 format %{ "CMPXCHG $mem,$newval\t# If EAX==$mem Then store $newval into $mem" %} |
7939 // EDX:EAX is killed if there is contention, but then it's also unused. | 7939 ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval, mem) ); |
7940 // In the common case of no contention, EDX:EAX holds the new oop address. | |
7941 format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" | |
7942 "MOV $res,0\n\t" | |
7943 "JNE,s fail\n\t" | |
7944 "MOV $res,1\n" | |
7945 "fail:" %} | |
7946 ins_encode( enc_cmpxchg8(mem_ptr), | |
7947 enc_flags_ne_to_boolean(res) ); | |
7948 ins_pipe( pipe_cmpxchg ); | 7940 ins_pipe( pipe_cmpxchg ); |
7949 %} | 7941 %} |
7950 | 7942 |
7951 // Conditional-store of a long value | 7943 // Conditional-store of a long value. |
7952 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG8 on Intel. | 7944 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG8 on Intel. |
7953 // mem_ptr can actually be in either ESI or EDI | 7945 instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{ |
7954 instruct storeLConditional_flags( eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr, immI0 zero ) %{ | 7946 match(Set cr (StoreLConditional mem (Binary oldval newval))); |
7955 match(Set cr (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero)); | 7947 effect(KILL oldval); |
7956 // EDX:EAX is killed if there is contention, but then it's also unused. | 7948 format %{ "XCHG EBX,ECX\t# correct order for CMPXCHG8 instruction\n\t" |
7957 // In the common case of no contention, EDX:EAX holds the new oop address. | 7949 "CMPXCHG8 $mem,ECX:EBX\t# If EDX:EAX==$mem Then store ECX:EBX into $mem\n\t" |
7958 format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" %} | 7950 "XCHG EBX,ECX" |
7959 ins_encode( enc_cmpxchg8(mem_ptr) ); | 7951 %} |
7952 ins_encode %{ | |
7953 // Note: we need to swap rbx, and rcx before and after the | |
7954 // cmpxchg8 instruction because the instruction uses | |
7955 // rcx as the high order word of the new value to store but | |
7956 // our register encoding uses rbx. | |
7957 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc)); | |
7958 if( os::is_MP() ) | |
7959 __ lock(); | |
7960 __ cmpxchg8(Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp)); | |
7961 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc)); | |
7962 %} | |
7960 ins_pipe( pipe_cmpxchg ); | 7963 ins_pipe( pipe_cmpxchg ); |
7961 %} | 7964 %} |
7962 | 7965 |
7963 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them | 7966 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them |
7964 | 7967 |
8421 opcode(0xC1, 0x5); /* C1 /5 ib */ | 8424 opcode(0xC1, 0x5); /* C1 /5 ib */ |
8422 ins_encode( RegOpcImm( dst, shift) ); | 8425 ins_encode( RegOpcImm( dst, shift) ); |
8423 ins_pipe( ialu_reg ); | 8426 ins_pipe( ialu_reg ); |
8424 %} | 8427 %} |
8425 | 8428 |
8429 | |
8426 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. | 8430 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. |
8427 // This idiom is used by the compiler for the i2b bytecode. | 8431 // This idiom is used by the compiler for the i2b bytecode. |
8428 instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour, eFlagsReg cr) %{ | 8432 instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour, eFlagsReg cr) %{ |
8429 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); | 8433 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); |
8430 effect(KILL cr); | 8434 effect(KILL cr); |
8537 format %{ "OR $dst,$src" %} | 8541 format %{ "OR $dst,$src" %} |
8538 opcode(0x0B); | 8542 opcode(0x0B); |
8539 ins_encode( OpcP, RegReg( dst, src) ); | 8543 ins_encode( OpcP, RegReg( dst, src) ); |
8540 ins_pipe( ialu_reg_reg ); | 8544 ins_pipe( ialu_reg_reg ); |
8541 %} | 8545 %} |
8546 | |
8547 instruct orI_eReg_castP2X(eRegI dst, eRegP src, eFlagsReg cr) %{ | |
8548 match(Set dst (OrI dst (CastP2X src))); | |
8549 effect(KILL cr); | |
8550 | |
8551 size(2); | |
8552 format %{ "OR $dst,$src" %} | |
8553 opcode(0x0B); | |
8554 ins_encode( OpcP, RegReg( dst, src) ); | |
8555 ins_pipe( ialu_reg_reg ); | |
8556 %} | |
8557 | |
8542 | 8558 |
8543 // Or Register with Immediate | 8559 // Or Register with Immediate |
8544 instruct orI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{ | 8560 instruct orI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{ |
8545 match(Set dst (OrI dst src)); | 8561 match(Set dst (OrI dst src)); |
8546 effect(KILL cr); | 8562 effect(KILL cr); |