1.1 --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Fri Mar 13 11:35:17 2009 -0700 1.2 +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Fri Mar 13 18:39:22 2009 -0700 1.3 @@ -2393,23 +2393,11 @@ 1.4 1.5 // get instance klass 1.6 load(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc), k_RInfo, T_OBJECT, NULL); 1.7 - // get super_check_offset 1.8 - load(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes(), Rtmp1, T_INT, NULL); 1.9 - // See if we get an immediate positive hit 1.10 - __ ld_ptr(klass_RInfo, Rtmp1, FrameMap::O7_oop_opr->as_register()); 1.11 - __ cmp(k_RInfo, O7); 1.12 - __ br(Assembler::equal, false, Assembler::pn, done); 1.13 - __ delayed()->nop(); 1.14 - // check for immediate negative hit 1.15 - __ cmp(Rtmp1, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); 1.16 - __ br(Assembler::notEqual, false, Assembler::pn, *stub->entry()); 1.17 - __ delayed()->nop(); 1.18 - // check for self 1.19 - __ cmp(klass_RInfo, k_RInfo); 1.20 - __ br(Assembler::equal, false, Assembler::pn, done); 1.21 - __ delayed()->nop(); 1.22 - 1.23 - // assert(sub.is_same(FrameMap::G3_RInfo) && super.is_same(FrameMap::G1_RInfo), "incorrect call setup"); 1.24 + // perform the fast part of the checking logic 1.25 + __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, &done, stub->entry(), NULL); 1.26 + 1.27 + // call out-of-line instance of __ check_klass_subtype_slow_path(...): 1.28 + assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup"); 1.29 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); 1.30 __ delayed()->nop(); 1.31 __ cmp(G3, 0); 1.32 @@ -2493,58 +2481,30 @@ 1.33 __ delayed()->nop(); 1.34 __ bind(done); 1.35 } else { 1.36 + bool need_slow_path = true; 1.37 if (k->is_loaded()) { 1.38 - load(klass_RInfo, k->super_check_offset(), Rtmp1, T_OBJECT, NULL); 1.39 - 1.40 - if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) { 1.41 - // See if we get an immediate positive hit 1.42 - __ cmp(Rtmp1, k_RInfo ); 1.43 - __ br(Assembler::notEqual, false, Assembler::pn, *stub->entry()); 1.44 - __ delayed()->nop(); 1.45 - } else { 1.46 - // See if we get an immediate positive hit 1.47 - assert_different_registers(Rtmp1, k_RInfo, klass_RInfo); 1.48 - __ cmp(Rtmp1, k_RInfo ); 1.49 - __ br(Assembler::equal, false, Assembler::pn, done); 1.50 - // check for self 1.51 - __ delayed()->cmp(klass_RInfo, k_RInfo); 1.52 - __ br(Assembler::equal, false, Assembler::pn, done); 1.53 - __ delayed()->nop(); 1.54 - 1.55 - // assert(sub.is_same(FrameMap::G3_RInfo) && super.is_same(FrameMap::G1_RInfo), "incorrect call setup"); 1.56 - __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); 1.57 - __ delayed()->nop(); 1.58 - __ cmp(G3, 0); 1.59 - __ br(Assembler::equal, false, Assembler::pn, *stub->entry()); 1.60 - __ delayed()->nop(); 1.61 - } 1.62 - __ bind(done); 1.63 + if (k->super_check_offset() != sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()) 1.64 + need_slow_path = false; 1.65 + // perform the fast part of the checking logic 1.66 + __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, noreg, 1.67 + (need_slow_path ? &done : NULL), 1.68 + stub->entry(), NULL, 1.69 + RegisterConstant(k->super_check_offset())); 1.70 } else { 1.71 - assert_different_registers(Rtmp1, klass_RInfo, k_RInfo); 1.72 - 1.73 - load(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes(), Rtmp1, T_INT, NULL); 1.74 - // See if we get an immediate positive hit 1.75 - load(klass_RInfo, Rtmp1, FrameMap::O7_oop_opr, T_OBJECT); 1.76 - __ cmp(k_RInfo, O7); 1.77 - __ br(Assembler::equal, false, Assembler::pn, done); 1.78 - __ delayed()->nop(); 1.79 - // check for immediate negative hit 1.80 - __ cmp(Rtmp1, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); 1.81 - __ br(Assembler::notEqual, false, Assembler::pn, *stub->entry()); 1.82 - // check for self 1.83 - __ delayed()->cmp(klass_RInfo, k_RInfo); 1.84 - __ br(Assembler::equal, false, Assembler::pn, done); 1.85 - __ delayed()->nop(); 1.86 - 1.87 - // assert(sub.is_same(FrameMap::G3_RInfo) && super.is_same(FrameMap::G1_RInfo), "incorrect call setup"); 1.88 + // perform the fast part of the checking logic 1.89 + __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, 1.90 + &done, stub->entry(), NULL); 1.91 + } 1.92 + if (need_slow_path) { 1.93 + // call out-of-line instance of __ check_klass_subtype_slow_path(...): 1.94 + assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup"); 1.95 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); 1.96 __ delayed()->nop(); 1.97 __ cmp(G3, 0); 1.98 __ br(Assembler::equal, false, Assembler::pn, *stub->entry()); 1.99 __ delayed()->nop(); 1.100 - __ bind(done); 1.101 } 1.102 - 1.103 + __ bind(done); 1.104 } 1.105 __ mov(obj, dst); 1.106 } else if (code == lir_instanceof) { 1.107 @@ -2582,58 +2542,32 @@ 1.108 __ set(0, dst); 1.109 __ bind(done); 1.110 } else { 1.111 + bool need_slow_path = true; 1.112 if (k->is_loaded()) { 1.113 - assert_different_registers(Rtmp1, klass_RInfo, k_RInfo); 1.114 - load(klass_RInfo, k->super_check_offset(), Rtmp1, T_OBJECT, NULL); 1.115 - 1.116 - if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) { 1.117 - // See if we get an immediate positive hit 1.118 - __ cmp(Rtmp1, k_RInfo ); 1.119 - __ br(Assembler::equal, true, Assembler::pt, done); 1.120 - __ delayed()->set(1, dst); 1.121 - __ set(0, dst); 1.122 - __ bind(done); 1.123 - } else { 1.124 - // See if we get an immediate positive hit 1.125 - assert_different_registers(Rtmp1, k_RInfo, klass_RInfo); 1.126 - __ cmp(Rtmp1, k_RInfo ); 1.127 - __ br(Assembler::equal, true, Assembler::pt, done); 1.128 - __ delayed()->set(1, dst); 1.129 - // check for self 1.130 - __ cmp(klass_RInfo, k_RInfo); 1.131 - __ br(Assembler::equal, true, Assembler::pt, done); 1.132 - __ delayed()->set(1, dst); 1.133 - 1.134 - // assert(sub.is_same(FrameMap::G3_RInfo) && super.is_same(FrameMap::G1_RInfo), "incorrect call setup"); 1.135 - __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); 1.136 - __ delayed()->nop(); 1.137 - __ mov(G3, dst); 1.138 - __ bind(done); 1.139 - } 1.140 + if (k->super_check_offset() != sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()) 1.141 + need_slow_path = false; 1.142 + // perform the fast part of the checking logic 1.143 + __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, O7, noreg, 1.144 + (need_slow_path ? &done : NULL), 1.145 + (need_slow_path ? &done : NULL), NULL, 1.146 + RegisterConstant(k->super_check_offset()), 1.147 + dst); 1.148 } else { 1.149 assert(dst != klass_RInfo && dst != k_RInfo, "need 3 registers"); 1.150 - 1.151 - load(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes(), dst, T_INT, NULL); 1.152 - // See if we get an immediate positive hit 1.153 - load(klass_RInfo, dst, FrameMap::O7_oop_opr, T_OBJECT); 1.154 - __ cmp(k_RInfo, O7); 1.155 - __ br(Assembler::equal, true, Assembler::pt, done); 1.156 - __ delayed()->set(1, dst); 1.157 - // check for immediate negative hit 1.158 - __ cmp(dst, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); 1.159 - __ br(Assembler::notEqual, true, Assembler::pt, done); 1.160 - __ delayed()->set(0, dst); 1.161 - // check for self 1.162 - __ cmp(klass_RInfo, k_RInfo); 1.163 - __ br(Assembler::equal, true, Assembler::pt, done); 1.164 - __ delayed()->set(1, dst); 1.165 - 1.166 - // assert(sub.is_same(FrameMap::G3_RInfo) && super.is_same(FrameMap::G1_RInfo), "incorrect call setup"); 1.167 + // perform the fast part of the checking logic 1.168 + __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, O7, dst, 1.169 + &done, &done, NULL, 1.170 + RegisterConstant(-1), 1.171 + dst); 1.172 + } 1.173 + if (need_slow_path) { 1.174 + // call out-of-line instance of __ check_klass_subtype_slow_path(...): 1.175 + assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup"); 1.176 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); 1.177 __ delayed()->nop(); 1.178 __ mov(G3, dst); 1.179 - __ bind(done); 1.180 } 1.181 + __ bind(done); 1.182 } 1.183 } else { 1.184 ShouldNotReachHere();