Merge
This commit is contained in:
commit
0f58116e47
@ -13,3 +13,4 @@ bb1ef4ee3d2c8cbf43a37d372325a7952be590b9 jdk7-b33
|
|||||||
4b4f5fea8d7d0743f0c30d91fcd9bf9d96e5d2ad jdk7-b36
|
4b4f5fea8d7d0743f0c30d91fcd9bf9d96e5d2ad jdk7-b36
|
||||||
744554f5a3290e11c71cd2ddb1aff49e431f9ed0 jdk7-b37
|
744554f5a3290e11c71cd2ddb1aff49e431f9ed0 jdk7-b37
|
||||||
cc47a76899ed33a2c513cb688348244c9b5a1288 jdk7-b38
|
cc47a76899ed33a2c513cb688348244c9b5a1288 jdk7-b38
|
||||||
|
ab523b49de1fc73fefe6855ce1e0349bdbd7af29 jdk7-b39
|
||||||
|
@ -13,3 +13,4 @@ ef6af34d75a7b44e77083f1d4ee47631fa09d3b4 jdk7-b31
|
|||||||
0723891eb8d1c27e67c54163af0b4cea05a4e036 jdk7-b36
|
0723891eb8d1c27e67c54163af0b4cea05a4e036 jdk7-b36
|
||||||
59d5848bdedebe91cc2753acce78911bcb4a66db jdk7-b37
|
59d5848bdedebe91cc2753acce78911bcb4a66db jdk7-b37
|
||||||
08be802754b0296c91a7713b6d85a015dbcd5349 jdk7-b38
|
08be802754b0296c91a7713b6d85a015dbcd5349 jdk7-b38
|
||||||
|
55078b6661e286e90387d1d9950bd865f5cc436e jdk7-b39
|
||||||
|
@ -13,3 +13,4 @@ b727c32788a906c04839516ae7443a085185a300 jdk7-b32
|
|||||||
e91159f921a58af3698e6479ea1fc5818da66d09 jdk7-b36
|
e91159f921a58af3698e6479ea1fc5818da66d09 jdk7-b36
|
||||||
9ee9cf798b59e7d51f8c0a686959f313867a55d6 jdk7-b37
|
9ee9cf798b59e7d51f8c0a686959f313867a55d6 jdk7-b37
|
||||||
d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38
|
d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38
|
||||||
|
49ca90d77f34571b0757ebfcb8a7848ef2696b88 jdk7-b39
|
||||||
|
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2008
|
|||||||
|
|
||||||
HS_MAJOR_VER=14
|
HS_MAJOR_VER=14
|
||||||
HS_MINOR_VER=0
|
HS_MINOR_VER=0
|
||||||
HS_BUILD_NUMBER=06
|
HS_BUILD_NUMBER=07
|
||||||
|
|
||||||
JDK_MAJOR_VER=1
|
JDK_MAJOR_VER=1
|
||||||
JDK_MINOR_VER=7
|
JDK_MINOR_VER=7
|
||||||
|
@ -2615,7 +2615,8 @@ void MacroAssembler::cas_under_lock(Register top_ptr_reg, Register top_reg, Regi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, Register temp_reg,
|
void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg,
|
||||||
|
Register temp_reg,
|
||||||
Label& done, Label* slow_case,
|
Label& done, Label* slow_case,
|
||||||
BiasedLockingCounters* counters) {
|
BiasedLockingCounters* counters) {
|
||||||
assert(UseBiasedLocking, "why call this otherwise?");
|
assert(UseBiasedLocking, "why call this otherwise?");
|
||||||
@ -2691,8 +2692,7 @@ void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, R
|
|||||||
markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place,
|
markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place,
|
||||||
mark_reg);
|
mark_reg);
|
||||||
or3(G2_thread, mark_reg, temp_reg);
|
or3(G2_thread, mark_reg, temp_reg);
|
||||||
casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
|
casn(mark_addr.base(), mark_reg, temp_reg);
|
||||||
(address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
|
|
||||||
// If the biasing toward our thread failed, this means that
|
// If the biasing toward our thread failed, this means that
|
||||||
// another thread succeeded in biasing it toward itself and we
|
// another thread succeeded in biasing it toward itself and we
|
||||||
// need to revoke that bias. The revocation will occur in the
|
// need to revoke that bias. The revocation will occur in the
|
||||||
@ -2721,8 +2721,7 @@ void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, R
|
|||||||
load_klass(obj_reg, temp_reg);
|
load_klass(obj_reg, temp_reg);
|
||||||
ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg);
|
ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg);
|
||||||
or3(G2_thread, temp_reg, temp_reg);
|
or3(G2_thread, temp_reg, temp_reg);
|
||||||
casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
|
casn(mark_addr.base(), mark_reg, temp_reg);
|
||||||
(address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
|
|
||||||
// If the biasing toward our thread failed, this means that
|
// If the biasing toward our thread failed, this means that
|
||||||
// another thread succeeded in biasing it toward itself and we
|
// another thread succeeded in biasing it toward itself and we
|
||||||
// need to revoke that bias. The revocation will occur in the
|
// need to revoke that bias. The revocation will occur in the
|
||||||
@ -2752,8 +2751,7 @@ void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, R
|
|||||||
// bits in this situation. Should attempt to preserve them.
|
// bits in this situation. Should attempt to preserve them.
|
||||||
load_klass(obj_reg, temp_reg);
|
load_klass(obj_reg, temp_reg);
|
||||||
ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg);
|
ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg);
|
||||||
casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
|
casn(mark_addr.base(), mark_reg, temp_reg);
|
||||||
(address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
|
|
||||||
// Fall through to the normal CAS-based lock, because no matter what
|
// Fall through to the normal CAS-based lock, because no matter what
|
||||||
// the result of the above CAS, some thread must have succeeded in
|
// the result of the above CAS, some thread must have succeeded in
|
||||||
// removing the bias bit from the object's header.
|
// removing the bias bit from the object's header.
|
||||||
@ -2815,8 +2813,10 @@ void MacroAssembler::casn (Register addr_reg, Register cmp_reg, Register set_reg
|
|||||||
// effect).
|
// effect).
|
||||||
|
|
||||||
|
|
||||||
void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch,
|
void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark,
|
||||||
BiasedLockingCounters* counters) {
|
Register Rbox, Register Rscratch,
|
||||||
|
BiasedLockingCounters* counters,
|
||||||
|
bool try_bias) {
|
||||||
Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes());
|
Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes());
|
||||||
|
|
||||||
verify_oop(Roop);
|
verify_oop(Roop);
|
||||||
@ -2838,7 +2838,7 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Registe
|
|||||||
// Fetch object's markword
|
// Fetch object's markword
|
||||||
ld_ptr(mark_addr, Rmark);
|
ld_ptr(mark_addr, Rmark);
|
||||||
|
|
||||||
if (UseBiasedLocking) {
|
if (try_bias) {
|
||||||
biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
|
biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2881,7 +2881,7 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Registe
|
|||||||
|
|
||||||
ld_ptr (mark_addr, Rmark); // fetch obj->mark
|
ld_ptr (mark_addr, Rmark); // fetch obj->mark
|
||||||
// Triage: biased, stack-locked, neutral, inflated
|
// Triage: biased, stack-locked, neutral, inflated
|
||||||
if (UseBiasedLocking) {
|
if (try_bias) {
|
||||||
biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
|
biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
|
||||||
// Invariant: if control reaches this point in the emitted stream
|
// Invariant: if control reaches this point in the emitted stream
|
||||||
// then Rmark has not been modified.
|
// then Rmark has not been modified.
|
||||||
@ -2945,7 +2945,7 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Registe
|
|||||||
ld_ptr (mark_addr, Rmark); // fetch obj->mark
|
ld_ptr (mark_addr, Rmark); // fetch obj->mark
|
||||||
// Triage: biased, stack-locked, neutral, inflated
|
// Triage: biased, stack-locked, neutral, inflated
|
||||||
|
|
||||||
if (UseBiasedLocking) {
|
if (try_bias) {
|
||||||
biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
|
biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
|
||||||
// Invariant: if control reaches this point in the emitted stream
|
// Invariant: if control reaches this point in the emitted stream
|
||||||
// then Rmark has not been modified.
|
// then Rmark has not been modified.
|
||||||
@ -3039,7 +3039,9 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Registe
|
|||||||
bind (done) ;
|
bind (done) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch) {
|
void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark,
|
||||||
|
Register Rbox, Register Rscratch,
|
||||||
|
bool try_bias) {
|
||||||
Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes());
|
Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes());
|
||||||
|
|
||||||
Label done ;
|
Label done ;
|
||||||
@ -3050,7 +3052,7 @@ void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark, Regis
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (EmitSync & 8) {
|
if (EmitSync & 8) {
|
||||||
if (UseBiasedLocking) {
|
if (try_bias) {
|
||||||
biased_locking_exit(mark_addr, Rscratch, done);
|
biased_locking_exit(mark_addr, Rscratch, done);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3077,7 +3079,7 @@ void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark, Regis
|
|||||||
// I$ effects.
|
// I$ effects.
|
||||||
Label LStacked ;
|
Label LStacked ;
|
||||||
|
|
||||||
if (UseBiasedLocking) {
|
if (try_bias) {
|
||||||
// TODO: eliminate redundant LDs of obj->mark
|
// TODO: eliminate redundant LDs of obj->mark
|
||||||
biased_locking_exit(mark_addr, Rscratch, done);
|
biased_locking_exit(mark_addr, Rscratch, done);
|
||||||
}
|
}
|
||||||
|
@ -2220,9 +2220,13 @@ class MacroAssembler: public Assembler {
|
|||||||
|
|
||||||
// These set the icc condition code to equal if the lock succeeded
|
// These set the icc condition code to equal if the lock succeeded
|
||||||
// and notEqual if it failed and requires a slow case
|
// and notEqual if it failed and requires a slow case
|
||||||
void compiler_lock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch,
|
void compiler_lock_object(Register Roop, Register Rmark, Register Rbox,
|
||||||
BiasedLockingCounters* counters = NULL);
|
Register Rscratch,
|
||||||
void compiler_unlock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch);
|
BiasedLockingCounters* counters = NULL,
|
||||||
|
bool try_bias = UseBiasedLocking);
|
||||||
|
void compiler_unlock_object(Register Roop, Register Rmark, Register Rbox,
|
||||||
|
Register Rscratch,
|
||||||
|
bool try_bias = UseBiasedLocking);
|
||||||
|
|
||||||
// Biased locking support
|
// Biased locking support
|
||||||
// Upon entry, lock_reg must point to the lock record on the stack,
|
// Upon entry, lock_reg must point to the lock record on the stack,
|
||||||
|
@ -906,7 +906,7 @@ void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass,
|
|||||||
|
|
||||||
// load next super to check
|
// load next super to check
|
||||||
if (UseCompressedOops) {
|
if (UseCompressedOops) {
|
||||||
ld( Rtmp2, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Rtmp3);
|
lduw( Rtmp2, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Rtmp3);
|
||||||
// Bump array pointer forward one oop
|
// Bump array pointer forward one oop
|
||||||
add( Rtmp2, 4, Rtmp2 );
|
add( Rtmp2, 4, Rtmp2 );
|
||||||
} else {
|
} else {
|
||||||
|
@ -395,6 +395,7 @@ reg_class long_reg( R_G1H,R_G1, R_G3H,R_G3, R_G4H,R_G4,
|
|||||||
);
|
);
|
||||||
|
|
||||||
reg_class g1_regL(R_G1H,R_G1);
|
reg_class g1_regL(R_G1H,R_G1);
|
||||||
|
reg_class g3_regL(R_G3H,R_G3);
|
||||||
reg_class o2_regL(R_O2H,R_O2);
|
reg_class o2_regL(R_O2H,R_O2);
|
||||||
reg_class o7_regL(R_O7H,R_O7);
|
reg_class o7_regL(R_O7H,R_O7);
|
||||||
|
|
||||||
@ -1743,7 +1744,7 @@ const bool Matcher::convL2FSupported(void) {
|
|||||||
//
|
//
|
||||||
// NOTE: If the platform does not provide any short branch variants, then
|
// NOTE: If the platform does not provide any short branch variants, then
|
||||||
// this method should return false for offset 0.
|
// this method should return false for offset 0.
|
||||||
bool Matcher::is_short_branch_offset(int offset) {
|
bool Matcher::is_short_branch_offset(int rule, int offset) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1926,18 +1927,23 @@ encode %{
|
|||||||
$mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
|
$mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
enc_class simple_form3_mem_reg( memory mem, iRegI dst ) %{
|
||||||
|
emit_form3_mem_reg(cbuf, this, $primary, -1,
|
||||||
|
$mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
|
||||||
|
%}
|
||||||
|
|
||||||
enc_class form3_mem_reg_little( memory mem, iRegI dst) %{
|
enc_class form3_mem_reg_little( memory mem, iRegI dst) %{
|
||||||
emit_form3_mem_reg_asi(cbuf, this, $primary, $tertiary,
|
emit_form3_mem_reg_asi(cbuf, this, $primary, -1,
|
||||||
$mem$$base, $mem$$disp, $mem$$index, $dst$$reg, Assembler::ASI_PRIMARY_LITTLE);
|
$mem$$base, $mem$$disp, $mem$$index, $dst$$reg, Assembler::ASI_PRIMARY_LITTLE);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class form3_mem_prefetch_read( memory mem ) %{
|
enc_class form3_mem_prefetch_read( memory mem ) %{
|
||||||
emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
|
emit_form3_mem_reg(cbuf, this, $primary, -1,
|
||||||
$mem$$base, $mem$$disp, $mem$$index, 0/*prefetch function many-reads*/);
|
$mem$$base, $mem$$disp, $mem$$index, 0/*prefetch function many-reads*/);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class form3_mem_prefetch_write( memory mem ) %{
|
enc_class form3_mem_prefetch_write( memory mem ) %{
|
||||||
emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
|
emit_form3_mem_reg(cbuf, this, $primary, -1,
|
||||||
$mem$$base, $mem$$disp, $mem$$index, 2/*prefetch function many-writes*/);
|
$mem$$base, $mem$$disp, $mem$$index, 2/*prefetch function many-writes*/);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -1945,8 +1951,8 @@ encode %{
|
|||||||
assert( Assembler::is_simm13($mem$$disp ), "need disp and disp+4" );
|
assert( Assembler::is_simm13($mem$$disp ), "need disp and disp+4" );
|
||||||
assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
|
assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
|
||||||
guarantee($mem$$index == R_G0_enc, "double index?");
|
guarantee($mem$$index == R_G0_enc, "double index?");
|
||||||
emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc );
|
emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc );
|
||||||
emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg );
|
emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg );
|
||||||
emit3_simm13( cbuf, Assembler::arith_op, $reg$$reg, Assembler::sllx_op3, $reg$$reg, 0x1020 );
|
emit3_simm13( cbuf, Assembler::arith_op, $reg$$reg, Assembler::sllx_op3, $reg$$reg, 0x1020 );
|
||||||
emit3( cbuf, Assembler::arith_op, $reg$$reg, Assembler::or_op3, $reg$$reg, 0, R_O7_enc );
|
emit3( cbuf, Assembler::arith_op, $reg$$reg, Assembler::or_op3, $reg$$reg, 0, R_O7_enc );
|
||||||
%}
|
%}
|
||||||
@ -1956,14 +1962,14 @@ encode %{
|
|||||||
assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
|
assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
|
||||||
guarantee($mem$$index == R_G0_enc, "double index?");
|
guarantee($mem$$index == R_G0_enc, "double index?");
|
||||||
// Load long with 2 instructions
|
// Load long with 2 instructions
|
||||||
emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg+0 );
|
emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg+0 );
|
||||||
emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 );
|
emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
//%%% form3_mem_plus_4_reg is a hack--get rid of it
|
//%%% form3_mem_plus_4_reg is a hack--get rid of it
|
||||||
enc_class form3_mem_plus_4_reg( memory mem, iRegI dst ) %{
|
enc_class form3_mem_plus_4_reg( memory mem, iRegI dst ) %{
|
||||||
guarantee($mem$$disp, "cannot offset a reg-reg operand by 4");
|
guarantee($mem$$disp, "cannot offset a reg-reg operand by 4");
|
||||||
emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg);
|
emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class form3_g0_rs2_rd_move( iRegI rs2, iRegI rd ) %{
|
enc_class form3_g0_rs2_rd_move( iRegI rs2, iRegI rd ) %{
|
||||||
@ -2683,7 +2689,7 @@ enc_class Fast_Lock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{
|
|||||||
assert(Rbox != Rscratch, "");
|
assert(Rbox != Rscratch, "");
|
||||||
assert(Rbox != Rmark, "");
|
assert(Rbox != Rmark, "");
|
||||||
|
|
||||||
__ compiler_lock_object(Roop, Rmark, Rbox, Rscratch, _counters);
|
__ compiler_lock_object(Roop, Rmark, Rbox, Rscratch, _counters, UseBiasedLocking && !UseOptoBiasInlining);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{
|
enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{
|
||||||
@ -2699,7 +2705,7 @@ enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{
|
|||||||
assert(Rbox != Rscratch, "");
|
assert(Rbox != Rscratch, "");
|
||||||
assert(Rbox != Rmark, "");
|
assert(Rbox != Rmark, "");
|
||||||
|
|
||||||
__ compiler_unlock_object(Roop, Rmark, Rbox, Rscratch);
|
__ compiler_unlock_object(Roop, Rmark, Rbox, Rscratch, UseBiasedLocking && !UseOptoBiasInlining);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class enc_cas( iRegP mem, iRegP old, iRegP new ) %{
|
enc_class enc_cas( iRegP mem, iRegP old, iRegP new ) %{
|
||||||
@ -2711,8 +2717,7 @@ enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{
|
|||||||
// casx_under_lock picks 1 of 3 encodings:
|
// casx_under_lock picks 1 of 3 encodings:
|
||||||
// For 32-bit pointers you get a 32-bit CAS
|
// For 32-bit pointers you get a 32-bit CAS
|
||||||
// For 64-bit pointers you get a 64-bit CASX
|
// For 64-bit pointers you get a 64-bit CASX
|
||||||
__ casx_under_lock(Rmem, Rold, Rnew, // Swap(*Rmem,Rnew) if *Rmem == Rold
|
__ casn(Rmem, Rold, Rnew); // Swap(*Rmem,Rnew) if *Rmem == Rold
|
||||||
(address) StubRoutines::Sparc::atomic_memory_operation_lock_addr());
|
|
||||||
__ cmp( Rold, Rnew );
|
__ cmp( Rold, Rnew );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -3761,6 +3766,14 @@ operand g1RegL() %{
|
|||||||
interface(REG_INTER);
|
interface(REG_INTER);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
operand g3RegL() %{
|
||||||
|
constraint(ALLOC_IN_RC(g3_regL));
|
||||||
|
match(iRegL);
|
||||||
|
|
||||||
|
format %{ %}
|
||||||
|
interface(REG_INTER);
|
||||||
|
%}
|
||||||
|
|
||||||
// Int Register safe
|
// Int Register safe
|
||||||
// This is 64bit safe
|
// This is 64bit safe
|
||||||
operand iRegIsafe() %{
|
operand iRegIsafe() %{
|
||||||
@ -5062,7 +5075,7 @@ instruct stkI_to_regF(regF dst, stackSlotI src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDF $src,$dst\t! stkI to regF" %}
|
format %{ "LDF $src,$dst\t! stkI to regF" %}
|
||||||
opcode(Assembler::ldf_op3);
|
opcode(Assembler::ldf_op3);
|
||||||
ins_encode(form3_mem_reg(src, dst));
|
ins_encode(simple_form3_mem_reg(src, dst));
|
||||||
ins_pipe(floadF_stk);
|
ins_pipe(floadF_stk);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5073,7 +5086,7 @@ instruct stkL_to_regD(regD dst, stackSlotL src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDDF $src,$dst\t! stkL to regD" %}
|
format %{ "LDDF $src,$dst\t! stkL to regD" %}
|
||||||
opcode(Assembler::lddf_op3);
|
opcode(Assembler::lddf_op3);
|
||||||
ins_encode(form3_mem_reg(src, dst));
|
ins_encode(simple_form3_mem_reg(src, dst));
|
||||||
ins_pipe(floadD_stk);
|
ins_pipe(floadD_stk);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5084,7 +5097,7 @@ instruct regF_to_stkI(stackSlotI dst, regF src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STF $src,$dst\t! regF to stkI" %}
|
format %{ "STF $src,$dst\t! regF to stkI" %}
|
||||||
opcode(Assembler::stf_op3);
|
opcode(Assembler::stf_op3);
|
||||||
ins_encode(form3_mem_reg(dst, src));
|
ins_encode(simple_form3_mem_reg(dst, src));
|
||||||
ins_pipe(fstoreF_stk_reg);
|
ins_pipe(fstoreF_stk_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5095,7 +5108,7 @@ instruct regD_to_stkL(stackSlotL dst, regD src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STDF $src,$dst\t! regD to stkL" %}
|
format %{ "STDF $src,$dst\t! regD to stkL" %}
|
||||||
opcode(Assembler::stdf_op3);
|
opcode(Assembler::stdf_op3);
|
||||||
ins_encode(form3_mem_reg(dst, src));
|
ins_encode(simple_form3_mem_reg(dst, src));
|
||||||
ins_pipe(fstoreD_stk_reg);
|
ins_pipe(fstoreD_stk_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5106,7 +5119,7 @@ instruct regI_to_stkLHi(stackSlotL dst, iRegI src) %{
|
|||||||
format %{ "STW $src,$dst.hi\t! long\n\t"
|
format %{ "STW $src,$dst.hi\t! long\n\t"
|
||||||
"STW R_G0,$dst.lo" %}
|
"STW R_G0,$dst.lo" %}
|
||||||
opcode(Assembler::stw_op3);
|
opcode(Assembler::stw_op3);
|
||||||
ins_encode(form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0));
|
ins_encode(simple_form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0));
|
||||||
ins_pipe(lstoreI_stk_reg);
|
ins_pipe(lstoreI_stk_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5117,7 +5130,7 @@ instruct regL_to_stkD(stackSlotD dst, iRegL src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STX $src,$dst\t! regL to stkD" %}
|
format %{ "STX $src,$dst\t! regL to stkD" %}
|
||||||
opcode(Assembler::stx_op3);
|
opcode(Assembler::stx_op3);
|
||||||
ins_encode( form3_mem_reg( dst, src ) );
|
ins_encode(simple_form3_mem_reg( dst, src ) );
|
||||||
ins_pipe(istore_stk_reg);
|
ins_pipe(istore_stk_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5131,7 +5144,7 @@ instruct stkI_to_regI( iRegI dst, stackSlotI src ) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDUW $src,$dst\t!stk" %}
|
format %{ "LDUW $src,$dst\t!stk" %}
|
||||||
opcode(Assembler::lduw_op3);
|
opcode(Assembler::lduw_op3);
|
||||||
ins_encode( form3_mem_reg( src, dst ) );
|
ins_encode(simple_form3_mem_reg( src, dst ) );
|
||||||
ins_pipe(iload_mem);
|
ins_pipe(iload_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5143,7 +5156,7 @@ instruct regI_to_stkI( stackSlotI dst, iRegI src ) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STW $src,$dst\t!stk" %}
|
format %{ "STW $src,$dst\t!stk" %}
|
||||||
opcode(Assembler::stw_op3);
|
opcode(Assembler::stw_op3);
|
||||||
ins_encode( form3_mem_reg( dst, src ) );
|
ins_encode(simple_form3_mem_reg( dst, src ) );
|
||||||
ins_pipe(istore_mem_reg);
|
ins_pipe(istore_mem_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5155,7 +5168,7 @@ instruct stkL_to_regL( iRegL dst, stackSlotL src ) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDX $src,$dst\t! long" %}
|
format %{ "LDX $src,$dst\t! long" %}
|
||||||
opcode(Assembler::ldx_op3);
|
opcode(Assembler::ldx_op3);
|
||||||
ins_encode( form3_mem_reg( src, dst ) );
|
ins_encode(simple_form3_mem_reg( src, dst ) );
|
||||||
ins_pipe(iload_mem);
|
ins_pipe(iload_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5167,7 +5180,7 @@ instruct regL_to_stkL(stackSlotL dst, iRegL src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STX $src,$dst\t! long" %}
|
format %{ "STX $src,$dst\t! long" %}
|
||||||
opcode(Assembler::stx_op3);
|
opcode(Assembler::stx_op3);
|
||||||
ins_encode( form3_mem_reg( dst, src ) );
|
ins_encode(simple_form3_mem_reg( dst, src ) );
|
||||||
ins_pipe(istore_mem_reg);
|
ins_pipe(istore_mem_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5179,7 +5192,7 @@ instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDX $src,$dst\t!ptr" %}
|
format %{ "LDX $src,$dst\t!ptr" %}
|
||||||
opcode(Assembler::ldx_op3);
|
opcode(Assembler::ldx_op3);
|
||||||
ins_encode( form3_mem_reg( src, dst ) );
|
ins_encode(simple_form3_mem_reg( src, dst ) );
|
||||||
ins_pipe(iload_mem);
|
ins_pipe(iload_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5190,7 +5203,7 @@ instruct regP_to_stkP(stackSlotP dst, iRegP src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STX $src,$dst\t!ptr" %}
|
format %{ "STX $src,$dst\t!ptr" %}
|
||||||
opcode(Assembler::stx_op3);
|
opcode(Assembler::stx_op3);
|
||||||
ins_encode( form3_mem_reg( dst, src ) );
|
ins_encode(simple_form3_mem_reg( dst, src ) );
|
||||||
ins_pipe(istore_mem_reg);
|
ins_pipe(istore_mem_reg);
|
||||||
%}
|
%}
|
||||||
#else // _LP64
|
#else // _LP64
|
||||||
@ -5200,7 +5213,7 @@ instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{
|
|||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
format %{ "LDUW $src,$dst\t!ptr" %}
|
format %{ "LDUW $src,$dst\t!ptr" %}
|
||||||
opcode(Assembler::lduw_op3, Assembler::ldst_op);
|
opcode(Assembler::lduw_op3, Assembler::ldst_op);
|
||||||
ins_encode( form3_mem_reg( src, dst ) );
|
ins_encode(simple_form3_mem_reg( src, dst ) );
|
||||||
ins_pipe(iload_mem);
|
ins_pipe(iload_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5210,7 +5223,7 @@ instruct regP_to_stkP(stackSlotP dst, iRegP src) %{
|
|||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
format %{ "STW $src,$dst\t!ptr" %}
|
format %{ "STW $src,$dst\t!ptr" %}
|
||||||
opcode(Assembler::stw_op3, Assembler::ldst_op);
|
opcode(Assembler::stw_op3, Assembler::ldst_op);
|
||||||
ins_encode( form3_mem_reg( dst, src ) );
|
ins_encode(simple_form3_mem_reg( dst, src ) );
|
||||||
ins_pipe(istore_mem_reg);
|
ins_pipe(istore_mem_reg);
|
||||||
%}
|
%}
|
||||||
#endif // _LP64
|
#endif // _LP64
|
||||||
@ -5273,7 +5286,7 @@ instruct loadB(iRegI dst, memory mem) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDSB $mem,$dst" %}
|
format %{ "LDSB $mem,$dst" %}
|
||||||
opcode(Assembler::ldsb_op3);
|
opcode(Assembler::ldsb_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mask_mem);
|
ins_pipe(iload_mask_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5285,7 +5298,7 @@ instruct loadUB(iRegI dst, memory mem, immI_255 bytemask) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDUB $mem,$dst" %}
|
format %{ "LDUB $mem,$dst" %}
|
||||||
opcode(Assembler::ldub_op3);
|
opcode(Assembler::ldub_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mask_mem);
|
ins_pipe(iload_mask_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5297,7 +5310,7 @@ instruct loadUBL(iRegL dst, memory mem, immL_FF bytemask) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDUB $mem,$dst" %}
|
format %{ "LDUB $mem,$dst" %}
|
||||||
opcode(Assembler::ldub_op3);
|
opcode(Assembler::ldub_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mask_mem);
|
ins_pipe(iload_mask_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5309,7 +5322,7 @@ instruct loadUCL(iRegL dst, memory mem, immL_FFFF bytemask) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDUH $mem,$dst" %}
|
format %{ "LDUH $mem,$dst" %}
|
||||||
opcode(Assembler::lduh_op3);
|
opcode(Assembler::lduh_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mask_mem);
|
ins_pipe(iload_mask_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5321,7 +5334,7 @@ instruct loadC(iRegI dst, memory mem) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDUH $mem,$dst" %}
|
format %{ "LDUH $mem,$dst" %}
|
||||||
opcode(Assembler::lduh_op3);
|
opcode(Assembler::lduh_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mask_mem);
|
ins_pipe(iload_mask_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5333,7 +5346,7 @@ instruct loadI(iRegI dst, memory mem) %{
|
|||||||
|
|
||||||
format %{ "LDUW $mem,$dst" %}
|
format %{ "LDUW $mem,$dst" %}
|
||||||
opcode(Assembler::lduw_op3);
|
opcode(Assembler::lduw_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mem);
|
ins_pipe(iload_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5344,7 +5357,7 @@ instruct loadL(iRegL dst, memory mem ) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDX $mem,$dst\t! long" %}
|
format %{ "LDX $mem,$dst\t! long" %}
|
||||||
opcode(Assembler::ldx_op3);
|
opcode(Assembler::ldx_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mem);
|
ins_pipe(iload_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5359,7 +5372,7 @@ instruct loadL_unaligned(iRegL dst, memory mem, o7RegI tmp) %{
|
|||||||
"\tSLLX #32, $dst, $dst\n"
|
"\tSLLX #32, $dst, $dst\n"
|
||||||
"\tOR $dst, R_O7, $dst" %}
|
"\tOR $dst, R_O7, $dst" %}
|
||||||
opcode(Assembler::lduw_op3);
|
opcode(Assembler::lduw_op3);
|
||||||
ins_encode( form3_mem_reg_long_unaligned_marshal( mem, dst ));
|
ins_encode(form3_mem_reg_long_unaligned_marshal( mem, dst ));
|
||||||
ins_pipe(iload_mem);
|
ins_pipe(iload_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5370,7 +5383,7 @@ instruct loadA8B(regD dst, memory mem) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDDF $mem,$dst\t! packed8B" %}
|
format %{ "LDDF $mem,$dst\t! packed8B" %}
|
||||||
opcode(Assembler::lddf_op3);
|
opcode(Assembler::lddf_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(floadD_mem);
|
ins_pipe(floadD_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5381,7 +5394,7 @@ instruct loadA4C(regD dst, memory mem) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDDF $mem,$dst\t! packed4C" %}
|
format %{ "LDDF $mem,$dst\t! packed4C" %}
|
||||||
opcode(Assembler::lddf_op3);
|
opcode(Assembler::lddf_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(floadD_mem);
|
ins_pipe(floadD_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5392,7 +5405,7 @@ instruct loadA4S(regD dst, memory mem) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDDF $mem,$dst\t! packed4S" %}
|
format %{ "LDDF $mem,$dst\t! packed4S" %}
|
||||||
opcode(Assembler::lddf_op3);
|
opcode(Assembler::lddf_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(floadD_mem);
|
ins_pipe(floadD_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5403,7 +5416,7 @@ instruct loadA2I(regD dst, memory mem) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDDF $mem,$dst\t! packed2I" %}
|
format %{ "LDDF $mem,$dst\t! packed2I" %}
|
||||||
opcode(Assembler::lddf_op3);
|
opcode(Assembler::lddf_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(floadD_mem);
|
ins_pipe(floadD_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5415,7 +5428,7 @@ instruct loadRange(iRegI dst, memory mem) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDUW $mem,$dst\t! range" %}
|
format %{ "LDUW $mem,$dst\t! range" %}
|
||||||
opcode(Assembler::lduw_op3);
|
opcode(Assembler::lduw_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mem);
|
ins_pipe(iload_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5427,7 +5440,7 @@ instruct loadI_freg(regF dst, memory mem) %{
|
|||||||
|
|
||||||
format %{ "LDF $mem,$dst\t! for fitos/fitod" %}
|
format %{ "LDF $mem,$dst\t! for fitos/fitod" %}
|
||||||
opcode(Assembler::ldf_op3);
|
opcode(Assembler::ldf_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(floadF_mem);
|
ins_pipe(floadF_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5514,7 +5527,7 @@ instruct loadS(iRegI dst, memory mem) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDSH $mem,$dst" %}
|
format %{ "LDSH $mem,$dst" %}
|
||||||
opcode(Assembler::ldsh_op3);
|
opcode(Assembler::ldsh_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mask_mem);
|
ins_pipe(iload_mask_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5526,7 +5539,7 @@ instruct loadD(regD dst, memory mem) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDDF $mem,$dst" %}
|
format %{ "LDDF $mem,$dst" %}
|
||||||
opcode(Assembler::lddf_op3);
|
opcode(Assembler::lddf_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(floadD_mem);
|
ins_pipe(floadD_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5550,7 +5563,7 @@ instruct loadF(regF dst, memory mem) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDF $mem,$dst" %}
|
format %{ "LDF $mem,$dst" %}
|
||||||
opcode(Assembler::ldf_op3);
|
opcode(Assembler::ldf_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(floadF_mem);
|
ins_pipe(floadF_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5719,7 +5732,7 @@ instruct storeB(memory mem, iRegI src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STB $src,$mem\t! byte" %}
|
format %{ "STB $src,$mem\t! byte" %}
|
||||||
opcode(Assembler::stb_op3);
|
opcode(Assembler::stb_op3);
|
||||||
ins_encode( form3_mem_reg( mem, src ) );
|
ins_encode(simple_form3_mem_reg( mem, src ) );
|
||||||
ins_pipe(istore_mem_reg);
|
ins_pipe(istore_mem_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5730,7 +5743,7 @@ instruct storeB0(memory mem, immI0 src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STB $src,$mem\t! byte" %}
|
format %{ "STB $src,$mem\t! byte" %}
|
||||||
opcode(Assembler::stb_op3);
|
opcode(Assembler::stb_op3);
|
||||||
ins_encode( form3_mem_reg( mem, R_G0 ) );
|
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
|
||||||
ins_pipe(istore_mem_zero);
|
ins_pipe(istore_mem_zero);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5741,7 +5754,7 @@ instruct storeCM0(memory mem, immI0 src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STB $src,$mem\t! CMS card-mark byte 0" %}
|
format %{ "STB $src,$mem\t! CMS card-mark byte 0" %}
|
||||||
opcode(Assembler::stb_op3);
|
opcode(Assembler::stb_op3);
|
||||||
ins_encode( form3_mem_reg( mem, R_G0 ) );
|
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
|
||||||
ins_pipe(istore_mem_zero);
|
ins_pipe(istore_mem_zero);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5753,7 +5766,7 @@ instruct storeC(memory mem, iRegI src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STH $src,$mem\t! short" %}
|
format %{ "STH $src,$mem\t! short" %}
|
||||||
opcode(Assembler::sth_op3);
|
opcode(Assembler::sth_op3);
|
||||||
ins_encode( form3_mem_reg( mem, src ) );
|
ins_encode(simple_form3_mem_reg( mem, src ) );
|
||||||
ins_pipe(istore_mem_reg);
|
ins_pipe(istore_mem_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5764,7 +5777,7 @@ instruct storeC0(memory mem, immI0 src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STH $src,$mem\t! short" %}
|
format %{ "STH $src,$mem\t! short" %}
|
||||||
opcode(Assembler::sth_op3);
|
opcode(Assembler::sth_op3);
|
||||||
ins_encode( form3_mem_reg( mem, R_G0 ) );
|
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
|
||||||
ins_pipe(istore_mem_zero);
|
ins_pipe(istore_mem_zero);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5776,7 +5789,7 @@ instruct storeI(memory mem, iRegI src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STW $src,$mem" %}
|
format %{ "STW $src,$mem" %}
|
||||||
opcode(Assembler::stw_op3);
|
opcode(Assembler::stw_op3);
|
||||||
ins_encode( form3_mem_reg( mem, src ) );
|
ins_encode(simple_form3_mem_reg( mem, src ) );
|
||||||
ins_pipe(istore_mem_reg);
|
ins_pipe(istore_mem_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5787,7 +5800,7 @@ instruct storeL(memory mem, iRegL src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STX $src,$mem\t! long" %}
|
format %{ "STX $src,$mem\t! long" %}
|
||||||
opcode(Assembler::stx_op3);
|
opcode(Assembler::stx_op3);
|
||||||
ins_encode( form3_mem_reg( mem, src ) );
|
ins_encode(simple_form3_mem_reg( mem, src ) );
|
||||||
ins_pipe(istore_mem_reg);
|
ins_pipe(istore_mem_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5798,7 +5811,7 @@ instruct storeI0(memory mem, immI0 src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STW $src,$mem" %}
|
format %{ "STW $src,$mem" %}
|
||||||
opcode(Assembler::stw_op3);
|
opcode(Assembler::stw_op3);
|
||||||
ins_encode( form3_mem_reg( mem, R_G0 ) );
|
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
|
||||||
ins_pipe(istore_mem_zero);
|
ins_pipe(istore_mem_zero);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5809,7 +5822,7 @@ instruct storeL0(memory mem, immL0 src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STX $src,$mem" %}
|
format %{ "STX $src,$mem" %}
|
||||||
opcode(Assembler::stx_op3);
|
opcode(Assembler::stx_op3);
|
||||||
ins_encode( form3_mem_reg( mem, R_G0 ) );
|
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
|
||||||
ins_pipe(istore_mem_zero);
|
ins_pipe(istore_mem_zero);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5821,7 +5834,7 @@ instruct storeI_Freg(memory mem, regF src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STF $src,$mem\t! after fstoi/fdtoi" %}
|
format %{ "STF $src,$mem\t! after fstoi/fdtoi" %}
|
||||||
opcode(Assembler::stf_op3);
|
opcode(Assembler::stf_op3);
|
||||||
ins_encode( form3_mem_reg( mem, src ) );
|
ins_encode(simple_form3_mem_reg( mem, src ) );
|
||||||
ins_pipe(fstoreF_mem_reg);
|
ins_pipe(fstoreF_mem_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5904,7 +5917,7 @@ instruct storeD( memory mem, regD src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STDF $src,$mem" %}
|
format %{ "STDF $src,$mem" %}
|
||||||
opcode(Assembler::stdf_op3);
|
opcode(Assembler::stdf_op3);
|
||||||
ins_encode( form3_mem_reg( mem, src ) );
|
ins_encode(simple_form3_mem_reg( mem, src ) );
|
||||||
ins_pipe(fstoreD_mem_reg);
|
ins_pipe(fstoreD_mem_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5915,7 +5928,7 @@ instruct storeD0( memory mem, immD0 src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STX $src,$mem" %}
|
format %{ "STX $src,$mem" %}
|
||||||
opcode(Assembler::stx_op3);
|
opcode(Assembler::stx_op3);
|
||||||
ins_encode( form3_mem_reg( mem, R_G0 ) );
|
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
|
||||||
ins_pipe(fstoreD_mem_zero);
|
ins_pipe(fstoreD_mem_zero);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5927,7 +5940,7 @@ instruct storeF( memory mem, regF src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STF $src,$mem" %}
|
format %{ "STF $src,$mem" %}
|
||||||
opcode(Assembler::stf_op3);
|
opcode(Assembler::stf_op3);
|
||||||
ins_encode( form3_mem_reg( mem, src ) );
|
ins_encode(simple_form3_mem_reg( mem, src ) );
|
||||||
ins_pipe(fstoreF_mem_reg);
|
ins_pipe(fstoreF_mem_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5938,7 +5951,7 @@ instruct storeF0( memory mem, immF0 src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STW $src,$mem\t! storeF0" %}
|
format %{ "STW $src,$mem\t! storeF0" %}
|
||||||
opcode(Assembler::stw_op3);
|
opcode(Assembler::stw_op3);
|
||||||
ins_encode( form3_mem_reg( mem, R_G0 ) );
|
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
|
||||||
ins_pipe(fstoreF_mem_zero);
|
ins_pipe(fstoreF_mem_zero);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5949,7 +5962,7 @@ instruct storeA8B(memory mem, regD src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STDF $src,$mem\t! packed8B" %}
|
format %{ "STDF $src,$mem\t! packed8B" %}
|
||||||
opcode(Assembler::stdf_op3);
|
opcode(Assembler::stdf_op3);
|
||||||
ins_encode( form3_mem_reg( mem, src ) );
|
ins_encode(simple_form3_mem_reg( mem, src ) );
|
||||||
ins_pipe(fstoreD_mem_reg);
|
ins_pipe(fstoreD_mem_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -6004,7 +6017,7 @@ instruct storeA8B0(memory mem, immI0 zero) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STX $zero,$mem\t! packed8B" %}
|
format %{ "STX $zero,$mem\t! packed8B" %}
|
||||||
opcode(Assembler::stx_op3);
|
opcode(Assembler::stx_op3);
|
||||||
ins_encode( form3_mem_reg( mem, R_G0 ) );
|
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
|
||||||
ins_pipe(fstoreD_mem_zero);
|
ins_pipe(fstoreD_mem_zero);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -6015,7 +6028,7 @@ instruct storeA4C(memory mem, regD src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STDF $src,$mem\t! packed4C" %}
|
format %{ "STDF $src,$mem\t! packed4C" %}
|
||||||
opcode(Assembler::stdf_op3);
|
opcode(Assembler::stdf_op3);
|
||||||
ins_encode( form3_mem_reg( mem, src ) );
|
ins_encode(simple_form3_mem_reg( mem, src ) );
|
||||||
ins_pipe(fstoreD_mem_reg);
|
ins_pipe(fstoreD_mem_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -6026,7 +6039,7 @@ instruct storeA4C0(memory mem, immI0 zero) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STX $zero,$mem\t! packed4C" %}
|
format %{ "STX $zero,$mem\t! packed4C" %}
|
||||||
opcode(Assembler::stx_op3);
|
opcode(Assembler::stx_op3);
|
||||||
ins_encode( form3_mem_reg( mem, R_G0 ) );
|
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
|
||||||
ins_pipe(fstoreD_mem_zero);
|
ins_pipe(fstoreD_mem_zero);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -6037,7 +6050,7 @@ instruct storeA2I(memory mem, regD src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STDF $src,$mem\t! packed2I" %}
|
format %{ "STDF $src,$mem\t! packed2I" %}
|
||||||
opcode(Assembler::stdf_op3);
|
opcode(Assembler::stdf_op3);
|
||||||
ins_encode( form3_mem_reg( mem, src ) );
|
ins_encode(simple_form3_mem_reg( mem, src ) );
|
||||||
ins_pipe(fstoreD_mem_reg);
|
ins_pipe(fstoreD_mem_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -6048,7 +6061,7 @@ instruct storeA2I0(memory mem, immI0 zero) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STX $zero,$mem\t! packed2I" %}
|
format %{ "STX $zero,$mem\t! packed2I" %}
|
||||||
opcode(Assembler::stx_op3);
|
opcode(Assembler::stx_op3);
|
||||||
ins_encode( form3_mem_reg( mem, R_G0 ) );
|
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
|
||||||
ins_pipe(fstoreD_mem_zero);
|
ins_pipe(fstoreD_mem_zero);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -6162,7 +6175,7 @@ instruct stfSSD(stackSlotD stkSlot, regD src) %{
|
|||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
format %{ "STDF $src,$stkSlot\t!stk" %}
|
format %{ "STDF $src,$stkSlot\t!stk" %}
|
||||||
opcode(Assembler::stdf_op3);
|
opcode(Assembler::stdf_op3);
|
||||||
ins_encode(form3_mem_reg(stkSlot, src));
|
ins_encode(simple_form3_mem_reg(stkSlot, src));
|
||||||
ins_pipe(fstoreD_stk_reg);
|
ins_pipe(fstoreD_stk_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -6172,7 +6185,7 @@ instruct ldfSSD(regD dst, stackSlotD stkSlot) %{
|
|||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
format %{ "LDDF $stkSlot,$dst\t!stk" %}
|
format %{ "LDDF $stkSlot,$dst\t!stk" %}
|
||||||
opcode(Assembler::lddf_op3);
|
opcode(Assembler::lddf_op3);
|
||||||
ins_encode(form3_mem_reg(stkSlot, dst));
|
ins_encode(simple_form3_mem_reg(stkSlot, dst));
|
||||||
ins_pipe(floadD_stk);
|
ins_pipe(floadD_stk);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -6182,7 +6195,7 @@ instruct stfSSF(stackSlotF stkSlot, regF src) %{
|
|||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
format %{ "STF $src,$stkSlot\t!stk" %}
|
format %{ "STF $src,$stkSlot\t!stk" %}
|
||||||
opcode(Assembler::stf_op3);
|
opcode(Assembler::stf_op3);
|
||||||
ins_encode(form3_mem_reg(stkSlot, src));
|
ins_encode(simple_form3_mem_reg(stkSlot, src));
|
||||||
ins_pipe(fstoreF_stk_reg);
|
ins_pipe(fstoreF_stk_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -6584,7 +6597,7 @@ instruct loadLLocked(iRegL dst, memory mem) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDX $mem,$dst\t! long" %}
|
format %{ "LDX $mem,$dst\t! long" %}
|
||||||
opcode(Assembler::ldx_op3);
|
opcode(Assembler::ldx_op3);
|
||||||
ins_encode( form3_mem_reg( mem, dst ) );
|
ins_encode(simple_form3_mem_reg( mem, dst ) );
|
||||||
ins_pipe(iload_mem);
|
ins_pipe(iload_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -6597,32 +6610,23 @@ instruct storePConditional( iRegP heap_top_ptr, iRegP oldval, g3RegP newval, fla
|
|||||||
ins_pipe( long_memory_op );
|
ins_pipe( long_memory_op );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct storeLConditional_bool(iRegP mem_ptr, iRegL oldval, iRegL newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
|
// Conditional-store of an int value.
|
||||||
match(Set res (StoreLConditional mem_ptr (Binary oldval newval)));
|
instruct storeIConditional( iRegP mem_ptr, iRegI oldval, g3RegI newval, flagsReg icc ) %{
|
||||||
effect( USE mem_ptr, KILL ccr, KILL tmp1);
|
match(Set icc (StoreIConditional mem_ptr (Binary oldval newval)));
|
||||||
// Marshal the register pairs into V9 64-bit registers, then do the compare-and-swap
|
effect( KILL newval );
|
||||||
format %{
|
format %{ "CASA [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
|
||||||
"MOV $newval,R_O7\n\t"
|
"CMP $oldval,$newval\t\t! See if we made progress" %}
|
||||||
"CASXA [$mem_ptr],$oldval,R_O7\t! If $oldval==[$mem_ptr] Then store R_O7 into [$mem_ptr], set R_O7=[$mem_ptr] in any case\n\t"
|
ins_encode( enc_cas(mem_ptr,oldval,newval) );
|
||||||
"CMP $oldval,R_O7\t\t! See if we made progress\n\t"
|
|
||||||
"MOV 1,$res\n\t"
|
|
||||||
"MOVne xcc,R_G0,$res"
|
|
||||||
%}
|
|
||||||
ins_encode( enc_casx(mem_ptr, oldval, newval),
|
|
||||||
enc_lflags_ne_to_boolean(res) );
|
|
||||||
ins_pipe( long_memory_op );
|
ins_pipe( long_memory_op );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct storeLConditional_flags(iRegP mem_ptr, iRegL oldval, iRegL newval, flagsRegL xcc, o7RegI tmp1, immI0 zero) %{
|
// Conditional-store of a long value.
|
||||||
match(Set xcc (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero));
|
instruct storeLConditional( iRegP mem_ptr, iRegL oldval, g3RegL newval, flagsRegL xcc ) %{
|
||||||
effect( USE mem_ptr, KILL tmp1);
|
match(Set xcc (StoreLConditional mem_ptr (Binary oldval newval)));
|
||||||
// Marshal the register pairs into V9 64-bit registers, then do the compare-and-swap
|
effect( KILL newval );
|
||||||
format %{
|
format %{ "CASXA [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
|
||||||
"MOV $newval,R_O7\n\t"
|
"CMP $oldval,$newval\t\t! See if we made progress" %}
|
||||||
"CASXA [$mem_ptr],$oldval,R_O7\t! If $oldval==[$mem_ptr] Then store R_O7 into [$mem_ptr], set R_O7=[$mem_ptr] in any case\n\t"
|
ins_encode( enc_cas(mem_ptr,oldval,newval) );
|
||||||
"CMP $oldval,R_O7\t\t! See if we made progress"
|
|
||||||
%}
|
|
||||||
ins_encode( enc_casx(mem_ptr, oldval, newval));
|
|
||||||
ins_pipe( long_memory_op );
|
ins_pipe( long_memory_op );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -7405,6 +7409,34 @@ instruct orL_reg_imm13(iRegL dst, iRegL src1, immL13 con) %{
|
|||||||
ins_pipe(ialu_reg_imm);
|
ins_pipe(ialu_reg_imm);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
#ifndef _LP64
|
||||||
|
|
||||||
|
// Use sp_ptr_RegP to match G2 (TLS register) without spilling.
|
||||||
|
instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
|
||||||
|
match(Set dst (OrI src1 (CastP2X src2)));
|
||||||
|
|
||||||
|
size(4);
|
||||||
|
format %{ "OR $src1,$src2,$dst" %}
|
||||||
|
opcode(Assembler::or_op3, Assembler::arith_op);
|
||||||
|
ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
instruct orL_reg_castP2X(iRegL dst, iRegL src1, sp_ptr_RegP src2) %{
|
||||||
|
match(Set dst (OrL src1 (CastP2X src2)));
|
||||||
|
|
||||||
|
ins_cost(DEFAULT_COST);
|
||||||
|
size(4);
|
||||||
|
format %{ "OR $src1,$src2,$dst\t! long" %}
|
||||||
|
opcode(Assembler::or_op3, Assembler::arith_op);
|
||||||
|
ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// Xor Instructions
|
// Xor Instructions
|
||||||
// Register Xor
|
// Register Xor
|
||||||
instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
|
instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
|
||||||
@ -7666,7 +7698,7 @@ instruct convI2D_mem( regD_low dst, memory mem ) %{
|
|||||||
format %{ "LDF $mem,$dst\n\t"
|
format %{ "LDF $mem,$dst\n\t"
|
||||||
"FITOD $dst,$dst" %}
|
"FITOD $dst,$dst" %}
|
||||||
opcode(Assembler::ldf_op3, Assembler::fitod_opf);
|
opcode(Assembler::ldf_op3, Assembler::fitod_opf);
|
||||||
ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
|
ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
|
||||||
ins_pipe(floadF_mem);
|
ins_pipe(floadF_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -7696,7 +7728,7 @@ instruct convI2F_mem( regF dst, memory mem ) %{
|
|||||||
format %{ "LDF $mem,$dst\n\t"
|
format %{ "LDF $mem,$dst\n\t"
|
||||||
"FITOS $dst,$dst" %}
|
"FITOS $dst,$dst" %}
|
||||||
opcode(Assembler::ldf_op3, Assembler::fitos_opf);
|
opcode(Assembler::ldf_op3, Assembler::fitos_opf);
|
||||||
ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
|
ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
|
||||||
ins_pipe(floadF_mem);
|
ins_pipe(floadF_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -7738,7 +7770,7 @@ instruct MoveF2I_stack_reg(iRegI dst, stackSlotF src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDUW $src,$dst\t! MoveF2I" %}
|
format %{ "LDUW $src,$dst\t! MoveF2I" %}
|
||||||
opcode(Assembler::lduw_op3);
|
opcode(Assembler::lduw_op3);
|
||||||
ins_encode( form3_mem_reg( src, dst ) );
|
ins_encode(simple_form3_mem_reg( src, dst ) );
|
||||||
ins_pipe(iload_mem);
|
ins_pipe(iload_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -7750,7 +7782,7 @@ instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDF $src,$dst\t! MoveI2F" %}
|
format %{ "LDF $src,$dst\t! MoveI2F" %}
|
||||||
opcode(Assembler::ldf_op3);
|
opcode(Assembler::ldf_op3);
|
||||||
ins_encode(form3_mem_reg(src, dst));
|
ins_encode(simple_form3_mem_reg(src, dst));
|
||||||
ins_pipe(floadF_stk);
|
ins_pipe(floadF_stk);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -7762,7 +7794,7 @@ instruct MoveD2L_stack_reg(iRegL dst, stackSlotD src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDX $src,$dst\t! MoveD2L" %}
|
format %{ "LDX $src,$dst\t! MoveD2L" %}
|
||||||
opcode(Assembler::ldx_op3);
|
opcode(Assembler::ldx_op3);
|
||||||
ins_encode( form3_mem_reg( src, dst ) );
|
ins_encode(simple_form3_mem_reg( src, dst ) );
|
||||||
ins_pipe(iload_mem);
|
ins_pipe(iload_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -7774,7 +7806,7 @@ instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "LDDF $src,$dst\t! MoveL2D" %}
|
format %{ "LDDF $src,$dst\t! MoveL2D" %}
|
||||||
opcode(Assembler::lddf_op3);
|
opcode(Assembler::lddf_op3);
|
||||||
ins_encode(form3_mem_reg(src, dst));
|
ins_encode(simple_form3_mem_reg(src, dst));
|
||||||
ins_pipe(floadD_stk);
|
ins_pipe(floadD_stk);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -7786,7 +7818,7 @@ instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STF $src,$dst\t!MoveF2I" %}
|
format %{ "STF $src,$dst\t!MoveF2I" %}
|
||||||
opcode(Assembler::stf_op3);
|
opcode(Assembler::stf_op3);
|
||||||
ins_encode(form3_mem_reg(dst, src));
|
ins_encode(simple_form3_mem_reg(dst, src));
|
||||||
ins_pipe(fstoreF_stk_reg);
|
ins_pipe(fstoreF_stk_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -7798,7 +7830,7 @@ instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STW $src,$dst\t!MoveI2F" %}
|
format %{ "STW $src,$dst\t!MoveI2F" %}
|
||||||
opcode(Assembler::stw_op3);
|
opcode(Assembler::stw_op3);
|
||||||
ins_encode( form3_mem_reg( dst, src ) );
|
ins_encode(simple_form3_mem_reg( dst, src ) );
|
||||||
ins_pipe(istore_mem_reg);
|
ins_pipe(istore_mem_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -7810,7 +7842,7 @@ instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STDF $src,$dst\t!MoveD2L" %}
|
format %{ "STDF $src,$dst\t!MoveD2L" %}
|
||||||
opcode(Assembler::stdf_op3);
|
opcode(Assembler::stdf_op3);
|
||||||
ins_encode(form3_mem_reg(dst, src));
|
ins_encode(simple_form3_mem_reg(dst, src));
|
||||||
ins_pipe(fstoreD_stk_reg);
|
ins_pipe(fstoreD_stk_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -7822,7 +7854,7 @@ instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
|
|||||||
size(4);
|
size(4);
|
||||||
format %{ "STX $src,$dst\t!MoveL2D" %}
|
format %{ "STX $src,$dst\t!MoveL2D" %}
|
||||||
opcode(Assembler::stx_op3);
|
opcode(Assembler::stx_op3);
|
||||||
ins_encode( form3_mem_reg( dst, src ) );
|
ins_encode(simple_form3_mem_reg( dst, src ) );
|
||||||
ins_pipe(istore_mem_reg);
|
ins_pipe(istore_mem_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -956,7 +956,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
// Load a little early; will load 1 off the end of the array.
|
// Load a little early; will load 1 off the end of the array.
|
||||||
// Ok for now; revisit if we have other uses of this routine.
|
// Ok for now; revisit if we have other uses of this routine.
|
||||||
if (UseCompressedOops) {
|
if (UseCompressedOops) {
|
||||||
__ ld(L1_ary_ptr,0,L2_super);// Will load a little early
|
__ lduw(L1_ary_ptr,0,L2_super);// Will load a little early
|
||||||
} else {
|
} else {
|
||||||
__ ld_ptr(L1_ary_ptr,0,L2_super);// Will load a little early
|
__ ld_ptr(L1_ary_ptr,0,L2_super);// Will load a little early
|
||||||
}
|
}
|
||||||
@ -973,7 +973,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
__ subcc(L2_super,L4_ooptmp,Rret); // Check for match; zero in Rret for a hit
|
__ subcc(L2_super,L4_ooptmp,Rret); // Check for match; zero in Rret for a hit
|
||||||
__ br( Assembler::notEqual, false, Assembler::pt, loop );
|
__ br( Assembler::notEqual, false, Assembler::pt, loop );
|
||||||
__ delayed()->ld(L1_ary_ptr,0,L2_super);// Will load a little early
|
__ delayed()->lduw(L1_ary_ptr,0,L2_super);// Will load a little early
|
||||||
#else
|
#else
|
||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
#endif
|
#endif
|
||||||
|
@ -621,6 +621,10 @@ address Assembler::locate_operand(address inst, WhichOperand which) {
|
|||||||
debug_only(has_disp32 = true);
|
debug_only(has_disp32 = true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0xF0: // Lock
|
||||||
|
assert(os::is_MP(), "only on MP");
|
||||||
|
goto again_after_prefix;
|
||||||
|
|
||||||
case 0xF3: // For SSE
|
case 0xF3: // For SSE
|
||||||
case 0xF2: // For SSE2
|
case 0xF2: // For SSE2
|
||||||
switch (0xFF & *ip++) {
|
switch (0xFF & *ip++) {
|
||||||
|
@ -1780,7 +1780,8 @@ class MacroAssembler: public Assembler {
|
|||||||
// check info (currently consumed only by C1). If
|
// check info (currently consumed only by C1). If
|
||||||
// swap_reg_contains_mark is true then returns -1 as it is assumed
|
// swap_reg_contains_mark is true then returns -1 as it is assumed
|
||||||
// the calling code has already passed any potential faults.
|
// the calling code has already passed any potential faults.
|
||||||
int biased_locking_enter(Register lock_reg, Register obj_reg, Register swap_reg, Register tmp_reg,
|
int biased_locking_enter(Register lock_reg, Register obj_reg,
|
||||||
|
Register swap_reg, Register tmp_reg,
|
||||||
bool swap_reg_contains_mark,
|
bool swap_reg_contains_mark,
|
||||||
Label& done, Label* slow_case = NULL,
|
Label& done, Label* slow_case = NULL,
|
||||||
BiasedLockingCounters* counters = NULL);
|
BiasedLockingCounters* counters = NULL);
|
||||||
|
@ -495,8 +495,8 @@ void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) {
|
|||||||
void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
|
void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
|
||||||
Compile* C = ra_->C;
|
Compile* C = ra_->C;
|
||||||
if( C->in_24_bit_fp_mode() ) {
|
if( C->in_24_bit_fp_mode() ) {
|
||||||
tty->print("FLDCW 24 bit fpu control word");
|
st->print("FLDCW 24 bit fpu control word");
|
||||||
tty->print_cr(""); tty->print("\t");
|
st->print_cr(""); st->print("\t");
|
||||||
}
|
}
|
||||||
|
|
||||||
int framesize = C->frame_slots() << LogBytesPerInt;
|
int framesize = C->frame_slots() << LogBytesPerInt;
|
||||||
@ -510,22 +510,22 @@ void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
|
|||||||
// stack. But the stack safety zone should account for that.
|
// stack. But the stack safety zone should account for that.
|
||||||
// See bugs 4446381, 4468289, 4497237.
|
// See bugs 4446381, 4468289, 4497237.
|
||||||
if (C->need_stack_bang(framesize)) {
|
if (C->need_stack_bang(framesize)) {
|
||||||
tty->print_cr("# stack bang"); tty->print("\t");
|
st->print_cr("# stack bang"); st->print("\t");
|
||||||
}
|
}
|
||||||
tty->print_cr("PUSHL EBP"); tty->print("\t");
|
st->print_cr("PUSHL EBP"); st->print("\t");
|
||||||
|
|
||||||
if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth
|
if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth
|
||||||
tty->print("PUSH 0xBADB100D\t# Majik cookie for stack depth check");
|
st->print("PUSH 0xBADB100D\t# Majik cookie for stack depth check");
|
||||||
tty->print_cr(""); tty->print("\t");
|
st->print_cr(""); st->print("\t");
|
||||||
framesize -= wordSize;
|
framesize -= wordSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) {
|
if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) {
|
||||||
if (framesize) {
|
if (framesize) {
|
||||||
tty->print("SUB ESP,%d\t# Create frame",framesize);
|
st->print("SUB ESP,%d\t# Create frame",framesize);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tty->print("SUB ESP,%d\t# Create frame",framesize);
|
st->print("SUB ESP,%d\t# Create frame",framesize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -725,18 +725,19 @@ static enum RC rc_class( OptoReg::Name reg ) {
|
|||||||
return rc_xmm;
|
return rc_xmm;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg, int opcode, const char *op_str, int size ) {
|
static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg,
|
||||||
|
int opcode, const char *op_str, int size, outputStream* st ) {
|
||||||
if( cbuf ) {
|
if( cbuf ) {
|
||||||
emit_opcode (*cbuf, opcode );
|
emit_opcode (*cbuf, opcode );
|
||||||
encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, false);
|
encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, false);
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
} else if( !do_size ) {
|
} else if( !do_size ) {
|
||||||
if( size != 0 ) tty->print("\n\t");
|
if( size != 0 ) st->print("\n\t");
|
||||||
if( opcode == 0x8B || opcode == 0x89 ) { // MOV
|
if( opcode == 0x8B || opcode == 0x89 ) { // MOV
|
||||||
if( is_load ) tty->print("%s %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
|
if( is_load ) st->print("%s %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
|
||||||
else tty->print("%s [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
|
else st->print("%s [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
|
||||||
} else { // FLD, FST, PUSH, POP
|
} else { // FLD, FST, PUSH, POP
|
||||||
tty->print("%s [ESP + #%d]",op_str,offset);
|
st->print("%s [ESP + #%d]",op_str,offset);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -746,7 +747,7 @@ static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset
|
|||||||
|
|
||||||
// Helper for XMM registers. Extra opcode bits, limited syntax.
|
// Helper for XMM registers. Extra opcode bits, limited syntax.
|
||||||
static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
|
static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
|
||||||
int offset, int reg_lo, int reg_hi, int size ) {
|
int offset, int reg_lo, int reg_hi, int size, outputStream* st ) {
|
||||||
if( cbuf ) {
|
if( cbuf ) {
|
||||||
if( reg_lo+1 == reg_hi ) { // double move?
|
if( reg_lo+1 == reg_hi ) { // double move?
|
||||||
if( is_load && !UseXmmLoadAndClearUpper )
|
if( is_load && !UseXmmLoadAndClearUpper )
|
||||||
@ -764,17 +765,17 @@ static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
|
|||||||
encode_RegMem(*cbuf, Matcher::_regEncode[reg_lo], ESP_enc, 0x4, 0, offset, false);
|
encode_RegMem(*cbuf, Matcher::_regEncode[reg_lo], ESP_enc, 0x4, 0, offset, false);
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
} else if( !do_size ) {
|
} else if( !do_size ) {
|
||||||
if( size != 0 ) tty->print("\n\t");
|
if( size != 0 ) st->print("\n\t");
|
||||||
if( reg_lo+1 == reg_hi ) { // double move?
|
if( reg_lo+1 == reg_hi ) { // double move?
|
||||||
if( is_load ) tty->print("%s %s,[ESP + #%d]",
|
if( is_load ) st->print("%s %s,[ESP + #%d]",
|
||||||
UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD",
|
UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD",
|
||||||
Matcher::regName[reg_lo], offset);
|
Matcher::regName[reg_lo], offset);
|
||||||
else tty->print("MOVSD [ESP + #%d],%s",
|
else st->print("MOVSD [ESP + #%d],%s",
|
||||||
offset, Matcher::regName[reg_lo]);
|
offset, Matcher::regName[reg_lo]);
|
||||||
} else {
|
} else {
|
||||||
if( is_load ) tty->print("MOVSS %s,[ESP + #%d]",
|
if( is_load ) st->print("MOVSS %s,[ESP + #%d]",
|
||||||
Matcher::regName[reg_lo], offset);
|
Matcher::regName[reg_lo], offset);
|
||||||
else tty->print("MOVSS [ESP + #%d],%s",
|
else st->print("MOVSS [ESP + #%d],%s",
|
||||||
offset, Matcher::regName[reg_lo]);
|
offset, Matcher::regName[reg_lo]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -785,7 +786,7 @@ static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
|
|||||||
|
|
||||||
|
|
||||||
static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
|
static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
|
||||||
int src_hi, int dst_hi, int size ) {
|
int src_hi, int dst_hi, int size, outputStream* st ) {
|
||||||
if( UseXmmRegToRegMoveAll ) {//Use movaps,movapd to move between xmm registers
|
if( UseXmmRegToRegMoveAll ) {//Use movaps,movapd to move between xmm registers
|
||||||
if( cbuf ) {
|
if( cbuf ) {
|
||||||
if( (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ) {
|
if( (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ) {
|
||||||
@ -796,11 +797,11 @@ static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst
|
|||||||
emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
|
emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
} else if( !do_size ) {
|
} else if( !do_size ) {
|
||||||
if( size != 0 ) tty->print("\n\t");
|
if( size != 0 ) st->print("\n\t");
|
||||||
if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
|
if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
|
||||||
tty->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
|
st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
|
||||||
} else {
|
} else {
|
||||||
tty->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
|
st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -813,11 +814,11 @@ static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst
|
|||||||
emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
|
emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
} else if( !do_size ) {
|
} else if( !do_size ) {
|
||||||
if( size != 0 ) tty->print("\n\t");
|
if( size != 0 ) st->print("\n\t");
|
||||||
if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
|
if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
|
||||||
tty->print("MOVSD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
|
st->print("MOVSD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
|
||||||
} else {
|
} else {
|
||||||
tty->print("MOVSS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
|
st->print("MOVSS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -825,28 +826,29 @@ static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size ) {
|
static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size, outputStream* st ) {
|
||||||
if( cbuf ) {
|
if( cbuf ) {
|
||||||
emit_opcode(*cbuf, 0x8B );
|
emit_opcode(*cbuf, 0x8B );
|
||||||
emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst], Matcher::_regEncode[src] );
|
emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst], Matcher::_regEncode[src] );
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
} else if( !do_size ) {
|
} else if( !do_size ) {
|
||||||
if( size != 0 ) tty->print("\n\t");
|
if( size != 0 ) st->print("\n\t");
|
||||||
tty->print("MOV %s,%s",Matcher::regName[dst],Matcher::regName[src]);
|
st->print("MOV %s,%s",Matcher::regName[dst],Matcher::regName[src]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return size+2;
|
return size+2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi, int offset, int size ) {
|
static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi,
|
||||||
|
int offset, int size, outputStream* st ) {
|
||||||
if( src_lo != FPR1L_num ) { // Move value to top of FP stack, if not already there
|
if( src_lo != FPR1L_num ) { // Move value to top of FP stack, if not already there
|
||||||
if( cbuf ) {
|
if( cbuf ) {
|
||||||
emit_opcode( *cbuf, 0xD9 ); // FLD (i.e., push it)
|
emit_opcode( *cbuf, 0xD9 ); // FLD (i.e., push it)
|
||||||
emit_d8( *cbuf, 0xC0-1+Matcher::_regEncode[src_lo] );
|
emit_d8( *cbuf, 0xC0-1+Matcher::_regEncode[src_lo] );
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
} else if( !do_size ) {
|
} else if( !do_size ) {
|
||||||
if( size != 0 ) tty->print("\n\t");
|
if( size != 0 ) st->print("\n\t");
|
||||||
tty->print("FLD %s",Matcher::regName[src_lo]);
|
st->print("FLD %s",Matcher::regName[src_lo]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
size += 2;
|
size += 2;
|
||||||
@ -864,7 +866,7 @@ static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int
|
|||||||
assert( !OptoReg::is_valid(src_hi) && !OptoReg::is_valid(dst_hi), "no non-adjacent float-stores" );
|
assert( !OptoReg::is_valid(src_hi) && !OptoReg::is_valid(dst_hi), "no non-adjacent float-stores" );
|
||||||
}
|
}
|
||||||
|
|
||||||
return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size);
|
return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
|
uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
|
||||||
@ -892,16 +894,16 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo
|
|||||||
if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
|
if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
|
||||||
if( src_second == dst_first ) { // overlapping stack copy ranges
|
if( src_second == dst_first ) { // overlapping stack copy ranges
|
||||||
assert( src_second_rc == rc_stack && dst_second_rc == rc_stack, "we only expect a stk-stk copy here" );
|
assert( src_second_rc == rc_stack && dst_second_rc == rc_stack, "we only expect a stk-stk copy here" );
|
||||||
size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size);
|
size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st);
|
||||||
size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size);
|
size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st);
|
||||||
src_second_rc = dst_second_rc = rc_bad; // flag as already moved the second bits
|
src_second_rc = dst_second_rc = rc_bad; // flag as already moved the second bits
|
||||||
}
|
}
|
||||||
// move low bits
|
// move low bits
|
||||||
size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH ",size);
|
size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH ",size, st);
|
||||||
size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP ",size);
|
size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP ",size, st);
|
||||||
if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { // mov second bits
|
if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { // mov second bits
|
||||||
size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size);
|
size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st);
|
||||||
size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size);
|
size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st);
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@ -909,15 +911,15 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo
|
|||||||
// --------------------------------------
|
// --------------------------------------
|
||||||
// Check for integer reg-reg copy
|
// Check for integer reg-reg copy
|
||||||
if( src_first_rc == rc_int && dst_first_rc == rc_int )
|
if( src_first_rc == rc_int && dst_first_rc == rc_int )
|
||||||
size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size);
|
size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size, st);
|
||||||
|
|
||||||
// Check for integer store
|
// Check for integer store
|
||||||
if( src_first_rc == rc_int && dst_first_rc == rc_stack )
|
if( src_first_rc == rc_int && dst_first_rc == rc_stack )
|
||||||
size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size);
|
size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size, st);
|
||||||
|
|
||||||
// Check for integer load
|
// Check for integer load
|
||||||
if( dst_first_rc == rc_int && src_first_rc == rc_stack )
|
if( dst_first_rc == rc_int && src_first_rc == rc_stack )
|
||||||
size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size);
|
size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size, st);
|
||||||
|
|
||||||
// --------------------------------------
|
// --------------------------------------
|
||||||
// Check for float reg-reg copy
|
// Check for float reg-reg copy
|
||||||
@ -951,7 +953,7 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo
|
|||||||
|
|
||||||
// Check for float store
|
// Check for float store
|
||||||
if( src_first_rc == rc_float && dst_first_rc == rc_stack ) {
|
if( src_first_rc == rc_float && dst_first_rc == rc_stack ) {
|
||||||
return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size);
|
return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for float load
|
// Check for float load
|
||||||
@ -987,17 +989,17 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo
|
|||||||
assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) ||
|
assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) ||
|
||||||
(src_first+1 == src_second && dst_first+1 == dst_second),
|
(src_first+1 == src_second && dst_first+1 == dst_second),
|
||||||
"no non-adjacent float-moves" );
|
"no non-adjacent float-moves" );
|
||||||
return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size);
|
return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for xmm store
|
// Check for xmm store
|
||||||
if( src_first_rc == rc_xmm && dst_first_rc == rc_stack ) {
|
if( src_first_rc == rc_xmm && dst_first_rc == rc_stack ) {
|
||||||
return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size);
|
return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for float xmm load
|
// Check for float xmm load
|
||||||
if( dst_first_rc == rc_xmm && src_first_rc == rc_stack ) {
|
if( dst_first_rc == rc_xmm && src_first_rc == rc_stack ) {
|
||||||
return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size);
|
return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy from float reg to xmm reg
|
// Copy from float reg to xmm reg
|
||||||
@ -1017,10 +1019,10 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo
|
|||||||
}
|
}
|
||||||
size += 4;
|
size += 4;
|
||||||
|
|
||||||
size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size);
|
size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size, st);
|
||||||
|
|
||||||
// Copy from the temp memory to the xmm reg.
|
// Copy from the temp memory to the xmm reg.
|
||||||
size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size);
|
size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size, st);
|
||||||
|
|
||||||
if( cbuf ) {
|
if( cbuf ) {
|
||||||
emit_opcode(*cbuf,0x8D); // LEA ESP,[ESP+8]
|
emit_opcode(*cbuf,0x8D); // LEA ESP,[ESP+8]
|
||||||
@ -1047,15 +1049,15 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo
|
|||||||
|
|
||||||
// Check for second word int-int move
|
// Check for second word int-int move
|
||||||
if( src_second_rc == rc_int && dst_second_rc == rc_int )
|
if( src_second_rc == rc_int && dst_second_rc == rc_int )
|
||||||
return impl_mov_helper(cbuf,do_size,src_second,dst_second,size);
|
return impl_mov_helper(cbuf,do_size,src_second,dst_second,size, st);
|
||||||
|
|
||||||
// Check for second word integer store
|
// Check for second word integer store
|
||||||
if( src_second_rc == rc_int && dst_second_rc == rc_stack )
|
if( src_second_rc == rc_int && dst_second_rc == rc_stack )
|
||||||
return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size);
|
return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size, st);
|
||||||
|
|
||||||
// Check for second word integer load
|
// Check for second word integer load
|
||||||
if( dst_second_rc == rc_int && src_second_rc == rc_stack )
|
if( dst_second_rc == rc_int && src_second_rc == rc_stack )
|
||||||
return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size);
|
return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size, st);
|
||||||
|
|
||||||
|
|
||||||
Unimplemented();
|
Unimplemented();
|
||||||
@ -1318,7 +1320,11 @@ const uint Matcher::vector_ideal_reg(void) {
|
|||||||
//
|
//
|
||||||
// NOTE: If the platform does not provide any short branch variants, then
|
// NOTE: If the platform does not provide any short branch variants, then
|
||||||
// this method should return false for offset 0.
|
// this method should return false for offset 0.
|
||||||
bool Matcher::is_short_branch_offset(int offset) {
|
bool Matcher::is_short_branch_offset(int rule, int offset) {
|
||||||
|
// the short version of jmpConUCF2 contains multiple branches,
|
||||||
|
// making the reach slightly less
|
||||||
|
if (rule == jmpConUCF2_rule)
|
||||||
|
return (-126 <= offset && offset <= 125);
|
||||||
return (-128 <= offset && offset <= 127);
|
return (-128 <= offset && offset <= 127);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3307,7 +3313,7 @@ encode %{
|
|||||||
// Beware -- there's a subtle invariant that fetch of the markword
|
// Beware -- there's a subtle invariant that fetch of the markword
|
||||||
// at [FETCH], below, will never observe a biased encoding (*101b).
|
// at [FETCH], below, will never observe a biased encoding (*101b).
|
||||||
// If this invariant is not held we risk exclusion (safety) failure.
|
// If this invariant is not held we risk exclusion (safety) failure.
|
||||||
if (UseBiasedLocking) {
|
if (UseBiasedLocking && !UseOptoBiasInlining) {
|
||||||
masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters);
|
masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3528,7 +3534,7 @@ encode %{
|
|||||||
|
|
||||||
// Critically, the biased locking test must have precedence over
|
// Critically, the biased locking test must have precedence over
|
||||||
// and appear before the (box->dhw == 0) recursive stack-lock test.
|
// and appear before the (box->dhw == 0) recursive stack-lock test.
|
||||||
if (UseBiasedLocking) {
|
if (UseBiasedLocking && !UseOptoBiasInlining) {
|
||||||
masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
|
masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5272,6 +5278,15 @@ operand eFlagsRegU() %{
|
|||||||
interface(REG_INTER);
|
interface(REG_INTER);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
operand eFlagsRegUCF() %{
|
||||||
|
constraint(ALLOC_IN_RC(int_flags));
|
||||||
|
match(RegFlags);
|
||||||
|
predicate(false);
|
||||||
|
|
||||||
|
format %{ "EFLAGS_U_CF" %}
|
||||||
|
interface(REG_INTER);
|
||||||
|
%}
|
||||||
|
|
||||||
// Condition Code Register used by long compare
|
// Condition Code Register used by long compare
|
||||||
operand flagsReg_long_LTGE() %{
|
operand flagsReg_long_LTGE() %{
|
||||||
constraint(ALLOC_IN_RC(int_flags));
|
constraint(ALLOC_IN_RC(int_flags));
|
||||||
@ -5749,12 +5764,12 @@ operand cmpOp() %{
|
|||||||
|
|
||||||
format %{ "" %}
|
format %{ "" %}
|
||||||
interface(COND_INTER) %{
|
interface(COND_INTER) %{
|
||||||
equal(0x4);
|
equal(0x4, "e");
|
||||||
not_equal(0x5);
|
not_equal(0x5, "ne");
|
||||||
less(0xC);
|
less(0xC, "l");
|
||||||
greater_equal(0xD);
|
greater_equal(0xD, "ge");
|
||||||
less_equal(0xE);
|
less_equal(0xE, "le");
|
||||||
greater(0xF);
|
greater(0xF, "g");
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5766,12 +5781,47 @@ operand cmpOpU() %{
|
|||||||
|
|
||||||
format %{ "" %}
|
format %{ "" %}
|
||||||
interface(COND_INTER) %{
|
interface(COND_INTER) %{
|
||||||
equal(0x4);
|
equal(0x4, "e");
|
||||||
not_equal(0x5);
|
not_equal(0x5, "ne");
|
||||||
less(0x2);
|
less(0x2, "b");
|
||||||
greater_equal(0x3);
|
greater_equal(0x3, "nb");
|
||||||
less_equal(0x6);
|
less_equal(0x6, "be");
|
||||||
greater(0x7);
|
greater(0x7, "nbe");
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Floating comparisons that don't require any fixup for the unordered case
|
||||||
|
operand cmpOpUCF() %{
|
||||||
|
match(Bool);
|
||||||
|
predicate(n->as_Bool()->_test._test == BoolTest::lt ||
|
||||||
|
n->as_Bool()->_test._test == BoolTest::ge ||
|
||||||
|
n->as_Bool()->_test._test == BoolTest::le ||
|
||||||
|
n->as_Bool()->_test._test == BoolTest::gt);
|
||||||
|
format %{ "" %}
|
||||||
|
interface(COND_INTER) %{
|
||||||
|
equal(0x4, "e");
|
||||||
|
not_equal(0x5, "ne");
|
||||||
|
less(0x2, "b");
|
||||||
|
greater_equal(0x3, "nb");
|
||||||
|
less_equal(0x6, "be");
|
||||||
|
greater(0x7, "nbe");
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
// Floating comparisons that can be fixed up with extra conditional jumps
|
||||||
|
operand cmpOpUCF2() %{
|
||||||
|
match(Bool);
|
||||||
|
predicate(n->as_Bool()->_test._test == BoolTest::ne ||
|
||||||
|
n->as_Bool()->_test._test == BoolTest::eq);
|
||||||
|
format %{ "" %}
|
||||||
|
interface(COND_INTER) %{
|
||||||
|
equal(0x4, "e");
|
||||||
|
not_equal(0x5, "ne");
|
||||||
|
less(0x2, "b");
|
||||||
|
greater_equal(0x3, "nb");
|
||||||
|
less_equal(0x6, "be");
|
||||||
|
greater(0x7, "nbe");
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5796,12 +5846,12 @@ operand cmpOp_commute() %{
|
|||||||
|
|
||||||
format %{ "" %}
|
format %{ "" %}
|
||||||
interface(COND_INTER) %{
|
interface(COND_INTER) %{
|
||||||
equal(0x4);
|
equal(0x4, "e");
|
||||||
not_equal(0x5);
|
not_equal(0x5, "ne");
|
||||||
less(0xF);
|
less(0xF, "g");
|
||||||
greater_equal(0xE);
|
greater_equal(0xE, "le");
|
||||||
less_equal(0xD);
|
less_equal(0xD, "ge");
|
||||||
greater(0xC);
|
greater(0xC, "l");
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -7357,7 +7407,7 @@ instruct cmovI_reg(eRegI dst, eRegI src, eFlagsReg cr, cmpOp cop ) %{
|
|||||||
ins_pipe( pipe_cmov_reg );
|
ins_pipe( pipe_cmov_reg );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct cmovI_regU( eRegI dst, eRegI src, eFlagsRegU cr, cmpOpU cop ) %{
|
instruct cmovI_regU( cmpOpU cop, eFlagsRegU cr, eRegI dst, eRegI src ) %{
|
||||||
predicate(VM_Version::supports_cmov() );
|
predicate(VM_Version::supports_cmov() );
|
||||||
match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
|
match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
|
||||||
ins_cost(200);
|
ins_cost(200);
|
||||||
@ -7367,6 +7417,15 @@ instruct cmovI_regU( eRegI dst, eRegI src, eFlagsRegU cr, cmpOpU cop ) %{
|
|||||||
ins_pipe( pipe_cmov_reg );
|
ins_pipe( pipe_cmov_reg );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmovI_regUCF( cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, eRegI src ) %{
|
||||||
|
predicate(VM_Version::supports_cmov() );
|
||||||
|
match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
|
||||||
|
ins_cost(200);
|
||||||
|
expand %{
|
||||||
|
cmovI_regU(cop, cr, dst, src);
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
// Conditional move
|
// Conditional move
|
||||||
instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{
|
instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{
|
||||||
predicate(VM_Version::supports_cmov() );
|
predicate(VM_Version::supports_cmov() );
|
||||||
@ -7379,7 +7438,7 @@ instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
// Conditional move
|
// Conditional move
|
||||||
instruct cmovI_memu(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
|
instruct cmovI_memU(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
|
||||||
predicate(VM_Version::supports_cmov() );
|
predicate(VM_Version::supports_cmov() );
|
||||||
match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
|
match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
|
||||||
ins_cost(250);
|
ins_cost(250);
|
||||||
@ -7389,6 +7448,15 @@ instruct cmovI_memu(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
|
|||||||
ins_pipe( pipe_cmov_mem );
|
ins_pipe( pipe_cmov_mem );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmovI_memUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, memory src) %{
|
||||||
|
predicate(VM_Version::supports_cmov() );
|
||||||
|
match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
|
||||||
|
ins_cost(250);
|
||||||
|
expand %{
|
||||||
|
cmovI_memU(cop, cr, dst, src);
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
// Conditional move
|
// Conditional move
|
||||||
instruct cmovP_reg(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{
|
instruct cmovP_reg(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{
|
||||||
predicate(VM_Version::supports_cmov() );
|
predicate(VM_Version::supports_cmov() );
|
||||||
@ -7416,7 +7484,7 @@ instruct cmovP_reg_nonP6(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
// Conditional move
|
// Conditional move
|
||||||
instruct cmovP_regU(eRegP dst, eRegP src, eFlagsRegU cr, cmpOpU cop ) %{
|
instruct cmovP_regU(cmpOpU cop, eFlagsRegU cr, eRegP dst, eRegP src ) %{
|
||||||
predicate(VM_Version::supports_cmov() );
|
predicate(VM_Version::supports_cmov() );
|
||||||
match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
|
match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
|
||||||
ins_cost(200);
|
ins_cost(200);
|
||||||
@ -7426,6 +7494,15 @@ instruct cmovP_regU(eRegP dst, eRegP src, eFlagsRegU cr, cmpOpU cop ) %{
|
|||||||
ins_pipe( pipe_cmov_reg );
|
ins_pipe( pipe_cmov_reg );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmovP_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegP dst, eRegP src ) %{
|
||||||
|
predicate(VM_Version::supports_cmov() );
|
||||||
|
match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
|
||||||
|
ins_cost(200);
|
||||||
|
expand %{
|
||||||
|
cmovP_regU(cop, cr, dst, src);
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
// DISABLED: Requires the ADLC to emit a bottom_type call that
|
// DISABLED: Requires the ADLC to emit a bottom_type call that
|
||||||
// correctly meets the two pointer arguments; one is an incoming
|
// correctly meets the two pointer arguments; one is an incoming
|
||||||
// register but the other is a memory operand. ALSO appears to
|
// register but the other is a memory operand. ALSO appears to
|
||||||
@ -7555,6 +7632,15 @@ instruct fcmovX_regU(cmpOpU cop, eFlagsRegU cr, regX dst, regX src) %{
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct fcmovX_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regX dst, regX src) %{
|
||||||
|
predicate (UseSSE>=1);
|
||||||
|
match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
|
||||||
|
ins_cost(200);
|
||||||
|
expand %{
|
||||||
|
fcmovX_regU(cop, cr, dst, src);
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
// unsigned version
|
// unsigned version
|
||||||
instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{
|
instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{
|
||||||
predicate (UseSSE>=2);
|
predicate (UseSSE>=2);
|
||||||
@ -7573,6 +7659,15 @@ instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct fcmovXD_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regXD dst, regXD src) %{
|
||||||
|
predicate (UseSSE>=2);
|
||||||
|
match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
|
||||||
|
ins_cost(200);
|
||||||
|
expand %{
|
||||||
|
fcmovXD_regU(cop, cr, dst, src);
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
instruct cmovL_reg(cmpOp cop, eFlagsReg cr, eRegL dst, eRegL src) %{
|
instruct cmovL_reg(cmpOp cop, eFlagsReg cr, eRegL dst, eRegL src) %{
|
||||||
predicate(VM_Version::supports_cmov() );
|
predicate(VM_Version::supports_cmov() );
|
||||||
match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
|
match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
|
||||||
@ -7595,6 +7690,15 @@ instruct cmovL_regU(cmpOpU cop, eFlagsRegU cr, eRegL dst, eRegL src) %{
|
|||||||
ins_pipe( pipe_cmov_reg_long );
|
ins_pipe( pipe_cmov_reg_long );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{
|
||||||
|
predicate(VM_Version::supports_cmov() );
|
||||||
|
match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
|
||||||
|
ins_cost(200);
|
||||||
|
expand %{
|
||||||
|
cmovL_regU(cop, cr, dst, src);
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
//----------Arithmetic Instructions--------------------------------------------
|
//----------Arithmetic Instructions--------------------------------------------
|
||||||
//----------Addition Instructions----------------------------------------------
|
//----------Addition Instructions----------------------------------------------
|
||||||
// Integer Addition Instructions
|
// Integer Addition Instructions
|
||||||
@ -7826,33 +7930,36 @@ instruct storePConditional( memory heap_top_ptr, eAXRegP oldval, eRegP newval, e
|
|||||||
ins_pipe( pipe_cmpxchg );
|
ins_pipe( pipe_cmpxchg );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Conditional-store of a long value
|
// Conditional-store of an int value.
|
||||||
// Returns a boolean value (0/1) on success. Implemented with a CMPXCHG8 on Intel.
|
// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel.
|
||||||
// mem_ptr can actually be in either ESI or EDI
|
instruct storeIConditional( memory mem, eAXRegI oldval, eRegI newval, eFlagsReg cr ) %{
|
||||||
instruct storeLConditional( eRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
|
match(Set cr (StoreIConditional mem (Binary oldval newval)));
|
||||||
match(Set res (StoreLConditional mem_ptr (Binary oldval newval)));
|
effect(KILL oldval);
|
||||||
effect(KILL cr);
|
format %{ "CMPXCHG $mem,$newval\t# If EAX==$mem Then store $newval into $mem" %}
|
||||||
// EDX:EAX is killed if there is contention, but then it's also unused.
|
ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval, mem) );
|
||||||
// In the common case of no contention, EDX:EAX holds the new oop address.
|
|
||||||
format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
|
|
||||||
"MOV $res,0\n\t"
|
|
||||||
"JNE,s fail\n\t"
|
|
||||||
"MOV $res,1\n"
|
|
||||||
"fail:" %}
|
|
||||||
ins_encode( enc_cmpxchg8(mem_ptr),
|
|
||||||
enc_flags_ne_to_boolean(res) );
|
|
||||||
ins_pipe( pipe_cmpxchg );
|
ins_pipe( pipe_cmpxchg );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Conditional-store of a long value
|
// Conditional-store of a long value.
|
||||||
// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG8 on Intel.
|
// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG8 on Intel.
|
||||||
// mem_ptr can actually be in either ESI or EDI
|
instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
|
||||||
instruct storeLConditional_flags( eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr, immI0 zero ) %{
|
match(Set cr (StoreLConditional mem (Binary oldval newval)));
|
||||||
match(Set cr (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero));
|
effect(KILL oldval);
|
||||||
// EDX:EAX is killed if there is contention, but then it's also unused.
|
format %{ "XCHG EBX,ECX\t# correct order for CMPXCHG8 instruction\n\t"
|
||||||
// In the common case of no contention, EDX:EAX holds the new oop address.
|
"CMPXCHG8 $mem,ECX:EBX\t# If EDX:EAX==$mem Then store ECX:EBX into $mem\n\t"
|
||||||
format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" %}
|
"XCHG EBX,ECX"
|
||||||
ins_encode( enc_cmpxchg8(mem_ptr) );
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
// Note: we need to swap rbx, and rcx before and after the
|
||||||
|
// cmpxchg8 instruction because the instruction uses
|
||||||
|
// rcx as the high order word of the new value to store but
|
||||||
|
// our register encoding uses rbx.
|
||||||
|
__ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
|
||||||
|
if( os::is_MP() )
|
||||||
|
__ lock();
|
||||||
|
__ cmpxchg8(Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp));
|
||||||
|
__ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
|
||||||
|
%}
|
||||||
ins_pipe( pipe_cmpxchg );
|
ins_pipe( pipe_cmpxchg );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -8319,6 +8426,7 @@ instruct shrI_eReg_imm(eRegI dst, immI8 shift, eFlagsReg cr) %{
|
|||||||
ins_pipe( ialu_reg );
|
ins_pipe( ialu_reg );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
// Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
|
// Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
|
||||||
// This idiom is used by the compiler for the i2b bytecode.
|
// This idiom is used by the compiler for the i2b bytecode.
|
||||||
instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour, eFlagsReg cr) %{
|
instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour, eFlagsReg cr) %{
|
||||||
@ -8436,6 +8544,18 @@ instruct orI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
|
|||||||
ins_pipe( ialu_reg_reg );
|
ins_pipe( ialu_reg_reg );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct orI_eReg_castP2X(eRegI dst, eRegP src, eFlagsReg cr) %{
|
||||||
|
match(Set dst (OrI dst (CastP2X src)));
|
||||||
|
effect(KILL cr);
|
||||||
|
|
||||||
|
size(2);
|
||||||
|
format %{ "OR $dst,$src" %}
|
||||||
|
opcode(0x0B);
|
||||||
|
ins_encode( OpcP, RegReg( dst, src) );
|
||||||
|
ins_pipe( ialu_reg_reg );
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
// Or Register with Immediate
|
// Or Register with Immediate
|
||||||
instruct orI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
|
instruct orI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
|
||||||
match(Set dst (OrI dst src));
|
match(Set dst (OrI dst src));
|
||||||
@ -9200,6 +9320,18 @@ instruct cmpD_cc_P6(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmpD_cc_P6CF(eFlagsRegUCF cr, regD src1, regD src2) %{
|
||||||
|
predicate(VM_Version::supports_cmov() && UseSSE <=1);
|
||||||
|
match(Set cr (CmpD src1 src2));
|
||||||
|
ins_cost(150);
|
||||||
|
format %{ "FLD $src1\n\t"
|
||||||
|
"FUCOMIP ST,$src2 // P6 instruction" %}
|
||||||
|
opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
|
||||||
|
ins_encode( Push_Reg_D(src1),
|
||||||
|
OpcP, RegOpc(src2));
|
||||||
|
ins_pipe( pipe_slow );
|
||||||
|
%}
|
||||||
|
|
||||||
// Compare & branch
|
// Compare & branch
|
||||||
instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{
|
instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{
|
||||||
predicate(UseSSE<=1);
|
predicate(UseSSE<=1);
|
||||||
@ -9264,6 +9396,16 @@ instruct cmpXD_cc(eFlagsRegU cr, regXD dst, regXD src, eAXRegI rax) %{
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmpXD_ccCF(eFlagsRegUCF cr, regXD dst, regXD src) %{
|
||||||
|
predicate(UseSSE>=2);
|
||||||
|
match(Set cr (CmpD dst src));
|
||||||
|
ins_cost(100);
|
||||||
|
format %{ "COMISD $dst,$src" %}
|
||||||
|
opcode(0x66, 0x0F, 0x2F);
|
||||||
|
ins_encode(OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
|
||||||
|
ins_pipe( pipe_slow );
|
||||||
|
%}
|
||||||
|
|
||||||
// float compare and set condition codes in EFLAGS by XMM regs
|
// float compare and set condition codes in EFLAGS by XMM regs
|
||||||
instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{
|
instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{
|
||||||
predicate(UseSSE>=2);
|
predicate(UseSSE>=2);
|
||||||
@ -9280,6 +9422,16 @@ instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmpXD_ccmemCF(eFlagsRegUCF cr, regXD dst, memory src) %{
|
||||||
|
predicate(UseSSE>=2);
|
||||||
|
match(Set cr (CmpD dst (LoadD src)));
|
||||||
|
ins_cost(100);
|
||||||
|
format %{ "COMISD $dst,$src" %}
|
||||||
|
opcode(0x66, 0x0F, 0x2F);
|
||||||
|
ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(dst, src));
|
||||||
|
ins_pipe( pipe_slow );
|
||||||
|
%}
|
||||||
|
|
||||||
// Compare into -1,0,1 in XMM
|
// Compare into -1,0,1 in XMM
|
||||||
instruct cmpXD_reg(eRegI dst, regXD src1, regXD src2, eFlagsReg cr) %{
|
instruct cmpXD_reg(eRegI dst, regXD src1, regXD src2, eFlagsReg cr) %{
|
||||||
predicate(UseSSE>=2);
|
predicate(UseSSE>=2);
|
||||||
@ -10167,6 +10319,18 @@ instruct cmpF_cc_P6(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmpF_cc_P6CF(eFlagsRegUCF cr, regF src1, regF src2) %{
|
||||||
|
predicate(VM_Version::supports_cmov() && UseSSE == 0);
|
||||||
|
match(Set cr (CmpF src1 src2));
|
||||||
|
ins_cost(100);
|
||||||
|
format %{ "FLD $src1\n\t"
|
||||||
|
"FUCOMIP ST,$src2 // P6 instruction" %}
|
||||||
|
opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
|
||||||
|
ins_encode( Push_Reg_D(src1),
|
||||||
|
OpcP, RegOpc(src2));
|
||||||
|
ins_pipe( pipe_slow );
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
// Compare & branch
|
// Compare & branch
|
||||||
instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{
|
instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{
|
||||||
@ -10232,6 +10396,16 @@ instruct cmpX_cc(eFlagsRegU cr, regX dst, regX src, eAXRegI rax) %{
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmpX_ccCF(eFlagsRegUCF cr, regX dst, regX src) %{
|
||||||
|
predicate(UseSSE>=1);
|
||||||
|
match(Set cr (CmpF dst src));
|
||||||
|
ins_cost(100);
|
||||||
|
format %{ "COMISS $dst,$src" %}
|
||||||
|
opcode(0x0F, 0x2F);
|
||||||
|
ins_encode(OpcP, OpcS, RegReg(dst, src));
|
||||||
|
ins_pipe( pipe_slow );
|
||||||
|
%}
|
||||||
|
|
||||||
// float compare and set condition codes in EFLAGS by XMM regs
|
// float compare and set condition codes in EFLAGS by XMM regs
|
||||||
instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{
|
instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{
|
||||||
predicate(UseSSE>=1);
|
predicate(UseSSE>=1);
|
||||||
@ -10248,6 +10422,16 @@ instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmpX_ccmemCF(eFlagsRegUCF cr, regX dst, memory src) %{
|
||||||
|
predicate(UseSSE>=1);
|
||||||
|
match(Set cr (CmpF dst (LoadF src)));
|
||||||
|
ins_cost(100);
|
||||||
|
format %{ "COMISS $dst,$src" %}
|
||||||
|
opcode(0x0F, 0x2F);
|
||||||
|
ins_encode(OpcP, OpcS, RegMem(dst, src));
|
||||||
|
ins_pipe( pipe_slow );
|
||||||
|
%}
|
||||||
|
|
||||||
// Compare into -1,0,1 in XMM
|
// Compare into -1,0,1 in XMM
|
||||||
instruct cmpX_reg(eRegI dst, regX src1, regX src2, eFlagsReg cr) %{
|
instruct cmpX_reg(eRegI dst, regX src1, regX src2, eFlagsReg cr) %{
|
||||||
predicate(UseSSE>=1);
|
predicate(UseSSE>=1);
|
||||||
@ -12099,6 +12283,19 @@ instruct jmpLoopEndU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
|
|||||||
ins_pc_relative(1);
|
ins_pc_relative(1);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
|
||||||
|
match(CountedLoopEnd cop cmp);
|
||||||
|
effect(USE labl);
|
||||||
|
|
||||||
|
ins_cost(200);
|
||||||
|
format %{ "J$cop,u $labl\t# Loop end" %}
|
||||||
|
size(6);
|
||||||
|
opcode(0x0F, 0x80);
|
||||||
|
ins_encode( Jcc( cop, labl) );
|
||||||
|
ins_pipe( pipe_jcc );
|
||||||
|
ins_pc_relative(1);
|
||||||
|
%}
|
||||||
|
|
||||||
// Jump Direct Conditional - using unsigned comparison
|
// Jump Direct Conditional - using unsigned comparison
|
||||||
instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
|
instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
|
||||||
match(If cop cmp);
|
match(If cop cmp);
|
||||||
@ -12108,8 +12305,63 @@ instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
|
|||||||
format %{ "J$cop,u $labl" %}
|
format %{ "J$cop,u $labl" %}
|
||||||
size(6);
|
size(6);
|
||||||
opcode(0x0F, 0x80);
|
opcode(0x0F, 0x80);
|
||||||
ins_encode( Jcc( cop, labl) );
|
ins_encode(Jcc(cop, labl));
|
||||||
ins_pipe( pipe_jcc );
|
ins_pipe(pipe_jcc);
|
||||||
|
ins_pc_relative(1);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct jmpConUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
|
||||||
|
match(If cop cmp);
|
||||||
|
effect(USE labl);
|
||||||
|
|
||||||
|
ins_cost(200);
|
||||||
|
format %{ "J$cop,u $labl" %}
|
||||||
|
size(6);
|
||||||
|
opcode(0x0F, 0x80);
|
||||||
|
ins_encode(Jcc(cop, labl));
|
||||||
|
ins_pipe(pipe_jcc);
|
||||||
|
ins_pc_relative(1);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
|
||||||
|
match(If cop cmp);
|
||||||
|
effect(USE labl);
|
||||||
|
|
||||||
|
ins_cost(200);
|
||||||
|
format %{ $$template
|
||||||
|
if ($cop$$cmpcode == Assembler::notEqual) {
|
||||||
|
$$emit$$"JP,u $labl\n\t"
|
||||||
|
$$emit$$"J$cop,u $labl"
|
||||||
|
} else {
|
||||||
|
$$emit$$"JP,u done\n\t"
|
||||||
|
$$emit$$"J$cop,u $labl\n\t"
|
||||||
|
$$emit$$"done:"
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
size(12);
|
||||||
|
opcode(0x0F, 0x80);
|
||||||
|
ins_encode %{
|
||||||
|
Label* l = $labl$$label;
|
||||||
|
$$$emit8$primary;
|
||||||
|
emit_cc(cbuf, $secondary, Assembler::parity);
|
||||||
|
int parity_disp = -1;
|
||||||
|
bool ok = false;
|
||||||
|
if ($cop$$cmpcode == Assembler::notEqual) {
|
||||||
|
// the two jumps 6 bytes apart so the jump distances are too
|
||||||
|
parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
|
||||||
|
} else if ($cop$$cmpcode == Assembler::equal) {
|
||||||
|
parity_disp = 6;
|
||||||
|
ok = true;
|
||||||
|
} else {
|
||||||
|
ShouldNotReachHere();
|
||||||
|
}
|
||||||
|
emit_d32(cbuf, parity_disp);
|
||||||
|
$$$emit8$primary;
|
||||||
|
emit_cc(cbuf, $secondary, $cop$$cmpcode);
|
||||||
|
int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
|
||||||
|
emit_d32(cbuf, disp);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_jcc);
|
||||||
ins_pc_relative(1);
|
ins_pc_relative(1);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -12208,7 +12460,7 @@ instruct jmpLoopEnd_short(cmpOp cop, eFlagsReg cr, label labl) %{
|
|||||||
effect(USE labl);
|
effect(USE labl);
|
||||||
|
|
||||||
ins_cost(300);
|
ins_cost(300);
|
||||||
format %{ "J$cop,s $labl" %}
|
format %{ "J$cop,s $labl\t# Loop end" %}
|
||||||
size(2);
|
size(2);
|
||||||
opcode(0x70);
|
opcode(0x70);
|
||||||
ins_encode( JccShort( cop, labl) );
|
ins_encode( JccShort( cop, labl) );
|
||||||
@ -12223,7 +12475,21 @@ instruct jmpLoopEndU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{
|
|||||||
effect(USE labl);
|
effect(USE labl);
|
||||||
|
|
||||||
ins_cost(300);
|
ins_cost(300);
|
||||||
format %{ "J$cop,us $labl" %}
|
format %{ "J$cop,us $labl\t# Loop end" %}
|
||||||
|
size(2);
|
||||||
|
opcode(0x70);
|
||||||
|
ins_encode( JccShort( cop, labl) );
|
||||||
|
ins_pipe( pipe_jcc );
|
||||||
|
ins_pc_relative(1);
|
||||||
|
ins_short_branch(1);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct jmpLoopEndUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
|
||||||
|
match(CountedLoopEnd cop cmp);
|
||||||
|
effect(USE labl);
|
||||||
|
|
||||||
|
ins_cost(300);
|
||||||
|
format %{ "J$cop,us $labl\t# Loop end" %}
|
||||||
size(2);
|
size(2);
|
||||||
opcode(0x70);
|
opcode(0x70);
|
||||||
ins_encode( JccShort( cop, labl) );
|
ins_encode( JccShort( cop, labl) );
|
||||||
@ -12247,6 +12513,60 @@ instruct jmpConU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{
|
|||||||
ins_short_branch(1);
|
ins_short_branch(1);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct jmpConUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
|
||||||
|
match(If cop cmp);
|
||||||
|
effect(USE labl);
|
||||||
|
|
||||||
|
ins_cost(300);
|
||||||
|
format %{ "J$cop,us $labl" %}
|
||||||
|
size(2);
|
||||||
|
opcode(0x70);
|
||||||
|
ins_encode( JccShort( cop, labl) );
|
||||||
|
ins_pipe( pipe_jcc );
|
||||||
|
ins_pc_relative(1);
|
||||||
|
ins_short_branch(1);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
|
||||||
|
match(If cop cmp);
|
||||||
|
effect(USE labl);
|
||||||
|
|
||||||
|
ins_cost(300);
|
||||||
|
format %{ $$template
|
||||||
|
if ($cop$$cmpcode == Assembler::notEqual) {
|
||||||
|
$$emit$$"JP,u,s $labl\n\t"
|
||||||
|
$$emit$$"J$cop,u,s $labl"
|
||||||
|
} else {
|
||||||
|
$$emit$$"JP,u,s done\n\t"
|
||||||
|
$$emit$$"J$cop,u,s $labl\n\t"
|
||||||
|
$$emit$$"done:"
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
size(4);
|
||||||
|
opcode(0x70);
|
||||||
|
ins_encode %{
|
||||||
|
Label* l = $labl$$label;
|
||||||
|
emit_cc(cbuf, $primary, Assembler::parity);
|
||||||
|
int parity_disp = -1;
|
||||||
|
if ($cop$$cmpcode == Assembler::notEqual) {
|
||||||
|
parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
|
||||||
|
} else if ($cop$$cmpcode == Assembler::equal) {
|
||||||
|
parity_disp = 2;
|
||||||
|
} else {
|
||||||
|
ShouldNotReachHere();
|
||||||
|
}
|
||||||
|
emit_d8(cbuf, parity_disp);
|
||||||
|
emit_cc(cbuf, $primary, $cop$$cmpcode);
|
||||||
|
int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
|
||||||
|
emit_d8(cbuf, disp);
|
||||||
|
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
|
||||||
|
assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_jcc);
|
||||||
|
ins_pc_relative(1);
|
||||||
|
ins_short_branch(1);
|
||||||
|
%}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Long Compare
|
// Long Compare
|
||||||
//
|
//
|
||||||
|
@ -2004,9 +2004,12 @@ const uint Matcher::vector_ideal_reg(void) {
|
|||||||
//
|
//
|
||||||
// NOTE: If the platform does not provide any short branch variants, then
|
// NOTE: If the platform does not provide any short branch variants, then
|
||||||
// this method should return false for offset 0.
|
// this method should return false for offset 0.
|
||||||
bool Matcher::is_short_branch_offset(int offset)
|
bool Matcher::is_short_branch_offset(int rule, int offset) {
|
||||||
{
|
// the short version of jmpConUCF2 contains multiple branches,
|
||||||
return -0x80 <= offset && offset < 0x80;
|
// making the reach slightly less
|
||||||
|
if (rule == jmpConUCF2_rule)
|
||||||
|
return (-126 <= offset && offset <= 125);
|
||||||
|
return (-128 <= offset && offset <= 127);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool Matcher::isSimpleConstant64(jlong value) {
|
const bool Matcher::isSimpleConstant64(jlong value) {
|
||||||
@ -3569,7 +3572,7 @@ encode %{
|
|||||||
// at [FETCH], below, will never observe a biased encoding (*101b).
|
// at [FETCH], below, will never observe a biased encoding (*101b).
|
||||||
// If this invariant is not held we'll suffer exclusion (safety) failure.
|
// If this invariant is not held we'll suffer exclusion (safety) failure.
|
||||||
|
|
||||||
if (UseBiasedLocking) {
|
if (UseBiasedLocking && !UseOptoBiasInlining) {
|
||||||
masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters);
|
masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters);
|
||||||
masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH]
|
masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH]
|
||||||
}
|
}
|
||||||
@ -3657,7 +3660,7 @@ encode %{
|
|||||||
} else {
|
} else {
|
||||||
Label DONE_LABEL, Stacked, CheckSucc ;
|
Label DONE_LABEL, Stacked, CheckSucc ;
|
||||||
|
|
||||||
if (UseBiasedLocking) {
|
if (UseBiasedLocking && !UseOptoBiasInlining) {
|
||||||
masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
|
masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5134,6 +5137,15 @@ operand rFlagsRegU()
|
|||||||
interface(REG_INTER);
|
interface(REG_INTER);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
operand rFlagsRegUCF() %{
|
||||||
|
constraint(ALLOC_IN_RC(int_flags));
|
||||||
|
match(RegFlags);
|
||||||
|
predicate(false);
|
||||||
|
|
||||||
|
format %{ "RFLAGS_U_CF" %}
|
||||||
|
interface(REG_INTER);
|
||||||
|
%}
|
||||||
|
|
||||||
// Float register operands
|
// Float register operands
|
||||||
operand regF()
|
operand regF()
|
||||||
%{
|
%{
|
||||||
@ -5405,12 +5417,12 @@ operand cmpOp()
|
|||||||
|
|
||||||
format %{ "" %}
|
format %{ "" %}
|
||||||
interface(COND_INTER) %{
|
interface(COND_INTER) %{
|
||||||
equal(0x4);
|
equal(0x4, "e");
|
||||||
not_equal(0x5);
|
not_equal(0x5, "ne");
|
||||||
less(0xC);
|
less(0xC, "l");
|
||||||
greater_equal(0xD);
|
greater_equal(0xD, "ge");
|
||||||
less_equal(0xE);
|
less_equal(0xE, "le");
|
||||||
greater(0xF);
|
greater(0xF, "g");
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -5423,12 +5435,48 @@ operand cmpOpU()
|
|||||||
|
|
||||||
format %{ "" %}
|
format %{ "" %}
|
||||||
interface(COND_INTER) %{
|
interface(COND_INTER) %{
|
||||||
equal(0x4);
|
equal(0x4, "e");
|
||||||
not_equal(0x5);
|
not_equal(0x5, "ne");
|
||||||
less(0x2);
|
less(0x2, "b");
|
||||||
greater_equal(0x3);
|
greater_equal(0x3, "nb");
|
||||||
less_equal(0x6);
|
less_equal(0x6, "be");
|
||||||
greater(0x7);
|
greater(0x7, "nbe");
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
// Floating comparisons that don't require any fixup for the unordered case
|
||||||
|
operand cmpOpUCF() %{
|
||||||
|
match(Bool);
|
||||||
|
predicate(n->as_Bool()->_test._test == BoolTest::lt ||
|
||||||
|
n->as_Bool()->_test._test == BoolTest::ge ||
|
||||||
|
n->as_Bool()->_test._test == BoolTest::le ||
|
||||||
|
n->as_Bool()->_test._test == BoolTest::gt);
|
||||||
|
format %{ "" %}
|
||||||
|
interface(COND_INTER) %{
|
||||||
|
equal(0x4, "e");
|
||||||
|
not_equal(0x5, "ne");
|
||||||
|
less(0x2, "b");
|
||||||
|
greater_equal(0x3, "nb");
|
||||||
|
less_equal(0x6, "be");
|
||||||
|
greater(0x7, "nbe");
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
// Floating comparisons that can be fixed up with extra conditional jumps
|
||||||
|
operand cmpOpUCF2() %{
|
||||||
|
match(Bool);
|
||||||
|
predicate(n->as_Bool()->_test._test == BoolTest::ne ||
|
||||||
|
n->as_Bool()->_test._test == BoolTest::eq);
|
||||||
|
format %{ "" %}
|
||||||
|
interface(COND_INTER) %{
|
||||||
|
equal(0x4, "e");
|
||||||
|
not_equal(0x5, "ne");
|
||||||
|
less(0x2, "b");
|
||||||
|
greater_equal(0x3, "nb");
|
||||||
|
less_equal(0x6, "be");
|
||||||
|
greater(0x7, "nbe");
|
||||||
%}
|
%}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -7176,8 +7224,7 @@ instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop)
|
|||||||
ins_pipe(pipe_cmov_reg);
|
ins_pipe(pipe_cmov_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct cmovI_regU(rRegI dst, rRegI src, rFlagsRegU cr, cmpOpU cop)
|
instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
|
||||||
%{
|
|
||||||
match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
|
match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
|
||||||
|
|
||||||
ins_cost(200); // XXX
|
ins_cost(200); // XXX
|
||||||
@ -7187,9 +7234,16 @@ instruct cmovI_regU(rRegI dst, rRegI src, rFlagsRegU cr, cmpOpU cop)
|
|||||||
ins_pipe(pipe_cmov_reg);
|
ins_pipe(pipe_cmov_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{
|
||||||
|
match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
|
||||||
|
ins_cost(200);
|
||||||
|
expand %{
|
||||||
|
cmovI_regU(cop, cr, dst, src);
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
// Conditional move
|
// Conditional move
|
||||||
instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src)
|
instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
|
||||||
%{
|
|
||||||
match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
|
match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
|
||||||
|
|
||||||
ins_cost(250); // XXX
|
ins_cost(250); // XXX
|
||||||
@ -7211,6 +7265,14 @@ instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src)
|
|||||||
ins_pipe(pipe_cmov_mem);
|
ins_pipe(pipe_cmov_mem);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
|
||||||
|
match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
|
||||||
|
ins_cost(250);
|
||||||
|
expand %{
|
||||||
|
cmovI_memU(cop, cr, dst, src);
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
// Conditional move
|
// Conditional move
|
||||||
instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
|
instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
|
||||||
%{
|
%{
|
||||||
@ -7224,7 +7286,7 @@ instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
// Conditional move
|
// Conditional move
|
||||||
instruct cmovN_regU(rRegN dst, rRegN src, rFlagsRegU cr, cmpOpU cop)
|
instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src)
|
||||||
%{
|
%{
|
||||||
match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
|
match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
|
||||||
|
|
||||||
@ -7235,6 +7297,14 @@ instruct cmovN_regU(rRegN dst, rRegN src, rFlagsRegU cr, cmpOpU cop)
|
|||||||
ins_pipe(pipe_cmov_reg);
|
ins_pipe(pipe_cmov_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{
|
||||||
|
match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
|
||||||
|
ins_cost(200);
|
||||||
|
expand %{
|
||||||
|
cmovN_regU(cop, cr, dst, src);
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
// Conditional move
|
// Conditional move
|
||||||
instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
|
instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
|
||||||
%{
|
%{
|
||||||
@ -7248,7 +7318,7 @@ instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
// Conditional move
|
// Conditional move
|
||||||
instruct cmovP_regU(rRegP dst, rRegP src, rFlagsRegU cr, cmpOpU cop)
|
instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src)
|
||||||
%{
|
%{
|
||||||
match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
|
match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
|
||||||
|
|
||||||
@ -7259,6 +7329,14 @@ instruct cmovP_regU(rRegP dst, rRegP src, rFlagsRegU cr, cmpOpU cop)
|
|||||||
ins_pipe(pipe_cmov_reg); // XXX
|
ins_pipe(pipe_cmov_reg); // XXX
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{
|
||||||
|
match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
|
||||||
|
ins_cost(200);
|
||||||
|
expand %{
|
||||||
|
cmovP_regU(cop, cr, dst, src);
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
// DISABLED: Requires the ADLC to emit a bottom_type call that
|
// DISABLED: Requires the ADLC to emit a bottom_type call that
|
||||||
// correctly meets the two pointer arguments; one is an incoming
|
// correctly meets the two pointer arguments; one is an incoming
|
||||||
// register but the other is a memory operand. ALSO appears to
|
// register but the other is a memory operand. ALSO appears to
|
||||||
@ -7319,6 +7397,14 @@ instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src)
|
|||||||
ins_pipe(pipe_cmov_reg); // XXX
|
ins_pipe(pipe_cmov_reg); // XXX
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{
|
||||||
|
match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
|
||||||
|
ins_cost(200);
|
||||||
|
expand %{
|
||||||
|
cmovL_regU(cop, cr, dst, src);
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
|
instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
|
||||||
%{
|
%{
|
||||||
match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
|
match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
|
||||||
@ -7330,6 +7416,14 @@ instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
|
|||||||
ins_pipe(pipe_cmov_mem); // XXX
|
ins_pipe(pipe_cmov_mem); // XXX
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
|
||||||
|
match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
|
||||||
|
ins_cost(200);
|
||||||
|
expand %{
|
||||||
|
cmovL_memU(cop, cr, dst, src);
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
|
instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
|
||||||
%{
|
%{
|
||||||
match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
|
match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
|
||||||
@ -7366,6 +7460,14 @@ instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
|
||||||
|
match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
|
||||||
|
ins_cost(200);
|
||||||
|
expand %{
|
||||||
|
cmovF_regU(cop, cr, dst, src);
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
|
instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
|
||||||
%{
|
%{
|
||||||
match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
|
match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
|
||||||
@ -7390,6 +7492,14 @@ instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
|
||||||
|
match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
|
||||||
|
ins_cost(200);
|
||||||
|
expand %{
|
||||||
|
cmovD_regU(cop, cr, dst, src);
|
||||||
|
%}
|
||||||
|
%}
|
||||||
|
|
||||||
//----------Arithmetic Instructions--------------------------------------------
|
//----------Arithmetic Instructions--------------------------------------------
|
||||||
//----------Addition Instructions----------------------------------------------
|
//----------Addition Instructions----------------------------------------------
|
||||||
|
|
||||||
@ -7735,7 +7845,7 @@ instruct storePConditional(memory heap_top_ptr,
|
|||||||
rFlagsReg cr)
|
rFlagsReg cr)
|
||||||
%{
|
%{
|
||||||
match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
|
match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
|
||||||
|
|
||||||
format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
|
format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
|
||||||
"If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
|
"If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
|
||||||
opcode(0x0F, 0xB1);
|
opcode(0x0F, 0xB1);
|
||||||
@ -7746,53 +7856,40 @@ instruct storePConditional(memory heap_top_ptr,
|
|||||||
ins_pipe(pipe_cmpxchg);
|
ins_pipe(pipe_cmpxchg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Conditional-store of a long value
|
// Conditional-store of an int value.
|
||||||
// Returns a boolean value (0/1) on success. Implemented with a
|
// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
|
||||||
// CMPXCHG8 on Intel. mem_ptr can actually be in either RSI or RDI
|
instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr)
|
||||||
|
|
||||||
instruct storeLConditional(rRegI res,
|
|
||||||
memory mem_ptr,
|
|
||||||
rax_RegL oldval, rRegL newval,
|
|
||||||
rFlagsReg cr)
|
|
||||||
%{
|
%{
|
||||||
match(Set res (StoreLConditional mem_ptr (Binary oldval newval)));
|
match(Set cr (StoreIConditional mem (Binary oldval newval)));
|
||||||
effect(KILL cr);
|
effect(KILL oldval);
|
||||||
|
|
||||||
format %{ "cmpxchgq $mem_ptr, $newval\t# (long) "
|
format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
|
||||||
"If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
|
|
||||||
"sete $res\n\t"
|
|
||||||
"movzbl $res, $res" %}
|
|
||||||
opcode(0x0F, 0xB1);
|
opcode(0x0F, 0xB1);
|
||||||
ins_encode(lock_prefix,
|
ins_encode(lock_prefix,
|
||||||
REX_reg_mem_wide(newval, mem_ptr),
|
REX_reg_mem(newval, mem),
|
||||||
OpcP, OpcS,
|
OpcP, OpcS,
|
||||||
reg_mem(newval, mem_ptr),
|
reg_mem(newval, mem));
|
||||||
REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
|
|
||||||
REX_reg_breg(res, res), // movzbl
|
|
||||||
Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
|
|
||||||
ins_pipe(pipe_cmpxchg);
|
ins_pipe(pipe_cmpxchg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Conditional-store of a long value
|
// Conditional-store of a long value.
|
||||||
// ZF flag is set on success, reset otherwise. Implemented with a
|
// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
|
||||||
// CMPXCHG8 on Intel. mem_ptr can actually be in either RSI or RDI
|
instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr)
|
||||||
instruct storeLConditional_flags(memory mem_ptr,
|
|
||||||
rax_RegL oldval, rRegL newval,
|
|
||||||
rFlagsReg cr,
|
|
||||||
immI0 zero)
|
|
||||||
%{
|
%{
|
||||||
match(Set cr (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero));
|
match(Set cr (StoreLConditional mem (Binary oldval newval)));
|
||||||
|
effect(KILL oldval);
|
||||||
|
|
||||||
format %{ "cmpxchgq $mem_ptr, $newval\t# (long) "
|
format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
|
||||||
"If rax == $mem_ptr then store $newval into $mem_ptr" %}
|
|
||||||
opcode(0x0F, 0xB1);
|
opcode(0x0F, 0xB1);
|
||||||
ins_encode(lock_prefix,
|
ins_encode(lock_prefix,
|
||||||
REX_reg_mem_wide(newval, mem_ptr),
|
REX_reg_mem_wide(newval, mem),
|
||||||
OpcP, OpcS,
|
OpcP, OpcS,
|
||||||
reg_mem(newval, mem_ptr));
|
reg_mem(newval, mem));
|
||||||
ins_pipe(pipe_cmpxchg);
|
ins_pipe(pipe_cmpxchg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
|
||||||
instruct compareAndSwapP(rRegI res,
|
instruct compareAndSwapP(rRegI res,
|
||||||
memory mem_ptr,
|
memory mem_ptr,
|
||||||
rax_RegP oldval, rRegP newval,
|
rax_RegP oldval, rRegP newval,
|
||||||
@ -7816,7 +7913,6 @@ instruct compareAndSwapP(rRegI res,
|
|||||||
ins_pipe( pipe_cmpxchg );
|
ins_pipe( pipe_cmpxchg );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
|
|
||||||
instruct compareAndSwapL(rRegI res,
|
instruct compareAndSwapL(rRegI res,
|
||||||
memory mem_ptr,
|
memory mem_ptr,
|
||||||
rax_RegL oldval, rRegL newval,
|
rax_RegL oldval, rRegL newval,
|
||||||
@ -8766,6 +8862,7 @@ instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
|
|||||||
ins_pipe(ialu_reg);
|
ins_pipe(ialu_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
// Logical Shift Right by 8-bit immediate
|
// Logical Shift Right by 8-bit immediate
|
||||||
instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
|
instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
|
||||||
%{
|
%{
|
||||||
@ -9475,6 +9572,18 @@ instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
|
|||||||
ins_pipe(ialu_reg_reg);
|
ins_pipe(ialu_reg_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// Use any_RegP to match R15 (TLS register) without spilling.
|
||||||
|
instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{
|
||||||
|
match(Set dst (OrL dst (CastP2X src)));
|
||||||
|
effect(KILL cr);
|
||||||
|
|
||||||
|
format %{ "orq $dst, $src\t# long" %}
|
||||||
|
opcode(0x0B);
|
||||||
|
ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
// Or Register with Immediate
|
// Or Register with Immediate
|
||||||
instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
|
instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
|
||||||
%{
|
%{
|
||||||
@ -9716,6 +9825,17 @@ instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
|
||||||
|
match(Set cr (CmpF src1 src2));
|
||||||
|
|
||||||
|
ins_cost(145);
|
||||||
|
format %{ "ucomiss $src1, $src2" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
|
instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
|
||||||
%{
|
%{
|
||||||
match(Set cr (CmpF src1 (LoadF src2)));
|
match(Set cr (CmpF src1 (LoadF src2)));
|
||||||
@ -9733,6 +9853,16 @@ instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
|
||||||
|
match(Set cr (CmpF src1 (LoadF src2)));
|
||||||
|
|
||||||
|
ins_cost(100);
|
||||||
|
format %{ "ucomiss $src1, $src2" %}
|
||||||
|
opcode(0x0F, 0x2E);
|
||||||
|
ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2));
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2)
|
instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2)
|
||||||
%{
|
%{
|
||||||
match(Set cr (CmpF src1 src2));
|
match(Set cr (CmpF src1 src2));
|
||||||
@ -9750,6 +9880,16 @@ instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src1, immF src2) %{
|
||||||
|
match(Set cr (CmpF src1 src2));
|
||||||
|
|
||||||
|
ins_cost(100);
|
||||||
|
format %{ "ucomiss $src1, $src2" %}
|
||||||
|
opcode(0x0F, 0x2E);
|
||||||
|
ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2));
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
|
instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
|
||||||
%{
|
%{
|
||||||
match(Set cr (CmpD src1 src2));
|
match(Set cr (CmpD src1 src2));
|
||||||
@ -9767,6 +9907,17 @@ instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
|
||||||
|
match(Set cr (CmpD src1 src2));
|
||||||
|
|
||||||
|
ins_cost(100);
|
||||||
|
format %{ "ucomisd $src1, $src2 test" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
|
instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
|
||||||
%{
|
%{
|
||||||
match(Set cr (CmpD src1 (LoadD src2)));
|
match(Set cr (CmpD src1 (LoadD src2)));
|
||||||
@ -9784,6 +9935,16 @@ instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
|
||||||
|
match(Set cr (CmpD src1 (LoadD src2)));
|
||||||
|
|
||||||
|
ins_cost(100);
|
||||||
|
format %{ "ucomisd $src1, $src2" %}
|
||||||
|
opcode(0x66, 0x0F, 0x2E);
|
||||||
|
ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2));
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2)
|
instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2)
|
||||||
%{
|
%{
|
||||||
match(Set cr (CmpD src1 src2));
|
match(Set cr (CmpD src1 src2));
|
||||||
@ -9801,6 +9962,16 @@ instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src1, immD src2) %{
|
||||||
|
match(Set cr (CmpD src1 src2));
|
||||||
|
|
||||||
|
ins_cost(100);
|
||||||
|
format %{ "ucomisd $src1, [$src2]" %}
|
||||||
|
opcode(0x66, 0x0F, 0x2E);
|
||||||
|
ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2));
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
// Compare into -1,0,1
|
// Compare into -1,0,1
|
||||||
instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
|
instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
|
||||||
%{
|
%{
|
||||||
@ -11406,8 +11577,7 @@ instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl)
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
// Jump Direct Conditional - Label defines a relative address from Jcc+1
|
// Jump Direct Conditional - Label defines a relative address from Jcc+1
|
||||||
instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl)
|
instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
|
||||||
%{
|
|
||||||
match(CountedLoopEnd cop cmp);
|
match(CountedLoopEnd cop cmp);
|
||||||
effect(USE labl);
|
effect(USE labl);
|
||||||
|
|
||||||
@ -11420,14 +11590,26 @@ instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl)
|
|||||||
ins_pc_relative(1);
|
ins_pc_relative(1);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
|
||||||
|
match(CountedLoopEnd cop cmp);
|
||||||
|
effect(USE labl);
|
||||||
|
|
||||||
|
ins_cost(200);
|
||||||
|
format %{ "j$cop,u $labl\t# loop end" %}
|
||||||
|
size(6);
|
||||||
|
opcode(0x0F, 0x80);
|
||||||
|
ins_encode(Jcc(cop, labl));
|
||||||
|
ins_pipe(pipe_jcc);
|
||||||
|
ins_pc_relative(1);
|
||||||
|
%}
|
||||||
|
|
||||||
// Jump Direct Conditional - using unsigned comparison
|
// Jump Direct Conditional - using unsigned comparison
|
||||||
instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl)
|
instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
|
||||||
%{
|
|
||||||
match(If cop cmp);
|
match(If cop cmp);
|
||||||
effect(USE labl);
|
effect(USE labl);
|
||||||
|
|
||||||
ins_cost(300);
|
ins_cost(300);
|
||||||
format %{ "j$cop,u $labl" %}
|
format %{ "j$cop,u $labl" %}
|
||||||
size(6);
|
size(6);
|
||||||
opcode(0x0F, 0x80);
|
opcode(0x0F, 0x80);
|
||||||
ins_encode(Jcc(cop, labl));
|
ins_encode(Jcc(cop, labl));
|
||||||
@ -11435,6 +11617,59 @@ instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl)
|
|||||||
ins_pc_relative(1);
|
ins_pc_relative(1);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
|
||||||
|
match(If cop cmp);
|
||||||
|
effect(USE labl);
|
||||||
|
|
||||||
|
ins_cost(200);
|
||||||
|
format %{ "j$cop,u $labl" %}
|
||||||
|
size(6);
|
||||||
|
opcode(0x0F, 0x80);
|
||||||
|
ins_encode(Jcc(cop, labl));
|
||||||
|
ins_pipe(pipe_jcc);
|
||||||
|
ins_pc_relative(1);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
|
||||||
|
match(If cop cmp);
|
||||||
|
effect(USE labl);
|
||||||
|
|
||||||
|
ins_cost(200);
|
||||||
|
format %{ $$template
|
||||||
|
if ($cop$$cmpcode == Assembler::notEqual) {
|
||||||
|
$$emit$$"jp,u $labl\n\t"
|
||||||
|
$$emit$$"j$cop,u $labl"
|
||||||
|
} else {
|
||||||
|
$$emit$$"jp,u done\n\t"
|
||||||
|
$$emit$$"j$cop,u $labl\n\t"
|
||||||
|
$$emit$$"done:"
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
size(12);
|
||||||
|
opcode(0x0F, 0x80);
|
||||||
|
ins_encode %{
|
||||||
|
Label* l = $labl$$label;
|
||||||
|
$$$emit8$primary;
|
||||||
|
emit_cc(cbuf, $secondary, Assembler::parity);
|
||||||
|
int parity_disp = -1;
|
||||||
|
if ($cop$$cmpcode == Assembler::notEqual) {
|
||||||
|
// the two jumps 6 bytes apart so the jump distances are too
|
||||||
|
parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
|
||||||
|
} else if ($cop$$cmpcode == Assembler::equal) {
|
||||||
|
parity_disp = 6;
|
||||||
|
} else {
|
||||||
|
ShouldNotReachHere();
|
||||||
|
}
|
||||||
|
emit_d32(cbuf, parity_disp);
|
||||||
|
$$$emit8$primary;
|
||||||
|
emit_cc(cbuf, $secondary, $cop$$cmpcode);
|
||||||
|
int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
|
||||||
|
emit_d32(cbuf, disp);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_jcc);
|
||||||
|
ins_pc_relative(1);
|
||||||
|
%}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary
|
// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary
|
||||||
// superklass array for an instance of the superklass. Set a hidden
|
// superklass array for an instance of the superklass. Set a hidden
|
||||||
@ -11505,8 +11740,7 @@ instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr,
|
|||||||
// specific code section of the file.
|
// specific code section of the file.
|
||||||
|
|
||||||
// Jump Direct - Label defines a relative address from JMP+1
|
// Jump Direct - Label defines a relative address from JMP+1
|
||||||
instruct jmpDir_short(label labl)
|
instruct jmpDir_short(label labl) %{
|
||||||
%{
|
|
||||||
match(Goto);
|
match(Goto);
|
||||||
effect(USE labl);
|
effect(USE labl);
|
||||||
|
|
||||||
@ -11521,8 +11755,7 @@ instruct jmpDir_short(label labl)
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
// Jump Direct Conditional - Label defines a relative address from Jcc+1
|
// Jump Direct Conditional - Label defines a relative address from Jcc+1
|
||||||
instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl)
|
instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
|
||||||
%{
|
|
||||||
match(If cop cr);
|
match(If cop cr);
|
||||||
effect(USE labl);
|
effect(USE labl);
|
||||||
|
|
||||||
@ -11537,13 +11770,12 @@ instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl)
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
// Jump Direct Conditional - Label defines a relative address from Jcc+1
|
// Jump Direct Conditional - Label defines a relative address from Jcc+1
|
||||||
instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl)
|
instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
|
||||||
%{
|
|
||||||
match(CountedLoopEnd cop cr);
|
match(CountedLoopEnd cop cr);
|
||||||
effect(USE labl);
|
effect(USE labl);
|
||||||
|
|
||||||
ins_cost(300);
|
ins_cost(300);
|
||||||
format %{ "j$cop,s $labl" %}
|
format %{ "j$cop,s $labl\t# loop end" %}
|
||||||
size(2);
|
size(2);
|
||||||
opcode(0x70);
|
opcode(0x70);
|
||||||
ins_encode(JccShort(cop, labl));
|
ins_encode(JccShort(cop, labl));
|
||||||
@ -11553,11 +11785,39 @@ instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl)
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
// Jump Direct Conditional - Label defines a relative address from Jcc+1
|
// Jump Direct Conditional - Label defines a relative address from Jcc+1
|
||||||
instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl)
|
instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
|
||||||
%{
|
|
||||||
match(CountedLoopEnd cop cmp);
|
match(CountedLoopEnd cop cmp);
|
||||||
effect(USE labl);
|
effect(USE labl);
|
||||||
|
|
||||||
|
ins_cost(300);
|
||||||
|
format %{ "j$cop,us $labl\t# loop end" %}
|
||||||
|
size(2);
|
||||||
|
opcode(0x70);
|
||||||
|
ins_encode(JccShort(cop, labl));
|
||||||
|
ins_pipe(pipe_jcc);
|
||||||
|
ins_pc_relative(1);
|
||||||
|
ins_short_branch(1);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
|
||||||
|
match(CountedLoopEnd cop cmp);
|
||||||
|
effect(USE labl);
|
||||||
|
|
||||||
|
ins_cost(300);
|
||||||
|
format %{ "j$cop,us $labl\t# loop end" %}
|
||||||
|
size(2);
|
||||||
|
opcode(0x70);
|
||||||
|
ins_encode(JccShort(cop, labl));
|
||||||
|
ins_pipe(pipe_jcc);
|
||||||
|
ins_pc_relative(1);
|
||||||
|
ins_short_branch(1);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Jump Direct Conditional - using unsigned comparison
|
||||||
|
instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
|
||||||
|
match(If cop cmp);
|
||||||
|
effect(USE labl);
|
||||||
|
|
||||||
ins_cost(300);
|
ins_cost(300);
|
||||||
format %{ "j$cop,us $labl" %}
|
format %{ "j$cop,us $labl" %}
|
||||||
size(2);
|
size(2);
|
||||||
@ -11568,9 +11828,7 @@ instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl)
|
|||||||
ins_short_branch(1);
|
ins_short_branch(1);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Jump Direct Conditional - using unsigned comparison
|
instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
|
||||||
instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl)
|
|
||||||
%{
|
|
||||||
match(If cop cmp);
|
match(If cop cmp);
|
||||||
effect(USE labl);
|
effect(USE labl);
|
||||||
|
|
||||||
@ -11584,6 +11842,46 @@ instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl)
|
|||||||
ins_short_branch(1);
|
ins_short_branch(1);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
|
||||||
|
match(If cop cmp);
|
||||||
|
effect(USE labl);
|
||||||
|
|
||||||
|
ins_cost(300);
|
||||||
|
format %{ $$template
|
||||||
|
if ($cop$$cmpcode == Assembler::notEqual) {
|
||||||
|
$$emit$$"jp,u,s $labl\n\t"
|
||||||
|
$$emit$$"j$cop,u,s $labl"
|
||||||
|
} else {
|
||||||
|
$$emit$$"jp,u,s done\n\t"
|
||||||
|
$$emit$$"j$cop,u,s $labl\n\t"
|
||||||
|
$$emit$$"done:"
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
size(4);
|
||||||
|
opcode(0x70);
|
||||||
|
ins_encode %{
|
||||||
|
Label* l = $labl$$label;
|
||||||
|
emit_cc(cbuf, $primary, Assembler::parity);
|
||||||
|
int parity_disp = -1;
|
||||||
|
if ($cop$$cmpcode == Assembler::notEqual) {
|
||||||
|
parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
|
||||||
|
} else if ($cop$$cmpcode == Assembler::equal) {
|
||||||
|
parity_disp = 2;
|
||||||
|
} else {
|
||||||
|
ShouldNotReachHere();
|
||||||
|
}
|
||||||
|
emit_d8(cbuf, parity_disp);
|
||||||
|
emit_cc(cbuf, $primary, $cop$$cmpcode);
|
||||||
|
int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
|
||||||
|
emit_d8(cbuf, disp);
|
||||||
|
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
|
||||||
|
assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_jcc);
|
||||||
|
ins_pc_relative(1);
|
||||||
|
ins_short_branch(1);
|
||||||
|
%}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// inlined locking and unlocking
|
// inlined locking and unlocking
|
||||||
|
|
||||||
|
@ -103,16 +103,16 @@ encode %{
|
|||||||
// This name is KNOWN by the ADLC and cannot be changed.
|
// This name is KNOWN by the ADLC and cannot be changed.
|
||||||
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
|
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
|
||||||
// for this guy.
|
// for this guy.
|
||||||
instruct tlsLoadP(eAXRegP dst, eFlagsReg cr) %{
|
instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
|
||||||
match(Set dst (ThreadLocal));
|
match(Set dst (ThreadLocal));
|
||||||
effect(DEF dst, KILL cr);
|
effect(DEF dst, KILL cr);
|
||||||
|
|
||||||
format %{ "MOV EAX, Thread::current()" %}
|
format %{ "MOV $dst, Thread::current()" %}
|
||||||
ins_encode( linux_tlsencode(dst) );
|
ins_encode( linux_tlsencode(dst) );
|
||||||
ins_pipe( ialu_reg_fat );
|
ins_pipe( ialu_reg_fat );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct TLS(eAXRegP dst) %{
|
instruct TLS(eRegP dst) %{
|
||||||
match(Set dst (ThreadLocal));
|
match(Set dst (ThreadLocal));
|
||||||
|
|
||||||
expand %{
|
expand %{
|
||||||
|
@ -110,16 +110,16 @@ encode %{
|
|||||||
// This name is KNOWN by the ADLC and cannot be changed.
|
// This name is KNOWN by the ADLC and cannot be changed.
|
||||||
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
|
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
|
||||||
// for this guy.
|
// for this guy.
|
||||||
instruct tlsLoadP(eAXRegP dst, eFlagsReg cr) %{
|
instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
|
||||||
match(Set dst (ThreadLocal));
|
match(Set dst (ThreadLocal));
|
||||||
effect(DEF dst, KILL cr);
|
effect(DEF dst, KILL cr);
|
||||||
|
|
||||||
format %{ "MOV EAX, Thread::current()" %}
|
format %{ "MOV $dst, Thread::current()" %}
|
||||||
ins_encode( solaris_tlsencode(dst) );
|
ins_encode( solaris_tlsencode(dst) );
|
||||||
ins_pipe( ialu_reg_fat );
|
ins_pipe( ialu_reg_fat );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct TLS(eAXRegP dst) %{
|
instruct TLS(eRegP dst) %{
|
||||||
match(Set dst (ThreadLocal));
|
match(Set dst (ThreadLocal));
|
||||||
|
|
||||||
expand %{
|
expand %{
|
||||||
|
@ -28,6 +28,7 @@ import com.sun.hotspot.igv.data.InputGraph;
|
|||||||
import com.sun.hotspot.igv.data.services.InputGraphProvider;
|
import com.sun.hotspot.igv.data.services.InputGraphProvider;
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import org.openide.ErrorManager;
|
import org.openide.ErrorManager;
|
||||||
import org.openide.explorer.ExplorerManager;
|
import org.openide.explorer.ExplorerManager;
|
||||||
import org.openide.explorer.ExplorerUtils;
|
import org.openide.explorer.ExplorerUtils;
|
||||||
@ -151,14 +152,18 @@ final class BytecodeViewTopComponent extends TopComponent implements ExplorerMan
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void resultChanged(LookupEvent lookupEvent) {
|
public void resultChanged(LookupEvent lookupEvent) {
|
||||||
InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
|
final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
InputGraph graph = p.getGraph();
|
InputGraph graph = p.getGraph();
|
||||||
if (graph != null) {
|
if (graph != null) {
|
||||||
Group g = graph.getGroup();
|
Group g = graph.getGroup();
|
||||||
rootNode.update(graph, g.getMethod());
|
rootNode.update(graph, g.getMethod());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final static class ResolvableHelper implements Serializable {
|
final static class ResolvableHelper implements Serializable {
|
||||||
|
@ -33,7 +33,7 @@ import java.awt.Point;
|
|||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Hashtable;
|
import java.util.HashMap;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import org.netbeans.api.visual.action.ActionFactory;
|
import org.netbeans.api.visual.action.ActionFactory;
|
||||||
@ -44,7 +44,6 @@ import org.netbeans.api.visual.action.SelectProvider;
|
|||||||
import org.netbeans.api.visual.action.WidgetAction;
|
import org.netbeans.api.visual.action.WidgetAction;
|
||||||
import org.netbeans.api.visual.anchor.AnchorFactory;
|
import org.netbeans.api.visual.anchor.AnchorFactory;
|
||||||
import org.netbeans.api.visual.anchor.AnchorShape;
|
import org.netbeans.api.visual.anchor.AnchorShape;
|
||||||
import com.sun.hotspot.igv.controlflow.HierarchicalGraphLayout;
|
|
||||||
import org.netbeans.api.visual.layout.LayoutFactory;
|
import org.netbeans.api.visual.layout.LayoutFactory;
|
||||||
import org.netbeans.api.visual.router.RouterFactory;
|
import org.netbeans.api.visual.router.RouterFactory;
|
||||||
import org.netbeans.api.visual.widget.LayerWidget;
|
import org.netbeans.api.visual.widget.LayerWidget;
|
||||||
@ -61,8 +60,8 @@ import org.openide.util.Lookup;
|
|||||||
*/
|
*/
|
||||||
public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> implements SelectProvider, MoveProvider, RectangularSelectDecorator, RectangularSelectProvider {
|
public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> implements SelectProvider, MoveProvider, RectangularSelectDecorator, RectangularSelectProvider {
|
||||||
|
|
||||||
private Set<BlockWidget> selection;
|
private HashSet<BlockWidget> selection;
|
||||||
private Hashtable<InputBlock, BlockWidget> blockMap;
|
private HashMap<InputBlock, BlockWidget> blockMap;
|
||||||
private InputGraph oldGraph;
|
private InputGraph oldGraph;
|
||||||
private LayerWidget edgeLayer;
|
private LayerWidget edgeLayer;
|
||||||
private LayerWidget mainLayer;
|
private LayerWidget mainLayer;
|
||||||
|
@ -28,6 +28,7 @@ import com.sun.hotspot.igv.data.services.InputGraphProvider;
|
|||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import org.openide.ErrorManager;
|
import org.openide.ErrorManager;
|
||||||
import org.openide.util.Lookup;
|
import org.openide.util.Lookup;
|
||||||
import org.openide.util.LookupEvent;
|
import org.openide.util.LookupEvent;
|
||||||
@ -143,13 +144,17 @@ final class ControlFlowTopComponent extends TopComponent implements LookupListen
|
|||||||
|
|
||||||
public void resultChanged(LookupEvent lookupEvent) {
|
public void resultChanged(LookupEvent lookupEvent) {
|
||||||
|
|
||||||
InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
|
final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
InputGraph g = p.getGraph();
|
InputGraph g = p.getGraph();
|
||||||
if (g != null) {
|
if (g != null) {
|
||||||
scene.setGraph(g);
|
scene.setGraph(g);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
package com.sun.hotspot.igv.coordinator;
|
package com.sun.hotspot.igv.coordinator;
|
||||||
|
|
||||||
import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
|
import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
|
||||||
|
import com.sun.hotspot.igv.data.ChangedListener;
|
||||||
import com.sun.hotspot.igv.data.Group;
|
import com.sun.hotspot.igv.data.Group;
|
||||||
import com.sun.hotspot.igv.data.services.GroupOrganizer;
|
import com.sun.hotspot.igv.data.services.GroupOrganizer;
|
||||||
import com.sun.hotspot.igv.data.InputGraph;
|
import com.sun.hotspot.igv.data.InputGraph;
|
||||||
@ -50,17 +51,24 @@ public class FolderNode extends AbstractNode {
|
|||||||
private List<String> subFolders;
|
private List<String> subFolders;
|
||||||
private FolderChildren children;
|
private FolderChildren children;
|
||||||
|
|
||||||
private static class FolderChildren extends Children.Keys {
|
private static class FolderChildren extends Children.Keys implements ChangedListener<Group> {
|
||||||
|
|
||||||
private FolderNode parent;
|
private FolderNode parent;
|
||||||
|
private List<Group> registeredGroups;
|
||||||
|
|
||||||
public void setParent(FolderNode parent) {
|
public void setParent(FolderNode parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
this.registeredGroups = new ArrayList<Group>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Node[] createNodes(Object arg0) {
|
protected Node[] createNodes(Object arg0) {
|
||||||
|
|
||||||
|
for(Group g : registeredGroups) {
|
||||||
|
g.getChangedEvent().removeListener(this);
|
||||||
|
}
|
||||||
|
registeredGroups.clear();
|
||||||
|
|
||||||
Pair<String, List<Group>> p = (Pair<String, List<Group>>) arg0;
|
Pair<String, List<Group>> p = (Pair<String, List<Group>>) arg0;
|
||||||
if (p.getLeft().length() == 0) {
|
if (p.getLeft().length() == 0) {
|
||||||
|
|
||||||
@ -69,6 +77,8 @@ public class FolderNode extends AbstractNode {
|
|||||||
for (InputGraph graph : g.getGraphs()) {
|
for (InputGraph graph : g.getGraphs()) {
|
||||||
curNodes.add(new GraphNode(graph));
|
curNodes.add(new GraphNode(graph));
|
||||||
}
|
}
|
||||||
|
g.getChangedEvent().addListener(this);
|
||||||
|
registeredGroups.add(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node[] result = new Node[curNodes.size()];
|
Node[] result = new Node[curNodes.size()];
|
||||||
@ -85,7 +95,13 @@ public class FolderNode extends AbstractNode {
|
|||||||
@Override
|
@Override
|
||||||
public void addNotify() {
|
public void addNotify() {
|
||||||
this.setKeys(parent.structure);
|
this.setKeys(parent.structure);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changed(Group source) {
|
||||||
|
List<Pair<String, List<Group>>> newStructure = new ArrayList<Pair<String, List<Group>>>();
|
||||||
|
for(Pair<String, List<Group>> p : parent.structure) {
|
||||||
|
refreshKey(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ import java.util.List;
|
|||||||
*
|
*
|
||||||
* @author Thomas Wuerthinger
|
* @author Thomas Wuerthinger
|
||||||
*/
|
*/
|
||||||
public class GraphDocument extends Properties.Object implements ChangedEventProvider<GraphDocument> {
|
public class GraphDocument extends Properties.Entity implements ChangedEventProvider<GraphDocument> {
|
||||||
|
|
||||||
private List<Group> groups;
|
private List<Group> groups;
|
||||||
private ChangedEvent<GraphDocument> changedEvent;
|
private ChangedEvent<GraphDocument> changedEvent;
|
||||||
|
@ -37,7 +37,7 @@ import java.util.Set;
|
|||||||
*
|
*
|
||||||
* @author Thomas Wuerthinger
|
* @author Thomas Wuerthinger
|
||||||
*/
|
*/
|
||||||
public class Group extends Properties.Object implements ChangedEventProvider<Group> {
|
public class Group extends Properties.Entity implements ChangedEventProvider<Group> {
|
||||||
|
|
||||||
private List<InputGraph> graphs;
|
private List<InputGraph> graphs;
|
||||||
private transient ChangedEvent<Group> changedEvent;
|
private transient ChangedEvent<Group> changedEvent;
|
||||||
|
@ -23,26 +23,25 @@
|
|||||||
*/
|
*/
|
||||||
package com.sun.hotspot.igv.data;
|
package com.sun.hotspot.igv.data;
|
||||||
|
|
||||||
import com.sun.hotspot.igv.data.Properties;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Hashtable;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Thomas Wuerthinger
|
* @author Thomas Wuerthinger
|
||||||
*/
|
*/
|
||||||
public class InputGraph extends Properties.Object {
|
public class InputGraph extends Properties.Entity {
|
||||||
|
|
||||||
private Map<Integer, InputNode> nodes;
|
private HashMap<Integer, InputNode> nodes;
|
||||||
private Set<InputEdge> edges;
|
private ArrayList<InputEdge> edges;
|
||||||
private Group parent;
|
private Group parent;
|
||||||
private Map<String, InputBlock> blocks;
|
private HashMap<String, InputBlock> blocks;
|
||||||
private Map<Integer, InputBlock> nodeToBlock;
|
private HashMap<Integer, InputBlock> nodeToBlock;
|
||||||
private boolean isDifferenceGraph;
|
private boolean isDifferenceGraph;
|
||||||
|
|
||||||
public InputGraph(Group parent) {
|
public InputGraph(Group parent) {
|
||||||
@ -61,10 +60,10 @@ public class InputGraph extends Properties.Object {
|
|||||||
public InputGraph(Group parent, InputGraph last, String name) {
|
public InputGraph(Group parent, InputGraph last, String name) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
setName(name);
|
setName(name);
|
||||||
nodes = new Hashtable<Integer, InputNode>();
|
nodes = new HashMap<Integer, InputNode>();
|
||||||
edges = new HashSet<InputEdge>();
|
edges = new ArrayList<InputEdge>();
|
||||||
blocks = new Hashtable<String, InputBlock>();
|
blocks = new HashMap<String, InputBlock>();
|
||||||
nodeToBlock = new Hashtable<Integer, InputBlock>();
|
nodeToBlock = new HashMap<Integer, InputBlock>();
|
||||||
if (last != null) {
|
if (last != null) {
|
||||||
|
|
||||||
for (InputNode n : last.getNodes()) {
|
for (InputNode n : last.getNodes()) {
|
||||||
@ -182,8 +181,8 @@ public class InputGraph extends Properties.Object {
|
|||||||
return nodes.remove(index);
|
return nodes.remove(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<InputEdge> getEdges() {
|
public Collection<InputEdge> getEdges() {
|
||||||
return Collections.unmodifiableSet(edges);
|
return Collections.unmodifiableList(edges);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeEdge(InputEdge c) {
|
public void removeEdge(InputEdge c) {
|
||||||
|
@ -32,7 +32,7 @@ import java.util.List;
|
|||||||
*
|
*
|
||||||
* @author Thomas Wuerthinger
|
* @author Thomas Wuerthinger
|
||||||
*/
|
*/
|
||||||
public class InputMethod extends Properties.Object {
|
public class InputMethod extends Properties.Entity {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private int bci;
|
private int bci;
|
||||||
|
@ -27,7 +27,7 @@ package com.sun.hotspot.igv.data;
|
|||||||
*
|
*
|
||||||
* @author Thomas Wuerthinger
|
* @author Thomas Wuerthinger
|
||||||
*/
|
*/
|
||||||
public class InputNode extends Properties.Object {
|
public class InputNode extends Properties.Entity {
|
||||||
|
|
||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
|
@ -26,24 +26,22 @@ package com.sun.hotspot.igv.data;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Iterator;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Thomas Wuerthinger
|
* @author Thomas Wuerthinger
|
||||||
*/
|
*/
|
||||||
public class Properties implements Serializable {
|
public class Properties implements Serializable, Iterable<Property> {
|
||||||
|
|
||||||
public static final long serialVersionUID = 1L;
|
public static final long serialVersionUID = 1L;
|
||||||
private Map<String, Property> map;
|
private String[] map = new String[4];
|
||||||
|
|
||||||
public Properties() {
|
public Properties() {
|
||||||
map = new HashMap<String, Property>(5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -54,10 +52,7 @@ public class Properties implements Serializable {
|
|||||||
|
|
||||||
Properties p = (Properties) o;
|
Properties p = (Properties) o;
|
||||||
|
|
||||||
if (getProperties().size() != p.getProperties().size()) {
|
for (Property prop : this) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (Property prop : getProperties()) {
|
|
||||||
String value = p.get(prop.getName());
|
String value = p.get(prop.getName());
|
||||||
if (value == null || !value.equals(prop.getValue())) {
|
if (value == null || !value.equals(prop.getValue())) {
|
||||||
return false;
|
return false;
|
||||||
@ -75,32 +70,33 @@ public class Properties implements Serializable {
|
|||||||
|
|
||||||
public Properties(String name, String value) {
|
public Properties(String name, String value) {
|
||||||
this();
|
this();
|
||||||
this.add(new Property(name, value));
|
this.setProperty(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Properties(String name, String value, String name1, String value1) {
|
public Properties(String name, String value, String name1, String value1) {
|
||||||
this(name, value);
|
this(name, value);
|
||||||
this.add(new Property(name1, value1));
|
this.setProperty(name1, value1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Properties(String name, String value, String name1, String value1, String name2, String value2) {
|
public Properties(String name, String value, String name1, String value1, String name2, String value2) {
|
||||||
this(name, value, name1, value1);
|
this(name, value, name1, value1);
|
||||||
this.add(new Property(name2, value2));
|
this.setProperty(name2, value2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Properties(Properties p) {
|
public Properties(Properties p) {
|
||||||
map = new HashMap<String, Property>(p.map);
|
map = new String[p.map.length];
|
||||||
|
System.arraycopy(map, 0, p.map, 0, p.map.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Object implements Provider {
|
public static class Entity implements Provider {
|
||||||
|
|
||||||
private Properties properties;
|
private Properties properties;
|
||||||
|
|
||||||
public Object() {
|
public Entity() {
|
||||||
properties = new Properties();
|
properties = new Properties();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object(Properties.Object object) {
|
public Entity(Properties.Entity object) {
|
||||||
properties = new Properties(object.getProperties());
|
properties = new Properties(object.getProperties());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +105,14 @@ public class Properties implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getProperty(String key) {
|
||||||
|
for (int i = 0; i < map.length; i += 2)
|
||||||
|
if (map[i] != null && map[i].equals(key)) {
|
||||||
|
return map[i + 1];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public interface PropertyMatcher {
|
public interface PropertyMatcher {
|
||||||
|
|
||||||
String getName();
|
String getName();
|
||||||
@ -173,13 +177,15 @@ public class Properties implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Property selectSingle(PropertyMatcher matcher) {
|
public Property selectSingle(PropertyMatcher matcher) {
|
||||||
|
String value = null;
|
||||||
Property p = this.map.get(matcher.getName());
|
for (int i = 0; i < map.length; i += 2) {
|
||||||
if (p == null) {
|
if (map[i] != null && matcher.getName().equals(map[i])) {
|
||||||
return null;
|
value = map[i + 1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (matcher.match(p.getValue())) {
|
if (value != null && matcher.match(value)) {
|
||||||
return p;
|
return new Property(matcher.getName(), value);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -194,8 +200,11 @@ public class Properties implements Serializable {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("[");
|
sb.append("[");
|
||||||
for (Property p : map.values()) {
|
for (int i = 0; i < map.length; i += 2) {
|
||||||
sb.append(p.toString());
|
if (map[i + 1] != null) {
|
||||||
|
String p = map[i + 1];
|
||||||
|
sb.append(map[i] + " = " + map[i + 1] + "; ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return sb.append("]").toString();
|
return sb.append("]").toString();
|
||||||
}
|
}
|
||||||
@ -241,41 +250,51 @@ public class Properties implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String get(String key) {
|
public String get(String key) {
|
||||||
Property p = map.get(key);
|
for (int i = 0; i < map.length; i += 2) {
|
||||||
if (p == null) {
|
if (map[i] != null && map[i].equals(key)) {
|
||||||
return null;
|
return map[i + 1];
|
||||||
} else {
|
|
||||||
return p.getValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProperty(String string) {
|
|
||||||
return get(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Property setProperty(String name, String value) {
|
|
||||||
|
|
||||||
if (value == null) {
|
|
||||||
// remove this property
|
|
||||||
return map.remove(name);
|
|
||||||
} else {
|
|
||||||
Property p = map.get(name);
|
|
||||||
if (p == null) {
|
|
||||||
p = new Property(name, value);
|
|
||||||
map.put(name, p);
|
|
||||||
} else {
|
|
||||||
p.setValue(value);
|
|
||||||
}
|
}
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Property> getProperties() {
|
public void setProperty(String name, String value) {
|
||||||
return Collections.unmodifiableCollection(map.values());
|
for (int i = 0; i < map.length; i += 2) {
|
||||||
|
if (map[i] != null && map[i].equals(name)) {
|
||||||
|
String p = map[i + 1];
|
||||||
|
if (value == null) {
|
||||||
|
// remove this property
|
||||||
|
map[i] = null;
|
||||||
|
map[i + 1] = null;
|
||||||
|
} else {
|
||||||
|
map[i + 1] = value;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < map.length; i += 2) {
|
||||||
|
if (map[i] == null) {
|
||||||
|
map[i] = name;
|
||||||
|
map[i + 1] = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String[] newMap = new String[map.length + 4];
|
||||||
|
System.arraycopy(map, 0, newMap, 0, map.length);
|
||||||
|
newMap[map.length] = name;
|
||||||
|
newMap[map.length + 1] = value;
|
||||||
|
map = newMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<Property> getProperties() {
|
||||||
|
return iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(Properties properties) {
|
public void add(Properties properties) {
|
||||||
for (Property p : properties.getProperties()) {
|
for (Property p : properties) {
|
||||||
add(p);
|
add(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,6 +302,35 @@ public class Properties implements Serializable {
|
|||||||
public void add(Property property) {
|
public void add(Property property) {
|
||||||
assert property.getName() != null;
|
assert property.getName() != null;
|
||||||
assert property.getValue() != null;
|
assert property.getValue() != null;
|
||||||
map.put(property.getName(), property);
|
setProperty(property.getName(), property.getValue());
|
||||||
|
}
|
||||||
|
class PropertiesIterator implements Iterator<Property>, Iterable<Property> {
|
||||||
|
public Iterator<Property> iterator() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index;
|
||||||
|
|
||||||
|
public boolean hasNext() {
|
||||||
|
while (index < map.length && map[index + 1] == null)
|
||||||
|
index += 2;
|
||||||
|
return index < map.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Property next() {
|
||||||
|
if (index < map.length) {
|
||||||
|
index += 2;
|
||||||
|
return new Property(map[index - 2], map[index - 1]);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove() {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public Iterator<Property> iterator() {
|
||||||
|
return new PropertiesIterator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,18 +32,19 @@ import java.io.Serializable;
|
|||||||
public class Property implements Serializable {
|
public class Property implements Serializable {
|
||||||
|
|
||||||
public static final long serialVersionUID = 1L;
|
public static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
public Property() {
|
private Property() {
|
||||||
this(null, null);
|
this(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Property(Property p) {
|
private Property(Property p) {
|
||||||
this(p.getName(), p.getValue());
|
this(p.getName(), p.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Property(String name) {
|
private Property(String name) {
|
||||||
this(name, null);
|
this(name, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,16 +61,19 @@ public class Property implements Serializable {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String s) {
|
|
||||||
this.name = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String s) {
|
|
||||||
this.value = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name + " = " + value + "; ";
|
return name + " = " + value + "; ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof Property)) return false;
|
||||||
|
Property p2 = (Property)o;
|
||||||
|
return name.equals(p2.name) && value.equals(p2.value);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return name.hashCode() + value == null ? 0 : value.hashCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ import com.sun.hotspot.igv.data.serialization.XMLParser.HandoverElementHandler;
|
|||||||
import com.sun.hotspot.igv.data.serialization.XMLParser.ParseMonitor;
|
import com.sun.hotspot.igv.data.serialization.XMLParser.ParseMonitor;
|
||||||
import com.sun.hotspot.igv.data.serialization.XMLParser.TopElementHandler;
|
import com.sun.hotspot.igv.data.serialization.XMLParser.TopElementHandler;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
import org.xml.sax.XMLReader;
|
import org.xml.sax.XMLReader;
|
||||||
@ -88,6 +89,18 @@ public class Parser {
|
|||||||
private TopElementHandler xmlDocument = new TopElementHandler();
|
private TopElementHandler xmlDocument = new TopElementHandler();
|
||||||
private boolean difference;
|
private boolean difference;
|
||||||
private GroupCallback groupCallback;
|
private GroupCallback groupCallback;
|
||||||
|
private HashMap<String, Integer> idCache = new HashMap<String, Integer>();
|
||||||
|
private int maxId = 0;
|
||||||
|
|
||||||
|
private int lookupID(String i) {
|
||||||
|
Integer id = idCache.get(i);
|
||||||
|
if (id == null) {
|
||||||
|
id = maxId++;
|
||||||
|
idCache.put(i, id);
|
||||||
|
}
|
||||||
|
return id.intValue();
|
||||||
|
}
|
||||||
|
|
||||||
// <graphDocument>
|
// <graphDocument>
|
||||||
private ElementHandler<GraphDocument, Object> topHandler = new ElementHandler<GraphDocument, Object>(TOP_ELEMENT) {
|
private ElementHandler<GraphDocument, Object> topHandler = new ElementHandler<GraphDocument, Object>(TOP_ELEMENT) {
|
||||||
|
|
||||||
@ -187,13 +200,13 @@ public class Parser {
|
|||||||
previous = null;
|
previous = null;
|
||||||
}
|
}
|
||||||
InputGraph curGraph = new InputGraph(getParentObject(), previous, name);
|
InputGraph curGraph = new InputGraph(getParentObject(), previous, name);
|
||||||
getParentObject().addGraph(curGraph);
|
|
||||||
this.graph = curGraph;
|
this.graph = curGraph;
|
||||||
return curGraph;
|
return curGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void end(String text) throws SAXException {
|
protected void end(String text) throws SAXException {
|
||||||
|
getParentObject().addGraph(graph);
|
||||||
graph.resolveBlockLinks();
|
graph.resolveBlockLinks();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -207,7 +220,7 @@ public class Parser {
|
|||||||
@Override
|
@Override
|
||||||
protected InputBlock start() throws SAXException {
|
protected InputBlock start() throws SAXException {
|
||||||
InputGraph graph = getParentObject();
|
InputGraph graph = getParentObject();
|
||||||
String name = readRequiredAttribute(BLOCK_NAME_PROPERTY);
|
String name = readRequiredAttribute(BLOCK_NAME_PROPERTY).intern();
|
||||||
InputBlock b = new InputBlock(getParentObject(), name);
|
InputBlock b = new InputBlock(getParentObject(), name);
|
||||||
graph.addBlock(b);
|
graph.addBlock(b);
|
||||||
return b;
|
return b;
|
||||||
@ -224,7 +237,7 @@ public class Parser {
|
|||||||
|
|
||||||
int id = 0;
|
int id = 0;
|
||||||
try {
|
try {
|
||||||
id = Integer.parseInt(s);
|
id = lookupID(s);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new SAXException(e);
|
throw new SAXException(e);
|
||||||
}
|
}
|
||||||
@ -252,7 +265,7 @@ public class Parser {
|
|||||||
String s = readRequiredAttribute(NODE_ID_PROPERTY);
|
String s = readRequiredAttribute(NODE_ID_PROPERTY);
|
||||||
int id = 0;
|
int id = 0;
|
||||||
try {
|
try {
|
||||||
id = Integer.parseInt(s);
|
id = lookupID(s);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new SAXException(e);
|
throw new SAXException(e);
|
||||||
}
|
}
|
||||||
@ -269,7 +282,7 @@ public class Parser {
|
|||||||
String s = readRequiredAttribute(NODE_ID_PROPERTY);
|
String s = readRequiredAttribute(NODE_ID_PROPERTY);
|
||||||
int id = 0;
|
int id = 0;
|
||||||
try {
|
try {
|
||||||
id = Integer.parseInt(s);
|
id = lookupID(s);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new SAXException(e);
|
throw new SAXException(e);
|
||||||
}
|
}
|
||||||
@ -280,7 +293,7 @@ public class Parser {
|
|||||||
private HandoverElementHandler<InputGraph> edgesHandler = new HandoverElementHandler<InputGraph>(EDGES_ELEMENT);
|
private HandoverElementHandler<InputGraph> edgesHandler = new HandoverElementHandler<InputGraph>(EDGES_ELEMENT);
|
||||||
|
|
||||||
// Local class for edge elements
|
// Local class for edge elements
|
||||||
private static class EdgeElementHandler extends ElementHandler<InputEdge, InputGraph> {
|
private class EdgeElementHandler extends ElementHandler<InputEdge, InputGraph> {
|
||||||
|
|
||||||
public EdgeElementHandler(String name) {
|
public EdgeElementHandler(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
@ -298,8 +311,8 @@ public class Parser {
|
|||||||
toIndex = Integer.parseInt(toIndexString);
|
toIndex = Integer.parseInt(toIndexString);
|
||||||
}
|
}
|
||||||
|
|
||||||
from = Integer.parseInt(readRequiredAttribute(FROM_PROPERTY));
|
from = lookupID(readRequiredAttribute(FROM_PROPERTY));
|
||||||
to = Integer.parseInt(readRequiredAttribute(TO_PROPERTY));
|
to = lookupID(readRequiredAttribute(TO_PROPERTY));
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new SAXException(e);
|
throw new SAXException(e);
|
||||||
}
|
}
|
||||||
@ -344,18 +357,16 @@ public class Parser {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
// <property>
|
// <property>
|
||||||
private ElementHandler<Property, Properties.Provider> propertyHandler = new XMLParser.ElementHandler<Property, Properties.Provider>(PROPERTY_ELEMENT, true) {
|
private ElementHandler<String, Properties.Provider> propertyHandler = new XMLParser.ElementHandler<String, Properties.Provider>(PROPERTY_ELEMENT, true) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Property start() throws SAXException {
|
public String start() throws SAXException {
|
||||||
String value = "";
|
return readRequiredAttribute(PROPERTY_NAME_PROPERTY).intern();
|
||||||
String name = readRequiredAttribute(PROPERTY_NAME_PROPERTY).intern();
|
|
||||||
return getParentObject().getProperties().setProperty(name, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void end(String text) {
|
public void end(String text) {
|
||||||
getObject().setValue(text.trim().intern());
|
getParentObject().getProperties().setProperty(getObject(), text.trim().intern());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ public class Printer {
|
|||||||
|
|
||||||
private void export(XMLWriter writer, Group g) throws IOException {
|
private void export(XMLWriter writer, Group g) throws IOException {
|
||||||
Properties attributes = new Properties();
|
Properties attributes = new Properties();
|
||||||
attributes.add(new Property("difference", Boolean.toString(true)));
|
attributes.setProperty("difference", Boolean.toString(true));
|
||||||
writer.startTag(Parser.GROUP_ELEMENT, attributes);
|
writer.startTag(Parser.GROUP_ELEMENT, attributes);
|
||||||
writer.writeProperties(g.getProperties());
|
writer.writeProperties(g.getProperties());
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ package com.sun.hotspot.igv.data.serialization;
|
|||||||
|
|
||||||
import com.sun.hotspot.igv.data.Property;
|
import com.sun.hotspot.igv.data.Property;
|
||||||
import com.sun.hotspot.igv.data.Properties;
|
import com.sun.hotspot.igv.data.Properties;
|
||||||
import java.util.Hashtable;
|
import java.util.HashMap;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
import org.xml.sax.Attributes;
|
import org.xml.sax.Attributes;
|
||||||
import org.xml.sax.ContentHandler;
|
import org.xml.sax.ContentHandler;
|
||||||
@ -89,7 +89,7 @@ public class XMLParser implements ContentHandler {
|
|||||||
private Attributes attr;
|
private Attributes attr;
|
||||||
private StringBuilder currentText;
|
private StringBuilder currentText;
|
||||||
private ParseMonitor monitor;
|
private ParseMonitor monitor;
|
||||||
private Hashtable<String, ElementHandler<?, ? super T>> hashtable;
|
private HashMap<String, ElementHandler<?, ? super T>> hashtable;
|
||||||
private boolean needsText;
|
private boolean needsText;
|
||||||
private ElementHandler<P, ?> parentElement;
|
private ElementHandler<P, ?> parentElement;
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ public class XMLParser implements ContentHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ElementHandler(String name, boolean needsText) {
|
public ElementHandler(String name, boolean needsText) {
|
||||||
this.hashtable = new Hashtable<String, ElementHandler<?, ? super T>>();
|
this.hashtable = new HashMap<String, ElementHandler<?, ? super T>>();
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.needsText = needsText;
|
this.needsText = needsText;
|
||||||
}
|
}
|
||||||
@ -153,7 +153,7 @@ public class XMLParser implements ContentHandler {
|
|||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
String val = attr.getValue(i).intern();
|
String val = attr.getValue(i).intern();
|
||||||
String localName = attr.getLocalName(i).intern();
|
String localName = attr.getLocalName(i).intern();
|
||||||
p.add(new Property(val, localName));
|
p.setProperty(val, localName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ public class XMLWriter extends Writer {
|
|||||||
inner.write("<" + name);
|
inner.write("<" + name);
|
||||||
elementStack.push(name);
|
elementStack.push(name);
|
||||||
|
|
||||||
for (Property p : attributes.getProperties()) {
|
for (Property p : attributes) {
|
||||||
inner.write(" " + p.getName() + "=\"");
|
inner.write(" " + p.getName() + "=\"");
|
||||||
write(p.getValue().toCharArray());
|
write(p.getValue().toCharArray());
|
||||||
inner.write("\"");
|
inner.write("\"");
|
||||||
@ -101,7 +101,7 @@ public class XMLWriter extends Writer {
|
|||||||
public void simpleTag(String name, Properties attributes) throws IOException {
|
public void simpleTag(String name, Properties attributes) throws IOException {
|
||||||
inner.write("<" + name);
|
inner.write("<" + name);
|
||||||
|
|
||||||
for (Property p : attributes.getProperties()) {
|
for (Property p : attributes) {
|
||||||
inner.write(" " + p.getName() + "=\"");
|
inner.write(" " + p.getName() + "=\"");
|
||||||
write(p.getValue().toCharArray());
|
write(p.getValue().toCharArray());
|
||||||
inner.write("\"");
|
inner.write("\"");
|
||||||
@ -111,13 +111,13 @@ public class XMLWriter extends Writer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void writeProperties(Properties props) throws IOException {
|
public void writeProperties(Properties props) throws IOException {
|
||||||
if (props.getProperties().size() == 0) {
|
if (props.getProperties().hasNext() == false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
startTag(Parser.PROPERTIES_ELEMENT);
|
startTag(Parser.PROPERTIES_ELEMENT);
|
||||||
|
|
||||||
for (Property p : props.getProperties()) {
|
for (Property p : props) {
|
||||||
startTag(Parser.PROPERTY_ELEMENT, new Properties(Parser.PROPERTY_NAME_PROPERTY, p.getName()));
|
startTag(Parser.PROPERTY_ELEMENT, new Properties(Parser.PROPERTY_NAME_PROPERTY, p.getName()));
|
||||||
this.write(p.getValue().toCharArray());
|
this.write(p.getValue().toCharArray());
|
||||||
endTag();
|
endTag();
|
||||||
|
@ -29,6 +29,7 @@ import com.sun.hotspot.igv.data.InputEdge;
|
|||||||
import com.sun.hotspot.igv.data.InputGraph;
|
import com.sun.hotspot.igv.data.InputGraph;
|
||||||
import com.sun.hotspot.igv.data.InputNode;
|
import com.sun.hotspot.igv.data.InputNode;
|
||||||
import com.sun.hotspot.igv.data.Property;
|
import com.sun.hotspot.igv.data.Property;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -124,8 +125,8 @@ public class Difference {
|
|||||||
inputNodeMap.put(n, n2);
|
inputNodeMap.put(n, n2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<InputEdge> edgesA = a.getEdges();
|
Collection<InputEdge> edgesA = a.getEdges();
|
||||||
Set<InputEdge> edgesB = b.getEdges();
|
Collection<InputEdge> edgesB = b.getEdges();
|
||||||
|
|
||||||
Set<InputEdge> newEdges = new HashSet<InputEdge>();
|
Set<InputEdge> newEdges = new HashSet<InputEdge>();
|
||||||
|
|
||||||
@ -182,7 +183,7 @@ public class Difference {
|
|||||||
public double getValue() {
|
public double getValue() {
|
||||||
|
|
||||||
double result = 0.0;
|
double result = 0.0;
|
||||||
for (Property p : n1.getProperties().getProperties()) {
|
for (Property p : n1.getProperties()) {
|
||||||
double faktor = 1.0;
|
double faktor = 1.0;
|
||||||
for (String forbidden : IGNORE_PROPERTIES) {
|
for (String forbidden : IGNORE_PROPERTIES) {
|
||||||
if (p.getName().equals(forbidden)) {
|
if (p.getName().equals(forbidden)) {
|
||||||
@ -287,34 +288,34 @@ public class Difference {
|
|||||||
private static void markAsChanged(InputNode n, InputNode firstNode, InputNode otherNode) {
|
private static void markAsChanged(InputNode n, InputNode firstNode, InputNode otherNode) {
|
||||||
|
|
||||||
boolean difference = false;
|
boolean difference = false;
|
||||||
for (Property p : otherNode.getProperties().getProperties()) {
|
for (Property p : otherNode.getProperties()) {
|
||||||
String s = firstNode.getProperties().getProperty(p.getName());
|
String s = firstNode.getProperties().get(p.getName());
|
||||||
if (!p.getValue().equals(s)) {
|
if (!p.getValue().equals(s)) {
|
||||||
difference = true;
|
difference = true;
|
||||||
n.getProperties().add(new Property(OLD_PREFIX + p.getName(), p.getValue()));
|
n.getProperties().setProperty(OLD_PREFIX + p.getName(), p.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Property p : firstNode.getProperties().getProperties()) {
|
for (Property p : firstNode.getProperties()) {
|
||||||
String s = otherNode.getProperties().getProperty(p.getName());
|
String s = otherNode.getProperties().get(p.getName());
|
||||||
if (s == null && p.getValue().length() > 0) {
|
if (s == null && p.getValue().length() > 0) {
|
||||||
difference = true;
|
difference = true;
|
||||||
n.getProperties().add(new Property(OLD_PREFIX + p.getName(), ""));
|
n.getProperties().setProperty(OLD_PREFIX + p.getName(), "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (difference) {
|
if (difference) {
|
||||||
n.getProperties().add(new Property(PROPERTY_STATE, VALUE_CHANGED));
|
n.getProperties().setProperty(PROPERTY_STATE, VALUE_CHANGED);
|
||||||
} else {
|
} else {
|
||||||
n.getProperties().add(new Property(PROPERTY_STATE, VALUE_SAME));
|
n.getProperties().setProperty(PROPERTY_STATE, VALUE_SAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void markAsDeleted(InputNode n) {
|
private static void markAsDeleted(InputNode n) {
|
||||||
n.getProperties().add(new Property(PROPERTY_STATE, VALUE_DELETED));
|
n.getProperties().setProperty(PROPERTY_STATE, VALUE_DELETED);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void markAsNew(InputNode n) {
|
private static void markAsNew(InputNode n) {
|
||||||
n.getProperties().add(new Property(PROPERTY_STATE, VALUE_NEW));
|
n.getProperties().setProperty(PROPERTY_STATE, VALUE_NEW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Manifest-Version: 1.0
|
Manifest-Version: 1.0
|
||||||
OpenIDE-Module: com.sun.hotspot.igv.filter
|
OpenIDE-Module: com.sun.hotspot.igv.filter
|
||||||
OpenIDE-Module-Layer: com/sun/hotspot/igv/filter/layer.xml
|
OpenIDE-Module-Layer: com/sun/hotspot/igv/filter/layer.xml
|
||||||
OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/filter/Bundle.properties
|
OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/filter/Bundle.properties
|
||||||
OpenIDE-Module-Specification-Version: 1.0
|
OpenIDE-Module-Specification-Version: 1.0
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
package com.sun.hotspot.igv.filter;
|
package com.sun.hotspot.igv.filter;
|
||||||
|
|
||||||
import com.sun.hotspot.igv.graph.Diagram;
|
import com.sun.hotspot.igv.graph.Diagram;
|
||||||
import com.sun.hotspot.igv.data.Property;
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -56,7 +55,7 @@ public class CustomFilter extends AbstractFilter {
|
|||||||
public CustomFilter(String name, String code) {
|
public CustomFilter(String name, String code) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.code = code;
|
this.code = code;
|
||||||
getProperties().add(new Property("name", name));
|
getProperties().setProperty("name", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
@ -56,8 +56,8 @@ public class SplitFilter extends AbstractFilter {
|
|||||||
for (OutputSlot os : f.getOutputSlots()) {
|
for (OutputSlot os : f.getOutputSlots()) {
|
||||||
for (Connection c : os.getConnections()) {
|
for (Connection c : os.getConnections()) {
|
||||||
InputSlot is = c.getInputSlot();
|
InputSlot is = c.getInputSlot();
|
||||||
is.setName(f.getProperties().getProperty("dump_spec"));
|
is.setName(f.getProperties().get("dump_spec"));
|
||||||
String s = f.getProperties().getProperty("short_name");
|
String s = f.getProperties().get("short_name");
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
is.setShortName(s);
|
is.setShortName(s);
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ import java.util.Collections;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Hashtable;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -126,7 +126,7 @@ public class Diagram {
|
|||||||
d.updateBlocks();
|
d.updateBlocks();
|
||||||
|
|
||||||
Collection<InputNode> nodes = graph.getNodes();
|
Collection<InputNode> nodes = graph.getNodes();
|
||||||
Hashtable<Integer, Figure> figureHash = new Hashtable<Integer, Figure>();
|
HashMap<Integer, Figure> figureHash = new HashMap<Integer, Figure>();
|
||||||
for (InputNode n : nodes) {
|
for (InputNode n : nodes) {
|
||||||
Figure f = d.createFigure();
|
Figure f = d.createFigure();
|
||||||
f.getSource().addSourceNode(n);
|
f.getSource().addSourceNode(n);
|
||||||
|
@ -42,7 +42,7 @@ import java.util.Set;
|
|||||||
*
|
*
|
||||||
* @author Thomas Wuerthinger
|
* @author Thomas Wuerthinger
|
||||||
*/
|
*/
|
||||||
public class Figure extends Properties.Object implements Source.Provider, Vertex {
|
public class Figure extends Properties.Entity implements Source.Provider, Vertex {
|
||||||
|
|
||||||
public static final int INSET = 6;
|
public static final int INSET = 6;
|
||||||
public static final int SLOT_WIDTH = 10;
|
public static final int SLOT_WIDTH = 10;
|
||||||
|
@ -26,7 +26,7 @@ package com.sun.hotspot.igv.hierarchicallayout;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Hashtable;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
@ -37,13 +37,13 @@ import java.util.Queue;
|
|||||||
*/
|
*/
|
||||||
public class Graph<N, E> {
|
public class Graph<N, E> {
|
||||||
|
|
||||||
private Hashtable<Object, Node<N, E>> nodes;
|
private HashMap<Object, Node<N, E>> nodes;
|
||||||
private Hashtable<Object, Edge<N, E>> edges;
|
private HashMap<Object, Edge<N, E>> edges;
|
||||||
private List<Node<N, E>> nodeList;
|
private List<Node<N, E>> nodeList;
|
||||||
|
|
||||||
public Graph() {
|
public Graph() {
|
||||||
nodes = new Hashtable<Object, Node<N, E>>();
|
nodes = new HashMap<Object, Node<N, E>>();
|
||||||
edges = new Hashtable<Object, Edge<N, E>>();
|
edges = new HashMap<Object, Edge<N, E>>();
|
||||||
nodeList = new ArrayList<Node<N, E>>();
|
nodeList = new ArrayList<Node<N, E>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ package com.sun.hotspot.igv.hierarchicallayout;
|
|||||||
|
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.util.Hashtable;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -69,19 +69,19 @@ public class HierarchicalClusterLayoutManager implements LayoutManager {
|
|||||||
|
|
||||||
assert graph.verify();
|
assert graph.verify();
|
||||||
|
|
||||||
Hashtable<Cluster, List<Vertex>> lists = new Hashtable<Cluster, List<Vertex>>();
|
HashMap<Cluster, List<Vertex>> lists = new HashMap<Cluster, List<Vertex>>();
|
||||||
Hashtable<Cluster, List<Link>> listsConnection = new Hashtable<Cluster, List<Link>>();
|
HashMap<Cluster, List<Link>> listsConnection = new HashMap<Cluster, List<Link>>();
|
||||||
Hashtable<Cluster, Hashtable<Port, ClusterInputSlotNode>> clusterInputSlotHash = new Hashtable<Cluster, Hashtable<Port, ClusterInputSlotNode>>();
|
HashMap<Cluster, HashMap<Port, ClusterInputSlotNode>> clusterInputSlotHash = new HashMap<Cluster, HashMap<Port, ClusterInputSlotNode>>();
|
||||||
Hashtable<Cluster, Hashtable<Port, ClusterOutputSlotNode>> clusterOutputSlotHash = new Hashtable<Cluster, Hashtable<Port, ClusterOutputSlotNode>>();
|
HashMap<Cluster, HashMap<Port, ClusterOutputSlotNode>> clusterOutputSlotHash = new HashMap<Cluster, HashMap<Port, ClusterOutputSlotNode>>();
|
||||||
|
|
||||||
Hashtable<Cluster, ClusterNode> clusterNodes = new Hashtable<Cluster, ClusterNode>();
|
HashMap<Cluster, ClusterNode> clusterNodes = new HashMap<Cluster, ClusterNode>();
|
||||||
Hashtable<Cluster, Set<ClusterInputSlotNode>> clusterInputSlotSet = new Hashtable<Cluster, Set<ClusterInputSlotNode>>();
|
HashMap<Cluster, Set<ClusterInputSlotNode>> clusterInputSlotSet = new HashMap<Cluster, Set<ClusterInputSlotNode>>();
|
||||||
Hashtable<Cluster, Set<ClusterOutputSlotNode>> clusterOutputSlotSet = new Hashtable<Cluster, Set<ClusterOutputSlotNode>>();
|
HashMap<Cluster, Set<ClusterOutputSlotNode>> clusterOutputSlotSet = new HashMap<Cluster, Set<ClusterOutputSlotNode>>();
|
||||||
Set<Link> clusterEdges = new HashSet<Link>();
|
Set<Link> clusterEdges = new HashSet<Link>();
|
||||||
Set<Link> interClusterEdges = new HashSet<Link>();
|
Set<Link> interClusterEdges = new HashSet<Link>();
|
||||||
Hashtable<Link, ClusterOutgoingConnection> linkClusterOutgoingConnection = new Hashtable<Link, ClusterOutgoingConnection>();
|
HashMap<Link, ClusterOutgoingConnection> linkClusterOutgoingConnection = new HashMap<Link, ClusterOutgoingConnection>();
|
||||||
Hashtable<Link, InterClusterConnection> linkInterClusterConnection = new Hashtable<Link, InterClusterConnection>();
|
HashMap<Link, InterClusterConnection> linkInterClusterConnection = new HashMap<Link, InterClusterConnection>();
|
||||||
Hashtable<Link, ClusterIngoingConnection> linkClusterIngoingConnection = new Hashtable<Link, ClusterIngoingConnection>();
|
HashMap<Link, ClusterIngoingConnection> linkClusterIngoingConnection = new HashMap<Link, ClusterIngoingConnection>();
|
||||||
Set<ClusterNode> clusterNodeSet = new HashSet<ClusterNode>();
|
Set<ClusterNode> clusterNodeSet = new HashSet<ClusterNode>();
|
||||||
|
|
||||||
Set<Cluster> cluster = graph.getClusters();
|
Set<Cluster> cluster = graph.getClusters();
|
||||||
@ -89,8 +89,8 @@ public class HierarchicalClusterLayoutManager implements LayoutManager {
|
|||||||
for (Cluster c : cluster) {
|
for (Cluster c : cluster) {
|
||||||
lists.put(c, new ArrayList<Vertex>());
|
lists.put(c, new ArrayList<Vertex>());
|
||||||
listsConnection.put(c, new ArrayList<Link>());
|
listsConnection.put(c, new ArrayList<Link>());
|
||||||
clusterInputSlotHash.put(c, new Hashtable<Port, ClusterInputSlotNode>());
|
clusterInputSlotHash.put(c, new HashMap<Port, ClusterInputSlotNode>());
|
||||||
clusterOutputSlotHash.put(c, new Hashtable<Port, ClusterOutputSlotNode>());
|
clusterOutputSlotHash.put(c, new HashMap<Port, ClusterOutputSlotNode>());
|
||||||
clusterOutputSlotSet.put(c, new TreeSet<ClusterOutputSlotNode>());
|
clusterOutputSlotSet.put(c, new TreeSet<ClusterOutputSlotNode>());
|
||||||
clusterInputSlotSet.put(c, new TreeSet<ClusterInputSlotNode>());
|
clusterInputSlotSet.put(c, new TreeSet<ClusterInputSlotNode>());
|
||||||
ClusterNode cn = new ClusterNode(c, "" + z);
|
ClusterNode cn = new ClusterNode(c, "" + z);
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
package com.sun.hotspot.igv.layout;
|
package com.sun.hotspot.igv.layout;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Hashtable;
|
import java.util.HashMap;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
@ -37,9 +37,9 @@ public class LayoutGraph {
|
|||||||
|
|
||||||
private Set<? extends Link> links;
|
private Set<? extends Link> links;
|
||||||
private SortedSet<Vertex> vertices;
|
private SortedSet<Vertex> vertices;
|
||||||
private Hashtable<Vertex, Set<Port>> inputPorts;
|
private HashMap<Vertex, Set<Port>> inputPorts;
|
||||||
private Hashtable<Vertex, Set<Port>> outputPorts;
|
private HashMap<Vertex, Set<Port>> outputPorts;
|
||||||
private Hashtable<Port, Set<Link>> portLinks;
|
private HashMap<Port, Set<Link>> portLinks;
|
||||||
|
|
||||||
public LayoutGraph(Set<? extends Link> links) {
|
public LayoutGraph(Set<? extends Link> links) {
|
||||||
this(links, new HashSet<Vertex>());
|
this(links, new HashSet<Vertex>());
|
||||||
@ -50,9 +50,9 @@ public class LayoutGraph {
|
|||||||
assert verify();
|
assert verify();
|
||||||
|
|
||||||
vertices = new TreeSet<Vertex>();
|
vertices = new TreeSet<Vertex>();
|
||||||
portLinks = new Hashtable<Port, Set<Link>>();
|
portLinks = new HashMap<Port, Set<Link>>();
|
||||||
inputPorts = new Hashtable<Vertex, Set<Port>>();
|
inputPorts = new HashMap<Vertex, Set<Port>>();
|
||||||
outputPorts = new Hashtable<Vertex, Set<Port>>();
|
outputPorts = new HashMap<Vertex, Set<Port>>();
|
||||||
|
|
||||||
for (Link l : links) {
|
for (Link l : links) {
|
||||||
Port p = l.getFrom();
|
Port p = l.getFrom();
|
||||||
|
@ -5,21 +5,16 @@ of Linz in Austria and has been included as part of hotspot since that
|
|||||||
was the primary target of the tool. The tool itself is fairly general
|
was the primary target of the tool. The tool itself is fairly general
|
||||||
with only a few modules that contain C2 specific elements.
|
with only a few modules that contain C2 specific elements.
|
||||||
|
|
||||||
The tool is built on top of the NetBeans 6.0 rich client
|
The tool is built on top of the NetBeans 6.1 rich client
|
||||||
infrastructure and so requires NetBeans to build. It currently
|
infrastructure and so requires NetBeans to build. It currently
|
||||||
requires Java 6 to run as it needs support for JavaScript for its
|
requires Java 6 to run as it needs support for JavaScript for its
|
||||||
filtering mechanism and assumes it's built into the platform. It
|
filtering mechanism and assumes it's built into the platform. It
|
||||||
should build out of the box whit NetBeans 6 and Java 6 or later. It's
|
should build out of the box with NetBeans 6.1 and Java 6 or later.
|
||||||
possible to run it on 1.5 by including Rhino on the classpath though
|
It's possible to run it on 1.5 by including Rhino on the classpath
|
||||||
that currently isn't working correctly. Support for exporting graphs
|
though that currently isn't working correctly. Support for exporting
|
||||||
as SVG can be enabled by adding batik to the classpath which isn't
|
graphs as SVG can be enabled by adding batik to the classpath which
|
||||||
included by default.
|
isn't included by default. It can be built on top of NetBeans 6.0 if
|
||||||
|
you change the required modules to be platform7 instead of platform8.
|
||||||
It can be built on top of NetBeans 6.1 if you change the required
|
|
||||||
modules to be platform8 instead of platform7. The tool could run on
|
|
||||||
JDK 1.5 with some reworking of the how the JavaScript support is
|
|
||||||
enabled but currently it requires some tweaking of the setup. This
|
|
||||||
will be fixed in a later setup.
|
|
||||||
|
|
||||||
The JVM support is controlled by the flag -XX:PrintIdealGraphLevel=#
|
The JVM support is controlled by the flag -XX:PrintIdealGraphLevel=#
|
||||||
where # is:
|
where # is:
|
||||||
|
@ -36,11 +36,11 @@ import org.openide.nodes.Sheet;
|
|||||||
*/
|
*/
|
||||||
public class PropertiesSheet {
|
public class PropertiesSheet {
|
||||||
|
|
||||||
public static void initializeSheet(Properties properties, Sheet s) {
|
public static void initializeSheet(final Properties properties, Sheet s) {
|
||||||
|
|
||||||
Sheet.Set set1 = Sheet.createPropertiesSet();
|
Sheet.Set set1 = Sheet.createPropertiesSet();
|
||||||
set1.setDisplayName("Properties");
|
set1.setDisplayName("Properties");
|
||||||
for (final Property p : properties.getProperties()) {
|
for (final Property p : properties) {
|
||||||
Node.Property<String> prop = new Node.Property<String>(String.class) {
|
Node.Property<String> prop = new Node.Property<String>(String.class) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -60,7 +60,7 @@ public class PropertiesSheet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setValue(String arg0) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
public void setValue(String arg0) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
p.setValue(arg0);
|
properties.setProperty(p.getName(), arg0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
prop.setName(p.getName());
|
prop.setName(p.getName());
|
||||||
|
@ -65,13 +65,19 @@ public class RangeSliderModel implements ChangedEventProvider<RangeSliderModel>
|
|||||||
|
|
||||||
public RangeSliderModel(List<String> positions) {
|
public RangeSliderModel(List<String> positions) {
|
||||||
assert positions.size() > 0;
|
assert positions.size() > 0;
|
||||||
this.positions = positions;
|
|
||||||
this.changedEvent = new ChangedEvent<RangeSliderModel>(this);
|
this.changedEvent = new ChangedEvent<RangeSliderModel>(this);
|
||||||
this.colorChangedEvent = new ChangedEvent<RangeSliderModel>(this);
|
this.colorChangedEvent = new ChangedEvent<RangeSliderModel>(this);
|
||||||
|
setPositions(positions);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setPositions(List<String> positions) {
|
||||||
|
this.positions = positions;
|
||||||
colors = new ArrayList<Color>();
|
colors = new ArrayList<Color>();
|
||||||
for (int i = 0; i < positions.size(); i++) {
|
for (int i = 0; i < positions.size(); i++) {
|
||||||
colors.add(Color.black);
|
colors.add(Color.black);
|
||||||
}
|
}
|
||||||
|
changedEvent.fire();
|
||||||
|
colorChangedEvent.fire();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColors(List<Color> colors) {
|
public void setColors(List<Color> colors) {
|
||||||
|
@ -63,7 +63,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Hashtable;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -104,10 +104,10 @@ import org.openide.util.lookup.InstanceContent;
|
|||||||
*/
|
*/
|
||||||
public class DiagramScene extends Scene implements ChangedListener<DiagramViewModel> {
|
public class DiagramScene extends Scene implements ChangedListener<DiagramViewModel> {
|
||||||
|
|
||||||
private Hashtable<Figure, FigureWidget> figureWidgets;
|
private HashMap<Figure, FigureWidget> figureWidgets;
|
||||||
private Hashtable<Slot, SlotWidget> slotWidgets;
|
private HashMap<Slot, SlotWidget> slotWidgets;
|
||||||
private Hashtable<Connection, ConnectionWidget> connectionWidgets;
|
private HashMap<Connection, ConnectionWidget> connectionWidgets;
|
||||||
private Hashtable<InputBlock, BlockWidget> blockWidgets;
|
private HashMap<InputBlock, BlockWidget> blockWidgets;
|
||||||
private Widget hoverWidget;
|
private Widget hoverWidget;
|
||||||
private WidgetAction hoverAction;
|
private WidgetAction hoverAction;
|
||||||
private List<FigureWidget> selectedWidgets;
|
private List<FigureWidget> selectedWidgets;
|
||||||
@ -414,7 +414,7 @@ public class DiagramScene extends Scene implements ChangedListener<DiagramViewMo
|
|||||||
this.addChild(selectLayer);
|
this.addChild(selectLayer);
|
||||||
this.getActions().addAction(ActionFactory.createRectangularSelectAction(rectangularSelectDecorator, selectLayer, rectangularSelectProvider));
|
this.getActions().addAction(ActionFactory.createRectangularSelectAction(rectangularSelectDecorator, selectLayer, rectangularSelectProvider));
|
||||||
|
|
||||||
blockWidgets = new Hashtable<InputBlock, BlockWidget>();
|
blockWidgets = new HashMap<InputBlock, BlockWidget>();
|
||||||
|
|
||||||
boolean b = this.getUndoRedoEnabled();
|
boolean b = this.getUndoRedoEnabled();
|
||||||
this.setUndoRedoEnabled(false);
|
this.setUndoRedoEnabled(false);
|
||||||
@ -543,9 +543,9 @@ public class DiagramScene extends Scene implements ChangedListener<DiagramViewMo
|
|||||||
blockLayer.removeChildren();
|
blockLayer.removeChildren();
|
||||||
|
|
||||||
blockWidgets.clear();
|
blockWidgets.clear();
|
||||||
figureWidgets = new Hashtable<Figure, FigureWidget>();
|
figureWidgets = new HashMap<Figure, FigureWidget>();
|
||||||
slotWidgets = new Hashtable<Slot, SlotWidget>();
|
slotWidgets = new HashMap<Slot, SlotWidget>();
|
||||||
connectionWidgets = new Hashtable<Connection, ConnectionWidget>();
|
connectionWidgets = new HashMap<Connection, ConnectionWidget>();
|
||||||
|
|
||||||
WidgetAction selectAction = new ExtendedSelectAction(selectProvider);
|
WidgetAction selectAction = new ExtendedSelectAction(selectProvider);
|
||||||
Diagram d = getModel().getDiagramToView();
|
Diagram d = getModel().getDiagramToView();
|
||||||
|
@ -55,6 +55,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
|
|||||||
private FilterChain filterChain;
|
private FilterChain filterChain;
|
||||||
private FilterChain sequenceFilterChain;
|
private FilterChain sequenceFilterChain;
|
||||||
private Diagram diagram;
|
private Diagram diagram;
|
||||||
|
private ChangedEvent<DiagramViewModel> groupChangedEvent;
|
||||||
private ChangedEvent<DiagramViewModel> diagramChangedEvent;
|
private ChangedEvent<DiagramViewModel> diagramChangedEvent;
|
||||||
private ChangedEvent<DiagramViewModel> viewChangedEvent;
|
private ChangedEvent<DiagramViewModel> viewChangedEvent;
|
||||||
private ChangedEvent<DiagramViewModel> viewPropertiesChangedEvent;
|
private ChangedEvent<DiagramViewModel> viewPropertiesChangedEvent;
|
||||||
@ -67,6 +68,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
public DiagramViewModel copy() {
|
public DiagramViewModel copy() {
|
||||||
DiagramViewModel result = new DiagramViewModel(group, filterChain, sequenceFilterChain);
|
DiagramViewModel result = new DiagramViewModel(group, filterChain, sequenceFilterChain);
|
||||||
result.setData(this);
|
result.setData(this);
|
||||||
@ -79,6 +81,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
|
|||||||
boolean viewChanged = false;
|
boolean viewChanged = false;
|
||||||
boolean viewPropertiesChanged = false;
|
boolean viewPropertiesChanged = false;
|
||||||
|
|
||||||
|
boolean groupChanged = (group == newModel.group);
|
||||||
this.group = newModel.group;
|
this.group = newModel.group;
|
||||||
diagramChanged |= (filterChain != newModel.filterChain);
|
diagramChanged |= (filterChain != newModel.filterChain);
|
||||||
this.filterChain = newModel.filterChain;
|
this.filterChain = newModel.filterChain;
|
||||||
@ -97,6 +100,10 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
|
|||||||
viewPropertiesChanged |= (showNodeHull != newModel.showNodeHull);
|
viewPropertiesChanged |= (showNodeHull != newModel.showNodeHull);
|
||||||
this.showNodeHull = newModel.showNodeHull;
|
this.showNodeHull = newModel.showNodeHull;
|
||||||
|
|
||||||
|
if(groupChanged) {
|
||||||
|
groupChangedEvent.fire();
|
||||||
|
}
|
||||||
|
|
||||||
if (diagramChanged) {
|
if (diagramChanged) {
|
||||||
diagramChangedEvent.fire();
|
diagramChangedEvent.fire();
|
||||||
}
|
}
|
||||||
@ -143,11 +150,38 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
|
|||||||
diagramChangedEvent = new ChangedEvent<DiagramViewModel>(this);
|
diagramChangedEvent = new ChangedEvent<DiagramViewModel>(this);
|
||||||
viewChangedEvent = new ChangedEvent<DiagramViewModel>(this);
|
viewChangedEvent = new ChangedEvent<DiagramViewModel>(this);
|
||||||
viewPropertiesChangedEvent = new ChangedEvent<DiagramViewModel>(this);
|
viewPropertiesChangedEvent = new ChangedEvent<DiagramViewModel>(this);
|
||||||
|
groupChangedEvent = new ChangedEvent<DiagramViewModel>(this);
|
||||||
|
groupChangedEvent.addListener(groupChangedListener);
|
||||||
|
groupChangedEvent.fire();
|
||||||
|
|
||||||
filterChain.getChangedEvent().addListener(filterChainChangedListener);
|
filterChain.getChangedEvent().addListener(filterChainChangedListener);
|
||||||
sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
|
sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final ChangedListener<DiagramViewModel> groupChangedListener = new ChangedListener<DiagramViewModel>() {
|
||||||
|
|
||||||
|
private Group oldGroup;
|
||||||
|
|
||||||
|
public void changed(DiagramViewModel source) {
|
||||||
|
if(oldGroup != null) {
|
||||||
|
oldGroup.getChangedEvent().removeListener(groupContentChangedListener);
|
||||||
|
}
|
||||||
|
group.getChangedEvent().addListener(groupContentChangedListener);
|
||||||
|
oldGroup = group;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private final ChangedListener<Group> groupContentChangedListener = new ChangedListener<Group>() {
|
||||||
|
|
||||||
|
public void changed(Group source) {
|
||||||
|
assert source == group;
|
||||||
|
setPositions(calculateStringList(source));
|
||||||
|
setSelectedNodes(selectedNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
public ChangedEvent<DiagramViewModel> getDiagramChangedEvent() {
|
public ChangedEvent<DiagramViewModel> getDiagramChangedEvent() {
|
||||||
return diagramChangedEvent;
|
return diagramChangedEvent;
|
||||||
}
|
}
|
||||||
@ -268,7 +302,10 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
|
|||||||
}
|
}
|
||||||
|
|
||||||
public InputGraph getSecondGraph() {
|
public InputGraph getSecondGraph() {
|
||||||
return group.getGraphs().get(getSecondPosition());
|
List<InputGraph> graphs = group.getGraphs();
|
||||||
|
if (graphs.size() >= getSecondPosition())
|
||||||
|
return group.getGraphs().get(getSecondPosition());
|
||||||
|
return getFirstGraph();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void selectGraph(InputGraph g) {
|
public void selectGraph(InputGraph g) {
|
||||||
|
@ -67,7 +67,7 @@ class FindPanel extends JPanel implements KeyListener {
|
|||||||
|
|
||||||
for (Figure f : figures) {
|
for (Figure f : figures) {
|
||||||
Properties prop = f.getProperties();
|
Properties prop = f.getProperties();
|
||||||
for (Property p : prop.getProperties()) {
|
for (Property p : prop) {
|
||||||
if (!propertyNames.contains(p.getName())) {
|
if (!propertyNames.contains(p.getName())) {
|
||||||
propertyNames.add(p.getName());
|
propertyNames.add(p.getName());
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
# Deprecated since 5.0u1; for compatibility with 5.0:
|
# Deprecated since 5.0u1; for compatibility with 5.0:
|
||||||
disabled.clusters=\
|
disabled.clusters=\
|
||||||
apisupport1,\
|
apisupport1,\
|
||||||
|
gsf1,\
|
||||||
harness,\
|
harness,\
|
||||||
ide8,\
|
ide9,\
|
||||||
java1,\
|
java2,\
|
||||||
nb6.0,\
|
nb6.1,\
|
||||||
profiler2
|
profiler3
|
||||||
disabled.modules=\
|
disabled.modules=\
|
||||||
org.netbeans.core.execution,\
|
org.netbeans.core.execution,\
|
||||||
org.netbeans.core.multiview,\
|
org.netbeans.core.multiview,\
|
||||||
org.netbeans.core.output2,\
|
org.netbeans.core.output2,\
|
||||||
org.netbeans.modules.applemenu,\
|
|
||||||
org.netbeans.modules.autoupdate.services,\
|
org.netbeans.modules.autoupdate.services,\
|
||||||
org.netbeans.modules.autoupdate.ui,\
|
org.netbeans.modules.autoupdate.ui,\
|
||||||
org.netbeans.modules.core.kit,\
|
org.netbeans.modules.core.kit,\
|
||||||
@ -24,6 +24,6 @@ disabled.modules=\
|
|||||||
org.openide.execution,\
|
org.openide.execution,\
|
||||||
org.openide.util.enumerations
|
org.openide.util.enumerations
|
||||||
enabled.clusters=\
|
enabled.clusters=\
|
||||||
platform7
|
platform8
|
||||||
nbjdk.active=default
|
nbjdk.active=default
|
||||||
nbplatform.active=default
|
nbplatform.active=default
|
||||||
|
@ -15,7 +15,6 @@ modules=\
|
|||||||
${project.com.sun.hotspot.igv.difference}:\
|
${project.com.sun.hotspot.igv.difference}:\
|
||||||
${project.com.sun.hotspot.igv.settings}:\
|
${project.com.sun.hotspot.igv.settings}:\
|
||||||
${project.com.sun.hotspot.igv.util}:\
|
${project.com.sun.hotspot.igv.util}:\
|
||||||
${project.com.sun.hotspot.igv.rhino}:\
|
|
||||||
${project.com.sun.hotspot.igv.svg}:\
|
${project.com.sun.hotspot.igv.svg}:\
|
||||||
${project.com.sun.hotspot.connection}:\
|
${project.com.sun.hotspot.connection}:\
|
||||||
${project.com.sun.hotspot.igv.servercompilerscheduler}:\
|
${project.com.sun.hotspot.igv.servercompilerscheduler}:\
|
||||||
@ -31,10 +30,10 @@ project.com.sun.hotspot.igv.filterwindow=FilterWindow
|
|||||||
project.com.sun.hotspot.igv.graph=Graph
|
project.com.sun.hotspot.igv.graph=Graph
|
||||||
project.com.sun.hotspot.igv.hierarchicallayout=HierarchicalLayout
|
project.com.sun.hotspot.igv.hierarchicallayout=HierarchicalLayout
|
||||||
project.com.sun.hotspot.igv.layout=Layout
|
project.com.sun.hotspot.igv.layout=Layout
|
||||||
project.com.sun.hotspot.igv.rhino=RhinoScriptEngineProxy
|
|
||||||
project.com.sun.hotspot.igv.servercompilerscheduler=ServerCompiler
|
project.com.sun.hotspot.igv.servercompilerscheduler=ServerCompiler
|
||||||
project.com.sun.hotspot.igv.settings=Settings
|
project.com.sun.hotspot.igv.settings=Settings
|
||||||
project.com.sun.hotspot.igv.svg=BatikSVGProxy
|
project.com.sun.hotspot.igv.svg=BatikSVGProxy
|
||||||
project.com.sun.hotspot.igv.view=View
|
project.com.sun.hotspot.igv.view=View
|
||||||
project.com.sun.hotspot.igv.util=Util
|
project.com.sun.hotspot.igv.util=Util
|
||||||
run.args = -server -J-Xms64m -J-Xmx512m -J-da
|
run.args = -J-server -J-Xms64m -J-Xmx1g -J-da
|
||||||
|
run.args.extra = -J-server -J-Xms64m -J-Xmx1g -J-da
|
||||||
|
@ -33,7 +33,6 @@ ADLParser::ADLParser(FileBuff& buffer, ArchDesc& archDesc)
|
|||||||
_globalNames(archDesc.globalNames()) {
|
_globalNames(archDesc.globalNames()) {
|
||||||
_AD._syntax_errs = _AD._semantic_errs = 0; // No errors so far this file
|
_AD._syntax_errs = _AD._semantic_errs = 0; // No errors so far this file
|
||||||
_AD._warnings = 0; // No warnings either
|
_AD._warnings = 0; // No warnings either
|
||||||
_linenum = 0; // Will increment to first line
|
|
||||||
_curline = _ptr = NULL; // No pointers into buffer yet
|
_curline = _ptr = NULL; // No pointers into buffer yet
|
||||||
|
|
||||||
_preproc_depth = 0;
|
_preproc_depth = 0;
|
||||||
@ -76,7 +75,7 @@ ADLParser::~ADLParser() {
|
|||||||
}
|
}
|
||||||
if (!_AD._quiet_mode)
|
if (!_AD._quiet_mode)
|
||||||
fprintf(stderr,"-----------------------------------------------------------------------------\n");
|
fprintf(stderr,"-----------------------------------------------------------------------------\n");
|
||||||
_AD._TotalLines += _linenum-1; // -1 for overshoot in "nextline" routine
|
_AD._TotalLines += linenum()-1; // -1 for overshoot in "nextline" routine
|
||||||
|
|
||||||
// Write out information we have stored
|
// Write out information we have stored
|
||||||
// // UNIXism == fsync(stderr);
|
// // UNIXism == fsync(stderr);
|
||||||
@ -148,7 +147,7 @@ void ADLParser::instr_parse(void) {
|
|||||||
if( (ident = get_unique_ident(_globalNames,"instruction")) == NULL )
|
if( (ident = get_unique_ident(_globalNames,"instruction")) == NULL )
|
||||||
return;
|
return;
|
||||||
instr = new InstructForm(ident); // Create new instruction form
|
instr = new InstructForm(ident); // Create new instruction form
|
||||||
instr->_linenum = _linenum;
|
instr->_linenum = linenum();
|
||||||
_globalNames.Insert(ident, instr); // Add name to the name table
|
_globalNames.Insert(ident, instr); // Add name to the name table
|
||||||
// Debugging Stuff
|
// Debugging Stuff
|
||||||
if (_AD._adl_debug > 1)
|
if (_AD._adl_debug > 1)
|
||||||
@ -404,7 +403,7 @@ void ADLParser::oper_parse(void) {
|
|||||||
if( (ident = get_unique_ident(_globalNames,"operand")) == NULL )
|
if( (ident = get_unique_ident(_globalNames,"operand")) == NULL )
|
||||||
return;
|
return;
|
||||||
oper = new OperandForm(ident); // Create new operand form
|
oper = new OperandForm(ident); // Create new operand form
|
||||||
oper->_linenum = _linenum;
|
oper->_linenum = linenum();
|
||||||
_globalNames.Insert(ident, oper); // Add name to the name table
|
_globalNames.Insert(ident, oper); // Add name to the name table
|
||||||
|
|
||||||
// Debugging Stuff
|
// Debugging Stuff
|
||||||
@ -774,7 +773,7 @@ void ADLParser::reg_parse(void) {
|
|||||||
|
|
||||||
// Create the RegisterForm for the architecture description.
|
// Create the RegisterForm for the architecture description.
|
||||||
RegisterForm *regBlock = new RegisterForm(); // Build new Source object
|
RegisterForm *regBlock = new RegisterForm(); // Build new Source object
|
||||||
regBlock->_linenum = _linenum;
|
regBlock->_linenum = linenum();
|
||||||
_AD.addForm(regBlock);
|
_AD.addForm(regBlock);
|
||||||
|
|
||||||
skipws(); // Skip leading whitespace
|
skipws(); // Skip leading whitespace
|
||||||
@ -847,7 +846,7 @@ void ADLParser::enc_class_parse(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EncClass *encoding = _AD._encode->add_EncClass(ec_name);
|
EncClass *encoding = _AD._encode->add_EncClass(ec_name);
|
||||||
encoding->_linenum = _linenum;
|
encoding->_linenum = linenum();
|
||||||
|
|
||||||
skipws(); // Skip leading whitespace
|
skipws(); // Skip leading whitespace
|
||||||
// Check for optional parameter list
|
// Check for optional parameter list
|
||||||
@ -905,7 +904,7 @@ void ADLParser::enc_class_parse_block(EncClass* encoding, char* ec_name) {
|
|||||||
// Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
|
// Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
|
||||||
if (_AD._adlocation_debug) {
|
if (_AD._adlocation_debug) {
|
||||||
const char* file = _AD._ADL_file._name;
|
const char* file = _AD._ADL_file._name;
|
||||||
int line = _linenum;
|
int line = linenum();
|
||||||
char* location = (char *)malloc(strlen(file) + 100);
|
char* location = (char *)malloc(strlen(file) + 100);
|
||||||
sprintf(location, "#line %d \"%s\"\n", line, file);
|
sprintf(location, "#line %d \"%s\"\n", line, file);
|
||||||
encoding->add_code(location);
|
encoding->add_code(location);
|
||||||
@ -2776,7 +2775,7 @@ InsEncode *ADLParser::ins_encode_parse_block(InstructForm &inst) {
|
|||||||
|
|
||||||
assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
|
assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
|
||||||
EncClass *encoding = _AD._encode->add_EncClass(ec_name);
|
EncClass *encoding = _AD._encode->add_EncClass(ec_name);
|
||||||
encoding->_linenum = _linenum;
|
encoding->_linenum = linenum();
|
||||||
|
|
||||||
// synthesize the arguments list for the enc_class from the
|
// synthesize the arguments list for the enc_class from the
|
||||||
// arguments to the instruct definition.
|
// arguments to the instruct definition.
|
||||||
@ -2852,7 +2851,7 @@ InsEncode *ADLParser::ins_encode_parse(InstructForm &inst) {
|
|||||||
skipws();
|
skipws();
|
||||||
|
|
||||||
InsEncode *encrule = new InsEncode(); // Encode class for instruction
|
InsEncode *encrule = new InsEncode(); // Encode class for instruction
|
||||||
encrule->_linenum = _linenum;
|
encrule->_linenum = linenum();
|
||||||
char *ec_name = NULL; // String representation of encode rule
|
char *ec_name = NULL; // String representation of encode rule
|
||||||
// identifier is optional.
|
// identifier is optional.
|
||||||
while (_curchar != ')') {
|
while (_curchar != ')') {
|
||||||
@ -3203,6 +3202,12 @@ Interface *ADLParser::cond_interface_parse(void) {
|
|||||||
char *greater_equal;
|
char *greater_equal;
|
||||||
char *less_equal;
|
char *less_equal;
|
||||||
char *greater;
|
char *greater;
|
||||||
|
const char *equal_format = "eq";
|
||||||
|
const char *not_equal_format = "ne";
|
||||||
|
const char *less_format = "lt";
|
||||||
|
const char *greater_equal_format = "ge";
|
||||||
|
const char *less_equal_format = "le";
|
||||||
|
const char *greater_format = "gt";
|
||||||
|
|
||||||
if (_curchar != '%') {
|
if (_curchar != '%') {
|
||||||
parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n");
|
parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n");
|
||||||
@ -3222,22 +3227,22 @@ Interface *ADLParser::cond_interface_parse(void) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if ( strcmp(field,"equal") == 0 ) {
|
if ( strcmp(field,"equal") == 0 ) {
|
||||||
equal = interface_field_parse();
|
equal = interface_field_parse(&equal_format);
|
||||||
}
|
}
|
||||||
else if ( strcmp(field,"not_equal") == 0 ) {
|
else if ( strcmp(field,"not_equal") == 0 ) {
|
||||||
not_equal = interface_field_parse();
|
not_equal = interface_field_parse(¬_equal_format);
|
||||||
}
|
}
|
||||||
else if ( strcmp(field,"less") == 0 ) {
|
else if ( strcmp(field,"less") == 0 ) {
|
||||||
less = interface_field_parse();
|
less = interface_field_parse(&less_format);
|
||||||
}
|
}
|
||||||
else if ( strcmp(field,"greater_equal") == 0 ) {
|
else if ( strcmp(field,"greater_equal") == 0 ) {
|
||||||
greater_equal = interface_field_parse();
|
greater_equal = interface_field_parse(&greater_equal_format);
|
||||||
}
|
}
|
||||||
else if ( strcmp(field,"less_equal") == 0 ) {
|
else if ( strcmp(field,"less_equal") == 0 ) {
|
||||||
less_equal = interface_field_parse();
|
less_equal = interface_field_parse(&less_equal_format);
|
||||||
}
|
}
|
||||||
else if ( strcmp(field,"greater") == 0 ) {
|
else if ( strcmp(field,"greater") == 0 ) {
|
||||||
greater = interface_field_parse();
|
greater = interface_field_parse(&greater_format);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
|
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
|
||||||
@ -3252,14 +3257,18 @@ Interface *ADLParser::cond_interface_parse(void) {
|
|||||||
next_char(); // Skip '}'
|
next_char(); // Skip '}'
|
||||||
|
|
||||||
// Construct desired object and return
|
// Construct desired object and return
|
||||||
Interface *inter = new CondInterface(equal, not_equal, less, greater_equal,
|
Interface *inter = new CondInterface(equal, equal_format,
|
||||||
less_equal, greater);
|
not_equal, not_equal_format,
|
||||||
|
less, less_format,
|
||||||
|
greater_equal, greater_equal_format,
|
||||||
|
less_equal, less_equal_format,
|
||||||
|
greater, greater_format);
|
||||||
return inter;
|
return inter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------interface_field_parse--------------------------
|
//------------------------------interface_field_parse--------------------------
|
||||||
char *ADLParser::interface_field_parse(void) {
|
char *ADLParser::interface_field_parse(const char ** format) {
|
||||||
char *iface_field = NULL;
|
char *iface_field = NULL;
|
||||||
|
|
||||||
// Get interface field
|
// Get interface field
|
||||||
@ -3280,6 +3289,32 @@ char *ADLParser::interface_field_parse(void) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
skipws();
|
skipws();
|
||||||
|
if (format != NULL && _curchar == ',') {
|
||||||
|
next_char();
|
||||||
|
skipws();
|
||||||
|
if (_curchar != '"') {
|
||||||
|
parse_err(SYNERR, "Missing '\"' in field format .\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
next_char();
|
||||||
|
char *start = _ptr; // Record start of the next string
|
||||||
|
while ((_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
|
||||||
|
if (_curchar == '\\') next_char(); // superquote
|
||||||
|
if (_curchar == '\n') parse_err(SYNERR, "newline in string"); // unimplemented!
|
||||||
|
next_char();
|
||||||
|
}
|
||||||
|
if (_curchar != '"') {
|
||||||
|
parse_err(SYNERR, "Missing '\"' at end of field format .\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// If a string was found, terminate it and record in FormatRule
|
||||||
|
if ( start != _ptr ) {
|
||||||
|
*_ptr = '\0'; // Terminate the string
|
||||||
|
*format = start;
|
||||||
|
}
|
||||||
|
next_char();
|
||||||
|
skipws();
|
||||||
|
}
|
||||||
if (_curchar != ')') {
|
if (_curchar != ')') {
|
||||||
parse_err(SYNERR, "Missing ')' after interface field.\n");
|
parse_err(SYNERR, "Missing ')' after interface field.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -3342,6 +3377,12 @@ FormatRule* ADLParser::format_parse(void) {
|
|||||||
next_char(); // Move past the '{'
|
next_char(); // Move past the '{'
|
||||||
|
|
||||||
skipws();
|
skipws();
|
||||||
|
if (_curchar == '$') {
|
||||||
|
char* ident = get_rep_var_ident();
|
||||||
|
if (strcmp(ident, "$$template") == 0) return template_parse();
|
||||||
|
parse_err(SYNERR, "Unknown \"%s\" directive in format", ident);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
// Check for the opening '"' inside the format description
|
// Check for the opening '"' inside the format description
|
||||||
if ( _curchar == '"' ) {
|
if ( _curchar == '"' ) {
|
||||||
next_char(); // Move past the initial '"'
|
next_char(); // Move past the initial '"'
|
||||||
@ -3433,6 +3474,131 @@ FormatRule* ADLParser::format_parse(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------template_parse-----------------------------------
|
||||||
|
FormatRule* ADLParser::template_parse(void) {
|
||||||
|
char *desc = NULL;
|
||||||
|
FormatRule *format = (new FormatRule(desc));
|
||||||
|
|
||||||
|
skipws();
|
||||||
|
while ( (_curchar != '%') && (*(_ptr+1) != '}') ) {
|
||||||
|
|
||||||
|
// (1)
|
||||||
|
// Check if there is a string to pass through to output
|
||||||
|
char *start = _ptr; // Record start of the next string
|
||||||
|
while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) {
|
||||||
|
// If at the start of a comment, skip past it
|
||||||
|
if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) {
|
||||||
|
skipws_no_preproc();
|
||||||
|
} else {
|
||||||
|
// ELSE advance to the next character, or start of the next line
|
||||||
|
next_char_or_line();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If a string was found, terminate it and record in EncClass
|
||||||
|
if ( start != _ptr ) {
|
||||||
|
*_ptr = '\0'; // Terminate the string
|
||||||
|
// Add flag to _strings list indicating we should check _rep_vars
|
||||||
|
format->_strings.addName(NameList::_signal2);
|
||||||
|
format->_strings.addName(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
// (2)
|
||||||
|
// If we are at a replacement variable,
|
||||||
|
// copy it and record in EncClass
|
||||||
|
if ( _curchar == '$' ) {
|
||||||
|
// Found replacement Variable
|
||||||
|
char *rep_var = get_rep_var_ident_dup();
|
||||||
|
if (strcmp(rep_var, "$emit") == 0) {
|
||||||
|
// switch to normal format parsing
|
||||||
|
next_char();
|
||||||
|
next_char();
|
||||||
|
skipws();
|
||||||
|
// Check for the opening '"' inside the format description
|
||||||
|
if ( _curchar == '"' ) {
|
||||||
|
next_char(); // Move past the initial '"'
|
||||||
|
if( _curchar == '"' ) { // Handle empty format string case
|
||||||
|
*_ptr = '\0'; // Terminate empty string
|
||||||
|
format->_strings.addName(_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect the parts of the format description
|
||||||
|
// (1) strings that are passed through to tty->print
|
||||||
|
// (2) replacement/substitution variable, preceeded by a '$'
|
||||||
|
// (3) multi-token ANSIY C style strings
|
||||||
|
while ( true ) {
|
||||||
|
if ( _curchar == '%' || _curchar == '\n' ) {
|
||||||
|
parse_err(SYNERR, "missing '\"' at end of format block");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (1)
|
||||||
|
// Check if there is a string to pass through to output
|
||||||
|
char *start = _ptr; // Record start of the next string
|
||||||
|
while ((_curchar != '$') && (_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
|
||||||
|
if (_curchar == '\\') next_char(); // superquote
|
||||||
|
if (_curchar == '\n') parse_err(SYNERR, "newline in string"); // unimplemented!
|
||||||
|
next_char();
|
||||||
|
}
|
||||||
|
// If a string was found, terminate it and record in FormatRule
|
||||||
|
if ( start != _ptr ) {
|
||||||
|
*_ptr = '\0'; // Terminate the string
|
||||||
|
format->_strings.addName(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
// (2)
|
||||||
|
// If we are at a replacement variable,
|
||||||
|
// copy it and record in FormatRule
|
||||||
|
if ( _curchar == '$' ) {
|
||||||
|
next_char(); // Move past the '$'
|
||||||
|
char* rep_var = get_ident(); // Nil terminate the variable name
|
||||||
|
rep_var = strdup(rep_var);// Copy the string
|
||||||
|
*_ptr = _curchar; // and replace Nil with original character
|
||||||
|
format->_rep_vars.addName(rep_var);
|
||||||
|
// Add flag to _strings list indicating we should check _rep_vars
|
||||||
|
format->_strings.addName(NameList::_signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// (3)
|
||||||
|
// Allow very long strings to be broken up,
|
||||||
|
// using the ANSI C syntax "foo\n" <newline> "bar"
|
||||||
|
if ( _curchar == '"') {
|
||||||
|
next_char(); // Move past the '"'
|
||||||
|
skipws(); // Skip white space before next string token
|
||||||
|
if ( _curchar != '"') {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// Found one. Skip both " and the whitespace in between.
|
||||||
|
next_char();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // end while part of format description
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Add flag to _strings list indicating we should check _rep_vars
|
||||||
|
format->_rep_vars.addName(rep_var);
|
||||||
|
// Add flag to _strings list indicating we should check _rep_vars
|
||||||
|
format->_strings.addName(NameList::_signal3);
|
||||||
|
}
|
||||||
|
} // end while part of format description
|
||||||
|
}
|
||||||
|
|
||||||
|
skipws();
|
||||||
|
// Past format description, at '%'
|
||||||
|
if ( _curchar != '%' || *(_ptr+1) != '}' ) {
|
||||||
|
parse_err(SYNERR, "missing '%}' at end of format block");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
next_char(); // Move past the '%'
|
||||||
|
next_char(); // Move past the '}'
|
||||||
|
|
||||||
|
// Debug Stuff
|
||||||
|
if (_AD._adl_debug > 1) fprintf(stderr,"Format Rule: %s\n", desc);
|
||||||
|
|
||||||
|
skipws();
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------effect_parse-----------------------------------
|
//------------------------------effect_parse-----------------------------------
|
||||||
void ADLParser::effect_parse(InstructForm *instr) {
|
void ADLParser::effect_parse(InstructForm *instr) {
|
||||||
char* desc = NULL;
|
char* desc = NULL;
|
||||||
@ -3777,7 +3943,7 @@ char* ADLParser::find_cpp_block(const char* description) {
|
|||||||
skipws_no_preproc(); // Skip leading whitespace
|
skipws_no_preproc(); // Skip leading whitespace
|
||||||
cppBlock = _ptr; // Point to start of expression
|
cppBlock = _ptr; // Point to start of expression
|
||||||
const char* file = _AD._ADL_file._name;
|
const char* file = _AD._ADL_file._name;
|
||||||
int line = _linenum;
|
int line = linenum();
|
||||||
next = _ptr + 1;
|
next = _ptr + 1;
|
||||||
while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) {
|
while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) {
|
||||||
next_char_or_line();
|
next_char_or_line();
|
||||||
@ -4297,11 +4463,11 @@ void ADLParser::parse_err(int flag, const char *fmt, ...) {
|
|||||||
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
if (flag == 1)
|
if (flag == 1)
|
||||||
_AD._syntax_errs += _AD.emit_msg(0, flag, _linenum, fmt, args);
|
_AD._syntax_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
|
||||||
else if (flag == 2)
|
else if (flag == 2)
|
||||||
_AD._semantic_errs += _AD.emit_msg(0, flag, _linenum, fmt, args);
|
_AD._semantic_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
|
||||||
else
|
else
|
||||||
_AD._warnings += _AD.emit_msg(0, flag, _linenum, fmt, args);
|
_AD._warnings += _AD.emit_msg(0, flag, linenum(), fmt, args);
|
||||||
|
|
||||||
int error_char = _curchar;
|
int error_char = _curchar;
|
||||||
char* error_ptr = _ptr+1;
|
char* error_ptr = _ptr+1;
|
||||||
@ -4515,7 +4681,7 @@ void ADLParser::next_char_or_line() {
|
|||||||
|
|
||||||
//---------------------------next_line-----------------------------------------
|
//---------------------------next_line-----------------------------------------
|
||||||
void ADLParser::next_line() {
|
void ADLParser::next_line() {
|
||||||
_curline = _buf.get_line(); _linenum++;
|
_curline = _buf.get_line();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------is_literal_constant---------------------------------
|
//-------------------------is_literal_constant---------------------------------
|
||||||
|
@ -70,7 +70,6 @@ class ADLParser {
|
|||||||
protected:
|
protected:
|
||||||
char *_curline; // Start of current line
|
char *_curline; // Start of current line
|
||||||
char *_ptr; // Pointer into current location in File Buffer
|
char *_ptr; // Pointer into current location in File Buffer
|
||||||
int _linenum; // Count of line numbers seen so far
|
|
||||||
char _curchar; // Current character from buffer
|
char _curchar; // Current character from buffer
|
||||||
FormDict &_globalNames; // Global names
|
FormDict &_globalNames; // Global names
|
||||||
|
|
||||||
@ -160,9 +159,10 @@ protected:
|
|||||||
Interface *interface_parse(); // Parse operand interface rule
|
Interface *interface_parse(); // Parse operand interface rule
|
||||||
Interface *mem_interface_parse(); // Parse memory interface rule
|
Interface *mem_interface_parse(); // Parse memory interface rule
|
||||||
Interface *cond_interface_parse(); // Parse conditional interface rule
|
Interface *cond_interface_parse(); // Parse conditional interface rule
|
||||||
char *interface_field_parse();// Parse field contents
|
char *interface_field_parse(const char** format = NULL);// Parse field contents
|
||||||
|
|
||||||
FormatRule *format_parse(void); // Parse format rule
|
FormatRule *format_parse(void); // Parse format rule
|
||||||
|
FormatRule *template_parse(void); // Parse format rule
|
||||||
void effect_parse(InstructForm *instr); // Parse effect rule
|
void effect_parse(InstructForm *instr); // Parse effect rule
|
||||||
ExpandRule *expand_parse(InstructForm *instr); // Parse expand rule
|
ExpandRule *expand_parse(InstructForm *instr); // Parse expand rule
|
||||||
RewriteRule *rewrite_parse(void); // Parse rewrite rule
|
RewriteRule *rewrite_parse(void); // Parse rewrite rule
|
||||||
@ -263,7 +263,7 @@ public:
|
|||||||
|
|
||||||
void parse(void); // Do the parsing & build forms lists
|
void parse(void); // Do the parsing & build forms lists
|
||||||
|
|
||||||
int getlines( ) { return _linenum; }
|
int linenum() { return _buf.linenum(); }
|
||||||
|
|
||||||
static bool is_literal_constant(const char *hex_string);
|
static bool is_literal_constant(const char *hex_string);
|
||||||
static bool is_hex_digit(char digit);
|
static bool is_hex_digit(char digit);
|
||||||
|
@ -41,6 +41,7 @@ FileBuff::FileBuff( BufferedFile *fptr, ArchDesc& archDesc) : _fp(fptr), _AD(arc
|
|||||||
exit(1); // Exit on seek error
|
exit(1); // Exit on seek error
|
||||||
}
|
}
|
||||||
_filepos = ftell(_fp->_fp); // Reset current file position
|
_filepos = ftell(_fp->_fp); // Reset current file position
|
||||||
|
_linenum = 0;
|
||||||
|
|
||||||
_bigbuf = new char[_bufferSize]; // Create buffer to hold text for parser
|
_bigbuf = new char[_bufferSize]; // Create buffer to hold text for parser
|
||||||
if( !_bigbuf ) {
|
if( !_bigbuf ) {
|
||||||
@ -76,6 +77,7 @@ char *FileBuff::get_line(void) {
|
|||||||
// Check for end of file & return NULL
|
// Check for end of file & return NULL
|
||||||
if (_bufeol >= _bufmax) return NULL;
|
if (_bufeol >= _bufmax) return NULL;
|
||||||
|
|
||||||
|
_linenum++;
|
||||||
retval = ++_bufeol; // return character following end of previous line
|
retval = ++_bufeol; // return character following end of previous line
|
||||||
if (*retval == '\0') return NULL; // Check for EOF sentinal
|
if (*retval == '\0') return NULL; // Check for EOF sentinal
|
||||||
// Search for newline character which must end each line
|
// Search for newline character which must end each line
|
||||||
|
@ -51,6 +51,7 @@ class FileBuff {
|
|||||||
|
|
||||||
int _err; // Error flag for file seek/read operations
|
int _err; // Error flag for file seek/read operations
|
||||||
long _filepos; // Current offset from start of file
|
long _filepos; // Current offset from start of file
|
||||||
|
int _linenum;
|
||||||
|
|
||||||
ArchDesc& _AD; // Reference to Architecture Description
|
ArchDesc& _AD; // Reference to Architecture Description
|
||||||
|
|
||||||
@ -66,6 +67,7 @@ class FileBuff {
|
|||||||
// This returns a pointer to the start of the current line in the buffer,
|
// This returns a pointer to the start of the current line in the buffer,
|
||||||
// and increments bufeol and filepos to point at the end of that line.
|
// and increments bufeol and filepos to point at the end of that line.
|
||||||
char *get_line(void);
|
char *get_line(void);
|
||||||
|
int linenum() const { return _linenum; }
|
||||||
|
|
||||||
// This converts a pointer into the buffer to a file offset. It only works
|
// This converts a pointer into the buffer to a file offset. It only works
|
||||||
// when the pointer is valid (i.e. just obtained from getline()).
|
// when the pointer is valid (i.e. just obtained from getline()).
|
||||||
|
@ -35,6 +35,8 @@ Arena *Form::generate_arena() {
|
|||||||
//------------------------------NameList---------------------------------------
|
//------------------------------NameList---------------------------------------
|
||||||
// reserved user-defined string
|
// reserved user-defined string
|
||||||
const char *NameList::_signal = "$$SIGNAL$$";
|
const char *NameList::_signal = "$$SIGNAL$$";
|
||||||
|
const char *NameList::_signal2 = "$$SIGNAL2$$";
|
||||||
|
const char *NameList::_signal3 = "$$SIGNAL3$$";
|
||||||
|
|
||||||
// Constructor and Destructor
|
// Constructor and Destructor
|
||||||
NameList::NameList() : _cur(0), _max(4), _iter(0), _justReset(true) {
|
NameList::NameList() : _cur(0), _max(4), _iter(0), _justReset(true) {
|
||||||
|
@ -329,6 +329,8 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static const char *_signal; // reserved user-defined string
|
static const char *_signal; // reserved user-defined string
|
||||||
|
static const char *_signal2; // reserved user-defined string
|
||||||
|
static const char *_signal3; // reserved user-defined string
|
||||||
enum { Not_in_list = -1 };
|
enum { Not_in_list = -1 };
|
||||||
|
|
||||||
void addName(const char *name);
|
void addName(const char *name);
|
||||||
|
@ -1574,10 +1574,10 @@ Opcode::opcode_type Opcode::as_opcode_type(const char *param) {
|
|||||||
return Opcode::NOT_AN_OPCODE;
|
return Opcode::NOT_AN_OPCODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
|
bool Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
|
||||||
// Default values previously provided by MachNode::primary()...
|
// Default values previously provided by MachNode::primary()...
|
||||||
const char *description = "default_opcode()";
|
const char *description = NULL;
|
||||||
const char *value = "-1";
|
const char *value = NULL;
|
||||||
// Check if user provided any opcode definitions
|
// Check if user provided any opcode definitions
|
||||||
if( this != NULL ) {
|
if( this != NULL ) {
|
||||||
// Update 'value' if user provided a definition in the instruction
|
// Update 'value' if user provided a definition in the instruction
|
||||||
@ -1599,7 +1599,10 @@ void Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(fp, "(%s /*%s*/)", value, description);
|
if (value != NULL) {
|
||||||
|
fprintf(fp, "(%s /*%s*/)", value, description);
|
||||||
|
}
|
||||||
|
return value != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Opcode::dump() {
|
void Opcode::dump() {
|
||||||
@ -2610,14 +2613,19 @@ void MemInterface::output(FILE *fp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------CondInterface----------------------------------
|
//------------------------------CondInterface----------------------------------
|
||||||
CondInterface::CondInterface(char *equal, char *not_equal,
|
CondInterface::CondInterface(const char* equal, const char* equal_format,
|
||||||
char *less, char *greater_equal,
|
const char* not_equal, const char* not_equal_format,
|
||||||
char *less_equal, char *greater)
|
const char* less, const char* less_format,
|
||||||
|
const char* greater_equal, const char* greater_equal_format,
|
||||||
|
const char* less_equal, const char* less_equal_format,
|
||||||
|
const char* greater, const char* greater_format)
|
||||||
: Interface("COND_INTER"),
|
: Interface("COND_INTER"),
|
||||||
_equal(equal), _not_equal(not_equal),
|
_equal(equal), _equal_format(equal_format),
|
||||||
_less(less), _greater_equal(greater_equal),
|
_not_equal(not_equal), _not_equal_format(not_equal_format),
|
||||||
_less_equal(less_equal), _greater(greater) {
|
_less(less), _less_format(less_format),
|
||||||
//
|
_greater_equal(greater_equal), _greater_equal_format(greater_equal_format),
|
||||||
|
_less_equal(less_equal), _less_equal_format(less_equal_format),
|
||||||
|
_greater(greater), _greater_format(greater_format) {
|
||||||
}
|
}
|
||||||
CondInterface::~CondInterface() {
|
CondInterface::~CondInterface() {
|
||||||
// not owner of any character arrays
|
// not owner of any character arrays
|
||||||
@ -3316,7 +3324,7 @@ int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
|
|||||||
"Load8B" ,"Load4B" ,"Load8C" ,"Load4C" ,"Load2C" ,"Load8S", "Load4S","Load2S",
|
"Load8B" ,"Load4B" ,"Load8C" ,"Load4C" ,"Load2C" ,"Load8S", "Load4S","Load2S",
|
||||||
"LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
|
"LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
|
||||||
"LoadPLocked", "LoadLLocked",
|
"LoadPLocked", "LoadLLocked",
|
||||||
"StorePConditional", "StoreLConditional",
|
"StorePConditional", "StoreIConditional", "StoreLConditional",
|
||||||
"CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
|
"CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
|
||||||
"StoreCM",
|
"StoreCM",
|
||||||
"ClearArray"
|
"ClearArray"
|
||||||
|
@ -397,7 +397,7 @@ public:
|
|||||||
void output(FILE *fp);
|
void output(FILE *fp);
|
||||||
|
|
||||||
// --------------------------- FILE *output_routines
|
// --------------------------- FILE *output_routines
|
||||||
void print_opcode(FILE *fp, Opcode::opcode_type desired_opcode);
|
bool print_opcode(FILE *fp, Opcode::opcode_type desired_opcode);
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------InsEncode--------------------------------------
|
//------------------------------InsEncode--------------------------------------
|
||||||
@ -779,10 +779,20 @@ public:
|
|||||||
const char *_greater_equal;
|
const char *_greater_equal;
|
||||||
const char *_less_equal;
|
const char *_less_equal;
|
||||||
const char *_greater;
|
const char *_greater;
|
||||||
|
const char *_equal_format;
|
||||||
|
const char *_not_equal_format;
|
||||||
|
const char *_less_format;
|
||||||
|
const char *_greater_equal_format;
|
||||||
|
const char *_less_equal_format;
|
||||||
|
const char *_greater_format;
|
||||||
|
|
||||||
// Public Methods
|
// Public Methods
|
||||||
CondInterface(char *equal, char *not_equal, char *less, char *greater_equal,
|
CondInterface(const char* equal, const char* equal_format,
|
||||||
char *less_equal, char *greater);
|
const char* not_equal, const char* not_equal_format,
|
||||||
|
const char* less, const char* less_format,
|
||||||
|
const char* greater_equal, const char* greater_equal_format,
|
||||||
|
const char* less_equal, const char* less_equal_format,
|
||||||
|
const char* greater, const char* greater_format);
|
||||||
~CondInterface();
|
~CondInterface();
|
||||||
|
|
||||||
void dump();
|
void dump();
|
||||||
|
@ -1619,6 +1619,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over the new instruction's operands
|
// Iterate over the new instruction's operands
|
||||||
|
int prev_pos = -1;
|
||||||
for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) {
|
for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) {
|
||||||
// Use 'parameter' at current position in list of new instruction's formals
|
// Use 'parameter' at current position in list of new instruction's formals
|
||||||
// instead of 'opid' when looking up info internal to new_inst
|
// instead of 'opid' when looking up info internal to new_inst
|
||||||
@ -1642,6 +1643,18 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
|
|||||||
// ins = (InstructForm *) _globalNames[new_id];
|
// ins = (InstructForm *) _globalNames[new_id];
|
||||||
exp_pos = node->operand_position_format(opid);
|
exp_pos = node->operand_position_format(opid);
|
||||||
assert(exp_pos != -1, "Bad expand rule");
|
assert(exp_pos != -1, "Bad expand rule");
|
||||||
|
if (prev_pos > exp_pos && expand_instruction->_matrule != NULL) {
|
||||||
|
// For the add_req calls below to work correctly they need
|
||||||
|
// to added in the same order that a match would add them.
|
||||||
|
// This means that they would need to be in the order of
|
||||||
|
// the components list instead of the formal parameters.
|
||||||
|
// This is a sort of hidden invariant that previously
|
||||||
|
// wasn't checked and could lead to incorrectly
|
||||||
|
// constructed nodes.
|
||||||
|
syntax_err(node->_linenum, "For expand in %s to work, parameter declaration order in %s must follow matchrule\n",
|
||||||
|
node->_ident, new_inst->_ident);
|
||||||
|
}
|
||||||
|
prev_pos = exp_pos;
|
||||||
|
|
||||||
new_pos = new_inst->operand_position(parameter,Component::USE);
|
new_pos = new_inst->operand_position(parameter,Component::USE);
|
||||||
if (new_pos != -1) {
|
if (new_pos != -1) {
|
||||||
@ -2306,7 +2319,12 @@ private:
|
|||||||
_processing_noninput = false;
|
_processing_noninput = false;
|
||||||
// A replacement variable, originally '$'
|
// A replacement variable, originally '$'
|
||||||
if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
|
if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
|
||||||
_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) );
|
if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
|
||||||
|
// Missing opcode
|
||||||
|
_AD.syntax_err( _inst._linenum,
|
||||||
|
"Missing $%s opcode definition in %s, used by encoding %s\n",
|
||||||
|
rep_var, _inst._ident, _encoding._name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Lookup its position in parameter list
|
// Lookup its position in parameter list
|
||||||
@ -2348,7 +2366,13 @@ private:
|
|||||||
else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
|
else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
|
||||||
// else check if "primary", "secondary", "tertiary"
|
// else check if "primary", "secondary", "tertiary"
|
||||||
assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
|
assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
|
||||||
_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) );
|
if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) )) {
|
||||||
|
// Missing opcode
|
||||||
|
_AD.syntax_err( _inst._linenum,
|
||||||
|
"Missing $%s opcode definition in %s\n",
|
||||||
|
rep_var, _inst._ident);
|
||||||
|
|
||||||
|
}
|
||||||
_constant_status = LITERAL_OUTPUT;
|
_constant_status = LITERAL_OUTPUT;
|
||||||
}
|
}
|
||||||
else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) {
|
else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) {
|
||||||
|
@ -355,17 +355,19 @@ static void defineConstructor(FILE *fp, const char *name, uint num_consts,
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Generate the format rule for condition codes
|
// Generate the format rule for condition codes
|
||||||
static void defineCCodeDump(FILE *fp, int i) {
|
static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) {
|
||||||
fprintf(fp, " if( _c%d == BoolTest::eq ) st->print(\"eq\");\n",i);
|
assert(oper != NULL, "what");
|
||||||
fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print(\"ne\");\n",i);
|
CondInterface* cond = oper->_interface->is_CondInterface();
|
||||||
fprintf(fp, " else if( _c%d == BoolTest::le ) st->print(\"le\");\n",i);
|
fprintf(fp, " if( _c%d == BoolTest::eq ) st->print(\"%s\");\n",i,cond->_equal_format);
|
||||||
fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"ge\");\n",i);
|
fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print(\"%s\");\n",i,cond->_not_equal_format);
|
||||||
fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"lt\");\n",i);
|
fprintf(fp, " else if( _c%d == BoolTest::le ) st->print(\"%s\");\n",i,cond->_less_equal_format);
|
||||||
fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"gt\");\n",i);
|
fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format);
|
||||||
|
fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format);
|
||||||
|
fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output code that dumps constant values, increment "i" if type is constant
|
// Output code that dumps constant values, increment "i" if type is constant
|
||||||
static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) {
|
static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, OperandForm* oper) {
|
||||||
if (!strcmp(ideal_type, "ConI")) {
|
if (!strcmp(ideal_type, "ConI")) {
|
||||||
fprintf(fp," st->print(\"#%%d\", _c%d);\n", i);
|
fprintf(fp," st->print(\"#%%d\", _c%d);\n", i);
|
||||||
++i;
|
++i;
|
||||||
@ -375,7 +377,7 @@ static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) {
|
|||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
else if (!strcmp(ideal_type, "ConN")) {
|
else if (!strcmp(ideal_type, "ConN")) {
|
||||||
fprintf(fp," _c%d->dump();\n", i);
|
fprintf(fp," _c%d->dump_on(st);\n", i);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
else if (!strcmp(ideal_type, "ConL")) {
|
else if (!strcmp(ideal_type, "ConL")) {
|
||||||
@ -391,7 +393,7 @@ static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) {
|
|||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
else if (!strcmp(ideal_type, "Bool")) {
|
else if (!strcmp(ideal_type, "Bool")) {
|
||||||
defineCCodeDump(fp,i);
|
defineCCodeDump(oper, fp,i);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,7 +478,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_
|
|||||||
}
|
}
|
||||||
// ALWAYS! Provide a special case output for condition codes.
|
// ALWAYS! Provide a special case output for condition codes.
|
||||||
if( oper.is_ideal_bool() ) {
|
if( oper.is_ideal_bool() ) {
|
||||||
defineCCodeDump(fp,0);
|
defineCCodeDump(&oper, fp,0);
|
||||||
}
|
}
|
||||||
fprintf(fp,"}\n");
|
fprintf(fp,"}\n");
|
||||||
|
|
||||||
@ -549,7 +551,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_
|
|||||||
}
|
}
|
||||||
// ALWAYS! Provide a special case output for condition codes.
|
// ALWAYS! Provide a special case output for condition codes.
|
||||||
if( oper.is_ideal_bool() ) {
|
if( oper.is_ideal_bool() ) {
|
||||||
defineCCodeDump(fp,0);
|
defineCCodeDump(&oper, fp,0);
|
||||||
}
|
}
|
||||||
fprintf(fp, "}\n");
|
fprintf(fp, "}\n");
|
||||||
fprintf(fp, "#endif\n");
|
fprintf(fp, "#endif\n");
|
||||||
@ -583,10 +585,53 @@ void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &inst, bool for_c
|
|||||||
while( (string = inst._format->_strings.iter()) != NULL ) {
|
while( (string = inst._format->_strings.iter()) != NULL ) {
|
||||||
fprintf(fp," ");
|
fprintf(fp," ");
|
||||||
// Check if this is a standard string or a replacement variable
|
// Check if this is a standard string or a replacement variable
|
||||||
if( string != NameList::_signal ) // Normal string. Pass through.
|
if( string == NameList::_signal ) { // Replacement variable
|
||||||
|
const char* rep_var = inst._format->_rep_vars.iter();
|
||||||
|
inst.rep_var_format( fp, rep_var);
|
||||||
|
} else if( string == NameList::_signal3 ) { // Replacement variable in raw text
|
||||||
|
const char* rep_var = inst._format->_rep_vars.iter();
|
||||||
|
const Form *form = inst._localNames[rep_var];
|
||||||
|
if (form == NULL) {
|
||||||
|
fprintf(stderr, "unknown replacement variable in format statement: '%s'\n", rep_var);
|
||||||
|
assert(false, "ShouldNotReachHere()");
|
||||||
|
}
|
||||||
|
OpClassForm *opc = form->is_opclass();
|
||||||
|
assert( opc, "replacement variable was not found in local names");
|
||||||
|
// Lookup the index position of the replacement variable
|
||||||
|
int idx = inst.operand_position_format(rep_var);
|
||||||
|
if ( idx == -1 ) {
|
||||||
|
assert( strcmp(opc->_ident,"label")==0, "Unimplemented");
|
||||||
|
assert( false, "ShouldNotReachHere()");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inst.is_noninput_operand(idx)) {
|
||||||
|
assert( false, "ShouldNotReachHere()");
|
||||||
|
} else {
|
||||||
|
// Output the format call for this operand
|
||||||
|
fprintf(fp,"opnd_array(%d)",idx);
|
||||||
|
}
|
||||||
|
rep_var = inst._format->_rep_vars.iter();
|
||||||
|
inst._format->_strings.iter();
|
||||||
|
if ( strcmp(rep_var,"$constant") == 0 && opc->is_operand()) {
|
||||||
|
Form::DataType constant_type = form->is_operand()->is_base_constant(globals);
|
||||||
|
if ( constant_type == Form::idealD ) {
|
||||||
|
fprintf(fp,"->constantD()");
|
||||||
|
} else if ( constant_type == Form::idealF ) {
|
||||||
|
fprintf(fp,"->constantF()");
|
||||||
|
} else if ( constant_type == Form::idealL ) {
|
||||||
|
fprintf(fp,"->constantL()");
|
||||||
|
} else {
|
||||||
|
fprintf(fp,"->constant()");
|
||||||
|
}
|
||||||
|
} else if ( strcmp(rep_var,"$cmpcode") == 0) {
|
||||||
|
fprintf(fp,"->ccode()");
|
||||||
|
} else {
|
||||||
|
assert( false, "ShouldNotReachHere()");
|
||||||
|
}
|
||||||
|
} else if( string == NameList::_signal2 ) // Raw program text
|
||||||
|
fputs(inst._format->_strings.iter(), fp);
|
||||||
|
else
|
||||||
fprintf(fp,"st->print(\"%s\");\n", string);
|
fprintf(fp,"st->print(\"%s\");\n", string);
|
||||||
else // Replacement variable
|
|
||||||
inst.rep_var_format( fp, inst._format->_rep_vars.iter() );
|
|
||||||
} // Done with all format strings
|
} // Done with all format strings
|
||||||
} // Done generating the user-defined portion of the format
|
} // Done generating the user-defined portion of the format
|
||||||
|
|
||||||
@ -1404,7 +1449,7 @@ void ArchDesc::declareClasses(FILE *fp) {
|
|||||||
oper->_components.reset();
|
oper->_components.reset();
|
||||||
if ((comp = oper->_components.iter()) == NULL) {
|
if ((comp = oper->_components.iter()) == NULL) {
|
||||||
assert(num_consts == 1, "Bad component list detected.\n");
|
assert(num_consts == 1, "Bad component list detected.\n");
|
||||||
i = dump_spec_constant( fp, type, i );
|
i = dump_spec_constant( fp, type, i, oper );
|
||||||
// Check that type actually matched
|
// Check that type actually matched
|
||||||
assert( i != 0, "Non-constant operand lacks component list.");
|
assert( i != 0, "Non-constant operand lacks component list.");
|
||||||
} // end if NULL
|
} // end if NULL
|
||||||
@ -1414,7 +1459,7 @@ void ArchDesc::declareClasses(FILE *fp) {
|
|||||||
oper->_components.reset();
|
oper->_components.reset();
|
||||||
while((comp = oper->_components.iter()) != NULL) {
|
while((comp = oper->_components.iter()) != NULL) {
|
||||||
type = comp->base_type(_globalNames);
|
type = comp->base_type(_globalNames);
|
||||||
i = dump_spec_constant( fp, type, i );
|
i = dump_spec_constant( fp, type, i, NULL );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// finish line (3)
|
// finish line (3)
|
||||||
|
@ -28,8 +28,9 @@
|
|||||||
Bytecodes::Code RawBytecodeStream::raw_next_special(Bytecodes::Code code) {
|
Bytecodes::Code RawBytecodeStream::raw_next_special(Bytecodes::Code code) {
|
||||||
assert(!is_last_bytecode(), "should have been checked");
|
assert(!is_last_bytecode(), "should have been checked");
|
||||||
// set next bytecode position
|
// set next bytecode position
|
||||||
address bcp = RawBytecodeStream::bcp();
|
address bcp = RawBytecodeStream::bcp();
|
||||||
int l = Bytecodes::raw_special_length_at(bcp);
|
address end = method()->code_base() + end_bci();
|
||||||
|
int l = Bytecodes::raw_special_length_at(bcp, end);
|
||||||
if (l <= 0 || (_bci + l) > _end_bci) {
|
if (l <= 0 || (_bci + l) > _end_bci) {
|
||||||
code = Bytecodes::_illegal;
|
code = Bytecodes::_illegal;
|
||||||
} else {
|
} else {
|
||||||
@ -39,8 +40,12 @@ Bytecodes::Code RawBytecodeStream::raw_next_special(Bytecodes::Code code) {
|
|||||||
_is_wide = false;
|
_is_wide = false;
|
||||||
// check for special (uncommon) cases
|
// check for special (uncommon) cases
|
||||||
if (code == Bytecodes::_wide) {
|
if (code == Bytecodes::_wide) {
|
||||||
code = (Bytecodes::Code)bcp[1];
|
if (bcp + 1 >= end) {
|
||||||
_is_wide = true;
|
code = Bytecodes::_illegal;
|
||||||
|
} else {
|
||||||
|
code = (Bytecodes::Code)bcp[1];
|
||||||
|
_is_wide = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_code = code;
|
_code = code;
|
||||||
|
@ -54,13 +54,19 @@ Bytecodes::Code Bytecodes::non_breakpoint_code_at(address bcp, methodOop method)
|
|||||||
return method->orig_bytecode_at(method->bci_from(bcp));
|
return method->orig_bytecode_at(method->bci_from(bcp));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Bytecodes::special_length_at(address bcp) {
|
int Bytecodes::special_length_at(address bcp, address end) {
|
||||||
Code code = code_at(bcp);
|
Code code = code_at(bcp);
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case _wide:
|
case _wide:
|
||||||
|
if (end != NULL && bcp + 1 >= end) {
|
||||||
|
return -1; // don't read past end of code buffer
|
||||||
|
}
|
||||||
return wide_length_for(cast(*(bcp + 1)));
|
return wide_length_for(cast(*(bcp + 1)));
|
||||||
case _tableswitch:
|
case _tableswitch:
|
||||||
{ address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
|
{ address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
|
||||||
|
if (end != NULL && aligned_bcp + 3*jintSize >= end) {
|
||||||
|
return -1; // don't read past end of code buffer
|
||||||
|
}
|
||||||
jlong lo = (jint)Bytes::get_Java_u4(aligned_bcp + 1*jintSize);
|
jlong lo = (jint)Bytes::get_Java_u4(aligned_bcp + 1*jintSize);
|
||||||
jlong hi = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
|
jlong hi = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
|
||||||
jlong len = (aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize;
|
jlong len = (aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize;
|
||||||
@ -73,6 +79,9 @@ int Bytecodes::special_length_at(address bcp) {
|
|||||||
case _fast_binaryswitch: // fall through
|
case _fast_binaryswitch: // fall through
|
||||||
case _fast_linearswitch:
|
case _fast_linearswitch:
|
||||||
{ address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
|
{ address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
|
||||||
|
if (end != NULL && aligned_bcp + 2*jintSize >= end) {
|
||||||
|
return -1; // don't read past end of code buffer
|
||||||
|
}
|
||||||
jlong npairs = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
|
jlong npairs = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
|
||||||
jlong len = (aligned_bcp - bcp) + (2 + 2*npairs)*jintSize;
|
jlong len = (aligned_bcp - bcp) + (2 + 2*npairs)*jintSize;
|
||||||
// only return len if it can be represented as a positive int;
|
// only return len if it can be represented as a positive int;
|
||||||
@ -90,14 +99,17 @@ int Bytecodes::special_length_at(address bcp) {
|
|||||||
// verifier when reading in bytecode to verify. Other mechanisms that
|
// verifier when reading in bytecode to verify. Other mechanisms that
|
||||||
// run at runtime (such as generateOopMaps) need to iterate over the code
|
// run at runtime (such as generateOopMaps) need to iterate over the code
|
||||||
// and don't expect to see breakpoints: they want to see the instruction
|
// and don't expect to see breakpoints: they want to see the instruction
|
||||||
// which was replaces so that they can get the correct length and find
|
// which was replaced so that they can get the correct length and find
|
||||||
// the next bytecode.
|
// the next bytecode.
|
||||||
int Bytecodes::raw_special_length_at(address bcp) {
|
//
|
||||||
|
// 'end' indicates the end of the code buffer, which we should not try to read
|
||||||
|
// past.
|
||||||
|
int Bytecodes::raw_special_length_at(address bcp, address end) {
|
||||||
Code code = code_or_bp_at(bcp);
|
Code code = code_or_bp_at(bcp);
|
||||||
if (code == _breakpoint) {
|
if (code == _breakpoint) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return special_length_at(bcp);
|
return special_length_at(bcp, end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,8 +340,10 @@ class Bytecodes: AllStatic {
|
|||||||
const char* wf = wide_format(code);
|
const char* wf = wide_format(code);
|
||||||
return (wf == NULL) ? 0 : (int)strlen(wf);
|
return (wf == NULL) ? 0 : (int)strlen(wf);
|
||||||
}
|
}
|
||||||
static int special_length_at(address bcp);
|
// if 'end' is provided, it indicates the end of the code buffer which
|
||||||
static int raw_special_length_at(address bcp);
|
// should not be read past when parsing.
|
||||||
|
static int special_length_at(address bcp, address end = NULL);
|
||||||
|
static int raw_special_length_at(address bcp, address end = NULL);
|
||||||
static int length_at (address bcp) { int l = length_for(code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
|
static int length_at (address bcp) { int l = length_for(code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
|
||||||
static int java_length_at (address bcp) { int l = length_for(java_code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
|
static int java_length_at (address bcp) { int l = length_for(java_code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
|
||||||
static bool is_java_code (Code code) { return 0 <= code && code < number_of_java_codes; }
|
static bool is_java_code (Code code) { return 0 <= code && code < number_of_java_codes; }
|
||||||
|
@ -57,6 +57,14 @@ void Block_List::insert(uint i, Block *b) {
|
|||||||
_blocks[i] = b;
|
_blocks[i] = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PRODUCT
|
||||||
|
void Block_List::print() {
|
||||||
|
for (uint i=0; i < size(); i++) {
|
||||||
|
tty->print("B%d ", _blocks[i]->_pre_order);
|
||||||
|
}
|
||||||
|
tty->print("size = %d\n", size());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
@ -66,6 +74,12 @@ uint Block::code_alignment() {
|
|||||||
// Check for Start block
|
// Check for Start block
|
||||||
if( _pre_order == 1 ) return InteriorEntryAlignment;
|
if( _pre_order == 1 ) return InteriorEntryAlignment;
|
||||||
// Check for loop alignment
|
// Check for loop alignment
|
||||||
|
if (has_loop_alignment()) return loop_alignment();
|
||||||
|
|
||||||
|
return 1; // no particular alignment
|
||||||
|
}
|
||||||
|
|
||||||
|
uint Block::compute_loop_alignment() {
|
||||||
Node *h = head();
|
Node *h = head();
|
||||||
if( h->is_Loop() && h->as_Loop()->is_inner_loop() ) {
|
if( h->is_Loop() && h->as_Loop()->is_inner_loop() ) {
|
||||||
// Pre- and post-loops have low trip count so do not bother with
|
// Pre- and post-loops have low trip count so do not bother with
|
||||||
@ -83,13 +97,15 @@ uint Block::code_alignment() {
|
|||||||
}
|
}
|
||||||
return OptoLoopAlignment; // Otherwise align loop head
|
return OptoLoopAlignment; // Otherwise align loop head
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1; // no particular alignment
|
return 1; // no particular alignment
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Compute the size of first 'inst_cnt' instructions in this block.
|
// Compute the size of first 'inst_cnt' instructions in this block.
|
||||||
// Return the number of instructions left to compute if the block has
|
// Return the number of instructions left to compute if the block has
|
||||||
// less then 'inst_cnt' instructions.
|
// less then 'inst_cnt' instructions. Stop, and return 0 if sum_size
|
||||||
|
// exceeds OptoLoopAlignment.
|
||||||
uint Block::compute_first_inst_size(uint& sum_size, uint inst_cnt,
|
uint Block::compute_first_inst_size(uint& sum_size, uint inst_cnt,
|
||||||
PhaseRegAlloc* ra) {
|
PhaseRegAlloc* ra) {
|
||||||
uint last_inst = _nodes.size();
|
uint last_inst = _nodes.size();
|
||||||
@ -307,6 +323,8 @@ void Block::dump_head( const Block_Array *bbs ) const {
|
|||||||
tty->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order);
|
tty->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order);
|
||||||
// Dump any loop-specific bits, especially for CountedLoops.
|
// Dump any loop-specific bits, especially for CountedLoops.
|
||||||
loop->dump_spec(tty);
|
loop->dump_spec(tty);
|
||||||
|
} else if (has_loop_alignment()) {
|
||||||
|
tty->print(" top-of-loop");
|
||||||
}
|
}
|
||||||
tty->print(" Freq: %g",_freq);
|
tty->print(" Freq: %g",_freq);
|
||||||
if( Verbose || WizardMode ) {
|
if( Verbose || WizardMode ) {
|
||||||
@ -509,9 +527,11 @@ static bool no_flip_branch( Block *b ) {
|
|||||||
int branch_idx = b->_nodes.size() - b->_num_succs-1;
|
int branch_idx = b->_nodes.size() - b->_num_succs-1;
|
||||||
if( branch_idx < 1 ) return false;
|
if( branch_idx < 1 ) return false;
|
||||||
Node *bra = b->_nodes[branch_idx];
|
Node *bra = b->_nodes[branch_idx];
|
||||||
if( bra->is_Catch() ) return true;
|
if( bra->is_Catch() )
|
||||||
|
return true;
|
||||||
if( bra->is_Mach() ) {
|
if( bra->is_Mach() ) {
|
||||||
if( bra->is_MachNullCheck() ) return true;
|
if( bra->is_MachNullCheck() )
|
||||||
|
return true;
|
||||||
int iop = bra->as_Mach()->ideal_Opcode();
|
int iop = bra->as_Mach()->ideal_Opcode();
|
||||||
if( iop == Op_FastLock || iop == Op_FastUnlock )
|
if( iop == Op_FastLock || iop == Op_FastUnlock )
|
||||||
return true;
|
return true;
|
||||||
@ -557,10 +577,10 @@ void PhaseCFG::convert_NeverBranch_to_Goto(Block *b) {
|
|||||||
dead->_nodes[k]->del_req(j);
|
dead->_nodes[k]->del_req(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------MoveToNext-------------------------------------
|
//------------------------------move_to_next-----------------------------------
|
||||||
// Helper function to move block bx to the slot following b_index. Return
|
// Helper function to move block bx to the slot following b_index. Return
|
||||||
// true if the move is successful, otherwise false
|
// true if the move is successful, otherwise false
|
||||||
bool PhaseCFG::MoveToNext(Block* bx, uint b_index) {
|
bool PhaseCFG::move_to_next(Block* bx, uint b_index) {
|
||||||
if (bx == NULL) return false;
|
if (bx == NULL) return false;
|
||||||
|
|
||||||
// Return false if bx is already scheduled.
|
// Return false if bx is already scheduled.
|
||||||
@ -591,9 +611,9 @@ bool PhaseCFG::MoveToNext(Block* bx, uint b_index) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------MoveToEnd--------------------------------------
|
//------------------------------move_to_end------------------------------------
|
||||||
// Move empty and uncommon blocks to the end.
|
// Move empty and uncommon blocks to the end.
|
||||||
void PhaseCFG::MoveToEnd(Block *b, uint i) {
|
void PhaseCFG::move_to_end(Block *b, uint i) {
|
||||||
int e = b->is_Empty();
|
int e = b->is_Empty();
|
||||||
if (e != Block::not_empty) {
|
if (e != Block::not_empty) {
|
||||||
if (e == Block::empty_with_goto) {
|
if (e == Block::empty_with_goto) {
|
||||||
@ -609,15 +629,31 @@ void PhaseCFG::MoveToEnd(Block *b, uint i) {
|
|||||||
_blocks.push(b);
|
_blocks.push(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------RemoveEmpty------------------------------------
|
//---------------------------set_loop_alignment--------------------------------
|
||||||
// Remove empty basic blocks and useless branches.
|
// Set loop alignment for every block
|
||||||
void PhaseCFG::RemoveEmpty() {
|
void PhaseCFG::set_loop_alignment() {
|
||||||
|
uint last = _num_blocks;
|
||||||
|
assert( _blocks[0] == _broot, "" );
|
||||||
|
|
||||||
|
for (uint i = 1; i < last; i++ ) {
|
||||||
|
Block *b = _blocks[i];
|
||||||
|
if (b->head()->is_Loop()) {
|
||||||
|
b->set_loop_alignment(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------remove_empty------------------------------------
|
||||||
|
// Make empty basic blocks to be "connector" blocks, Move uncommon blocks
|
||||||
|
// to the end.
|
||||||
|
void PhaseCFG::remove_empty() {
|
||||||
// Move uncommon blocks to the end
|
// Move uncommon blocks to the end
|
||||||
uint last = _num_blocks;
|
uint last = _num_blocks;
|
||||||
uint i;
|
|
||||||
assert( _blocks[0] == _broot, "" );
|
assert( _blocks[0] == _broot, "" );
|
||||||
for( i = 1; i < last; i++ ) {
|
|
||||||
|
for (uint i = 1; i < last; i++) {
|
||||||
Block *b = _blocks[i];
|
Block *b = _blocks[i];
|
||||||
|
if (b->is_connector()) break;
|
||||||
|
|
||||||
// Check for NeverBranch at block end. This needs to become a GOTO to the
|
// Check for NeverBranch at block end. This needs to become a GOTO to the
|
||||||
// true target. NeverBranch are treated as a conditional branch that
|
// true target. NeverBranch are treated as a conditional branch that
|
||||||
@ -629,37 +665,40 @@ void PhaseCFG::RemoveEmpty() {
|
|||||||
convert_NeverBranch_to_Goto(b);
|
convert_NeverBranch_to_Goto(b);
|
||||||
|
|
||||||
// Look for uncommon blocks and move to end.
|
// Look for uncommon blocks and move to end.
|
||||||
if( b->is_uncommon(_bbs) ) {
|
if (!C->do_freq_based_layout()) {
|
||||||
MoveToEnd(b, i);
|
if( b->is_uncommon(_bbs) ) {
|
||||||
last--; // No longer check for being uncommon!
|
move_to_end(b, i);
|
||||||
if( no_flip_branch(b) ) { // Fall-thru case must follow?
|
last--; // No longer check for being uncommon!
|
||||||
b = _blocks[i]; // Find the fall-thru block
|
if( no_flip_branch(b) ) { // Fall-thru case must follow?
|
||||||
MoveToEnd(b, i);
|
b = _blocks[i]; // Find the fall-thru block
|
||||||
last--;
|
move_to_end(b, i);
|
||||||
|
last--;
|
||||||
|
}
|
||||||
|
i--; // backup block counter post-increment
|
||||||
}
|
}
|
||||||
i--; // backup block counter post-increment
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove empty blocks
|
// Move empty blocks to the end
|
||||||
uint j1;
|
|
||||||
last = _num_blocks;
|
last = _num_blocks;
|
||||||
for( i=0; i < last; i++ ) {
|
for (uint i = 1; i < last; i++) {
|
||||||
Block *b = _blocks[i];
|
Block *b = _blocks[i];
|
||||||
if (i > 0) {
|
if (b->is_Empty() != Block::not_empty) {
|
||||||
if (b->is_Empty() != Block::not_empty) {
|
move_to_end(b, i);
|
||||||
MoveToEnd(b, i);
|
last--;
|
||||||
last--;
|
i--;
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} // End of for all blocks
|
} // End of for all blocks
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------fixup_flow--------------------------------------
|
||||||
|
// Fix up the final control flow for basic blocks.
|
||||||
|
void PhaseCFG::fixup_flow() {
|
||||||
// Fixup final control flow for the blocks. Remove jump-to-next
|
// Fixup final control flow for the blocks. Remove jump-to-next
|
||||||
// block. If neither arm of a IF follows the conditional branch, we
|
// block. If neither arm of a IF follows the conditional branch, we
|
||||||
// have to add a second jump after the conditional. We place the
|
// have to add a second jump after the conditional. We place the
|
||||||
// TRUE branch target in succs[0] for both GOTOs and IFs.
|
// TRUE branch target in succs[0] for both GOTOs and IFs.
|
||||||
for( i=0; i < _num_blocks; i++ ) {
|
for (uint i=0; i < _num_blocks; i++) {
|
||||||
Block *b = _blocks[i];
|
Block *b = _blocks[i];
|
||||||
b->_pre_order = i; // turn pre-order into block-index
|
b->_pre_order = i; // turn pre-order into block-index
|
||||||
|
|
||||||
@ -700,7 +739,7 @@ void PhaseCFG::RemoveEmpty() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Remove all CatchProjs
|
// Remove all CatchProjs
|
||||||
for (j1 = 0; j1 < b->_num_succs; j1++) b->_nodes.pop();
|
for (uint j1 = 0; j1 < b->_num_succs; j1++) b->_nodes.pop();
|
||||||
|
|
||||||
} else if (b->_num_succs == 1) {
|
} else if (b->_num_succs == 1) {
|
||||||
// Block ends in a Goto?
|
// Block ends in a Goto?
|
||||||
@ -730,8 +769,7 @@ void PhaseCFG::RemoveEmpty() {
|
|||||||
// successors after the current one, provided that the
|
// successors after the current one, provided that the
|
||||||
// successor was previously unscheduled, but moveable
|
// successor was previously unscheduled, but moveable
|
||||||
// (i.e., all paths to it involve a branch).
|
// (i.e., all paths to it involve a branch).
|
||||||
if( bnext != bs0 && bnext != bs1 ) {
|
if( !C->do_freq_based_layout() && bnext != bs0 && bnext != bs1 ) {
|
||||||
|
|
||||||
// Choose the more common successor based on the probability
|
// Choose the more common successor based on the probability
|
||||||
// of the conditional branch.
|
// of the conditional branch.
|
||||||
Block *bx = bs0;
|
Block *bx = bs0;
|
||||||
@ -751,9 +789,9 @@ void PhaseCFG::RemoveEmpty() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attempt the more common successor first
|
// Attempt the more common successor first
|
||||||
if (MoveToNext(bx, i)) {
|
if (move_to_next(bx, i)) {
|
||||||
bnext = bx;
|
bnext = bx;
|
||||||
} else if (MoveToNext(by, i)) {
|
} else if (move_to_next(by, i)) {
|
||||||
bnext = by;
|
bnext = by;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -774,10 +812,8 @@ void PhaseCFG::RemoveEmpty() {
|
|||||||
// Flip projection for each target
|
// Flip projection for each target
|
||||||
{ ProjNode *tmp = proj0; proj0 = proj1; proj1 = tmp; }
|
{ ProjNode *tmp = proj0; proj0 = proj1; proj1 = tmp; }
|
||||||
|
|
||||||
} else if( bnext == bs1 ) { // Fall-thru is already in succs[1]
|
} else if( bnext != bs1 ) {
|
||||||
|
// Need a double-branch
|
||||||
} else { // Else need a double-branch
|
|
||||||
|
|
||||||
// The existing conditional branch need not change.
|
// The existing conditional branch need not change.
|
||||||
// Add a unconditional branch to the false target.
|
// Add a unconditional branch to the false target.
|
||||||
// Alas, it must appear in its own block and adding a
|
// Alas, it must appear in its own block and adding a
|
||||||
@ -786,8 +822,9 @@ void PhaseCFG::RemoveEmpty() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we TRUE branch to the target
|
// Make sure we TRUE branch to the target
|
||||||
if( proj0->Opcode() == Op_IfFalse )
|
if( proj0->Opcode() == Op_IfFalse ) {
|
||||||
iff->negate();
|
iff->negate();
|
||||||
|
}
|
||||||
|
|
||||||
b->_nodes.pop(); // Remove IfFalse & IfTrue projections
|
b->_nodes.pop(); // Remove IfFalse & IfTrue projections
|
||||||
b->_nodes.pop();
|
b->_nodes.pop();
|
||||||
@ -796,9 +833,7 @@ void PhaseCFG::RemoveEmpty() {
|
|||||||
// Multi-exit block, e.g. a switch statement
|
// Multi-exit block, e.g. a switch statement
|
||||||
// But we don't need to do anything here
|
// But we don't need to do anything here
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of for all blocks
|
} // End of for all blocks
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -905,7 +940,7 @@ void UnionFind::reset( uint max ) {
|
|||||||
// Force the Union-Find mapping to be at least this large
|
// Force the Union-Find mapping to be at least this large
|
||||||
extend(max,0);
|
extend(max,0);
|
||||||
// Initialize to be the ID mapping.
|
// Initialize to be the ID mapping.
|
||||||
for( uint i=0; i<_max; i++ ) map(i,i);
|
for( uint i=0; i<max; i++ ) map(i,i);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------Find_compress----------------------------------
|
//------------------------------Find_compress----------------------------------
|
||||||
@ -937,7 +972,6 @@ uint UnionFind::Find_const( uint idx ) const {
|
|||||||
if( idx >= _max ) return idx;
|
if( idx >= _max ) return idx;
|
||||||
uint next = lookup(idx);
|
uint next = lookup(idx);
|
||||||
while( next != idx ) { // Scan chain of equivalences
|
while( next != idx ) { // Scan chain of equivalences
|
||||||
assert( next < idx, "always union smaller" );
|
|
||||||
idx = next; // until find a fixed-point
|
idx = next; // until find a fixed-point
|
||||||
next = lookup(idx);
|
next = lookup(idx);
|
||||||
}
|
}
|
||||||
@ -956,3 +990,491 @@ void UnionFind::Union( uint idx1, uint idx2 ) {
|
|||||||
assert( src < dst, "always union smaller" );
|
assert( src < dst, "always union smaller" );
|
||||||
map(dst,src);
|
map(dst,src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PRODUCT
|
||||||
|
static void edge_dump(GrowableArray<CFGEdge *> *edges) {
|
||||||
|
tty->print_cr("---- Edges ----");
|
||||||
|
for (int i = 0; i < edges->length(); i++) {
|
||||||
|
CFGEdge *e = edges->at(i);
|
||||||
|
if (e != NULL) {
|
||||||
|
edges->at(i)->dump();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void trace_dump(Trace *traces[], int count) {
|
||||||
|
tty->print_cr("---- Traces ----");
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
Trace *tr = traces[i];
|
||||||
|
if (tr != NULL) {
|
||||||
|
tr->dump();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Trace::dump( ) const {
|
||||||
|
tty->print_cr("Trace (freq %f)", first_block()->_freq);
|
||||||
|
for (Block *b = first_block(); b != NULL; b = next(b)) {
|
||||||
|
tty->print(" B%d", b->_pre_order);
|
||||||
|
if (b->head()->is_Loop()) {
|
||||||
|
tty->print(" (L%d)", b->compute_loop_alignment());
|
||||||
|
}
|
||||||
|
if (b->has_loop_alignment()) {
|
||||||
|
tty->print(" (T%d)", b->code_alignment());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tty->cr();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFGEdge::dump( ) const {
|
||||||
|
tty->print(" B%d --> B%d Freq: %f out:%3d%% in:%3d%% State: ",
|
||||||
|
from()->_pre_order, to()->_pre_order, freq(), _from_pct, _to_pct);
|
||||||
|
switch(state()) {
|
||||||
|
case connected:
|
||||||
|
tty->print("connected");
|
||||||
|
break;
|
||||||
|
case open:
|
||||||
|
tty->print("open");
|
||||||
|
break;
|
||||||
|
case interior:
|
||||||
|
tty->print("interior");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (infrequent()) {
|
||||||
|
tty->print(" infrequent");
|
||||||
|
}
|
||||||
|
tty->cr();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
//------------------------------edge_order-------------------------------------
|
||||||
|
// Comparison function for edges
|
||||||
|
static int edge_order(CFGEdge **e0, CFGEdge **e1) {
|
||||||
|
float freq0 = (*e0)->freq();
|
||||||
|
float freq1 = (*e1)->freq();
|
||||||
|
if (freq0 != freq1) {
|
||||||
|
return freq0 > freq1 ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dist0 = (*e0)->to()->_rpo - (*e0)->from()->_rpo;
|
||||||
|
int dist1 = (*e1)->to()->_rpo - (*e1)->from()->_rpo;
|
||||||
|
|
||||||
|
return dist1 - dist0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------trace_frequency_order--------------------------
|
||||||
|
// Comparison function for edges
|
||||||
|
static int trace_frequency_order(const void *p0, const void *p1) {
|
||||||
|
Trace *tr0 = *(Trace **) p0;
|
||||||
|
Trace *tr1 = *(Trace **) p1;
|
||||||
|
Block *b0 = tr0->first_block();
|
||||||
|
Block *b1 = tr1->first_block();
|
||||||
|
|
||||||
|
// The trace of connector blocks goes at the end;
|
||||||
|
// we only expect one such trace
|
||||||
|
if (b0->is_connector() != b1->is_connector()) {
|
||||||
|
return b1->is_connector() ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pull more frequently executed blocks to the beginning
|
||||||
|
float freq0 = b0->_freq;
|
||||||
|
float freq1 = b1->_freq;
|
||||||
|
if (freq0 != freq1) {
|
||||||
|
return freq0 > freq1 ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int diff = tr0->first_block()->_rpo - tr1->first_block()->_rpo;
|
||||||
|
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------find_edges-------------------------------------
|
||||||
|
// Find edges of interest, i.e, those which can fall through. Presumes that
|
||||||
|
// edges which don't fall through are of low frequency and can be generally
|
||||||
|
// ignored. Initialize the list of traces.
|
||||||
|
void PhaseBlockLayout::find_edges()
|
||||||
|
{
|
||||||
|
// Walk the blocks, creating edges and Traces
|
||||||
|
uint i;
|
||||||
|
Trace *tr = NULL;
|
||||||
|
for (i = 0; i < _cfg._num_blocks; i++) {
|
||||||
|
Block *b = _cfg._blocks[i];
|
||||||
|
tr = new Trace(b, next, prev);
|
||||||
|
traces[tr->id()] = tr;
|
||||||
|
|
||||||
|
// All connector blocks should be at the end of the list
|
||||||
|
if (b->is_connector()) break;
|
||||||
|
|
||||||
|
// If this block and the next one have a one-to-one successor
|
||||||
|
// predecessor relationship, simply append the next block
|
||||||
|
int nfallthru = b->num_fall_throughs();
|
||||||
|
while (nfallthru == 1 &&
|
||||||
|
b->succ_fall_through(0)) {
|
||||||
|
Block *n = b->_succs[0];
|
||||||
|
|
||||||
|
// Skip over single-entry connector blocks, we don't want to
|
||||||
|
// add them to the trace.
|
||||||
|
while (n->is_connector() && n->num_preds() == 1) {
|
||||||
|
n = n->_succs[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// We see a merge point, so stop search for the next block
|
||||||
|
if (n->num_preds() != 1) break;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
assert(n = _cfg._blocks[i], "expecting next block");
|
||||||
|
tr->append(n);
|
||||||
|
uf->map(n->_pre_order, tr->id());
|
||||||
|
traces[n->_pre_order] = NULL;
|
||||||
|
nfallthru = b->num_fall_throughs();
|
||||||
|
b = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nfallthru > 0) {
|
||||||
|
// Create a CFGEdge for each outgoing
|
||||||
|
// edge that could be a fall-through.
|
||||||
|
for (uint j = 0; j < b->_num_succs; j++ ) {
|
||||||
|
if (b->succ_fall_through(j)) {
|
||||||
|
Block *target = b->non_connector_successor(j);
|
||||||
|
float freq = b->_freq * b->succ_prob(j);
|
||||||
|
int from_pct = (int) ((100 * freq) / b->_freq);
|
||||||
|
int to_pct = (int) ((100 * freq) / target->_freq);
|
||||||
|
edges->append(new CFGEdge(b, target, freq, from_pct, to_pct));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group connector blocks into one trace
|
||||||
|
for (i++; i < _cfg._num_blocks; i++) {
|
||||||
|
Block *b = _cfg._blocks[i];
|
||||||
|
assert(b->is_connector(), "connector blocks at the end");
|
||||||
|
tr->append(b);
|
||||||
|
uf->map(b->_pre_order, tr->id());
|
||||||
|
traces[b->_pre_order] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------union_traces----------------------------------
|
||||||
|
// Union two traces together in uf, and null out the trace in the list
|
||||||
|
void PhaseBlockLayout::union_traces(Trace* updated_trace, Trace* old_trace)
|
||||||
|
{
|
||||||
|
uint old_id = old_trace->id();
|
||||||
|
uint updated_id = updated_trace->id();
|
||||||
|
|
||||||
|
uint lo_id = updated_id;
|
||||||
|
uint hi_id = old_id;
|
||||||
|
|
||||||
|
// If from is greater than to, swap values to meet
|
||||||
|
// UnionFind guarantee.
|
||||||
|
if (updated_id > old_id) {
|
||||||
|
lo_id = old_id;
|
||||||
|
hi_id = updated_id;
|
||||||
|
|
||||||
|
// Fix up the trace ids
|
||||||
|
traces[lo_id] = traces[updated_id];
|
||||||
|
updated_trace->set_id(lo_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Union the lower with the higher and remove the pointer
|
||||||
|
// to the higher.
|
||||||
|
uf->Union(lo_id, hi_id);
|
||||||
|
traces[hi_id] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------grow_traces-------------------------------------
|
||||||
|
// Append traces together via the most frequently executed edges
|
||||||
|
void PhaseBlockLayout::grow_traces()
|
||||||
|
{
|
||||||
|
// Order the edges, and drive the growth of Traces via the most
|
||||||
|
// frequently executed edges.
|
||||||
|
edges->sort(edge_order);
|
||||||
|
for (int i = 0; i < edges->length(); i++) {
|
||||||
|
CFGEdge *e = edges->at(i);
|
||||||
|
|
||||||
|
if (e->state() != CFGEdge::open) continue;
|
||||||
|
|
||||||
|
Block *src_block = e->from();
|
||||||
|
Block *targ_block = e->to();
|
||||||
|
|
||||||
|
// Don't grow traces along backedges?
|
||||||
|
if (!BlockLayoutRotateLoops) {
|
||||||
|
if (targ_block->_rpo <= src_block->_rpo) {
|
||||||
|
targ_block->set_loop_alignment(targ_block);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Trace *src_trace = trace(src_block);
|
||||||
|
Trace *targ_trace = trace(targ_block);
|
||||||
|
|
||||||
|
// If the edge in question can join two traces at their ends,
|
||||||
|
// append one trace to the other.
|
||||||
|
if (src_trace->last_block() == src_block) {
|
||||||
|
if (src_trace == targ_trace) {
|
||||||
|
e->set_state(CFGEdge::interior);
|
||||||
|
if (targ_trace->backedge(e)) {
|
||||||
|
// Reset i to catch any newly eligible edge
|
||||||
|
// (Or we could remember the first "open" edge, and reset there)
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
} else if (targ_trace->first_block() == targ_block) {
|
||||||
|
e->set_state(CFGEdge::connected);
|
||||||
|
src_trace->append(targ_trace);
|
||||||
|
union_traces(src_trace, targ_trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------merge_traces-----------------------------------
|
||||||
|
// Embed one trace into another, if the fork or join points are sufficiently
|
||||||
|
// balanced.
|
||||||
|
void PhaseBlockLayout::merge_traces(bool fall_thru_only)
|
||||||
|
{
|
||||||
|
// Walk the edge list a another time, looking at unprocessed edges.
|
||||||
|
// Fold in diamonds
|
||||||
|
for (int i = 0; i < edges->length(); i++) {
|
||||||
|
CFGEdge *e = edges->at(i);
|
||||||
|
|
||||||
|
if (e->state() != CFGEdge::open) continue;
|
||||||
|
if (fall_thru_only) {
|
||||||
|
if (e->infrequent()) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block *src_block = e->from();
|
||||||
|
Trace *src_trace = trace(src_block);
|
||||||
|
bool src_at_tail = src_trace->last_block() == src_block;
|
||||||
|
|
||||||
|
Block *targ_block = e->to();
|
||||||
|
Trace *targ_trace = trace(targ_block);
|
||||||
|
bool targ_at_start = targ_trace->first_block() == targ_block;
|
||||||
|
|
||||||
|
if (src_trace == targ_trace) {
|
||||||
|
// This may be a loop, but we can't do much about it.
|
||||||
|
e->set_state(CFGEdge::interior);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fall_thru_only) {
|
||||||
|
// If the edge links the middle of two traces, we can't do anything.
|
||||||
|
// Mark the edge and continue.
|
||||||
|
if (!src_at_tail & !targ_at_start) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't grow traces along backedges?
|
||||||
|
if (!BlockLayoutRotateLoops && (targ_block->_rpo <= src_block->_rpo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If both ends of the edge are available, why didn't we handle it earlier?
|
||||||
|
assert(src_at_tail ^ targ_at_start, "Should have caught this edge earlier.");
|
||||||
|
|
||||||
|
if (targ_at_start) {
|
||||||
|
// Insert the "targ" trace in the "src" trace if the insertion point
|
||||||
|
// is a two way branch.
|
||||||
|
// Better profitability check possible, but may not be worth it.
|
||||||
|
// Someday, see if the this "fork" has an associated "join";
|
||||||
|
// then make a policy on merging this trace at the fork or join.
|
||||||
|
// For example, other things being equal, it may be better to place this
|
||||||
|
// trace at the join point if the "src" trace ends in a two-way, but
|
||||||
|
// the insertion point is one-way.
|
||||||
|
assert(src_block->num_fall_throughs() == 2, "unexpected diamond");
|
||||||
|
e->set_state(CFGEdge::connected);
|
||||||
|
src_trace->insert_after(src_block, targ_trace);
|
||||||
|
union_traces(src_trace, targ_trace);
|
||||||
|
} else if (src_at_tail) {
|
||||||
|
if (src_trace != trace(_cfg._broot)) {
|
||||||
|
e->set_state(CFGEdge::connected);
|
||||||
|
targ_trace->insert_before(targ_block, src_trace);
|
||||||
|
union_traces(targ_trace, src_trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (e->state() == CFGEdge::open) {
|
||||||
|
// Append traces, even without a fall-thru connection.
|
||||||
|
// But leave root entry at the begining of the block list.
|
||||||
|
if (targ_trace != trace(_cfg._broot)) {
|
||||||
|
e->set_state(CFGEdge::connected);
|
||||||
|
src_trace->append(targ_trace);
|
||||||
|
union_traces(src_trace, targ_trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------reorder_traces-----------------------------------
|
||||||
|
// Order the sequence of the traces in some desirable way, and fixup the
|
||||||
|
// jumps at the end of each block.
|
||||||
|
void PhaseBlockLayout::reorder_traces(int count)
|
||||||
|
{
|
||||||
|
ResourceArea *area = Thread::current()->resource_area();
|
||||||
|
Trace ** new_traces = NEW_ARENA_ARRAY(area, Trace *, count);
|
||||||
|
Block_List worklist;
|
||||||
|
int new_count = 0;
|
||||||
|
|
||||||
|
// Compact the traces.
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
Trace *tr = traces[i];
|
||||||
|
if (tr != NULL) {
|
||||||
|
new_traces[new_count++] = tr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The entry block should be first on the new trace list.
|
||||||
|
Trace *tr = trace(_cfg._broot);
|
||||||
|
assert(tr == new_traces[0], "entry trace misplaced");
|
||||||
|
|
||||||
|
// Sort the new trace list by frequency
|
||||||
|
qsort(new_traces + 1, new_count - 1, sizeof(new_traces[0]), trace_frequency_order);
|
||||||
|
|
||||||
|
// Patch up the successor blocks
|
||||||
|
_cfg._blocks.reset();
|
||||||
|
_cfg._num_blocks = 0;
|
||||||
|
for (int i = 0; i < new_count; i++) {
|
||||||
|
Trace *tr = new_traces[i];
|
||||||
|
if (tr != NULL) {
|
||||||
|
tr->fixup_blocks(_cfg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------PhaseBlockLayout-------------------------------
|
||||||
|
// Order basic blocks based on frequency
|
||||||
|
PhaseBlockLayout::PhaseBlockLayout(PhaseCFG &cfg) :
|
||||||
|
Phase(BlockLayout),
|
||||||
|
_cfg(cfg)
|
||||||
|
{
|
||||||
|
ResourceMark rm;
|
||||||
|
ResourceArea *area = Thread::current()->resource_area();
|
||||||
|
|
||||||
|
// List of traces
|
||||||
|
int size = _cfg._num_blocks + 1;
|
||||||
|
traces = NEW_ARENA_ARRAY(area, Trace *, size);
|
||||||
|
memset(traces, 0, size*sizeof(Trace*));
|
||||||
|
next = NEW_ARENA_ARRAY(area, Block *, size);
|
||||||
|
memset(next, 0, size*sizeof(Block *));
|
||||||
|
prev = NEW_ARENA_ARRAY(area, Block *, size);
|
||||||
|
memset(prev , 0, size*sizeof(Block *));
|
||||||
|
|
||||||
|
// List of edges
|
||||||
|
edges = new GrowableArray<CFGEdge*>;
|
||||||
|
|
||||||
|
// Mapping block index --> block_trace
|
||||||
|
uf = new UnionFind(size);
|
||||||
|
uf->reset(size);
|
||||||
|
|
||||||
|
// Find edges and create traces.
|
||||||
|
find_edges();
|
||||||
|
|
||||||
|
// Grow traces at their ends via most frequent edges.
|
||||||
|
grow_traces();
|
||||||
|
|
||||||
|
// Merge one trace into another, but only at fall-through points.
|
||||||
|
// This may make diamonds and other related shapes in a trace.
|
||||||
|
merge_traces(true);
|
||||||
|
|
||||||
|
// Run merge again, allowing two traces to be catenated, even if
|
||||||
|
// one does not fall through into the other. This appends loosely
|
||||||
|
// related traces to be near each other.
|
||||||
|
merge_traces(false);
|
||||||
|
|
||||||
|
// Re-order all the remaining traces by frequency
|
||||||
|
reorder_traces(size);
|
||||||
|
|
||||||
|
assert(_cfg._num_blocks >= (uint) (size - 1), "number of blocks can not shrink");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------backedge---------------------------------------
|
||||||
|
// Edge e completes a loop in a trace. If the target block is head of the
|
||||||
|
// loop, rotate the loop block so that the loop ends in a conditional branch.
|
||||||
|
bool Trace::backedge(CFGEdge *e) {
|
||||||
|
bool loop_rotated = false;
|
||||||
|
Block *src_block = e->from();
|
||||||
|
Block *targ_block = e->to();
|
||||||
|
|
||||||
|
assert(last_block() == src_block, "loop discovery at back branch");
|
||||||
|
if (first_block() == targ_block) {
|
||||||
|
if (BlockLayoutRotateLoops && last_block()->num_fall_throughs() < 2) {
|
||||||
|
// Find the last block in the trace that has a conditional
|
||||||
|
// branch.
|
||||||
|
Block *b;
|
||||||
|
for (b = last_block(); b != NULL; b = prev(b)) {
|
||||||
|
if (b->num_fall_throughs() == 2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b != last_block() && b != NULL) {
|
||||||
|
loop_rotated = true;
|
||||||
|
|
||||||
|
// Rotate the loop by doing two-part linked-list surgery.
|
||||||
|
append(first_block());
|
||||||
|
break_loop_after(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backbranch to the top of a trace
|
||||||
|
// Scroll foward through the trace from the targ_block. If we find
|
||||||
|
// a loop head before another loop top, use the the loop head alignment.
|
||||||
|
for (Block *b = targ_block; b != NULL; b = next(b)) {
|
||||||
|
if (b->has_loop_alignment()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (b->head()->is_Loop()) {
|
||||||
|
targ_block = b;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
first_block()->set_loop_alignment(targ_block);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Backbranch into the middle of a trace
|
||||||
|
targ_block->set_loop_alignment(targ_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
return loop_rotated;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------fixup_blocks-----------------------------------
|
||||||
|
// push blocks onto the CFG list
|
||||||
|
// ensure that blocks have the correct two-way branch sense
|
||||||
|
void Trace::fixup_blocks(PhaseCFG &cfg) {
|
||||||
|
Block *last = last_block();
|
||||||
|
for (Block *b = first_block(); b != NULL; b = next(b)) {
|
||||||
|
cfg._blocks.push(b);
|
||||||
|
cfg._num_blocks++;
|
||||||
|
if (!b->is_connector()) {
|
||||||
|
int nfallthru = b->num_fall_throughs();
|
||||||
|
if (b != last) {
|
||||||
|
if (nfallthru == 2) {
|
||||||
|
// Ensure that the sense of the branch is correct
|
||||||
|
Block *bnext = next(b);
|
||||||
|
Block *bs0 = b->non_connector_successor(0);
|
||||||
|
|
||||||
|
MachNode *iff = b->_nodes[b->_nodes.size()-3]->as_Mach();
|
||||||
|
ProjNode *proj0 = b->_nodes[b->_nodes.size()-2]->as_Proj();
|
||||||
|
ProjNode *proj1 = b->_nodes[b->_nodes.size()-1]->as_Proj();
|
||||||
|
|
||||||
|
if (bnext == bs0) {
|
||||||
|
// Fall-thru case in succs[0], should be in succs[1]
|
||||||
|
|
||||||
|
// Flip targets in _succs map
|
||||||
|
Block *tbs0 = b->_succs[0];
|
||||||
|
Block *tbs1 = b->_succs[1];
|
||||||
|
b->_succs.map( 0, tbs1 );
|
||||||
|
b->_succs.map( 1, tbs0 );
|
||||||
|
|
||||||
|
// Flip projections to match targets
|
||||||
|
b->_nodes.map(b->_nodes.size()-2, proj1);
|
||||||
|
b->_nodes.map(b->_nodes.size()-1, proj0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -75,6 +75,7 @@ public:
|
|||||||
void insert( uint i, Block *n );
|
void insert( uint i, Block *n );
|
||||||
uint size() const { return _cnt; }
|
uint size() const { return _cnt; }
|
||||||
void reset() { _cnt = 0; }
|
void reset() { _cnt = 0; }
|
||||||
|
void print();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -129,7 +130,11 @@ class Block : public CFGElement {
|
|||||||
uint _rpo; // Number in reverse post order walk
|
uint _rpo; // Number in reverse post order walk
|
||||||
|
|
||||||
virtual bool is_block() { return true; }
|
virtual bool is_block() { return true; }
|
||||||
float succ_prob(uint i); // return probability of i'th successor
|
float succ_prob(uint i); // return probability of i'th successor
|
||||||
|
int num_fall_throughs(); // How many fall-through candidate this block has
|
||||||
|
void update_uncommon_branch(Block* un); // Lower branch prob to uncommon code
|
||||||
|
bool succ_fall_through(uint i); // Is successor "i" is a fall-through candidate
|
||||||
|
Block* lone_fall_through(); // Return lone fall-through Block or null
|
||||||
|
|
||||||
Block* dom_lca(Block* that); // Compute LCA in dominator tree.
|
Block* dom_lca(Block* that); // Compute LCA in dominator tree.
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
@ -144,6 +149,7 @@ class Block : public CFGElement {
|
|||||||
// Report the alignment required by this block. Must be a power of 2.
|
// Report the alignment required by this block. Must be a power of 2.
|
||||||
// The previous block will insert nops to get this alignment.
|
// The previous block will insert nops to get this alignment.
|
||||||
uint code_alignment();
|
uint code_alignment();
|
||||||
|
uint compute_loop_alignment();
|
||||||
|
|
||||||
// BLOCK_FREQUENCY is a sentinel to mark uses of constant block frequencies.
|
// BLOCK_FREQUENCY is a sentinel to mark uses of constant block frequencies.
|
||||||
// It is currently also used to scale such frequencies relative to
|
// It is currently also used to scale such frequencies relative to
|
||||||
@ -184,11 +190,12 @@ class Block : public CFGElement {
|
|||||||
int current_alignment = current_offset & max_pad;
|
int current_alignment = current_offset & max_pad;
|
||||||
if( current_alignment != 0 ) {
|
if( current_alignment != 0 ) {
|
||||||
uint padding = (block_alignment-current_alignment) & max_pad;
|
uint padding = (block_alignment-current_alignment) & max_pad;
|
||||||
if( !head()->is_Loop() ||
|
if( has_loop_alignment() &&
|
||||||
padding <= (uint)MaxLoopPad ||
|
padding > (uint)MaxLoopPad &&
|
||||||
first_inst_size() > padding ) {
|
first_inst_size() <= padding ) {
|
||||||
return padding;
|
return 0;
|
||||||
}
|
}
|
||||||
|
return padding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -202,6 +209,21 @@ class Block : public CFGElement {
|
|||||||
void set_connector() { _connector = true; }
|
void set_connector() { _connector = true; }
|
||||||
bool is_connector() const { return _connector; };
|
bool is_connector() const { return _connector; };
|
||||||
|
|
||||||
|
// Loop_alignment will be set for blocks which are at the top of loops.
|
||||||
|
// The block layout pass may rotate loops such that the loop head may not
|
||||||
|
// be the sequentially first block of the loop encountered in the linear
|
||||||
|
// list of blocks. If the layout pass is not run, loop alignment is set
|
||||||
|
// for each block which is the head of a loop.
|
||||||
|
uint _loop_alignment;
|
||||||
|
void set_loop_alignment(Block *loop_top) {
|
||||||
|
uint new_alignment = loop_top->compute_loop_alignment();
|
||||||
|
if (new_alignment > _loop_alignment) {
|
||||||
|
_loop_alignment = new_alignment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint loop_alignment() const { return _loop_alignment; }
|
||||||
|
bool has_loop_alignment() const { return loop_alignment() > 0; }
|
||||||
|
|
||||||
// Create a new Block with given head Node.
|
// Create a new Block with given head Node.
|
||||||
// Creates the (empty) predecessor arrays.
|
// Creates the (empty) predecessor arrays.
|
||||||
Block( Arena *a, Node *headnode )
|
Block( Arena *a, Node *headnode )
|
||||||
@ -219,7 +241,8 @@ class Block : public CFGElement {
|
|||||||
_raise_LCA_mark(0),
|
_raise_LCA_mark(0),
|
||||||
_raise_LCA_visited(0),
|
_raise_LCA_visited(0),
|
||||||
_first_inst_size(999999),
|
_first_inst_size(999999),
|
||||||
_connector(false) {
|
_connector(false),
|
||||||
|
_loop_alignment(0) {
|
||||||
_nodes.push(headnode);
|
_nodes.push(headnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,6 +298,16 @@ class Block : public CFGElement {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return true if b is a successor of this block
|
||||||
|
bool has_successor(Block* b) const {
|
||||||
|
for (uint i = 0; i < _num_succs; i++ ) {
|
||||||
|
if (non_connector_successor(i) == b) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Successor block, after forwarding through connectors
|
// Successor block, after forwarding through connectors
|
||||||
Block* non_connector_successor(int i) const {
|
Block* non_connector_successor(int i) const {
|
||||||
return _succs[i]->non_connector();
|
return _succs[i]->non_connector();
|
||||||
@ -319,7 +352,6 @@ class PhaseCFG : public Phase {
|
|||||||
|
|
||||||
// I'll need a few machine-specific GotoNodes. Clone from this one.
|
// I'll need a few machine-specific GotoNodes. Clone from this one.
|
||||||
MachNode *_goto;
|
MachNode *_goto;
|
||||||
void insert_goto_at(uint block_no, uint succ_no);
|
|
||||||
|
|
||||||
Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
|
Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
|
||||||
void verify_anti_dependences(Block* LCA, Node* load) {
|
void verify_anti_dependences(Block* LCA, Node* load) {
|
||||||
@ -379,10 +411,15 @@ class PhaseCFG : public Phase {
|
|||||||
// Compute the instruction global latency with a backwards walk
|
// Compute the instruction global latency with a backwards walk
|
||||||
void ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack);
|
void ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack);
|
||||||
|
|
||||||
|
// Set loop alignment
|
||||||
|
void set_loop_alignment();
|
||||||
|
|
||||||
// Remove empty basic blocks
|
// Remove empty basic blocks
|
||||||
void RemoveEmpty();
|
void remove_empty();
|
||||||
bool MoveToNext(Block* bx, uint b_index);
|
void fixup_flow();
|
||||||
void MoveToEnd(Block* bx, uint b_index);
|
bool move_to_next(Block* bx, uint b_index);
|
||||||
|
void move_to_end(Block* bx, uint b_index);
|
||||||
|
void insert_goto_at(uint block_no, uint succ_no);
|
||||||
|
|
||||||
// Check for NeverBranch at block end. This needs to become a GOTO to the
|
// Check for NeverBranch at block end. This needs to become a GOTO to the
|
||||||
// true target. NeverBranch are treated as a conditional branch that always
|
// true target. NeverBranch are treated as a conditional branch that always
|
||||||
@ -413,7 +450,7 @@ class PhaseCFG : public Phase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//------------------------------UnionFindInfo----------------------------------
|
//------------------------------UnionFind--------------------------------------
|
||||||
// Map Block indices to a block-index for a cfg-cover.
|
// Map Block indices to a block-index for a cfg-cover.
|
||||||
// Array lookup in the optimized case.
|
// Array lookup in the optimized case.
|
||||||
class UnionFind : public ResourceObj {
|
class UnionFind : public ResourceObj {
|
||||||
@ -508,3 +545,166 @@ class CFGLoop : public CFGElement {
|
|||||||
void dump_tree() const;
|
void dump_tree() const;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------CFGEdge------------------------------------
|
||||||
|
// A edge between two basic blocks that will be embodied by a branch or a
|
||||||
|
// fall-through.
|
||||||
|
class CFGEdge : public ResourceObj {
|
||||||
|
private:
|
||||||
|
Block * _from; // Source basic block
|
||||||
|
Block * _to; // Destination basic block
|
||||||
|
float _freq; // Execution frequency (estimate)
|
||||||
|
int _state;
|
||||||
|
bool _infrequent;
|
||||||
|
int _from_pct;
|
||||||
|
int _to_pct;
|
||||||
|
|
||||||
|
// Private accessors
|
||||||
|
int from_pct() const { return _from_pct; }
|
||||||
|
int to_pct() const { return _to_pct; }
|
||||||
|
int from_infrequent() const { return from_pct() < BlockLayoutMinDiamondPercentage; }
|
||||||
|
int to_infrequent() const { return to_pct() < BlockLayoutMinDiamondPercentage; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
open, // initial edge state; unprocessed
|
||||||
|
connected, // edge used to connect two traces together
|
||||||
|
interior // edge is interior to trace (could be backedge)
|
||||||
|
};
|
||||||
|
|
||||||
|
CFGEdge(Block *from, Block *to, float freq, int from_pct, int to_pct) :
|
||||||
|
_from(from), _to(to), _freq(freq),
|
||||||
|
_from_pct(from_pct), _to_pct(to_pct), _state(open) {
|
||||||
|
_infrequent = from_infrequent() || to_infrequent();
|
||||||
|
}
|
||||||
|
|
||||||
|
float freq() const { return _freq; }
|
||||||
|
Block* from() const { return _from; }
|
||||||
|
Block* to () const { return _to; }
|
||||||
|
int infrequent() const { return _infrequent; }
|
||||||
|
int state() const { return _state; }
|
||||||
|
|
||||||
|
void set_state(int state) { _state = state; }
|
||||||
|
|
||||||
|
#ifndef PRODUCT
|
||||||
|
void dump( ) const;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------Trace-------------------------------------
|
||||||
|
// An ordered list of basic blocks.
|
||||||
|
class Trace : public ResourceObj {
|
||||||
|
private:
|
||||||
|
uint _id; // Unique Trace id (derived from initial block)
|
||||||
|
Block ** _next_list; // Array mapping index to next block
|
||||||
|
Block ** _prev_list; // Array mapping index to previous block
|
||||||
|
Block * _first; // First block in the trace
|
||||||
|
Block * _last; // Last block in the trace
|
||||||
|
|
||||||
|
// Return the block that follows "b" in the trace.
|
||||||
|
Block * next(Block *b) const { return _next_list[b->_pre_order]; }
|
||||||
|
void set_next(Block *b, Block *n) const { _next_list[b->_pre_order] = n; }
|
||||||
|
|
||||||
|
// Return the block that preceeds "b" in the trace.
|
||||||
|
Block * prev(Block *b) const { return _prev_list[b->_pre_order]; }
|
||||||
|
void set_prev(Block *b, Block *p) const { _prev_list[b->_pre_order] = p; }
|
||||||
|
|
||||||
|
// We've discovered a loop in this trace. Reset last to be "b", and first as
|
||||||
|
// the block following "b
|
||||||
|
void break_loop_after(Block *b) {
|
||||||
|
_last = b;
|
||||||
|
_first = next(b);
|
||||||
|
set_prev(_first, NULL);
|
||||||
|
set_next(_last, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Trace(Block *b, Block **next_list, Block **prev_list) :
|
||||||
|
_first(b),
|
||||||
|
_last(b),
|
||||||
|
_next_list(next_list),
|
||||||
|
_prev_list(prev_list),
|
||||||
|
_id(b->_pre_order) {
|
||||||
|
set_next(b, NULL);
|
||||||
|
set_prev(b, NULL);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Return the id number
|
||||||
|
uint id() const { return _id; }
|
||||||
|
void set_id(uint id) { _id = id; }
|
||||||
|
|
||||||
|
// Return the first block in the trace
|
||||||
|
Block * first_block() const { return _first; }
|
||||||
|
|
||||||
|
// Return the last block in the trace
|
||||||
|
Block * last_block() const { return _last; }
|
||||||
|
|
||||||
|
// Insert a trace in the middle of this one after b
|
||||||
|
void insert_after(Block *b, Trace *tr) {
|
||||||
|
set_next(tr->last_block(), next(b));
|
||||||
|
if (next(b) != NULL) {
|
||||||
|
set_prev(next(b), tr->last_block());
|
||||||
|
}
|
||||||
|
|
||||||
|
set_next(b, tr->first_block());
|
||||||
|
set_prev(tr->first_block(), b);
|
||||||
|
|
||||||
|
if (b == _last) {
|
||||||
|
_last = tr->last_block();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert_before(Block *b, Trace *tr) {
|
||||||
|
Block *p = prev(b);
|
||||||
|
assert(p != NULL, "use append instead");
|
||||||
|
insert_after(p, tr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append another trace to this one.
|
||||||
|
void append(Trace *tr) {
|
||||||
|
insert_after(_last, tr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append a block at the end of this trace
|
||||||
|
void append(Block *b) {
|
||||||
|
set_next(_last, b);
|
||||||
|
set_prev(b, _last);
|
||||||
|
_last = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust the the blocks in this trace
|
||||||
|
void fixup_blocks(PhaseCFG &cfg);
|
||||||
|
bool backedge(CFGEdge *e);
|
||||||
|
|
||||||
|
#ifndef PRODUCT
|
||||||
|
void dump( ) const;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------PhaseBlockLayout-------------------------------
|
||||||
|
// Rearrange blocks into some canonical order, based on edges and their frequencies
|
||||||
|
class PhaseBlockLayout : public Phase {
|
||||||
|
PhaseCFG &_cfg; // Control flow graph
|
||||||
|
|
||||||
|
GrowableArray<CFGEdge *> *edges;
|
||||||
|
Trace **traces;
|
||||||
|
Block **next;
|
||||||
|
Block **prev;
|
||||||
|
UnionFind *uf;
|
||||||
|
|
||||||
|
// Given a block, find its encompassing Trace
|
||||||
|
Trace * trace(Block *b) {
|
||||||
|
return traces[uf->Find_compress(b->_pre_order)];
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
PhaseBlockLayout(PhaseCFG &cfg);
|
||||||
|
|
||||||
|
void find_edges();
|
||||||
|
void grow_traces();
|
||||||
|
void merge_traces(bool loose_connections);
|
||||||
|
void reorder_traces(int count);
|
||||||
|
void union_traces(Trace* from, Trace* to);
|
||||||
|
};
|
||||||
|
@ -388,6 +388,9 @@
|
|||||||
product(intx, EliminateAllocationArraySizeLimit, 64, \
|
product(intx, EliminateAllocationArraySizeLimit, 64, \
|
||||||
"Array size (number of elements) limit for scalar replacement") \
|
"Array size (number of elements) limit for scalar replacement") \
|
||||||
\
|
\
|
||||||
|
product(bool, UseOptoBiasInlining, true, \
|
||||||
|
"Generate biased locking code in C2 ideal graph") \
|
||||||
|
\
|
||||||
product(intx, ValueSearchLimit, 1000, \
|
product(intx, ValueSearchLimit, 1000, \
|
||||||
"Recursion limit in PhaseMacroExpand::value_from_mem_phi") \
|
"Recursion limit in PhaseMacroExpand::value_from_mem_phi") \
|
||||||
\
|
\
|
||||||
@ -396,5 +399,15 @@
|
|||||||
\
|
\
|
||||||
diagnostic(intx, DominatorSearchLimit, 1000, \
|
diagnostic(intx, DominatorSearchLimit, 1000, \
|
||||||
"Iterations limit in Node::dominates") \
|
"Iterations limit in Node::dominates") \
|
||||||
|
\
|
||||||
|
product(bool, BlockLayoutByFrequency, true, \
|
||||||
|
"Use edge frequencies to drive block ordering") \
|
||||||
|
\
|
||||||
|
product(intx, BlockLayoutMinDiamondPercentage, 20, \
|
||||||
|
"Miniumum %% of a successor (predecessor) for which block layout "\
|
||||||
|
"a will allow a fork (join) in a single chain") \
|
||||||
|
\
|
||||||
|
product(bool, BlockLayoutRotateLoops, false, \
|
||||||
|
"Allow back branches to be fall throughs in the block layour") \
|
||||||
|
|
||||||
C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
|
C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
|
||||||
|
@ -967,6 +967,7 @@ SafePointScalarObjectNode::SafePointScalarObjectNode(const TypeOopPtr* tp,
|
|||||||
init_class_id(Class_SafePointScalarObject);
|
init_class_id(Class_SafePointScalarObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SafePointScalarObjectNode::pinned() const { return true; }
|
||||||
|
|
||||||
uint SafePointScalarObjectNode::ideal_reg() const {
|
uint SafePointScalarObjectNode::ideal_reg() const {
|
||||||
return 0; // No matching to machine instruction
|
return 0; // No matching to machine instruction
|
||||||
|
@ -433,6 +433,10 @@ public:
|
|||||||
uint n_fields() const { return _n_fields; }
|
uint n_fields() const { return _n_fields; }
|
||||||
DEBUG_ONLY(AllocateNode* alloc() const { return _alloc; })
|
DEBUG_ONLY(AllocateNode* alloc() const { return _alloc; })
|
||||||
|
|
||||||
|
// SafePointScalarObject should be always pinned to the control edge
|
||||||
|
// of the SafePoint node for which it was generated.
|
||||||
|
virtual bool pinned() const; // { return true; }
|
||||||
|
|
||||||
virtual uint size_of() const { return sizeof(*this); }
|
virtual uint size_of() const { return sizeof(*this); }
|
||||||
|
|
||||||
// Assumes that "this" is an argument to a safepoint node "s", and that
|
// Assumes that "this" is an argument to a safepoint node "s", and that
|
||||||
|
@ -440,9 +440,7 @@ void PhaseChaitin::Register_Allocate() {
|
|||||||
assert((int)(_matcher._new_SP+_framesize) >= (int)_matcher._out_arg_limit, "framesize must be large enough");
|
assert((int)(_matcher._new_SP+_framesize) >= (int)_matcher._out_arg_limit, "framesize must be large enough");
|
||||||
|
|
||||||
// This frame must preserve the required fp alignment
|
// This frame must preserve the required fp alignment
|
||||||
const int stack_alignment_in_words = Matcher::stack_alignment_in_slots();
|
_framesize = round_to(_framesize, Matcher::stack_alignment_in_slots());
|
||||||
if (stack_alignment_in_words > 0)
|
|
||||||
_framesize = round_to(_framesize, Matcher::stack_alignment_in_bytes());
|
|
||||||
assert( _framesize >= 0 && _framesize <= 1000000, "sanity check" );
|
assert( _framesize >= 0 && _framesize <= 1000000, "sanity check" );
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
_total_framesize += _framesize;
|
_total_framesize += _framesize;
|
||||||
|
@ -205,6 +205,7 @@ macro(StoreB)
|
|||||||
macro(StoreC)
|
macro(StoreC)
|
||||||
macro(StoreCM)
|
macro(StoreCM)
|
||||||
macro(StorePConditional)
|
macro(StorePConditional)
|
||||||
|
macro(StoreIConditional)
|
||||||
macro(StoreLConditional)
|
macro(StoreLConditional)
|
||||||
macro(StoreD)
|
macro(StoreD)
|
||||||
macro(StoreF)
|
macro(StoreF)
|
||||||
|
@ -551,7 +551,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
|
|||||||
rethrow_exceptions(kit.transfer_exceptions_into_jvms());
|
rethrow_exceptions(kit.transfer_exceptions_into_jvms());
|
||||||
}
|
}
|
||||||
|
|
||||||
print_method("Before RemoveUseless");
|
print_method("Before RemoveUseless", 3);
|
||||||
|
|
||||||
// Remove clutter produced by parsing.
|
// Remove clutter produced by parsing.
|
||||||
if (!failing()) {
|
if (!failing()) {
|
||||||
@ -822,6 +822,7 @@ void Compile::Init(int aliaslevel) {
|
|||||||
Copy::zero_to_bytes(_trap_hist, sizeof(_trap_hist));
|
Copy::zero_to_bytes(_trap_hist, sizeof(_trap_hist));
|
||||||
set_decompile_count(0);
|
set_decompile_count(0);
|
||||||
|
|
||||||
|
set_do_freq_based_layout(BlockLayoutByFrequency || method_has_option("BlockLayoutByFrequency"));
|
||||||
// Compilation level related initialization
|
// Compilation level related initialization
|
||||||
if (env()->comp_level() == CompLevel_fast_compile) {
|
if (env()->comp_level() == CompLevel_fast_compile) {
|
||||||
set_num_loop_opts(Tier1LoopOptsCount);
|
set_num_loop_opts(Tier1LoopOptsCount);
|
||||||
@ -1701,8 +1702,14 @@ void Compile::Code_Gen() {
|
|||||||
// are not adding any new instructions. If any basic block is empty, we
|
// are not adding any new instructions. If any basic block is empty, we
|
||||||
// can now safely remove it.
|
// can now safely remove it.
|
||||||
{
|
{
|
||||||
NOT_PRODUCT( TracePhase t2("removeEmpty", &_t_removeEmptyBlocks, TimeCompiler); )
|
NOT_PRODUCT( TracePhase t2("blockOrdering", &_t_blockOrdering, TimeCompiler); )
|
||||||
cfg.RemoveEmpty();
|
cfg.remove_empty();
|
||||||
|
if (do_freq_based_layout()) {
|
||||||
|
PhaseBlockLayout layout(cfg);
|
||||||
|
} else {
|
||||||
|
cfg.set_loop_alignment();
|
||||||
|
}
|
||||||
|
cfg.fixup_flow();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform any platform dependent postallocation verifications.
|
// Perform any platform dependent postallocation verifications.
|
||||||
@ -1994,6 +2001,7 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
|
|||||||
case Op_StorePConditional:
|
case Op_StorePConditional:
|
||||||
case Op_StoreI:
|
case Op_StoreI:
|
||||||
case Op_StoreL:
|
case Op_StoreL:
|
||||||
|
case Op_StoreIConditional:
|
||||||
case Op_StoreLConditional:
|
case Op_StoreLConditional:
|
||||||
case Op_CompareAndSwapI:
|
case Op_CompareAndSwapI:
|
||||||
case Op_CompareAndSwapL:
|
case Op_CompareAndSwapL:
|
||||||
|
@ -154,6 +154,7 @@ class Compile : public Phase {
|
|||||||
uint _decompile_count; // Cumulative decompilation counts.
|
uint _decompile_count; // Cumulative decompilation counts.
|
||||||
bool _do_inlining; // True if we intend to do inlining
|
bool _do_inlining; // True if we intend to do inlining
|
||||||
bool _do_scheduling; // True if we intend to do scheduling
|
bool _do_scheduling; // True if we intend to do scheduling
|
||||||
|
bool _do_freq_based_layout; // True if we intend to do frequency based block layout
|
||||||
bool _do_count_invocations; // True if we generate code to count invocations
|
bool _do_count_invocations; // True if we generate code to count invocations
|
||||||
bool _do_method_data_update; // True if we generate code to update methodDataOops
|
bool _do_method_data_update; // True if we generate code to update methodDataOops
|
||||||
int _AliasLevel; // Locally-adjusted version of AliasLevel flag.
|
int _AliasLevel; // Locally-adjusted version of AliasLevel flag.
|
||||||
@ -307,6 +308,8 @@ class Compile : public Phase {
|
|||||||
void set_do_inlining(bool z) { _do_inlining = z; }
|
void set_do_inlining(bool z) { _do_inlining = z; }
|
||||||
bool do_scheduling() const { return _do_scheduling; }
|
bool do_scheduling() const { return _do_scheduling; }
|
||||||
void set_do_scheduling(bool z) { _do_scheduling = z; }
|
void set_do_scheduling(bool z) { _do_scheduling = z; }
|
||||||
|
bool do_freq_based_layout() const{ return _do_freq_based_layout; }
|
||||||
|
void set_do_freq_based_layout(bool z){ _do_freq_based_layout = z; }
|
||||||
bool do_count_invocations() const{ return _do_count_invocations; }
|
bool do_count_invocations() const{ return _do_count_invocations; }
|
||||||
void set_do_count_invocations(bool z){ _do_count_invocations = z; }
|
void set_do_count_invocations(bool z){ _do_count_invocations = z; }
|
||||||
bool do_method_data_update() const { return _do_method_data_update; }
|
bool do_method_data_update() const { return _do_method_data_update; }
|
||||||
|
@ -1319,11 +1319,33 @@ void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_
|
|||||||
//------------------------------Estimate_Block_Frequency-----------------------
|
//------------------------------Estimate_Block_Frequency-----------------------
|
||||||
// Estimate block frequencies based on IfNode probabilities.
|
// Estimate block frequencies based on IfNode probabilities.
|
||||||
void PhaseCFG::Estimate_Block_Frequency() {
|
void PhaseCFG::Estimate_Block_Frequency() {
|
||||||
int cnts = C->method() ? C->method()->interpreter_invocation_count() : 1;
|
|
||||||
// Most of our algorithms will die horribly if frequency can become
|
// Force conditional branches leading to uncommon traps to be unlikely,
|
||||||
// negative so make sure cnts is a sane value.
|
// not because we get to the uncommon_trap with less relative frequency,
|
||||||
if( cnts <= 0 ) cnts = 1;
|
// but because an uncommon_trap typically causes a deopt, so we only get
|
||||||
float f = (float)cnts/(float)FreqCountInvocations;
|
// there once.
|
||||||
|
if (C->do_freq_based_layout()) {
|
||||||
|
Block_List worklist;
|
||||||
|
Block* root_blk = _blocks[0];
|
||||||
|
for (uint i = 1; i < root_blk->num_preds(); i++) {
|
||||||
|
Block *pb = _bbs[root_blk->pred(i)->_idx];
|
||||||
|
if (pb->has_uncommon_code()) {
|
||||||
|
worklist.push(pb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (worklist.size() > 0) {
|
||||||
|
Block* uct = worklist.pop();
|
||||||
|
if (uct == _broot) continue;
|
||||||
|
for (uint i = 1; i < uct->num_preds(); i++) {
|
||||||
|
Block *pb = _bbs[uct->pred(i)->_idx];
|
||||||
|
if (pb->_num_succs == 1) {
|
||||||
|
worklist.push(pb);
|
||||||
|
} else if (pb->num_fall_throughs() == 2) {
|
||||||
|
pb->update_uncommon_branch(uct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create the loop tree and calculate loop depth.
|
// Create the loop tree and calculate loop depth.
|
||||||
_root_loop = create_loop_tree();
|
_root_loop = create_loop_tree();
|
||||||
@ -1333,27 +1355,29 @@ void PhaseCFG::Estimate_Block_Frequency() {
|
|||||||
_root_loop->compute_freq();
|
_root_loop->compute_freq();
|
||||||
|
|
||||||
// Adjust all frequencies to be relative to a single method entry
|
// Adjust all frequencies to be relative to a single method entry
|
||||||
_root_loop->_freq = f * 1.0;
|
_root_loop->_freq = 1.0;
|
||||||
_root_loop->scale_freq();
|
_root_loop->scale_freq();
|
||||||
|
|
||||||
// force paths ending at uncommon traps to be infrequent
|
// force paths ending at uncommon traps to be infrequent
|
||||||
Block_List worklist;
|
if (!C->do_freq_based_layout()) {
|
||||||
Block* root_blk = _blocks[0];
|
Block_List worklist;
|
||||||
for (uint i = 0; i < root_blk->num_preds(); i++) {
|
Block* root_blk = _blocks[0];
|
||||||
Block *pb = _bbs[root_blk->pred(i)->_idx];
|
for (uint i = 1; i < root_blk->num_preds(); i++) {
|
||||||
if (pb->has_uncommon_code()) {
|
Block *pb = _bbs[root_blk->pred(i)->_idx];
|
||||||
worklist.push(pb);
|
if (pb->has_uncommon_code()) {
|
||||||
}
|
|
||||||
}
|
|
||||||
while (worklist.size() > 0) {
|
|
||||||
Block* uct = worklist.pop();
|
|
||||||
uct->_freq = PROB_MIN;
|
|
||||||
for (uint i = 0; i < uct->num_preds(); i++) {
|
|
||||||
Block *pb = _bbs[uct->pred(i)->_idx];
|
|
||||||
if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) {
|
|
||||||
worklist.push(pb);
|
worklist.push(pb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
while (worklist.size() > 0) {
|
||||||
|
Block* uct = worklist.pop();
|
||||||
|
uct->_freq = PROB_MIN;
|
||||||
|
for (uint i = 1; i < uct->num_preds(); i++) {
|
||||||
|
Block *pb = _bbs[uct->pred(i)->_idx];
|
||||||
|
if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) {
|
||||||
|
worklist.push(pb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
@ -1556,22 +1580,6 @@ void CFGLoop::compute_freq() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Raise frequency of the loop backedge block, in an effort
|
|
||||||
// to keep it empty. Skip the method level "loop".
|
|
||||||
if (_parent != NULL) {
|
|
||||||
CFGElement* s = _members.at(_members.length() - 1);
|
|
||||||
if (s->is_block()) {
|
|
||||||
Block* bk = s->as_Block();
|
|
||||||
if (bk->_num_succs == 1 && bk->_succs[0] == hd) {
|
|
||||||
// almost any value >= 1.0f works
|
|
||||||
// FIXME: raw constant
|
|
||||||
bk->_freq = 1.05f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// For all loops other than the outer, "method" loop,
|
// For all loops other than the outer, "method" loop,
|
||||||
// sum and normalize the exit probability. The "method" loop
|
// sum and normalize the exit probability. The "method" loop
|
||||||
// should keep the initial exit probability of 1, so that
|
// should keep the initial exit probability of 1, so that
|
||||||
@ -1589,12 +1597,15 @@ void CFGLoop::compute_freq() {
|
|||||||
// the probability of exit per loop entry.
|
// the probability of exit per loop entry.
|
||||||
for (int i = 0; i < _exits.length(); i++) {
|
for (int i = 0; i < _exits.length(); i++) {
|
||||||
Block* et = _exits.at(i).get_target();
|
Block* et = _exits.at(i).get_target();
|
||||||
float new_prob = _exits.at(i).get_prob() / exits_sum;
|
float new_prob = 0.0f;
|
||||||
|
if (_exits.at(i).get_prob() > 0.0f) {
|
||||||
|
new_prob = _exits.at(i).get_prob() / exits_sum;
|
||||||
|
}
|
||||||
BlockProbPair bpp(et, new_prob);
|
BlockProbPair bpp(et, new_prob);
|
||||||
_exits.at_put(i, bpp);
|
_exits.at_put(i, bpp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the total, but guard against unreasoable probability,
|
// Save the total, but guard against unreasonable probability,
|
||||||
// as the value is used to estimate the loop trip count.
|
// as the value is used to estimate the loop trip count.
|
||||||
// An infinite trip count would blur relative block
|
// An infinite trip count would blur relative block
|
||||||
// frequencies.
|
// frequencies.
|
||||||
@ -1688,6 +1699,137 @@ float Block::succ_prob(uint i) {
|
|||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------num_fall_throughs-----------------------------
|
||||||
|
// Return the number of fall-through candidates for a block
|
||||||
|
int Block::num_fall_throughs() {
|
||||||
|
int eidx = end_idx();
|
||||||
|
Node *n = _nodes[eidx]; // Get ending Node
|
||||||
|
|
||||||
|
int op = n->Opcode();
|
||||||
|
if (n->is_Mach()) {
|
||||||
|
if (n->is_MachNullCheck()) {
|
||||||
|
// In theory, either side can fall-thru, for simplicity sake,
|
||||||
|
// let's say only the false branch can now.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
op = n->as_Mach()->ideal_Opcode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch on branch type
|
||||||
|
switch( op ) {
|
||||||
|
case Op_CountedLoopEnd:
|
||||||
|
case Op_If:
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
case Op_Root:
|
||||||
|
case Op_Goto:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case Op_Catch: {
|
||||||
|
for (uint i = 0; i < _num_succs; i++) {
|
||||||
|
const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
|
||||||
|
if (ci->_con == CatchProjNode::fall_through_index) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Op_Jump:
|
||||||
|
case Op_NeverBranch:
|
||||||
|
case Op_TailCall:
|
||||||
|
case Op_TailJump:
|
||||||
|
case Op_Return:
|
||||||
|
case Op_Halt:
|
||||||
|
case Op_Rethrow:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ShouldNotReachHere();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------succ_fall_through-----------------------------
|
||||||
|
// Return true if a specific successor could be fall-through target.
|
||||||
|
bool Block::succ_fall_through(uint i) {
|
||||||
|
int eidx = end_idx();
|
||||||
|
Node *n = _nodes[eidx]; // Get ending Node
|
||||||
|
|
||||||
|
int op = n->Opcode();
|
||||||
|
if (n->is_Mach()) {
|
||||||
|
if (n->is_MachNullCheck()) {
|
||||||
|
// In theory, either side can fall-thru, for simplicity sake,
|
||||||
|
// let's say only the false branch can now.
|
||||||
|
return _nodes[i + eidx + 1]->Opcode() == Op_IfFalse;
|
||||||
|
}
|
||||||
|
op = n->as_Mach()->ideal_Opcode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch on branch type
|
||||||
|
switch( op ) {
|
||||||
|
case Op_CountedLoopEnd:
|
||||||
|
case Op_If:
|
||||||
|
case Op_Root:
|
||||||
|
case Op_Goto:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case Op_Catch: {
|
||||||
|
const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
|
||||||
|
return ci->_con == CatchProjNode::fall_through_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Op_Jump:
|
||||||
|
case Op_NeverBranch:
|
||||||
|
case Op_TailCall:
|
||||||
|
case Op_TailJump:
|
||||||
|
case Op_Return:
|
||||||
|
case Op_Halt:
|
||||||
|
case Op_Rethrow:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ShouldNotReachHere();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------update_uncommon_branch------------------------
|
||||||
|
// Update the probability of a two-branch to be uncommon
|
||||||
|
void Block::update_uncommon_branch(Block* ub) {
|
||||||
|
int eidx = end_idx();
|
||||||
|
Node *n = _nodes[eidx]; // Get ending Node
|
||||||
|
|
||||||
|
int op = n->as_Mach()->ideal_Opcode();
|
||||||
|
|
||||||
|
assert(op == Op_CountedLoopEnd || op == Op_If, "must be a If");
|
||||||
|
assert(num_fall_throughs() == 2, "must be a two way branch block");
|
||||||
|
|
||||||
|
// Which successor is ub?
|
||||||
|
uint s;
|
||||||
|
for (s = 0; s <_num_succs; s++) {
|
||||||
|
if (_succs[s] == ub) break;
|
||||||
|
}
|
||||||
|
assert(s < 2, "uncommon successor must be found");
|
||||||
|
|
||||||
|
// If ub is the true path, make the proability small, else
|
||||||
|
// ub is the false path, and make the probability large
|
||||||
|
bool invert = (_nodes[s + eidx + 1]->Opcode() == Op_IfFalse);
|
||||||
|
|
||||||
|
// Get existing probability
|
||||||
|
float p = n->as_MachIf()->_prob;
|
||||||
|
|
||||||
|
if (invert) p = 1.0 - p;
|
||||||
|
if (p > PROB_MIN) {
|
||||||
|
p = PROB_MIN;
|
||||||
|
}
|
||||||
|
if (invert) p = 1.0 - p;
|
||||||
|
|
||||||
|
n->as_MachIf()->_prob = p;
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------update_succ_freq-------------------------------
|
//------------------------------update_succ_freq-------------------------------
|
||||||
// Update the appropriate frequency associated with block 'b', a succesor of
|
// Update the appropriate frequency associated with block 'b', a succesor of
|
||||||
// a block in this loop.
|
// a block in this loop.
|
||||||
|
@ -3485,11 +3485,32 @@ bool LibraryCallKit::inline_native_AtomicLong_attemptUpdate() {
|
|||||||
const TypePtr *adr_type = _gvn.type(adr)->is_ptr();
|
const TypePtr *adr_type = _gvn.type(adr)->is_ptr();
|
||||||
int alias_idx = C->get_alias_index(adr_type);
|
int alias_idx = C->get_alias_index(adr_type);
|
||||||
|
|
||||||
Node *result = _gvn.transform(new (C, 5) StoreLConditionalNode(control(), memory(alias_idx), adr, newVal, oldVal));
|
Node *cas = _gvn.transform(new (C, 5) StoreLConditionalNode(control(), memory(alias_idx), adr, newVal, oldVal));
|
||||||
Node *store_proj = _gvn.transform( new (C, 1) SCMemProjNode(result));
|
Node *store_proj = _gvn.transform( new (C, 1) SCMemProjNode(cas));
|
||||||
set_memory(store_proj, alias_idx);
|
set_memory(store_proj, alias_idx);
|
||||||
|
Node *bol = _gvn.transform( new (C, 2) BoolNode( cas, BoolTest::eq ) );
|
||||||
|
|
||||||
push(result);
|
Node *result;
|
||||||
|
// CMove node is not used to be able fold a possible check code
|
||||||
|
// after attemptUpdate() call. This code could be transformed
|
||||||
|
// into CMove node by loop optimizations.
|
||||||
|
{
|
||||||
|
RegionNode *r = new (C, 3) RegionNode(3);
|
||||||
|
result = new (C, 3) PhiNode(r, TypeInt::BOOL);
|
||||||
|
|
||||||
|
Node *iff = create_and_xform_if(control(), bol, PROB_FAIR, COUNT_UNKNOWN);
|
||||||
|
Node *iftrue = opt_iff(r, iff);
|
||||||
|
r->init_req(1, iftrue);
|
||||||
|
result->init_req(1, intcon(1));
|
||||||
|
result->init_req(2, intcon(0));
|
||||||
|
|
||||||
|
set_control(_gvn.transform(r));
|
||||||
|
record_for_igvn(r);
|
||||||
|
|
||||||
|
C->set_has_split_ifs(true); // Has chance for split-if optimization
|
||||||
|
}
|
||||||
|
|
||||||
|
push(_gvn.transform(result));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1519,6 +1519,7 @@ void IdealLoopTree::adjust_loop_exit_prob( PhaseIdealLoop *phase ) {
|
|||||||
Node *bol = iff->in(1);
|
Node *bol = iff->in(1);
|
||||||
if( bol && bol->req() > 1 && bol->in(1) &&
|
if( bol && bol->req() > 1 && bol->in(1) &&
|
||||||
((bol->in(1)->Opcode() == Op_StorePConditional ) ||
|
((bol->in(1)->Opcode() == Op_StorePConditional ) ||
|
||||||
|
(bol->in(1)->Opcode() == Op_StoreIConditional ) ||
|
||||||
(bol->in(1)->Opcode() == Op_StoreLConditional ) ||
|
(bol->in(1)->Opcode() == Op_StoreLConditional ) ||
|
||||||
(bol->in(1)->Opcode() == Op_CompareAndSwapI ) ||
|
(bol->in(1)->Opcode() == Op_CompareAndSwapI ) ||
|
||||||
(bol->in(1)->Opcode() == Op_CompareAndSwapL ) ||
|
(bol->in(1)->Opcode() == Op_CompareAndSwapL ) ||
|
||||||
|
@ -82,16 +82,31 @@ void PhaseMacroExpand::copy_call_debug_info(CallNode *oldcall, CallNode * newcal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* PhaseMacroExpand::opt_iff(Node* region, Node* iff) {
|
Node* PhaseMacroExpand::opt_bits_test(Node* ctrl, Node* region, int edge, Node* word, int mask, int bits, bool return_fast_path) {
|
||||||
IfNode *opt_iff = transform_later(iff)->as_If();
|
Node* cmp;
|
||||||
|
if (mask != 0) {
|
||||||
|
Node* and_node = transform_later(new (C, 3) AndXNode(word, MakeConX(mask)));
|
||||||
|
cmp = transform_later(new (C, 3) CmpXNode(and_node, MakeConX(bits)));
|
||||||
|
} else {
|
||||||
|
cmp = word;
|
||||||
|
}
|
||||||
|
Node* bol = transform_later(new (C, 2) BoolNode(cmp, BoolTest::ne));
|
||||||
|
IfNode* iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
|
||||||
|
transform_later(iff);
|
||||||
|
|
||||||
// Fast path taken; set region slot 2
|
// Fast path taken.
|
||||||
Node *fast_taken = transform_later( new (C, 1) IfFalseNode(opt_iff) );
|
Node *fast_taken = transform_later( new (C, 1) IfFalseNode(iff) );
|
||||||
region->init_req(2,fast_taken); // Capture fast-control
|
|
||||||
|
|
||||||
// Fast path not-taken, i.e. slow path
|
// Fast path not-taken, i.e. slow path
|
||||||
Node *slow_taken = transform_later( new (C, 1) IfTrueNode(opt_iff) );
|
Node *slow_taken = transform_later( new (C, 1) IfTrueNode(iff) );
|
||||||
return slow_taken;
|
|
||||||
|
if (return_fast_path) {
|
||||||
|
region->init_req(edge, slow_taken); // Capture slow-control
|
||||||
|
return fast_taken;
|
||||||
|
} else {
|
||||||
|
region->init_req(edge, fast_taken); // Capture fast-control
|
||||||
|
return slow_taken;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------copy_predefined_input_for_runtime_call--------------------
|
//--------------------copy_predefined_input_for_runtime_call--------------------
|
||||||
@ -854,7 +869,7 @@ void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_ad
|
|||||||
|
|
||||||
Node* PhaseMacroExpand::make_load(Node* ctl, Node* mem, Node* base, int offset, const Type* value_type, BasicType bt) {
|
Node* PhaseMacroExpand::make_load(Node* ctl, Node* mem, Node* base, int offset, const Type* value_type, BasicType bt) {
|
||||||
Node* adr = basic_plus_adr(base, offset);
|
Node* adr = basic_plus_adr(base, offset);
|
||||||
const TypePtr* adr_type = TypeRawPtr::BOTTOM;
|
const TypePtr* adr_type = adr->bottom_type()->is_ptr();
|
||||||
Node* value = LoadNode::make(_igvn, ctl, mem, adr, adr_type, value_type, bt);
|
Node* value = LoadNode::make(_igvn, ctl, mem, adr, adr_type, value_type, bt);
|
||||||
transform_later(value);
|
transform_later(value);
|
||||||
return value;
|
return value;
|
||||||
@ -1583,12 +1598,194 @@ void PhaseMacroExpand::expand_lock_node(LockNode *lock) {
|
|||||||
Node* flock = lock->fastlock_node();
|
Node* flock = lock->fastlock_node();
|
||||||
|
|
||||||
// Make the merge point
|
// Make the merge point
|
||||||
Node *region = new (C, 3) RegionNode(3);
|
Node *region;
|
||||||
|
Node *mem_phi;
|
||||||
|
Node *slow_path;
|
||||||
|
|
||||||
Node *bol = transform_later(new (C, 2) BoolNode(flock,BoolTest::ne));
|
if (UseOptoBiasInlining) {
|
||||||
Node *iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
|
/*
|
||||||
// Optimize test; set region slot 2
|
* See the full descrition in MacroAssembler::biased_locking_enter().
|
||||||
Node *slow_path = opt_iff(region,iff);
|
*
|
||||||
|
* if( (mark_word & biased_lock_mask) == biased_lock_pattern ) {
|
||||||
|
* // The object is biased.
|
||||||
|
* proto_node = klass->prototype_header;
|
||||||
|
* o_node = thread | proto_node;
|
||||||
|
* x_node = o_node ^ mark_word;
|
||||||
|
* if( (x_node & ~age_mask) == 0 ) { // Biased to the current thread ?
|
||||||
|
* // Done.
|
||||||
|
* } else {
|
||||||
|
* if( (x_node & biased_lock_mask) != 0 ) {
|
||||||
|
* // The klass's prototype header is no longer biased.
|
||||||
|
* cas(&mark_word, mark_word, proto_node)
|
||||||
|
* goto cas_lock;
|
||||||
|
* } else {
|
||||||
|
* // The klass's prototype header is still biased.
|
||||||
|
* if( (x_node & epoch_mask) != 0 ) { // Expired epoch?
|
||||||
|
* old = mark_word;
|
||||||
|
* new = o_node;
|
||||||
|
* } else {
|
||||||
|
* // Different thread or anonymous biased.
|
||||||
|
* old = mark_word & (epoch_mask | age_mask | biased_lock_mask);
|
||||||
|
* new = thread | old;
|
||||||
|
* }
|
||||||
|
* // Try to rebias.
|
||||||
|
* if( cas(&mark_word, old, new) == 0 ) {
|
||||||
|
* // Done.
|
||||||
|
* } else {
|
||||||
|
* goto slow_path; // Failed.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* } else {
|
||||||
|
* // The object is not biased.
|
||||||
|
* cas_lock:
|
||||||
|
* if( FastLock(obj) == 0 ) {
|
||||||
|
* // Done.
|
||||||
|
* } else {
|
||||||
|
* slow_path:
|
||||||
|
* OptoRuntime::complete_monitor_locking_Java(obj);
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
region = new (C, 5) RegionNode(5);
|
||||||
|
// create a Phi for the memory state
|
||||||
|
mem_phi = new (C, 5) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
|
||||||
|
|
||||||
|
Node* fast_lock_region = new (C, 3) RegionNode(3);
|
||||||
|
Node* fast_lock_mem_phi = new (C, 3) PhiNode( fast_lock_region, Type::MEMORY, TypeRawPtr::BOTTOM);
|
||||||
|
|
||||||
|
// First, check mark word for the biased lock pattern.
|
||||||
|
Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type());
|
||||||
|
|
||||||
|
// Get fast path - mark word has the biased lock pattern.
|
||||||
|
ctrl = opt_bits_test(ctrl, fast_lock_region, 1, mark_node,
|
||||||
|
markOopDesc::biased_lock_mask_in_place,
|
||||||
|
markOopDesc::biased_lock_pattern, true);
|
||||||
|
// fast_lock_region->in(1) is set to slow path.
|
||||||
|
fast_lock_mem_phi->init_req(1, mem);
|
||||||
|
|
||||||
|
// Now check that the lock is biased to the current thread and has
|
||||||
|
// the same epoch and bias as Klass::_prototype_header.
|
||||||
|
|
||||||
|
// Special-case a fresh allocation to avoid building nodes:
|
||||||
|
Node* klass_node = AllocateNode::Ideal_klass(obj, &_igvn);
|
||||||
|
if (klass_node == NULL) {
|
||||||
|
Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
|
||||||
|
klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) );
|
||||||
|
klass_node->init_req(0, ctrl);
|
||||||
|
}
|
||||||
|
Node *proto_node = make_load(ctrl, mem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeX_X, TypeX_X->basic_type());
|
||||||
|
|
||||||
|
Node* thread = transform_later(new (C, 1) ThreadLocalNode());
|
||||||
|
Node* cast_thread = transform_later(new (C, 2) CastP2XNode(ctrl, thread));
|
||||||
|
Node* o_node = transform_later(new (C, 3) OrXNode(cast_thread, proto_node));
|
||||||
|
Node* x_node = transform_later(new (C, 3) XorXNode(o_node, mark_node));
|
||||||
|
|
||||||
|
// Get slow path - mark word does NOT match the value.
|
||||||
|
Node* not_biased_ctrl = opt_bits_test(ctrl, region, 3, x_node,
|
||||||
|
(~markOopDesc::age_mask_in_place), 0);
|
||||||
|
// region->in(3) is set to fast path - the object is biased to the current thread.
|
||||||
|
mem_phi->init_req(3, mem);
|
||||||
|
|
||||||
|
|
||||||
|
// Mark word does NOT match the value (thread | Klass::_prototype_header).
|
||||||
|
|
||||||
|
|
||||||
|
// First, check biased pattern.
|
||||||
|
// Get fast path - _prototype_header has the same biased lock pattern.
|
||||||
|
ctrl = opt_bits_test(not_biased_ctrl, fast_lock_region, 2, x_node,
|
||||||
|
markOopDesc::biased_lock_mask_in_place, 0, true);
|
||||||
|
|
||||||
|
not_biased_ctrl = fast_lock_region->in(2); // Slow path
|
||||||
|
// fast_lock_region->in(2) - the prototype header is no longer biased
|
||||||
|
// and we have to revoke the bias on this object.
|
||||||
|
// We are going to try to reset the mark of this object to the prototype
|
||||||
|
// value and fall through to the CAS-based locking scheme.
|
||||||
|
Node* adr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
|
||||||
|
Node* cas = new (C, 5) StoreXConditionalNode(not_biased_ctrl, mem, adr,
|
||||||
|
proto_node, mark_node);
|
||||||
|
transform_later(cas);
|
||||||
|
Node* proj = transform_later( new (C, 1) SCMemProjNode(cas));
|
||||||
|
fast_lock_mem_phi->init_req(2, proj);
|
||||||
|
|
||||||
|
|
||||||
|
// Second, check epoch bits.
|
||||||
|
Node* rebiased_region = new (C, 3) RegionNode(3);
|
||||||
|
Node* old_phi = new (C, 3) PhiNode( rebiased_region, TypeX_X);
|
||||||
|
Node* new_phi = new (C, 3) PhiNode( rebiased_region, TypeX_X);
|
||||||
|
|
||||||
|
// Get slow path - mark word does NOT match epoch bits.
|
||||||
|
Node* epoch_ctrl = opt_bits_test(ctrl, rebiased_region, 1, x_node,
|
||||||
|
markOopDesc::epoch_mask_in_place, 0);
|
||||||
|
// The epoch of the current bias is not valid, attempt to rebias the object
|
||||||
|
// toward the current thread.
|
||||||
|
rebiased_region->init_req(2, epoch_ctrl);
|
||||||
|
old_phi->init_req(2, mark_node);
|
||||||
|
new_phi->init_req(2, o_node);
|
||||||
|
|
||||||
|
// rebiased_region->in(1) is set to fast path.
|
||||||
|
// The epoch of the current bias is still valid but we know
|
||||||
|
// nothing about the owner; it might be set or it might be clear.
|
||||||
|
Node* cmask = MakeConX(markOopDesc::biased_lock_mask_in_place |
|
||||||
|
markOopDesc::age_mask_in_place |
|
||||||
|
markOopDesc::epoch_mask_in_place);
|
||||||
|
Node* old = transform_later(new (C, 3) AndXNode(mark_node, cmask));
|
||||||
|
cast_thread = transform_later(new (C, 2) CastP2XNode(ctrl, thread));
|
||||||
|
Node* new_mark = transform_later(new (C, 3) OrXNode(cast_thread, old));
|
||||||
|
old_phi->init_req(1, old);
|
||||||
|
new_phi->init_req(1, new_mark);
|
||||||
|
|
||||||
|
transform_later(rebiased_region);
|
||||||
|
transform_later(old_phi);
|
||||||
|
transform_later(new_phi);
|
||||||
|
|
||||||
|
// Try to acquire the bias of the object using an atomic operation.
|
||||||
|
// If this fails we will go in to the runtime to revoke the object's bias.
|
||||||
|
cas = new (C, 5) StoreXConditionalNode(rebiased_region, mem, adr,
|
||||||
|
new_phi, old_phi);
|
||||||
|
transform_later(cas);
|
||||||
|
proj = transform_later( new (C, 1) SCMemProjNode(cas));
|
||||||
|
|
||||||
|
// Get slow path - Failed to CAS.
|
||||||
|
not_biased_ctrl = opt_bits_test(rebiased_region, region, 4, cas, 0, 0);
|
||||||
|
mem_phi->init_req(4, proj);
|
||||||
|
// region->in(4) is set to fast path - the object is rebiased to the current thread.
|
||||||
|
|
||||||
|
// Failed to CAS.
|
||||||
|
slow_path = new (C, 3) RegionNode(3);
|
||||||
|
Node *slow_mem = new (C, 3) PhiNode( slow_path, Type::MEMORY, TypeRawPtr::BOTTOM);
|
||||||
|
|
||||||
|
slow_path->init_req(1, not_biased_ctrl); // Capture slow-control
|
||||||
|
slow_mem->init_req(1, proj);
|
||||||
|
|
||||||
|
// Call CAS-based locking scheme (FastLock node).
|
||||||
|
|
||||||
|
transform_later(fast_lock_region);
|
||||||
|
transform_later(fast_lock_mem_phi);
|
||||||
|
|
||||||
|
// Get slow path - FastLock failed to lock the object.
|
||||||
|
ctrl = opt_bits_test(fast_lock_region, region, 2, flock, 0, 0);
|
||||||
|
mem_phi->init_req(2, fast_lock_mem_phi);
|
||||||
|
// region->in(2) is set to fast path - the object is locked to the current thread.
|
||||||
|
|
||||||
|
slow_path->init_req(2, ctrl); // Capture slow-control
|
||||||
|
slow_mem->init_req(2, fast_lock_mem_phi);
|
||||||
|
|
||||||
|
transform_later(slow_path);
|
||||||
|
transform_later(slow_mem);
|
||||||
|
// Reset lock's memory edge.
|
||||||
|
lock->set_req(TypeFunc::Memory, slow_mem);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
region = new (C, 3) RegionNode(3);
|
||||||
|
// create a Phi for the memory state
|
||||||
|
mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
|
||||||
|
|
||||||
|
// Optimize test; set region slot 2
|
||||||
|
slow_path = opt_bits_test(ctrl, region, 2, flock, 0, 0);
|
||||||
|
mem_phi->init_req(2, mem);
|
||||||
|
}
|
||||||
|
|
||||||
// Make slow path call
|
// Make slow path call
|
||||||
CallNode *call = make_slow_call( (CallNode *) lock, OptoRuntime::complete_monitor_enter_Type(), OptoRuntime::complete_monitor_locking_Java(), NULL, slow_path, obj, box );
|
CallNode *call = make_slow_call( (CallNode *) lock, OptoRuntime::complete_monitor_enter_Type(), OptoRuntime::complete_monitor_locking_Java(), NULL, slow_path, obj, box );
|
||||||
@ -1614,16 +1811,11 @@ void PhaseMacroExpand::expand_lock_node(LockNode *lock) {
|
|||||||
transform_later(region);
|
transform_later(region);
|
||||||
_igvn.subsume_node(_fallthroughproj, region);
|
_igvn.subsume_node(_fallthroughproj, region);
|
||||||
|
|
||||||
// create a Phi for the memory state
|
Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) );
|
||||||
Node *mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
|
|
||||||
Node *memproj = transform_later( new (C, 1) ProjNode(call, TypeFunc::Memory) );
|
|
||||||
mem_phi->init_req(1, memproj );
|
mem_phi->init_req(1, memproj );
|
||||||
mem_phi->init_req(2, mem);
|
|
||||||
transform_later(mem_phi);
|
transform_later(mem_phi);
|
||||||
_igvn.hash_delete(_memproj_fallthrough);
|
_igvn.hash_delete(_memproj_fallthrough);
|
||||||
_igvn.subsume_node(_memproj_fallthrough, mem_phi);
|
_igvn.subsume_node(_memproj_fallthrough, mem_phi);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------expand_unlock_node----------------------
|
//------------------------------expand_unlock_node----------------------
|
||||||
@ -1637,14 +1829,31 @@ void PhaseMacroExpand::expand_unlock_node(UnlockNode *unlock) {
|
|||||||
// No need for a null check on unlock
|
// No need for a null check on unlock
|
||||||
|
|
||||||
// Make the merge point
|
// Make the merge point
|
||||||
RegionNode *region = new (C, 3) RegionNode(3);
|
Node *region;
|
||||||
|
Node *mem_phi;
|
||||||
|
|
||||||
|
if (UseOptoBiasInlining) {
|
||||||
|
// Check for biased locking unlock case, which is a no-op.
|
||||||
|
// See the full descrition in MacroAssembler::biased_locking_exit().
|
||||||
|
region = new (C, 4) RegionNode(4);
|
||||||
|
// create a Phi for the memory state
|
||||||
|
mem_phi = new (C, 4) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
|
||||||
|
mem_phi->init_req(3, mem);
|
||||||
|
|
||||||
|
Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type());
|
||||||
|
ctrl = opt_bits_test(ctrl, region, 3, mark_node,
|
||||||
|
markOopDesc::biased_lock_mask_in_place,
|
||||||
|
markOopDesc::biased_lock_pattern);
|
||||||
|
} else {
|
||||||
|
region = new (C, 3) RegionNode(3);
|
||||||
|
// create a Phi for the memory state
|
||||||
|
mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
|
||||||
|
}
|
||||||
|
|
||||||
FastUnlockNode *funlock = new (C, 3) FastUnlockNode( ctrl, obj, box );
|
FastUnlockNode *funlock = new (C, 3) FastUnlockNode( ctrl, obj, box );
|
||||||
funlock = transform_later( funlock )->as_FastUnlock();
|
funlock = transform_later( funlock )->as_FastUnlock();
|
||||||
Node *bol = transform_later(new (C, 2) BoolNode(funlock,BoolTest::ne));
|
|
||||||
Node *iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
|
|
||||||
// Optimize test; set region slot 2
|
// Optimize test; set region slot 2
|
||||||
Node *slow_path = opt_iff(region,iff);
|
Node *slow_path = opt_bits_test(ctrl, region, 2, funlock, 0, 0);
|
||||||
|
|
||||||
CallNode *call = make_slow_call( (CallNode *) unlock, OptoRuntime::complete_monitor_exit_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), "complete_monitor_unlocking_C", slow_path, obj, box );
|
CallNode *call = make_slow_call( (CallNode *) unlock, OptoRuntime::complete_monitor_exit_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), "complete_monitor_unlocking_C", slow_path, obj, box );
|
||||||
|
|
||||||
@ -1666,16 +1875,12 @@ void PhaseMacroExpand::expand_unlock_node(UnlockNode *unlock) {
|
|||||||
transform_later(region);
|
transform_later(region);
|
||||||
_igvn.subsume_node(_fallthroughproj, region);
|
_igvn.subsume_node(_fallthroughproj, region);
|
||||||
|
|
||||||
// create a Phi for the memory state
|
|
||||||
Node *mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
|
|
||||||
Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) );
|
Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) );
|
||||||
mem_phi->init_req(1, memproj );
|
mem_phi->init_req(1, memproj );
|
||||||
mem_phi->init_req(2, mem);
|
mem_phi->init_req(2, mem);
|
||||||
transform_later(mem_phi);
|
transform_later(mem_phi);
|
||||||
_igvn.hash_delete(_memproj_fallthrough);
|
_igvn.hash_delete(_memproj_fallthrough);
|
||||||
_igvn.subsume_node(_memproj_fallthrough, mem_phi);
|
_igvn.subsume_node(_memproj_fallthrough, mem_phi);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------expand_macro_nodes----------------------
|
//------------------------------expand_macro_nodes----------------------
|
||||||
|
@ -93,7 +93,7 @@ private:
|
|||||||
|
|
||||||
int replace_input(Node *use, Node *oldref, Node *newref);
|
int replace_input(Node *use, Node *oldref, Node *newref);
|
||||||
void copy_call_debug_info(CallNode *oldcall, CallNode * newcall);
|
void copy_call_debug_info(CallNode *oldcall, CallNode * newcall);
|
||||||
Node* opt_iff(Node* region, Node* iff);
|
Node* opt_bits_test(Node* ctrl, Node* region, int edge, Node* word, int mask, int bits, bool return_fast_path = false);
|
||||||
void copy_predefined_input_for_runtime_call(Node * ctrl, CallNode* oldcall, CallNode* call);
|
void copy_predefined_input_for_runtime_call(Node * ctrl, CallNode* oldcall, CallNode* call);
|
||||||
CallNode* make_slow_call(CallNode *oldcall, const TypeFunc* slow_call_type, address slow_call,
|
CallNode* make_slow_call(CallNode *oldcall, const TypeFunc* slow_call_type, address slow_call,
|
||||||
const char* leaf_name, Node* slow_path, Node* parm0, Node* parm1);
|
const char* leaf_name, Node* slow_path, Node* parm0, Node* parm1);
|
||||||
|
@ -1951,6 +1951,7 @@ void Matcher::find_shared( Node *n ) {
|
|||||||
// Now hack a few special opcodes
|
// Now hack a few special opcodes
|
||||||
switch( n->Opcode() ) { // Handle some opcodes special
|
switch( n->Opcode() ) { // Handle some opcodes special
|
||||||
case Op_StorePConditional:
|
case Op_StorePConditional:
|
||||||
|
case Op_StoreIConditional:
|
||||||
case Op_StoreLConditional:
|
case Op_StoreLConditional:
|
||||||
case Op_CompareAndSwapI:
|
case Op_CompareAndSwapI:
|
||||||
case Op_CompareAndSwapL:
|
case Op_CompareAndSwapL:
|
||||||
|
@ -324,7 +324,7 @@ public:
|
|||||||
virtual int regnum_to_fpu_offset(int regnum);
|
virtual int regnum_to_fpu_offset(int regnum);
|
||||||
|
|
||||||
// Is this branch offset small enough to be addressed by a short branch?
|
// Is this branch offset small enough to be addressed by a short branch?
|
||||||
bool is_short_branch_offset(int offset);
|
bool is_short_branch_offset(int rule, int offset);
|
||||||
|
|
||||||
// Optional scaling for the parameter to the ClearArray/CopyArray node.
|
// Optional scaling for the parameter to the ClearArray/CopyArray node.
|
||||||
static const bool init_array_count_is_in_bytes;
|
static const bool init_array_count_is_in_bytes;
|
||||||
|
@ -227,6 +227,14 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) {
|
|||||||
const Type *t_adr = phase->type( address );
|
const Type *t_adr = phase->type( address );
|
||||||
if( t_adr == Type::TOP ) return NodeSentinel; // caller will return NULL
|
if( t_adr == Type::TOP ) return NodeSentinel; // caller will return NULL
|
||||||
|
|
||||||
|
PhaseIterGVN *igvn = phase->is_IterGVN();
|
||||||
|
if( can_reshape && igvn != NULL && igvn->_worklist.member(address) ) {
|
||||||
|
// The address's base and type may change when the address is processed.
|
||||||
|
// Delay this mem node transformation until the address is processed.
|
||||||
|
phase->is_IterGVN()->_worklist.push(this);
|
||||||
|
return NodeSentinel; // caller will return NULL
|
||||||
|
}
|
||||||
|
|
||||||
// Avoid independent memory operations
|
// Avoid independent memory operations
|
||||||
Node* old_mem = mem;
|
Node* old_mem = mem;
|
||||||
|
|
||||||
|
@ -632,6 +632,17 @@ public:
|
|||||||
virtual uint ideal_reg() const { return Op_RegFlags; }
|
virtual uint ideal_reg() const { return Op_RegFlags; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//------------------------------StoreIConditionalNode---------------------------
|
||||||
|
// Conditionally store int to memory, if no change since prior
|
||||||
|
// load-locked. Sets flags for success or failure of the store.
|
||||||
|
class StoreIConditionalNode : public LoadStoreNode {
|
||||||
|
public:
|
||||||
|
StoreIConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ii ) : LoadStoreNode(c, mem, adr, val, ii) { }
|
||||||
|
virtual int Opcode() const;
|
||||||
|
// Produces flags
|
||||||
|
virtual uint ideal_reg() const { return Op_RegFlags; }
|
||||||
|
};
|
||||||
|
|
||||||
//------------------------------StoreLConditionalNode---------------------------
|
//------------------------------StoreLConditionalNode---------------------------
|
||||||
// Conditionally store long to memory, if no change since prior
|
// Conditionally store long to memory, if no change since prior
|
||||||
// load-locked. Sets flags for success or failure of the store.
|
// load-locked. Sets flags for success or failure of the store.
|
||||||
@ -639,6 +650,8 @@ class StoreLConditionalNode : public LoadStoreNode {
|
|||||||
public:
|
public:
|
||||||
StoreLConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreNode(c, mem, adr, val, ll) { }
|
StoreLConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreNode(c, mem, adr, val, ll) { }
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
|
// Produces flags
|
||||||
|
virtual uint ideal_reg() const { return Op_RegFlags; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ bool Compile::is_node_getting_a_safepoint( Node* n) {
|
|||||||
# endif // ENABLE_ZAP_DEAD_LOCALS
|
# endif // ENABLE_ZAP_DEAD_LOCALS
|
||||||
|
|
||||||
//------------------------------compute_loop_first_inst_sizes------------------
|
//------------------------------compute_loop_first_inst_sizes------------------
|
||||||
// Compute the size of first NumberOfLoopInstrToAlign instructions at head
|
// Compute the size of first NumberOfLoopInstrToAlign instructions at the top
|
||||||
// of a loop. When aligning a loop we need to provide enough instructions
|
// of a loop. When aligning a loop we need to provide enough instructions
|
||||||
// in cpu's fetch buffer to feed decoders. The loop alignment could be
|
// in cpu's fetch buffer to feed decoders. The loop alignment could be
|
||||||
// avoided if we have enough instructions in fetch buffer at the head of a loop.
|
// avoided if we have enough instructions in fetch buffer at the head of a loop.
|
||||||
@ -284,34 +284,23 @@ void Compile::compute_loop_first_inst_sizes() {
|
|||||||
for( uint i=1; i <= last_block; i++ ) {
|
for( uint i=1; i <= last_block; i++ ) {
|
||||||
Block *b = _cfg->_blocks[i];
|
Block *b = _cfg->_blocks[i];
|
||||||
// Check the first loop's block which requires an alignment.
|
// Check the first loop's block which requires an alignment.
|
||||||
if( b->head()->is_Loop() &&
|
if( b->loop_alignment() > (uint)relocInfo::addr_unit() ) {
|
||||||
b->code_alignment() > (uint)relocInfo::addr_unit() ) {
|
|
||||||
uint sum_size = 0;
|
uint sum_size = 0;
|
||||||
uint inst_cnt = NumberOfLoopInstrToAlign;
|
uint inst_cnt = NumberOfLoopInstrToAlign;
|
||||||
inst_cnt = b->compute_first_inst_size(sum_size, inst_cnt,
|
inst_cnt = b->compute_first_inst_size(sum_size, inst_cnt, _regalloc);
|
||||||
_regalloc);
|
|
||||||
// Check the next fallthrough block if first loop's block does not have
|
// Check subsequent fallthrough blocks if the loop's first
|
||||||
// enough instructions.
|
// block(s) does not have enough instructions.
|
||||||
if( inst_cnt > 0 && i < last_block ) {
|
Block *nb = b;
|
||||||
// First, check if the first loop's block contains whole loop.
|
while( inst_cnt > 0 &&
|
||||||
// LoopNode::LoopBackControl == 2.
|
i < last_block &&
|
||||||
Block *bx = _cfg->_bbs[b->pred(2)->_idx];
|
!_cfg->_blocks[i+1]->has_loop_alignment() &&
|
||||||
// Skip connector blocks (with limit in case of irreducible loops).
|
!nb->has_successor(b) ) {
|
||||||
int search_limit = 16;
|
i++;
|
||||||
while( bx->is_connector() && search_limit-- > 0) {
|
nb = _cfg->_blocks[i];
|
||||||
bx = _cfg->_bbs[bx->pred(1)->_idx];
|
inst_cnt = nb->compute_first_inst_size(sum_size, inst_cnt, _regalloc);
|
||||||
}
|
} // while( inst_cnt > 0 && i < last_block )
|
||||||
if( bx != b ) { // loop body is in several blocks.
|
|
||||||
Block *nb = NULL;
|
|
||||||
while( inst_cnt > 0 && i < last_block && nb != bx &&
|
|
||||||
!_cfg->_blocks[i+1]->head()->is_Loop() ) {
|
|
||||||
i++;
|
|
||||||
nb = _cfg->_blocks[i];
|
|
||||||
inst_cnt = nb->compute_first_inst_size(sum_size, inst_cnt,
|
|
||||||
_regalloc);
|
|
||||||
} // while( inst_cnt > 0 && i < last_block )
|
|
||||||
} // if( bx != b )
|
|
||||||
} // if( inst_cnt > 0 && i < last_block )
|
|
||||||
b->set_first_inst_size(sum_size);
|
b->set_first_inst_size(sum_size);
|
||||||
} // f( b->head()->is_Loop() )
|
} // f( b->head()->is_Loop() )
|
||||||
} // for( i <= last_block )
|
} // for( i <= last_block )
|
||||||
@ -332,6 +321,7 @@ void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, i
|
|||||||
uint *jmp_end = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks);
|
uint *jmp_end = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks);
|
||||||
uint *blk_starts = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks+1);
|
uint *blk_starts = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks+1);
|
||||||
DEBUG_ONLY( uint *jmp_target = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks); )
|
DEBUG_ONLY( uint *jmp_target = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks); )
|
||||||
|
DEBUG_ONLY( uint *jmp_rule = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks); )
|
||||||
blk_starts[0] = 0;
|
blk_starts[0] = 0;
|
||||||
|
|
||||||
// Initialize the sizes to 0
|
// Initialize the sizes to 0
|
||||||
@ -443,9 +433,9 @@ void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, i
|
|||||||
uintptr_t target = blk_starts[bnum];
|
uintptr_t target = blk_starts[bnum];
|
||||||
if( mach->is_pc_relative() ) {
|
if( mach->is_pc_relative() ) {
|
||||||
int offset = target-(blk_starts[i] + jmp_end[i]);
|
int offset = target-(blk_starts[i] + jmp_end[i]);
|
||||||
if (_matcher->is_short_branch_offset(offset)) {
|
if (_matcher->is_short_branch_offset(mach->rule(), offset)) {
|
||||||
// We've got a winner. Replace this branch.
|
// We've got a winner. Replace this branch.
|
||||||
MachNode *replacement = mach->short_branch_version(this);
|
MachNode* replacement = mach->short_branch_version(this);
|
||||||
b->_nodes.map(j, replacement);
|
b->_nodes.map(j, replacement);
|
||||||
mach->subsume_by(replacement);
|
mach->subsume_by(replacement);
|
||||||
|
|
||||||
@ -453,6 +443,7 @@ void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, i
|
|||||||
// next pass.
|
// next pass.
|
||||||
jmp_end[i] -= (mach->size(_regalloc) - replacement->size(_regalloc));
|
jmp_end[i] -= (mach->size(_regalloc) - replacement->size(_regalloc));
|
||||||
DEBUG_ONLY( jmp_target[i] = bnum; );
|
DEBUG_ONLY( jmp_target[i] = bnum; );
|
||||||
|
DEBUG_ONLY( jmp_rule[i] = mach->rule(); );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
@ -510,7 +501,7 @@ void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, i
|
|||||||
// Get the size of the block
|
// Get the size of the block
|
||||||
uint blk_size = adr - blk_starts[i];
|
uint blk_size = adr - blk_starts[i];
|
||||||
|
|
||||||
// When the next block starts a loop, we may insert pad NOP
|
// When the next block is the top of a loop, we may insert pad NOP
|
||||||
// instructions.
|
// instructions.
|
||||||
Block *nb = _cfg->_blocks[i+1];
|
Block *nb = _cfg->_blocks[i+1];
|
||||||
int current_offset = blk_starts[i] + blk_size;
|
int current_offset = blk_starts[i] + blk_size;
|
||||||
@ -524,10 +515,10 @@ void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, i
|
|||||||
for( i=0; i<_cfg->_num_blocks; i++ ) { // For all blocks
|
for( i=0; i<_cfg->_num_blocks; i++ ) { // For all blocks
|
||||||
if( jmp_target[i] != 0 ) {
|
if( jmp_target[i] != 0 ) {
|
||||||
int offset = blk_starts[jmp_target[i]]-(blk_starts[i] + jmp_end[i]);
|
int offset = blk_starts[jmp_target[i]]-(blk_starts[i] + jmp_end[i]);
|
||||||
if (!_matcher->is_short_branch_offset(offset)) {
|
if (!_matcher->is_short_branch_offset(jmp_rule[i], offset)) {
|
||||||
tty->print_cr("target (%d) - jmp_end(%d) = offset (%d), jmp_block B%d, target_block B%d", blk_starts[jmp_target[i]], blk_starts[i] + jmp_end[i], offset, i, jmp_target[i]);
|
tty->print_cr("target (%d) - jmp_end(%d) = offset (%d), jmp_block B%d, target_block B%d", blk_starts[jmp_target[i]], blk_starts[i] + jmp_end[i], offset, i, jmp_target[i]);
|
||||||
}
|
}
|
||||||
assert(_matcher->is_short_branch_offset(offset), "Displacement too large for short jmp");
|
assert(_matcher->is_short_branch_offset(jmp_rule[i], offset), "Displacement too large for short jmp");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1069,7 +1060,7 @@ void Compile::Fill_buffer() {
|
|||||||
|
|
||||||
// If this machine supports different size branch offsets, then pre-compute
|
// If this machine supports different size branch offsets, then pre-compute
|
||||||
// the length of the blocks
|
// the length of the blocks
|
||||||
if( _matcher->is_short_branch_offset(0) ) {
|
if( _matcher->is_short_branch_offset(-1, 0) ) {
|
||||||
Shorten_branches(blk_labels, code_req, locs_req, stub_req, const_req);
|
Shorten_branches(blk_labels, code_req, locs_req, stub_req, const_req);
|
||||||
labels_not_set = false;
|
labels_not_set = false;
|
||||||
}
|
}
|
||||||
@ -1380,8 +1371,8 @@ void Compile::Fill_buffer() {
|
|||||||
|
|
||||||
} // End for all instructions in block
|
} // End for all instructions in block
|
||||||
|
|
||||||
// If the next block _starts_ a loop, pad this block out to align
|
// If the next block is the top of a loop, pad this block out to align
|
||||||
// the loop start a little. Helps prevent pipe stalls at loop starts
|
// the loop top a little. Helps prevent pipe stalls at loop back branches.
|
||||||
int nop_size = (new (this) MachNopNode())->size(_regalloc);
|
int nop_size = (new (this) MachNopNode())->size(_regalloc);
|
||||||
if( i<_cfg->_num_blocks-1 ) {
|
if( i<_cfg->_num_blocks-1 ) {
|
||||||
Block *nb = _cfg->_blocks[i+1];
|
Block *nb = _cfg->_blocks[i+1];
|
||||||
|
@ -46,7 +46,7 @@ elapsedTimer Phase::_t_output;
|
|||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
elapsedTimer Phase::_t_graphReshaping;
|
elapsedTimer Phase::_t_graphReshaping;
|
||||||
elapsedTimer Phase::_t_scheduler;
|
elapsedTimer Phase::_t_scheduler;
|
||||||
elapsedTimer Phase::_t_removeEmptyBlocks;
|
elapsedTimer Phase::_t_blockOrdering;
|
||||||
elapsedTimer Phase::_t_macroExpand;
|
elapsedTimer Phase::_t_macroExpand;
|
||||||
elapsedTimer Phase::_t_peephole;
|
elapsedTimer Phase::_t_peephole;
|
||||||
elapsedTimer Phase::_t_codeGeneration;
|
elapsedTimer Phase::_t_codeGeneration;
|
||||||
@ -128,7 +128,7 @@ void Phase::print_timers() {
|
|||||||
tty->print_cr (" subtotal : %3.3f sec, %3.2f %%", regalloc_subtotal, percent_of_regalloc);
|
tty->print_cr (" subtotal : %3.3f sec, %3.2f %%", regalloc_subtotal, percent_of_regalloc);
|
||||||
}
|
}
|
||||||
tty->print_cr (" macroExpand : %3.3f sec", Phase::_t_macroExpand.seconds());
|
tty->print_cr (" macroExpand : %3.3f sec", Phase::_t_macroExpand.seconds());
|
||||||
tty->print_cr (" removeEmpty : %3.3f sec", Phase::_t_removeEmptyBlocks.seconds());
|
tty->print_cr (" blockOrdering: %3.3f sec", Phase::_t_blockOrdering.seconds());
|
||||||
tty->print_cr (" peephole : %3.3f sec", Phase::_t_peephole.seconds());
|
tty->print_cr (" peephole : %3.3f sec", Phase::_t_peephole.seconds());
|
||||||
tty->print_cr (" codeGen : %3.3f sec", Phase::_t_codeGeneration.seconds());
|
tty->print_cr (" codeGen : %3.3f sec", Phase::_t_codeGeneration.seconds());
|
||||||
tty->print_cr (" install_code : %3.3f sec", Phase::_t_registerMethod.seconds());
|
tty->print_cr (" install_code : %3.3f sec", Phase::_t_registerMethod.seconds());
|
||||||
@ -137,7 +137,7 @@ void Phase::print_timers() {
|
|||||||
(DoEscapeAnalysis ? Phase::_t_escapeAnalysis.seconds() : 0.0) +
|
(DoEscapeAnalysis ? Phase::_t_escapeAnalysis.seconds() : 0.0) +
|
||||||
Phase::_t_optimizer.seconds() + Phase::_t_graphReshaping.seconds() +
|
Phase::_t_optimizer.seconds() + Phase::_t_graphReshaping.seconds() +
|
||||||
Phase::_t_matcher.seconds() + Phase::_t_scheduler.seconds() +
|
Phase::_t_matcher.seconds() + Phase::_t_scheduler.seconds() +
|
||||||
Phase::_t_registerAllocation.seconds() + Phase::_t_removeEmptyBlocks.seconds() +
|
Phase::_t_registerAllocation.seconds() + Phase::_t_blockOrdering.seconds() +
|
||||||
Phase::_t_macroExpand.seconds() + Phase::_t_peephole.seconds() +
|
Phase::_t_macroExpand.seconds() + Phase::_t_peephole.seconds() +
|
||||||
Phase::_t_codeGeneration.seconds() + Phase::_t_registerMethod.seconds();
|
Phase::_t_codeGeneration.seconds() + Phase::_t_registerMethod.seconds();
|
||||||
double percent_of_method_compile = ((phase_subtotal == 0.0) ? 0.0 : phase_subtotal / Phase::_t_methodCompilation.seconds()) * 100.0;
|
double percent_of_method_compile = ((phase_subtotal == 0.0) ? 0.0 : phase_subtotal / Phase::_t_methodCompilation.seconds()) * 100.0;
|
||||||
|
@ -40,16 +40,12 @@ public:
|
|||||||
Optimistic, // Optimistic analysis phase
|
Optimistic, // Optimistic analysis phase
|
||||||
GVN, // Pessimistic global value numbering phase
|
GVN, // Pessimistic global value numbering phase
|
||||||
Ins_Select, // Instruction selection phase
|
Ins_Select, // Instruction selection phase
|
||||||
Copy_Elimination, // Copy Elimination
|
|
||||||
Dead_Code_Elimination, // DCE and compress Nodes
|
|
||||||
Conditional_Constant, // Conditional Constant Propagation
|
|
||||||
CFG, // Build a CFG
|
CFG, // Build a CFG
|
||||||
DefUse, // Build Def->Use chains
|
BlockLayout, // Linear ordering of blocks
|
||||||
Register_Allocation, // Register allocation, duh
|
Register_Allocation, // Register allocation, duh
|
||||||
LIVE, // Dragon-book LIVE range problem
|
LIVE, // Dragon-book LIVE range problem
|
||||||
Interference_Graph, // Building the IFG
|
Interference_Graph, // Building the IFG
|
||||||
Coalesce, // Coalescing copies
|
Coalesce, // Coalescing copies
|
||||||
Conditional_CProp, // Conditional Constant Propagation
|
|
||||||
Ideal_Loop, // Find idealized trip-counted loops
|
Ideal_Loop, // Find idealized trip-counted loops
|
||||||
Macro_Expand, // Expand macro nodes
|
Macro_Expand, // Expand macro nodes
|
||||||
Peephole, // Apply peephole optimizations
|
Peephole, // Apply peephole optimizations
|
||||||
@ -80,7 +76,7 @@ protected:
|
|||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
static elapsedTimer _t_graphReshaping;
|
static elapsedTimer _t_graphReshaping;
|
||||||
static elapsedTimer _t_scheduler;
|
static elapsedTimer _t_scheduler;
|
||||||
static elapsedTimer _t_removeEmptyBlocks;
|
static elapsedTimer _t_blockOrdering;
|
||||||
static elapsedTimer _t_macroExpand;
|
static elapsedTimer _t_macroExpand;
|
||||||
static elapsedTimer _t_peephole;
|
static elapsedTimer _t_peephole;
|
||||||
static elapsedTimer _t_codeGeneration;
|
static elapsedTimer _t_codeGeneration;
|
||||||
|
@ -53,6 +53,7 @@ Node *PhaseChaitin::get_spillcopy_wide( Node *def, Node *use, uint uidx ) {
|
|||||||
// Bail rather than abort
|
// Bail rather than abort
|
||||||
int ireg = def->ideal_reg();
|
int ireg = def->ideal_reg();
|
||||||
if( ireg == 0 || ireg == Op_RegFlags ) {
|
if( ireg == 0 || ireg == Op_RegFlags ) {
|
||||||
|
assert(false, "attempted to spill a non-spillable item");
|
||||||
C->record_method_not_compilable("attempted to spill a non-spillable item");
|
C->record_method_not_compilable("attempted to spill a non-spillable item");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -3541,7 +3541,7 @@ intptr_t TypeNarrowOop::get_con() const {
|
|||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
void TypeNarrowOop::dump2( Dict & d, uint depth, outputStream *st ) const {
|
void TypeNarrowOop::dump2( Dict & d, uint depth, outputStream *st ) const {
|
||||||
tty->print("narrowoop: ");
|
st->print("narrowoop: ");
|
||||||
_ooptype->dump2(d, depth, st);
|
_ooptype->dump2(d, depth, st);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1183,6 +1183,9 @@ inline bool Type::is_floatingpoint() const {
|
|||||||
#define RShiftXNode RShiftLNode
|
#define RShiftXNode RShiftLNode
|
||||||
// For card marks and hashcodes
|
// For card marks and hashcodes
|
||||||
#define URShiftXNode URShiftLNode
|
#define URShiftXNode URShiftLNode
|
||||||
|
// UseOptoBiasInlining
|
||||||
|
#define XorXNode XorLNode
|
||||||
|
#define StoreXConditionalNode StoreLConditionalNode
|
||||||
// Opcodes
|
// Opcodes
|
||||||
#define Op_LShiftX Op_LShiftL
|
#define Op_LShiftX Op_LShiftL
|
||||||
#define Op_AndX Op_AndL
|
#define Op_AndX Op_AndL
|
||||||
@ -1222,6 +1225,9 @@ inline bool Type::is_floatingpoint() const {
|
|||||||
#define RShiftXNode RShiftINode
|
#define RShiftXNode RShiftINode
|
||||||
// For card marks and hashcodes
|
// For card marks and hashcodes
|
||||||
#define URShiftXNode URShiftINode
|
#define URShiftXNode URShiftINode
|
||||||
|
// UseOptoBiasInlining
|
||||||
|
#define XorXNode XorINode
|
||||||
|
#define StoreXConditionalNode StoreIConditionalNode
|
||||||
// Opcodes
|
// Opcodes
|
||||||
#define Op_LShiftX Op_LShiftI
|
#define Op_LShiftX Op_LShiftI
|
||||||
#define Op_AndX Op_AndI
|
#define Op_AndX Op_AndI
|
||||||
|
@ -1365,6 +1365,9 @@ void Arguments::set_aggressive_opts_flags() {
|
|||||||
if (AggressiveOpts && FLAG_IS_DEFAULT(SpecialArraysEquals)) {
|
if (AggressiveOpts && FLAG_IS_DEFAULT(SpecialArraysEquals)) {
|
||||||
FLAG_SET_DEFAULT(SpecialArraysEquals, true);
|
FLAG_SET_DEFAULT(SpecialArraysEquals, true);
|
||||||
}
|
}
|
||||||
|
if (AggressiveOpts && FLAG_IS_DEFAULT(BiasedLockingStartupDelay)) {
|
||||||
|
FLAG_SET_DEFAULT(BiasedLockingStartupDelay, 500);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (AggressiveOpts) {
|
if (AggressiveOpts) {
|
||||||
@ -2625,6 +2628,12 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
|
|||||||
FLAG_SET_DEFAULT(UseBiasedLocking, false);
|
FLAG_SET_DEFAULT(UseBiasedLocking, false);
|
||||||
#endif /* CC_INTERP */
|
#endif /* CC_INTERP */
|
||||||
|
|
||||||
|
#ifdef COMPILER2
|
||||||
|
if (!UseBiasedLocking || EmitSync != 0) {
|
||||||
|
UseOptoBiasInlining = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (PrintCommandLineFlags) {
|
if (PrintCommandLineFlags) {
|
||||||
CommandLineFlags::printSetFlags();
|
CommandLineFlags::printSetFlags();
|
||||||
}
|
}
|
||||||
|
@ -83,12 +83,12 @@ void RegisterMap::print_on(outputStream* st) const {
|
|||||||
intptr_t* src = (intptr_t*) location(r);
|
intptr_t* src = (intptr_t*) location(r);
|
||||||
if (src != NULL) {
|
if (src != NULL) {
|
||||||
|
|
||||||
r->print();
|
r->print_on(st);
|
||||||
tty->print(" [" INTPTR_FORMAT "] = ", src);
|
st->print(" [" INTPTR_FORMAT "] = ", src);
|
||||||
if (((uintptr_t)src & (sizeof(*src)-1)) != 0) {
|
if (((uintptr_t)src & (sizeof(*src)-1)) != 0) {
|
||||||
tty->print_cr("<misaligned>");
|
st->print_cr("<misaligned>");
|
||||||
} else {
|
} else {
|
||||||
tty->print_cr(INTPTR_FORMAT, *src);
|
st->print_cr(INTPTR_FORMAT, *src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,7 @@ void VMError::report(outputStream* st) {
|
|||||||
st->print("# java.lang.OutOfMemoryError: ");
|
st->print("# java.lang.OutOfMemoryError: ");
|
||||||
if (_size) {
|
if (_size) {
|
||||||
st->print("requested ");
|
st->print("requested ");
|
||||||
sprintf(buf,"%d",_size);
|
sprintf(buf,SIZE_FORMAT,_size);
|
||||||
st->print(buf);
|
st->print(buf);
|
||||||
st->print(" bytes");
|
st->print(" bytes");
|
||||||
if (_message != NULL) {
|
if (_message != NULL) {
|
||||||
|
@ -13,3 +13,4 @@ eac46d1eb7f0935ba04f1c7929ec15423fd0309e jdk7-b35
|
|||||||
c84ca638db42a8b6b227b4e3b63bca192c5ca634 jdk7-b36
|
c84ca638db42a8b6b227b4e3b63bca192c5ca634 jdk7-b36
|
||||||
af49591bc486d82aa04b832257de0d18adc9af52 jdk7-b37
|
af49591bc486d82aa04b832257de0d18adc9af52 jdk7-b37
|
||||||
e9f750f0a3a00413a7b77028b2ecdabb7129ae32 jdk7-b38
|
e9f750f0a3a00413a7b77028b2ecdabb7129ae32 jdk7-b38
|
||||||
|
831b80be6cea8e7d7da197ccdac5fd4c701a5033 jdk7-b39
|
||||||
|
@ -13,3 +13,4 @@ b0f01c2508b690dd225298edfec70b5e8b8dc367 jdk7-b35
|
|||||||
f60187f44a0d62906a5e2f6bd0989b5b24c1ca1e jdk7-b36
|
f60187f44a0d62906a5e2f6bd0989b5b24c1ca1e jdk7-b36
|
||||||
a2a6f9edf761934faf59ea60d7fe7178371302cd jdk7-b37
|
a2a6f9edf761934faf59ea60d7fe7178371302cd jdk7-b37
|
||||||
9ce439969184c753a9ba3caf8ed277b05230f2e5 jdk7-b38
|
9ce439969184c753a9ba3caf8ed277b05230f2e5 jdk7-b38
|
||||||
|
077bc9b1b035a409a76bd5366f73ed9dd9846934 jdk7-b39
|
||||||
|
@ -13,3 +13,4 @@ cf4894b78ceb966326e93bf221db0c2d14d59218 jdk7-b35
|
|||||||
134fd1a656ea85acd1f97f6700f75029b9b472a0 jdk7-b36
|
134fd1a656ea85acd1f97f6700f75029b9b472a0 jdk7-b36
|
||||||
14f50aee4989b75934d385c56a83da0c23d2f68b jdk7-b37
|
14f50aee4989b75934d385c56a83da0c23d2f68b jdk7-b37
|
||||||
cc5f810b5af8a3a83b0df5a29d9e24d7a0ff8086 jdk7-b38
|
cc5f810b5af8a3a83b0df5a29d9e24d7a0ff8086 jdk7-b38
|
||||||
|
4e51997582effa006dde5c6d8b8820b2045b9c7f jdk7-b39
|
||||||
|
@ -44,13 +44,13 @@
|
|||||||
<!-- because they depend on the values of BUILD_DATE and BUILD_DATE_SIMPLE -->
|
<!-- because they depend on the values of BUILD_DATE and BUILD_DATE_SIMPLE -->
|
||||||
<!-- At this time, ./build.properties has not been loaded yet. -->
|
<!-- At this time, ./build.properties has not been loaded yet. -->
|
||||||
<property name="project.build.name" value="openjdk-bXX"/>
|
<property name="project.build.name" value="openjdk-bXX"/>
|
||||||
<property name="project.build.fulltag"
|
<property name="project.build.fulltag"
|
||||||
value="${ant.project.name}-${project.build.name}-${BUILD_DATE}" />
|
value="${ant.project.name}-${project.build.name}-${BUILD_DATE}" />
|
||||||
|
|
||||||
<!-- unchecked warnings will be fixed in JMX 2.0 as part of the work
|
<!-- unchecked warnings will be fixed in JMX 2.0 as part of the work
|
||||||
being done on JSR 255 new features -->
|
being done on JSR 255 new features -->
|
||||||
<property name="javac.options"
|
<property name="javac.options"
|
||||||
value="-Xlint -Xlint:-unchecked -Xlint:-deprecation"/>
|
value="-Xlint -Xlint:-deprecation"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
|
||||||
@ -58,13 +58,13 @@
|
|||||||
<!-- Dir to keep generated stub source -->
|
<!-- Dir to keep generated stub source -->
|
||||||
<mkdir dir="${gensrc.dir}" />
|
<mkdir dir="${gensrc.dir}" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
|
||||||
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~ -->
|
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~ -->
|
||||||
<!-- Call rmic-jmx subtargets -->
|
<!-- Call rmic-jmx subtargets -->
|
||||||
|
|
||||||
<target name="-rmic-jmx" depends="-init,-rmic-jmx-jrmp,-rmic-jmx-iiop"
|
<target name="-rmic-jmx" depends="-init,-rmic-jmx-jrmp,-rmic-jmx-iiop"
|
||||||
description="Calls -init,-rmic-jmx-jrmp,-rmic-jmx-iiop"
|
description="Calls -init,-rmic-jmx-jrmp,-rmic-jmx-iiop"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
@ -96,7 +96,7 @@
|
|||||||
|
|
||||||
<target name="-rmic-jmx-iiop" depends="-init,-check-jmx-iiop-uptodate" unless="jmx-iiop-uptodate"
|
<target name="-rmic-jmx-iiop" depends="-init,-check-jmx-iiop-uptodate" unless="jmx-iiop-uptodate"
|
||||||
description="Generate RMI IIOP stub class files for remote objects. Do not keep generated java files." >
|
description="Generate RMI IIOP stub class files for remote objects. Do not keep generated java files." >
|
||||||
|
|
||||||
<rmic base="${classes.dir}"
|
<rmic base="${classes.dir}"
|
||||||
includeAntRuntime="no"
|
includeAntRuntime="no"
|
||||||
includeJavaRuntime="no"
|
includeJavaRuntime="no"
|
||||||
@ -115,11 +115,11 @@
|
|||||||
|
|
||||||
<target name="-check-jmx-iiop-uptodate" depends="-init">
|
<target name="-check-jmx-iiop-uptodate" depends="-init">
|
||||||
|
|
||||||
<uptodate property="jmx-iiop-uptodate"
|
<uptodate property="jmx-iiop-uptodate"
|
||||||
srcfile="${classes.dir}/javax/management/remote/rmi/RMIConnectionImpl.class"
|
srcfile="${classes.dir}/javax/management/remote/rmi/RMIConnectionImpl.class"
|
||||||
targetfile="${classes.dir}/org/omg/stub/javax/management/remote/rmi/_RMIConnectionImpl_Tie.class"
|
targetfile="${classes.dir}/org/omg/stub/javax/management/remote/rmi/_RMIConnectionImpl_Tie.class"
|
||||||
/>
|
/>
|
||||||
<uptodate property="jmx-iiop-uptodate"
|
<uptodate property="jmx-iiop-uptodate"
|
||||||
srcfile="${classes.dir}/javax/management/remote/rmi/RMIServerImpl.class"
|
srcfile="${classes.dir}/javax/management/remote/rmi/RMIServerImpl.class"
|
||||||
targetfile="${classes.dir}/org/omg/stub/javax/management/remote/rmi/_RMIServerImpl_Tie.class"
|
targetfile="${classes.dir}/org/omg/stub/javax/management/remote/rmi/_RMIServerImpl_Tie.class"
|
||||||
/>
|
/>
|
||||||
@ -131,7 +131,7 @@
|
|||||||
<target name="-post-compile" depends="-init,-rmic-jmx"
|
<target name="-post-compile" depends="-init,-rmic-jmx"
|
||||||
description="Jar JMX class files (including RMI stubs)" >
|
description="Jar JMX class files (including RMI stubs)" >
|
||||||
<mkdir dir="${dist.dir}/lib"/>
|
<mkdir dir="${dist.dir}/lib"/>
|
||||||
<jar jarfile="${dist.dir}/lib/${jar.jmx.name}"
|
<jar jarfile="${dist.dir}/lib/${jar.jmx.name}"
|
||||||
update="true"
|
update="true"
|
||||||
index="false"
|
index="false"
|
||||||
duplicate="fail">
|
duplicate="fail">
|
||||||
@ -144,7 +144,7 @@
|
|||||||
<attribute name="Specification-Version" value="${jar.jmx.spec.version}" />
|
<attribute name="Specification-Version" value="${jar.jmx.spec.version}" />
|
||||||
<attribute name="Specification-Vendor" value="${jar.jmx.spec.vendor}" />
|
<attribute name="Specification-Vendor" value="${jar.jmx.spec.vendor}" />
|
||||||
<attribute name="Implementation-Title" value="${jar.jmx.impl.title}" />
|
<attribute name="Implementation-Title" value="${jar.jmx.impl.title}" />
|
||||||
<attribute name="Implementation-Version" value="${project.build.fulltag}" />
|
<attribute name="Implementation-Version" value="${project.build.fulltag}" />
|
||||||
<attribute name="Implementation-Vendor" value="${jar.jmx.impl.vendor}" />
|
<attribute name="Implementation-Vendor" value="${jar.jmx.impl.vendor}" />
|
||||||
</section>
|
</section>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@ -141,7 +141,7 @@ public class LeaseManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final Runnable callback;
|
private final Runnable callback;
|
||||||
private ScheduledFuture scheduled; // If null, the lease has expired.
|
private ScheduledFuture<?> scheduled; // If null, the lease has expired.
|
||||||
|
|
||||||
private final ScheduledExecutorService executor
|
private final ScheduledExecutorService executor
|
||||||
= Executors.newScheduledThreadPool(1,
|
= Executors.newScheduledThreadPool(1,
|
||||||
|
@ -128,7 +128,7 @@ public class LeaseRenewer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private final Callable<Long> doRenew;
|
private final Callable<Long> doRenew;
|
||||||
private ScheduledFuture future;
|
private ScheduledFuture<?> future;
|
||||||
private boolean closed = false;
|
private boolean closed = false;
|
||||||
private long nextRenewTime;
|
private long nextRenewTime;
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ public class DefaultMBeanServerInterceptor
|
|||||||
MBeanRegistrationException, MBeanException,
|
MBeanRegistrationException, MBeanException,
|
||||||
NotCompliantMBeanException, InstanceNotFoundException {
|
NotCompliantMBeanException, InstanceNotFoundException {
|
||||||
|
|
||||||
Class theClass;
|
Class<?> theClass;
|
||||||
|
|
||||||
if (className == null) {
|
if (className == null) {
|
||||||
final RuntimeException wrapped =
|
final RuntimeException wrapped =
|
||||||
@ -327,7 +327,7 @@ public class DefaultMBeanServerInterceptor
|
|||||||
|
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
Class theClass = object.getClass();
|
Class<?> theClass = object.getClass();
|
||||||
|
|
||||||
Introspector.checkCompliance(theClass);
|
Introspector.checkCompliance(theClass);
|
||||||
|
|
||||||
@ -808,9 +808,8 @@ public class DefaultMBeanServerInterceptor
|
|||||||
// on each specific attribute
|
// on each specific attribute
|
||||||
//
|
//
|
||||||
allowedAttributes = new AttributeList(attributes.size());
|
allowedAttributes = new AttributeList(attributes.size());
|
||||||
for (Iterator i = attributes.iterator(); i.hasNext();) {
|
for (Attribute attribute : attributes.asList()) {
|
||||||
try {
|
try {
|
||||||
Attribute attribute = (Attribute) i.next();
|
|
||||||
checkMBeanPermission(mbeanServerName, classname, attribute.getName(),
|
checkMBeanPermission(mbeanServerName, classname, attribute.getName(),
|
||||||
name, "setAttribute");
|
name, "setAttribute");
|
||||||
allowedAttributes.add(attribute);
|
allowedAttributes.add(attribute);
|
||||||
@ -1857,7 +1856,7 @@ public class DefaultMBeanServerInterceptor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkMBeanTrustPermission(final Class theClass)
|
private static void checkMBeanTrustPermission(final Class<?> theClass)
|
||||||
throws SecurityException {
|
throws SecurityException {
|
||||||
SecurityManager sm = System.getSecurityManager();
|
SecurityManager sm = System.getSecurityManager();
|
||||||
if (sm != null) {
|
if (sm != null) {
|
||||||
|
@ -136,14 +136,14 @@ final class ClassLoaderRepositorySupport
|
|||||||
new Hashtable<ObjectName,ClassLoader>(10);
|
new Hashtable<ObjectName,ClassLoader>(10);
|
||||||
|
|
||||||
// from javax.management.loading.DefaultLoaderRepository
|
// from javax.management.loading.DefaultLoaderRepository
|
||||||
public final Class loadClass(String className)
|
public final Class<?> loadClass(String className)
|
||||||
throws ClassNotFoundException {
|
throws ClassNotFoundException {
|
||||||
return loadClass(loaders, className, null, null);
|
return loadClass(loaders, className, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// from javax.management.loading.DefaultLoaderRepository
|
// from javax.management.loading.DefaultLoaderRepository
|
||||||
public final Class loadClassWithout(ClassLoader without, String className)
|
public final Class<?> loadClassWithout(ClassLoader without, String className)
|
||||||
throws ClassNotFoundException {
|
throws ClassNotFoundException {
|
||||||
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
|
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
|
||||||
MBEANSERVER_LOGGER.logp(Level.FINER,
|
MBEANSERVER_LOGGER.logp(Level.FINER,
|
||||||
@ -167,7 +167,7 @@ final class ClassLoaderRepositorySupport
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public final Class loadClassBefore(ClassLoader stop, String className)
|
public final Class<?> loadClassBefore(ClassLoader stop, String className)
|
||||||
throws ClassNotFoundException {
|
throws ClassNotFoundException {
|
||||||
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
|
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
|
||||||
MBEANSERVER_LOGGER.logp(Level.FINER,
|
MBEANSERVER_LOGGER.logp(Level.FINER,
|
||||||
@ -187,10 +187,10 @@ final class ClassLoaderRepositorySupport
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Class loadClass(final LoaderEntry list[],
|
private Class<?> loadClass(final LoaderEntry list[],
|
||||||
final String className,
|
final String className,
|
||||||
final ClassLoader without,
|
final ClassLoader without,
|
||||||
final ClassLoader stop)
|
final ClassLoader stop)
|
||||||
throws ClassNotFoundException {
|
throws ClassNotFoundException {
|
||||||
final int size = list.length;
|
final int size = list.length;
|
||||||
for(int i=0; i<size; i++) {
|
for(int i=0; i<size; i++) {
|
||||||
|
@ -68,12 +68,12 @@ final class ConvertingMethod {
|
|||||||
return method.getName();
|
return method.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenType getOpenReturnType() {
|
OpenType<?> getOpenReturnType() {
|
||||||
return returnMapping.getOpenType();
|
return returnMapping.getOpenType();
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenType[] getOpenParameterTypes() {
|
OpenType<?>[] getOpenParameterTypes() {
|
||||||
final OpenType[] types = new OpenType[paramMappings.length];
|
final OpenType<?>[] types = new OpenType<?>[paramMappings.length];
|
||||||
for (int i = 0; i < paramMappings.length; i++)
|
for (int i = 0; i < paramMappings.length; i++)
|
||||||
types[i] = paramMappings[i].getOpenType();
|
types[i] = paramMappings[i].getOpenType();
|
||||||
return types;
|
return types;
|
||||||
|
@ -26,7 +26,8 @@
|
|||||||
package com.sun.jmx.mbeanserver;
|
package com.sun.jmx.mbeanserver;
|
||||||
|
|
||||||
import static com.sun.jmx.mbeanserver.Util.*;
|
import static com.sun.jmx.mbeanserver.Util.*;
|
||||||
import java.lang.annotation.ElementType;
|
import static com.sun.jmx.mbeanserver.MXBeanIntrospector.typeName;
|
||||||
|
|
||||||
import javax.management.openmbean.MXBeanMappingClass;
|
import javax.management.openmbean.MXBeanMappingClass;
|
||||||
|
|
||||||
import static javax.management.openmbean.SimpleType.*;
|
import static javax.management.openmbean.SimpleType.*;
|
||||||
@ -120,7 +121,7 @@ import javax.management.openmbean.TabularType;
|
|||||||
*/
|
*/
|
||||||
public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
||||||
static abstract class NonNullMXBeanMapping extends MXBeanMapping {
|
static abstract class NonNullMXBeanMapping extends MXBeanMapping {
|
||||||
NonNullMXBeanMapping(Type javaType, OpenType openType) {
|
NonNullMXBeanMapping(Type javaType, OpenType<?> openType) {
|
||||||
super(javaType, openType);
|
super(javaType, openType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,15 +196,15 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
static {
|
static {
|
||||||
/* Set up the mappings for Java types that map to SimpleType. */
|
/* Set up the mappings for Java types that map to SimpleType. */
|
||||||
|
|
||||||
final OpenType[] simpleTypes = {
|
final OpenType<?>[] simpleTypes = {
|
||||||
BIGDECIMAL, BIGINTEGER, BOOLEAN, BYTE, CHARACTER, DATE,
|
BIGDECIMAL, BIGINTEGER, BOOLEAN, BYTE, CHARACTER, DATE,
|
||||||
DOUBLE, FLOAT, INTEGER, LONG, OBJECTNAME, SHORT, STRING,
|
DOUBLE, FLOAT, INTEGER, LONG, OBJECTNAME, SHORT, STRING,
|
||||||
VOID,
|
VOID,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < simpleTypes.length; i++) {
|
for (int i = 0; i < simpleTypes.length; i++) {
|
||||||
final OpenType t = simpleTypes[i];
|
final OpenType<?> t = simpleTypes[i];
|
||||||
Class c;
|
Class<?> c;
|
||||||
try {
|
try {
|
||||||
c = Class.forName(t.getClassName(), false,
|
c = Class.forName(t.getClassName(), false,
|
||||||
ObjectName.class.getClassLoader());
|
ObjectName.class.getClassLoader());
|
||||||
@ -224,7 +225,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
if (primitiveType != void.class) {
|
if (primitiveType != void.class) {
|
||||||
final Class<?> primitiveArrayType =
|
final Class<?> primitiveArrayType =
|
||||||
Array.newInstance(primitiveType, 0).getClass();
|
Array.newInstance(primitiveType, 0).getClass();
|
||||||
final OpenType primitiveArrayOpenType =
|
final OpenType<?> primitiveArrayOpenType =
|
||||||
ArrayType.getPrimitiveArrayType(primitiveArrayType);
|
ArrayType.getPrimitiveArrayType(primitiveArrayType);
|
||||||
final MXBeanMapping primitiveArrayMapping =
|
final MXBeanMapping primitiveArrayMapping =
|
||||||
new IdentityMapping(primitiveArrayType,
|
new IdentityMapping(primitiveArrayType,
|
||||||
@ -247,8 +248,10 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
public synchronized MXBeanMapping mappingForType(Type objType,
|
public synchronized MXBeanMapping mappingForType(Type objType,
|
||||||
MXBeanMappingFactory factory)
|
MXBeanMappingFactory factory)
|
||||||
throws OpenDataException {
|
throws OpenDataException {
|
||||||
if (inProgress.containsKey(objType))
|
if (inProgress.containsKey(objType)) {
|
||||||
throw new OpenDataException("Recursive data structure");
|
throw new OpenDataException(
|
||||||
|
"Recursive data structure, including " + typeName(objType));
|
||||||
|
}
|
||||||
|
|
||||||
MXBeanMapping mapping;
|
MXBeanMapping mapping;
|
||||||
|
|
||||||
@ -259,6 +262,8 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
inProgress.put(objType, objType);
|
inProgress.put(objType, objType);
|
||||||
try {
|
try {
|
||||||
mapping = makeMapping(objType, factory);
|
mapping = makeMapping(objType, factory);
|
||||||
|
} catch (OpenDataException e) {
|
||||||
|
throw openDataException("Cannot convert type: " + typeName(objType), e);
|
||||||
} finally {
|
} finally {
|
||||||
inProgress.remove(objType);
|
inProgress.remove(objType);
|
||||||
}
|
}
|
||||||
@ -285,13 +290,13 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
Type componentType =
|
Type componentType =
|
||||||
((GenericArrayType) objType).getGenericComponentType();
|
((GenericArrayType) objType).getGenericComponentType();
|
||||||
return makeArrayOrCollectionMapping(objType, componentType, factory);
|
return makeArrayOrCollectionMapping(objType, componentType, factory);
|
||||||
} else if (objType instanceof Class) {
|
} else if (objType instanceof Class<?>) {
|
||||||
Class<?> objClass = (Class<?>) objType;
|
Class<?> objClass = (Class<?>) objType;
|
||||||
if (objClass.isEnum()) {
|
if (objClass.isEnum()) {
|
||||||
// Huge hack to avoid compiler warnings here. The ElementType
|
// Huge hack to avoid compiler warnings here. The ElementType
|
||||||
// parameter is ignored but allows us to obtain a type variable
|
// parameter is ignored but allows us to obtain a type variable
|
||||||
// T that matches <T extends Enum<T>>.
|
// T that matches <T extends Enum<T>>.
|
||||||
return makeEnumMapping((Class) objClass, ElementType.class);
|
return makeEnumMapping((Class<?>) objClass, ElementType.class);
|
||||||
} else if (objClass.isArray()) {
|
} else if (objClass.isArray()) {
|
||||||
Type componentType = objClass.getComponentType();
|
Type componentType = objClass.getComponentType();
|
||||||
return makeArrayOrCollectionMapping(objClass, componentType,
|
return makeArrayOrCollectionMapping(objClass, componentType,
|
||||||
@ -354,7 +359,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static <T extends Enum<T>> MXBeanMapping
|
private static <T extends Enum<T>> MXBeanMapping
|
||||||
makeEnumMapping(Class enumClass, Class<T> fake) {
|
makeEnumMapping(Class<?> enumClass, Class<T> fake) {
|
||||||
return new EnumMapping<T>(Util.<Class<T>>cast(enumClass));
|
return new EnumMapping<T>(Util.<Class<T>>cast(enumClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,17 +416,17 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
MXBeanMappingFactory factory)
|
MXBeanMappingFactory factory)
|
||||||
throws OpenDataException {
|
throws OpenDataException {
|
||||||
|
|
||||||
final String objTypeName = objType.toString();
|
final String objTypeName = typeName(objType);
|
||||||
final MXBeanMapping keyMapping = factory.mappingForType(keyType, factory);
|
final MXBeanMapping keyMapping = factory.mappingForType(keyType, factory);
|
||||||
final MXBeanMapping valueMapping = factory.mappingForType(valueType, factory);
|
final MXBeanMapping valueMapping = factory.mappingForType(valueType, factory);
|
||||||
final OpenType keyOpenType = keyMapping.getOpenType();
|
final OpenType<?> keyOpenType = keyMapping.getOpenType();
|
||||||
final OpenType valueOpenType = valueMapping.getOpenType();
|
final OpenType<?> valueOpenType = valueMapping.getOpenType();
|
||||||
final CompositeType rowType =
|
final CompositeType rowType =
|
||||||
new CompositeType(objTypeName,
|
new CompositeType(objTypeName,
|
||||||
objTypeName,
|
objTypeName,
|
||||||
keyValueArray,
|
keyValueArray,
|
||||||
keyValueArray,
|
keyValueArray,
|
||||||
new OpenType[] {keyOpenType, valueOpenType});
|
new OpenType<?>[] {keyOpenType, valueOpenType});
|
||||||
final TabularType tabularType =
|
final TabularType tabularType =
|
||||||
new TabularType(objTypeName, objTypeName, rowType, keyArray);
|
new TabularType(objTypeName, objTypeName, rowType, keyArray);
|
||||||
return new TabularMapping(objType, sortedMap, tabularType,
|
return new TabularMapping(objType, sortedMap, tabularType,
|
||||||
@ -440,8 +445,8 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
|
|
||||||
final Type rawType = objType.getRawType();
|
final Type rawType = objType.getRawType();
|
||||||
|
|
||||||
if (rawType instanceof Class) {
|
if (rawType instanceof Class<?>) {
|
||||||
Class c = (Class<?>) rawType;
|
Class<?> c = (Class<?>) rawType;
|
||||||
if (c == List.class || c == Set.class || c == SortedSet.class) {
|
if (c == List.class || c == Set.class || c == SortedSet.class) {
|
||||||
Type[] actuals = objType.getActualTypeArguments();
|
Type[] actuals = objType.getActualTypeArguments();
|
||||||
assert(actuals.length == 1);
|
assert(actuals.length == 1);
|
||||||
@ -468,7 +473,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
return new MXBeanRefMapping(t);
|
return new MXBeanRefMapping(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MXBeanMapping makeCompositeMapping(Class c,
|
private MXBeanMapping makeCompositeMapping(Class<?> c,
|
||||||
MXBeanMappingFactory factory)
|
MXBeanMappingFactory factory)
|
||||||
throws OpenDataException {
|
throws OpenDataException {
|
||||||
|
|
||||||
@ -514,7 +519,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
|
|
||||||
final Method[] getters = new Method[nitems];
|
final Method[] getters = new Method[nitems];
|
||||||
final String[] itemNames = new String[nitems];
|
final String[] itemNames = new String[nitems];
|
||||||
final OpenType[] openTypes = new OpenType[nitems];
|
final OpenType<?>[] openTypes = new OpenType<?>[nitems];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Map.Entry<String,Method> entry : getterMap.entrySet()) {
|
for (Map.Entry<String,Method> entry : getterMap.entrySet()) {
|
||||||
itemNames[i] = entry.getKey();
|
itemNames[i] = entry.getKey();
|
||||||
@ -546,7 +551,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
can be directly represented by an ArrayType, and an int needs no mapping
|
can be directly represented by an ArrayType, and an int needs no mapping
|
||||||
because reflection takes care of it. */
|
because reflection takes care of it. */
|
||||||
private static final class IdentityMapping extends NonNullMXBeanMapping {
|
private static final class IdentityMapping extends NonNullMXBeanMapping {
|
||||||
IdentityMapping(Type targetType, OpenType openType) {
|
IdentityMapping(Type targetType, OpenType<?> openType) {
|
||||||
super(targetType, openType);
|
super(targetType, openType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,7 +581,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
final Object toNonNullOpenValue(Object value) {
|
final Object toNonNullOpenValue(Object value) {
|
||||||
return ((Enum) value).name();
|
return ((Enum<?>) value).name();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -595,7 +600,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
|
|
||||||
private static final class ArrayMapping extends NonNullMXBeanMapping {
|
private static final class ArrayMapping extends NonNullMXBeanMapping {
|
||||||
ArrayMapping(Type targetType,
|
ArrayMapping(Type targetType,
|
||||||
ArrayType openArrayType, Class openArrayClass,
|
ArrayType<?> openArrayType, Class<?> openArrayClass,
|
||||||
MXBeanMapping elementMapping) {
|
MXBeanMapping elementMapping) {
|
||||||
super(targetType, openArrayType);
|
super(targetType, openArrayType);
|
||||||
this.elementMapping = elementMapping;
|
this.elementMapping = elementMapping;
|
||||||
@ -623,7 +628,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
if (javaType instanceof GenericArrayType) {
|
if (javaType instanceof GenericArrayType) {
|
||||||
componentType =
|
componentType =
|
||||||
((GenericArrayType) javaType).getGenericComponentType();
|
((GenericArrayType) javaType).getGenericComponentType();
|
||||||
} else if (javaType instanceof Class &&
|
} else if (javaType instanceof Class<?> &&
|
||||||
((Class<?>) javaType).isArray()) {
|
((Class<?>) javaType).isArray()) {
|
||||||
componentType = ((Class<?>) javaType).getComponentType();
|
componentType = ((Class<?>) javaType).getComponentType();
|
||||||
} else {
|
} else {
|
||||||
@ -651,8 +656,8 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
|
|
||||||
private static final class CollectionMapping extends NonNullMXBeanMapping {
|
private static final class CollectionMapping extends NonNullMXBeanMapping {
|
||||||
CollectionMapping(Type targetType,
|
CollectionMapping(Type targetType,
|
||||||
ArrayType openArrayType,
|
ArrayType<?> openArrayType,
|
||||||
Class openArrayClass,
|
Class<?> openArrayClass,
|
||||||
MXBeanMapping elementMapping) {
|
MXBeanMapping elementMapping) {
|
||||||
super(targetType, openArrayType);
|
super(targetType, openArrayType);
|
||||||
this.elementMapping = elementMapping;
|
this.elementMapping = elementMapping;
|
||||||
@ -662,26 +667,28 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
and all Sets to TreeSet. (TreeSet because it is a SortedSet,
|
and all Sets to TreeSet. (TreeSet because it is a SortedSet,
|
||||||
so works for both Set and SortedSet.) */
|
so works for both Set and SortedSet.) */
|
||||||
Type raw = ((ParameterizedType) targetType).getRawType();
|
Type raw = ((ParameterizedType) targetType).getRawType();
|
||||||
Class c = (Class<?>) raw;
|
Class<?> c = (Class<?>) raw;
|
||||||
|
final Class<?> collC;
|
||||||
if (c == List.class)
|
if (c == List.class)
|
||||||
collectionClass = ArrayList.class;
|
collC = ArrayList.class;
|
||||||
else if (c == Set.class)
|
else if (c == Set.class)
|
||||||
collectionClass = HashSet.class;
|
collC = HashSet.class;
|
||||||
else if (c == SortedSet.class)
|
else if (c == SortedSet.class)
|
||||||
collectionClass = TreeSet.class;
|
collC = TreeSet.class;
|
||||||
else { // can't happen
|
else { // can't happen
|
||||||
assert(false);
|
assert(false);
|
||||||
collectionClass = null;
|
collC = null;
|
||||||
}
|
}
|
||||||
|
collectionClass = Util.cast(collC);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
final Object toNonNullOpenValue(Object value)
|
final Object toNonNullOpenValue(Object value)
|
||||||
throws OpenDataException {
|
throws OpenDataException {
|
||||||
final Collection valueCollection = (Collection) value;
|
final Collection<?> valueCollection = (Collection<?>) value;
|
||||||
if (valueCollection instanceof SortedSet) {
|
if (valueCollection instanceof SortedSet<?>) {
|
||||||
Comparator comparator =
|
Comparator<?> comparator =
|
||||||
((SortedSet) valueCollection).comparator();
|
((SortedSet<?>) valueCollection).comparator();
|
||||||
if (comparator != null) {
|
if (comparator != null) {
|
||||||
final String msg =
|
final String msg =
|
||||||
"Cannot convert SortedSet with non-null comparator: " +
|
"Cannot convert SortedSet with non-null comparator: " +
|
||||||
@ -725,7 +732,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
elementMapping.checkReconstructible();
|
elementMapping.checkReconstructible();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Class<? extends Collection> collectionClass;
|
private final Class<? extends Collection<?>> collectionClass;
|
||||||
private final MXBeanMapping elementMapping;
|
private final MXBeanMapping elementMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -794,8 +801,8 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
@Override
|
@Override
|
||||||
final Object toNonNullOpenValue(Object value) throws OpenDataException {
|
final Object toNonNullOpenValue(Object value) throws OpenDataException {
|
||||||
final Map<Object, Object> valueMap = cast(value);
|
final Map<Object, Object> valueMap = cast(value);
|
||||||
if (valueMap instanceof SortedMap) {
|
if (valueMap instanceof SortedMap<?,?>) {
|
||||||
Comparator comparator = ((SortedMap) valueMap).comparator();
|
Comparator<?> comparator = ((SortedMap<?,?>) valueMap).comparator();
|
||||||
if (comparator != null) {
|
if (comparator != null) {
|
||||||
final String msg =
|
final String msg =
|
||||||
"Cannot convert SortedMap with non-null comparator: " +
|
"Cannot convert SortedMap with non-null comparator: " +
|
||||||
@ -806,7 +813,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
final TabularType tabularType = (TabularType) getOpenType();
|
final TabularType tabularType = (TabularType) getOpenType();
|
||||||
final TabularData table = new TabularDataSupport(tabularType);
|
final TabularData table = new TabularDataSupport(tabularType);
|
||||||
final CompositeType rowType = tabularType.getRowType();
|
final CompositeType rowType = tabularType.getRowType();
|
||||||
for (Map.Entry entry : valueMap.entrySet()) {
|
for (Map.Entry<Object, Object> entry : valueMap.entrySet()) {
|
||||||
final Object openKey = keyMapping.toOpenValue(entry.getKey());
|
final Object openKey = keyMapping.toOpenValue(entry.getKey());
|
||||||
final Object openValue = valueMapping.toOpenValue(entry.getValue());
|
final Object openValue = valueMapping.toOpenValue(entry.getValue());
|
||||||
final CompositeData row;
|
final CompositeData row;
|
||||||
@ -852,7 +859,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final class CompositeMapping extends NonNullMXBeanMapping {
|
private final class CompositeMapping extends NonNullMXBeanMapping {
|
||||||
CompositeMapping(Class targetClass,
|
CompositeMapping(Class<?> targetClass,
|
||||||
CompositeType compositeType,
|
CompositeType compositeType,
|
||||||
String[] itemNames,
|
String[] itemNames,
|
||||||
Method[] getters,
|
Method[] getters,
|
||||||
@ -901,7 +908,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
if (compositeBuilder != null)
|
if (compositeBuilder != null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Class targetClass = (Class<?>) getJavaType();
|
Class<?> targetClass = (Class<?>) getJavaType();
|
||||||
/* In this 2D array, each subarray is a set of builders where
|
/* In this 2D array, each subarray is a set of builders where
|
||||||
there is no point in consulting the ones after the first if
|
there is no point in consulting the ones after the first if
|
||||||
the first refuses. */
|
the first refuses. */
|
||||||
@ -924,6 +931,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
concatenating each Builder's explanation of why it
|
concatenating each Builder's explanation of why it
|
||||||
isn't applicable. */
|
isn't applicable. */
|
||||||
final StringBuilder whyNots = new StringBuilder();
|
final StringBuilder whyNots = new StringBuilder();
|
||||||
|
Throwable possibleCause = null;
|
||||||
find:
|
find:
|
||||||
for (CompositeBuilder[] relatedBuilders : builders) {
|
for (CompositeBuilder[] relatedBuilders : builders) {
|
||||||
for (int i = 0; i < relatedBuilders.length; i++) {
|
for (int i = 0; i < relatedBuilders.length; i++) {
|
||||||
@ -933,6 +941,9 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
foundBuilder = builder;
|
foundBuilder = builder;
|
||||||
break find;
|
break find;
|
||||||
}
|
}
|
||||||
|
Throwable cause = builder.possibleCause();
|
||||||
|
if (cause != null)
|
||||||
|
possibleCause = cause;
|
||||||
if (whyNot.length() > 0) {
|
if (whyNot.length() > 0) {
|
||||||
if (whyNots.length() > 0)
|
if (whyNots.length() > 0)
|
||||||
whyNots.append("; ");
|
whyNots.append("; ");
|
||||||
@ -943,10 +954,12 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (foundBuilder == null) {
|
if (foundBuilder == null) {
|
||||||
final String msg =
|
String msg =
|
||||||
"Do not know how to make a " + targetClass.getName() +
|
"Do not know how to make a " + targetClass.getName() +
|
||||||
" from a CompositeData: " + whyNots;
|
" from a CompositeData: " + whyNots;
|
||||||
throw new InvalidObjectException(msg);
|
if (possibleCause != null)
|
||||||
|
msg += ". Remaining exceptions show a POSSIBLE cause.";
|
||||||
|
throw invalidObjectException(msg, possibleCause);
|
||||||
}
|
}
|
||||||
compositeBuilder = foundBuilder;
|
compositeBuilder = foundBuilder;
|
||||||
}
|
}
|
||||||
@ -973,7 +986,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
|
|
||||||
/** Converts from a CompositeData to an instance of the targetClass. */
|
/** Converts from a CompositeData to an instance of the targetClass. */
|
||||||
private static abstract class CompositeBuilder {
|
private static abstract class CompositeBuilder {
|
||||||
CompositeBuilder(Class targetClass, String[] itemNames) {
|
CompositeBuilder(Class<?> targetClass, String[] itemNames) {
|
||||||
this.targetClass = targetClass;
|
this.targetClass = targetClass;
|
||||||
this.itemNames = itemNames;
|
this.itemNames = itemNames;
|
||||||
}
|
}
|
||||||
@ -994,6 +1007,16 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
abstract String applicable(Method[] getters)
|
abstract String applicable(Method[] getters)
|
||||||
throws InvalidObjectException;
|
throws InvalidObjectException;
|
||||||
|
|
||||||
|
/** If the subclass returns an explanation of why it is not applicable,
|
||||||
|
it can additionally indicate an exception with details. This is
|
||||||
|
potentially confusing, because the real problem could be that one
|
||||||
|
of the other subclasses is supposed to be applicable but isn't.
|
||||||
|
But the advantage of less information loss probably outweighs the
|
||||||
|
disadvantage of possible confusion. */
|
||||||
|
Throwable possibleCause() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
abstract Object fromCompositeData(CompositeData cd,
|
abstract Object fromCompositeData(CompositeData cd,
|
||||||
String[] itemNames,
|
String[] itemNames,
|
||||||
MXBeanMapping[] converters)
|
MXBeanMapping[] converters)
|
||||||
@ -1008,7 +1031,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
private static final class CompositeBuilderViaFrom
|
private static final class CompositeBuilderViaFrom
|
||||||
extends CompositeBuilder {
|
extends CompositeBuilder {
|
||||||
|
|
||||||
CompositeBuilderViaFrom(Class targetClass, String[] itemNames) {
|
CompositeBuilderViaFrom(Class<?> targetClass, String[] itemNames) {
|
||||||
super(targetClass, itemNames);
|
super(targetClass, itemNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1018,8 +1041,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
Class<?> targetClass = getTargetClass();
|
Class<?> targetClass = getTargetClass();
|
||||||
try {
|
try {
|
||||||
Method fromMethod =
|
Method fromMethod =
|
||||||
targetClass.getMethod("from",
|
targetClass.getMethod("from", CompositeData.class);
|
||||||
new Class[] {CompositeData.class});
|
|
||||||
|
|
||||||
if (!Modifier.isStatic(fromMethod.getModifiers())) {
|
if (!Modifier.isStatic(fromMethod.getModifiers())) {
|
||||||
final String msg =
|
final String msg =
|
||||||
@ -1030,8 +1052,8 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
if (fromMethod.getReturnType() != getTargetClass()) {
|
if (fromMethod.getReturnType() != getTargetClass()) {
|
||||||
final String msg =
|
final String msg =
|
||||||
"Method from(CompositeData) returns " +
|
"Method from(CompositeData) returns " +
|
||||||
fromMethod.getReturnType().getName() +
|
typeName(fromMethod.getReturnType()) +
|
||||||
" not " + targetClass.getName();
|
" not " + typeName(targetClass);
|
||||||
throw new InvalidObjectException(msg);
|
throw new InvalidObjectException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1071,7 +1093,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
If all the getters are OK, then the "applicable" method will return
|
If all the getters are OK, then the "applicable" method will return
|
||||||
an empty string and the other builders will be tried. */
|
an empty string and the other builders will be tried. */
|
||||||
private static class CompositeBuilderCheckGetters extends CompositeBuilder {
|
private static class CompositeBuilderCheckGetters extends CompositeBuilder {
|
||||||
CompositeBuilderCheckGetters(Class targetClass, String[] itemNames,
|
CompositeBuilderCheckGetters(Class<?> targetClass, String[] itemNames,
|
||||||
MXBeanMapping[] getterConverters) {
|
MXBeanMapping[] getterConverters) {
|
||||||
super(targetClass, itemNames);
|
super(targetClass, itemNames);
|
||||||
this.getterConverters = getterConverters;
|
this.getterConverters = getterConverters;
|
||||||
@ -1082,6 +1104,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
try {
|
try {
|
||||||
getterConverters[i].checkReconstructible();
|
getterConverters[i].checkReconstructible();
|
||||||
} catch (InvalidObjectException e) {
|
} catch (InvalidObjectException e) {
|
||||||
|
possibleCause = e;
|
||||||
return "method " + getters[i].getName() + " returns type " +
|
return "method " + getters[i].getName() + " returns type " +
|
||||||
"that cannot be mapped back from OpenData";
|
"that cannot be mapped back from OpenData";
|
||||||
}
|
}
|
||||||
@ -1089,6 +1112,11 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Throwable possibleCause() {
|
||||||
|
return possibleCause;
|
||||||
|
}
|
||||||
|
|
||||||
final Object fromCompositeData(CompositeData cd,
|
final Object fromCompositeData(CompositeData cd,
|
||||||
String[] itemNames,
|
String[] itemNames,
|
||||||
MXBeanMapping[] converters) {
|
MXBeanMapping[] converters) {
|
||||||
@ -1096,6 +1124,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final MXBeanMapping[] getterConverters;
|
private final MXBeanMapping[] getterConverters;
|
||||||
|
private Throwable possibleCause;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Builder for when the target class has a setter for every getter. */
|
/** Builder for when the target class has a setter for every getter. */
|
||||||
@ -1115,7 +1144,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
Method[] setters = new Method[getters.length];
|
Method[] setters = new Method[getters.length];
|
||||||
for (int i = 0; i < getters.length; i++) {
|
for (int i = 0; i < getters.length; i++) {
|
||||||
Method getter = getters[i];
|
Method getter = getters[i];
|
||||||
Class returnType = getter.getReturnType();
|
Class<?> returnType = getter.getReturnType();
|
||||||
String name = propertyName(getter);
|
String name = propertyName(getter);
|
||||||
String setterName = "set" + name;
|
String setterName = "set" + name;
|
||||||
Method setter;
|
Method setter;
|
||||||
@ -1163,7 +1192,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
private static final class CompositeBuilderViaConstructor
|
private static final class CompositeBuilderViaConstructor
|
||||||
extends CompositeBuilder {
|
extends CompositeBuilder {
|
||||||
|
|
||||||
CompositeBuilderViaConstructor(Class targetClass, String[] itemNames) {
|
CompositeBuilderViaConstructor(Class<?> targetClass, String[] itemNames) {
|
||||||
super(targetClass, itemNames);
|
super(targetClass, itemNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1171,7 +1200,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
|
|
||||||
final Class<ConstructorProperties> propertyNamesClass = ConstructorProperties.class;
|
final Class<ConstructorProperties> propertyNamesClass = ConstructorProperties.class;
|
||||||
|
|
||||||
Class targetClass = getTargetClass();
|
Class<?> targetClass = getTargetClass();
|
||||||
Constructor<?>[] constrs = targetClass.getConstructors();
|
Constructor<?>[] constrs = targetClass.getConstructors();
|
||||||
|
|
||||||
// Applicable if and only if there are any annotated constructors
|
// Applicable if and only if there are any annotated constructors
|
||||||
@ -1226,10 +1255,16 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
for (int i = 0; i < propertyNames.length; i++) {
|
for (int i = 0; i < propertyNames.length; i++) {
|
||||||
String propertyName = propertyNames[i];
|
String propertyName = propertyNames[i];
|
||||||
if (!getterMap.containsKey(propertyName)) {
|
if (!getterMap.containsKey(propertyName)) {
|
||||||
final String msg =
|
String msg =
|
||||||
"@ConstructorProperties includes name " + propertyName +
|
"@ConstructorProperties includes name " + propertyName +
|
||||||
" which does not correspond to a property: " +
|
" which does not correspond to a property";
|
||||||
constr;
|
for (String getterName : getterMap.keySet()) {
|
||||||
|
if (getterName.equalsIgnoreCase(propertyName)) {
|
||||||
|
msg += " (differs only in case from property " +
|
||||||
|
getterName + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg += ": " + constr;
|
||||||
throw new InvalidObjectException(msg);
|
throw new InvalidObjectException(msg);
|
||||||
}
|
}
|
||||||
int getterIndex = getterMap.get(propertyName);
|
int getterIndex = getterMap.get(propertyName);
|
||||||
@ -1384,12 +1419,12 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
private static final class CompositeBuilderViaProxy
|
private static final class CompositeBuilderViaProxy
|
||||||
extends CompositeBuilder {
|
extends CompositeBuilder {
|
||||||
|
|
||||||
CompositeBuilderViaProxy(Class targetClass, String[] itemNames) {
|
CompositeBuilderViaProxy(Class<?> targetClass, String[] itemNames) {
|
||||||
super(targetClass, itemNames);
|
super(targetClass, itemNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
String applicable(Method[] getters) {
|
String applicable(Method[] getters) {
|
||||||
Class targetClass = getTargetClass();
|
Class<?> targetClass = getTargetClass();
|
||||||
if (!targetClass.isInterface())
|
if (!targetClass.isInterface())
|
||||||
return "not an interface";
|
return "not an interface";
|
||||||
Set<Method> methods =
|
Set<Method> methods =
|
||||||
@ -1401,7 +1436,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
String bad = null;
|
String bad = null;
|
||||||
for (Method m : methods) {
|
for (Method m : methods) {
|
||||||
String mname = m.getName();
|
String mname = m.getName();
|
||||||
Class[] mparams = m.getParameterTypes();
|
Class<?>[] mparams = m.getParameterTypes();
|
||||||
try {
|
try {
|
||||||
Method om = Object.class.getMethod(mname, mparams);
|
Method om = Object.class.getMethod(mname, mparams);
|
||||||
if (!Modifier.isPublic(om.getModifiers()))
|
if (!Modifier.isPublic(om.getModifiers()))
|
||||||
@ -1422,10 +1457,10 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
final Object fromCompositeData(CompositeData cd,
|
final Object fromCompositeData(CompositeData cd,
|
||||||
String[] itemNames,
|
String[] itemNames,
|
||||||
MXBeanMapping[] converters) {
|
MXBeanMapping[] converters) {
|
||||||
final Class targetClass = getTargetClass();
|
final Class<?> targetClass = getTargetClass();
|
||||||
return
|
return
|
||||||
Proxy.newProxyInstance(targetClass.getClassLoader(),
|
Proxy.newProxyInstance(targetClass.getClassLoader(),
|
||||||
new Class[] {targetClass},
|
new Class<?>[] {targetClass},
|
||||||
new CompositeDataInvocationHandler(cd));
|
new CompositeDataInvocationHandler(cd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1447,9 +1482,9 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
|||||||
return openDataException(cause.getMessage(), cause);
|
return openDataException(cause.getMessage(), cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mustBeComparable(Class collection, Type element)
|
static void mustBeComparable(Class<?> collection, Type element)
|
||||||
throws OpenDataException {
|
throws OpenDataException {
|
||||||
if (!(element instanceof Class)
|
if (!(element instanceof Class<?>)
|
||||||
|| !Comparable.class.isAssignableFrom((Class<?>) element)) {
|
|| !Comparable.class.isAssignableFrom((Class<?>) element)) {
|
||||||
final String msg =
|
final String msg =
|
||||||
"Parameter class " + element + " of " +
|
"Parameter class " + element + " of " +
|
||||||
|
@ -115,7 +115,7 @@ public class Introspector {
|
|||||||
* Dynamic MBeans, <code>false</code> otherwise.
|
* Dynamic MBeans, <code>false</code> otherwise.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
public static final boolean isDynamic(final Class c) {
|
public static final boolean isDynamic(final Class<?> c) {
|
||||||
// Check if the MBean implements the DynamicMBean interface
|
// Check if the MBean implements the DynamicMBean interface
|
||||||
return javax.management.DynamicMBean.class.isAssignableFrom(c);
|
return javax.management.DynamicMBean.class.isAssignableFrom(c);
|
||||||
}
|
}
|
||||||
@ -134,7 +134,7 @@ public class Introspector {
|
|||||||
* MBeanServer.
|
* MBeanServer.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
public static void testCreation(Class c)
|
public static void testCreation(Class<?> c)
|
||||||
throws NotCompliantMBeanException {
|
throws NotCompliantMBeanException {
|
||||||
// Check if the class is a concrete class
|
// Check if the class is a concrete class
|
||||||
final int mods = c.getModifiers();
|
final int mods = c.getModifiers();
|
||||||
@ -143,7 +143,7 @@ public class Introspector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the MBean has a public constructor
|
// Check if the MBean has a public constructor
|
||||||
final Constructor[] consList = c.getConstructors();
|
final Constructor<?>[] consList = c.getConstructors();
|
||||||
if (consList.length == 0) {
|
if (consList.length == 0) {
|
||||||
throw new NotCompliantMBeanException("MBean class must have public constructor");
|
throw new NotCompliantMBeanException("MBean class must have public constructor");
|
||||||
}
|
}
|
||||||
@ -253,7 +253,7 @@ public class Introspector {
|
|||||||
* @exception NotCompliantMBeanException The specified class is not a
|
* @exception NotCompliantMBeanException The specified class is not a
|
||||||
* JMX compliant MBean
|
* JMX compliant MBean
|
||||||
*/
|
*/
|
||||||
public static MBeanInfo testCompliance(Class baseClass)
|
public static MBeanInfo testCompliance(Class<?> baseClass)
|
||||||
throws NotCompliantMBeanException {
|
throws NotCompliantMBeanException {
|
||||||
|
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
@ -267,7 +267,7 @@ public class Introspector {
|
|||||||
return testCompliance(baseClass, null);
|
return testCompliance(baseClass, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void testComplianceMXBeanInterface(Class interfaceClass,
|
public static void testComplianceMXBeanInterface(Class<?> interfaceClass,
|
||||||
MXBeanMappingFactory factory)
|
MXBeanMappingFactory factory)
|
||||||
throws NotCompliantMBeanException {
|
throws NotCompliantMBeanException {
|
||||||
MXBeanIntrospector.getInstance(factory).getAnalyzer(interfaceClass);
|
MXBeanIntrospector.getInstance(factory).getAnalyzer(interfaceClass);
|
||||||
@ -596,10 +596,10 @@ public class Introspector {
|
|||||||
ss[i] = (String) annotationToField(xx[i]);
|
ss[i] = (String) annotationToField(xx[i]);
|
||||||
return ss;
|
return ss;
|
||||||
}
|
}
|
||||||
if (x instanceof Class)
|
if (x instanceof Class<?>)
|
||||||
return ((Class<?>) x).getName();
|
return ((Class<?>) x).getName();
|
||||||
if (x instanceof Enum)
|
if (x instanceof Enum<?>)
|
||||||
return ((Enum) x).name();
|
return ((Enum<?>) x).name();
|
||||||
// The only other possibility is that the value is another
|
// The only other possibility is that the value is another
|
||||||
// annotation, or that the language has evolved since this code
|
// annotation, or that the language has evolved since this code
|
||||||
// was written. We don't allow for either of those currently.
|
// was written. We don't allow for either of those currently.
|
||||||
|
@ -33,6 +33,7 @@ import java.security.AccessController;
|
|||||||
import java.security.Permission;
|
import java.security.Permission;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
@ -1144,7 +1145,7 @@ public final class JmxMBeanServer
|
|||||||
// This call requires MBeanPermission 'getClassLoaderRepository'
|
// This call requires MBeanPermission 'getClassLoaderRepository'
|
||||||
final ClassLoaderRepository clr = getClassLoaderRepository();
|
final ClassLoaderRepository clr = getClassLoaderRepository();
|
||||||
|
|
||||||
Class theClass;
|
Class<?> theClass;
|
||||||
try {
|
try {
|
||||||
if (clr == null) throw new ClassNotFoundException(className);
|
if (clr == null) throw new ClassNotFoundException(className);
|
||||||
theClass = clr.loadClass(className);
|
theClass = clr.loadClass(className);
|
||||||
@ -1457,23 +1458,22 @@ public final class JmxMBeanServer
|
|||||||
*/
|
*/
|
||||||
private AttributeList cloneAttributeList(AttributeList list) {
|
private AttributeList cloneAttributeList(AttributeList list) {
|
||||||
if (list != null) {
|
if (list != null) {
|
||||||
|
List<Attribute> alist = list.asList();
|
||||||
if (!list.getClass().equals(AttributeList.class)) {
|
if (!list.getClass().equals(AttributeList.class)) {
|
||||||
// Create new attribute list
|
// Create new attribute list
|
||||||
//
|
//
|
||||||
AttributeList newList = new AttributeList(list.size());
|
AttributeList newList = new AttributeList(alist.size());
|
||||||
|
|
||||||
// Iterate through list and replace non JMX attributes
|
// Iterate through list and replace non JMX attributes
|
||||||
//
|
//
|
||||||
for (Iterator i = list.iterator(); i.hasNext(); ) {
|
for (Attribute attribute : alist)
|
||||||
Attribute attribute = (Attribute) i.next();
|
|
||||||
newList.add(cloneAttribute(attribute));
|
newList.add(cloneAttribute(attribute));
|
||||||
}
|
|
||||||
return newList;
|
return newList;
|
||||||
} else {
|
} else {
|
||||||
// Iterate through list and replace non JMX attributes
|
// Iterate through list and replace non JMX attributes
|
||||||
//
|
//
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (int i = 0; i < alist.size(); i++) {
|
||||||
Attribute attribute = (Attribute) list.get(i);
|
Attribute attribute = alist.get(i);
|
||||||
if (!attribute.getClass().equals(Attribute.class)) {
|
if (!attribute.getClass().equals(Attribute.class)) {
|
||||||
list.set(i, cloneAttribute(attribute));
|
list.set(i, cloneAttribute(attribute));
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ public class MBeanInstantiator {
|
|||||||
* instantiate an MBean of this class in the MBeanServer.
|
* instantiate an MBean of this class in the MBeanServer.
|
||||||
* e.g. it must have a public constructor, be a concrete class...
|
* e.g. it must have a public constructor, be a concrete class...
|
||||||
*/
|
*/
|
||||||
public void testCreation(Class c) throws NotCompliantMBeanException {
|
public void testCreation(Class<?> c) throws NotCompliantMBeanException {
|
||||||
Introspector.testCreation(c);
|
Introspector.testCreation(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,10 +78,10 @@ public class MBeanInstantiator {
|
|||||||
* Loads the class with the specified name using this object's
|
* Loads the class with the specified name using this object's
|
||||||
* Default Loader Repository.
|
* Default Loader Repository.
|
||||||
**/
|
**/
|
||||||
public Class findClassWithDefaultLoaderRepository(String className)
|
public Class<?> findClassWithDefaultLoaderRepository(String className)
|
||||||
throws ReflectionException {
|
throws ReflectionException {
|
||||||
|
|
||||||
Class theClass;
|
Class<?> theClass;
|
||||||
if (className == null) {
|
if (className == null) {
|
||||||
throw new RuntimeOperationsException(new
|
throw new RuntimeOperationsException(new
|
||||||
IllegalArgumentException("The class name cannot be null"),
|
IllegalArgumentException("The class name cannot be null"),
|
||||||
@ -105,7 +105,7 @@ public class MBeanInstantiator {
|
|||||||
* Gets the class for the specified class name using the MBean
|
* Gets the class for the specified class name using the MBean
|
||||||
* Interceptor's classloader
|
* Interceptor's classloader
|
||||||
*/
|
*/
|
||||||
public Class findClass(String className, ClassLoader loader)
|
public Class<?> findClass(String className, ClassLoader loader)
|
||||||
throws ReflectionException {
|
throws ReflectionException {
|
||||||
|
|
||||||
return loadClass(className,loader);
|
return loadClass(className,loader);
|
||||||
@ -115,7 +115,7 @@ public class MBeanInstantiator {
|
|||||||
* Gets the class for the specified class name using the specified
|
* Gets the class for the specified class name using the specified
|
||||||
* class loader
|
* class loader
|
||||||
*/
|
*/
|
||||||
public Class findClass(String className, ObjectName aLoader)
|
public Class<?> findClass(String className, ObjectName aLoader)
|
||||||
throws ReflectionException, InstanceNotFoundException {
|
throws ReflectionException, InstanceNotFoundException {
|
||||||
|
|
||||||
if (aLoader == null)
|
if (aLoader == null)
|
||||||
@ -140,14 +140,14 @@ public class MBeanInstantiator {
|
|||||||
* Return an array of Class corresponding to the given signature, using
|
* Return an array of Class corresponding to the given signature, using
|
||||||
* the specified class loader.
|
* the specified class loader.
|
||||||
*/
|
*/
|
||||||
public Class[] findSignatureClasses(String signature[],
|
public Class<?>[] findSignatureClasses(String signature[],
|
||||||
ClassLoader loader)
|
ClassLoader loader)
|
||||||
throws ReflectionException {
|
throws ReflectionException {
|
||||||
|
|
||||||
if (signature == null) return null;
|
if (signature == null) return null;
|
||||||
final ClassLoader aLoader = loader;
|
final ClassLoader aLoader = loader;
|
||||||
final int length= signature.length;
|
final int length= signature.length;
|
||||||
final Class tab[]=new Class[length];
|
final Class<?> tab[]=new Class<?>[length];
|
||||||
|
|
||||||
if (length == 0) return tab;
|
if (length == 0) return tab;
|
||||||
try {
|
try {
|
||||||
@ -156,7 +156,7 @@ public class MBeanInstantiator {
|
|||||||
// forth)
|
// forth)
|
||||||
//
|
//
|
||||||
|
|
||||||
final Class primCla = primitiveClasses.get(signature[i]);
|
final Class<?> primCla = primitiveClasses.get(signature[i]);
|
||||||
if (primCla != null) {
|
if (primCla != null) {
|
||||||
tab[i] = primCla;
|
tab[i] = primCla;
|
||||||
continue;
|
continue;
|
||||||
@ -203,14 +203,14 @@ public class MBeanInstantiator {
|
|||||||
* Instantiates an object given its class, using its empty constructor.
|
* Instantiates an object given its class, using its empty constructor.
|
||||||
* The call returns a reference to the newly created object.
|
* The call returns a reference to the newly created object.
|
||||||
*/
|
*/
|
||||||
public Object instantiate(Class theClass)
|
public Object instantiate(Class<?> theClass)
|
||||||
throws ReflectionException, MBeanException {
|
throws ReflectionException, MBeanException {
|
||||||
Object moi;
|
Object moi;
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
Constructor cons = findConstructor(theClass, null);
|
Constructor<?> cons = findConstructor(theClass, null);
|
||||||
if (cons == null) {
|
if (cons == null) {
|
||||||
throw new ReflectionException(new
|
throw new ReflectionException(new
|
||||||
NoSuchMethodException("No such constructor"));
|
NoSuchMethodException("No such constructor"));
|
||||||
@ -257,14 +257,14 @@ public class MBeanInstantiator {
|
|||||||
* signature of its constructor The call returns a reference to
|
* signature of its constructor The call returns a reference to
|
||||||
* the newly created object.
|
* the newly created object.
|
||||||
*/
|
*/
|
||||||
public Object instantiate(Class theClass, Object params[],
|
public Object instantiate(Class<?> theClass, Object params[],
|
||||||
String signature[], ClassLoader loader)
|
String signature[], ClassLoader loader)
|
||||||
throws ReflectionException, MBeanException {
|
throws ReflectionException, MBeanException {
|
||||||
// Instantiate the new object
|
// Instantiate the new object
|
||||||
|
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
final Class[] tab;
|
final Class<?>[] tab;
|
||||||
Object moi;
|
Object moi;
|
||||||
try {
|
try {
|
||||||
// Build the signature of the method
|
// Build the signature of the method
|
||||||
@ -283,7 +283,7 @@ public class MBeanInstantiator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Query the metadata service to get the right constructor
|
// Query the metadata service to get the right constructor
|
||||||
Constructor cons = findConstructor(theClass, tab);
|
Constructor<?> cons = findConstructor(theClass, tab);
|
||||||
|
|
||||||
if (cons == null) {
|
if (cons == null) {
|
||||||
throw new ReflectionException(new
|
throw new ReflectionException(new
|
||||||
@ -407,7 +407,7 @@ public class MBeanInstantiator {
|
|||||||
throw new RuntimeOperationsException(new
|
throw new RuntimeOperationsException(new
|
||||||
IllegalArgumentException(), "Null className passed in parameter");
|
IllegalArgumentException(), "Null className passed in parameter");
|
||||||
}
|
}
|
||||||
Class theClass;
|
Class<?> theClass;
|
||||||
if (loaderName == null) {
|
if (loaderName == null) {
|
||||||
// Load the class using the agent class loader
|
// Load the class using the agent class loader
|
||||||
theClass = findClass(className, loader);
|
theClass = findClass(className, loader);
|
||||||
@ -547,7 +547,7 @@ public class MBeanInstantiator {
|
|||||||
throws ReflectionException,
|
throws ReflectionException,
|
||||||
MBeanException {
|
MBeanException {
|
||||||
|
|
||||||
Class theClass = findClassWithDefaultLoaderRepository(className);
|
Class<?> theClass = findClassWithDefaultLoaderRepository(className);
|
||||||
return instantiate(theClass, params, signature, loader);
|
return instantiate(theClass, params, signature, loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,7 +595,7 @@ public class MBeanInstantiator {
|
|||||||
|
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
Class theClass;
|
Class<?> theClass;
|
||||||
|
|
||||||
if (loaderName == null) {
|
if (loaderName == null) {
|
||||||
theClass = findClass(className, loader);
|
theClass = findClass(className, loader);
|
||||||
@ -617,10 +617,10 @@ public class MBeanInstantiator {
|
|||||||
* Load a class with the specified loader, or with this object
|
* Load a class with the specified loader, or with this object
|
||||||
* class loader if the specified loader is null.
|
* class loader if the specified loader is null.
|
||||||
**/
|
**/
|
||||||
static Class loadClass(String className, ClassLoader loader)
|
static Class<?> loadClass(String className, ClassLoader loader)
|
||||||
throws ReflectionException {
|
throws ReflectionException {
|
||||||
|
|
||||||
Class theClass;
|
Class<?> theClass;
|
||||||
if (className == null) {
|
if (className == null) {
|
||||||
throw new RuntimeOperationsException(new
|
throw new RuntimeOperationsException(new
|
||||||
IllegalArgumentException("The class name cannot be null"),
|
IllegalArgumentException("The class name cannot be null"),
|
||||||
@ -647,15 +647,15 @@ public class MBeanInstantiator {
|
|||||||
* Load the classes specified in the signature with the given loader,
|
* Load the classes specified in the signature with the given loader,
|
||||||
* or with this object class loader.
|
* or with this object class loader.
|
||||||
**/
|
**/
|
||||||
static Class[] loadSignatureClasses(String signature[],
|
static Class<?>[] loadSignatureClasses(String signature[],
|
||||||
ClassLoader loader)
|
ClassLoader loader)
|
||||||
throws ReflectionException {
|
throws ReflectionException {
|
||||||
|
|
||||||
if (signature == null) return null;
|
if (signature == null) return null;
|
||||||
final ClassLoader aLoader =
|
final ClassLoader aLoader =
|
||||||
(loader==null?MBeanInstantiator.class.getClassLoader():loader);
|
(loader==null?MBeanInstantiator.class.getClassLoader():loader);
|
||||||
final int length= signature.length;
|
final int length= signature.length;
|
||||||
final Class tab[]=new Class[length];
|
final Class<?> tab[]=new Class<?>[length];
|
||||||
|
|
||||||
if (length == 0) return tab;
|
if (length == 0) return tab;
|
||||||
try {
|
try {
|
||||||
@ -664,7 +664,7 @@ public class MBeanInstantiator {
|
|||||||
// forth)
|
// forth)
|
||||||
//
|
//
|
||||||
|
|
||||||
final Class primCla = primitiveClasses.get(signature[i]);
|
final Class<?> primCla = primitiveClasses.get(signature[i]);
|
||||||
if (primCla != null) {
|
if (primCla != null) {
|
||||||
tab[i] = primCla;
|
tab[i] = primCla;
|
||||||
continue;
|
continue;
|
||||||
@ -710,9 +710,9 @@ public class MBeanInstantiator {
|
|||||||
|
|
||||||
private static final Map<String, Class<?>> primitiveClasses = Util.newMap();
|
private static final Map<String, Class<?>> primitiveClasses = Util.newMap();
|
||||||
static {
|
static {
|
||||||
for (Class<?> c : new Class[] {byte.class, short.class, int.class,
|
for (Class<?> c : new Class<?>[] {byte.class, short.class, int.class,
|
||||||
long.class, float.class, double.class,
|
long.class, float.class, double.class,
|
||||||
char.class, boolean.class})
|
char.class, boolean.class})
|
||||||
primitiveClasses.put(c.getName(), c);
|
primitiveClasses.put(c.getName(), c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user