1102 __ return_op(result.result()); |
1102 __ return_op(result.result()); |
1103 } |
1103 } |
1104 set_no_result(x); |
1104 set_no_result(x); |
1105 } |
1105 } |
1106 |
1106 |
|
1107 // Examble: ref.get() |
|
1108 // Combination of LoadField and g1 pre-write barrier |
|
1109 void LIRGenerator::do_Reference_get(Intrinsic* x) { |
|
1110 |
|
1111 const int referent_offset = java_lang_ref_Reference::referent_offset; |
|
1112 guarantee(referent_offset > 0, "referent offset not initialized"); |
|
1113 |
|
1114 assert(x->number_of_arguments() == 1, "wrong type"); |
|
1115 |
|
1116 LIRItem reference(x->argument_at(0), this); |
|
1117 reference.load_item(); |
|
1118 |
|
1119 // need to perform the null check on the reference objecy |
|
1120 CodeEmitInfo* info = NULL; |
|
1121 if (x->needs_null_check()) { |
|
1122 info = state_for(x); |
|
1123 } |
|
1124 |
|
1125 LIR_Address* referent_field_adr = |
|
1126 new LIR_Address(reference.result(), referent_offset, T_OBJECT); |
|
1127 |
|
1128 LIR_Opr result = rlock_result(x); |
|
1129 |
|
1130 __ load(referent_field_adr, result, info); |
|
1131 |
|
1132 // Register the value in the referent field with the pre-barrier |
|
1133 pre_barrier(LIR_OprFact::illegalOpr /* addr_opr */, |
|
1134 result /* pre_val */, |
|
1135 false /* do_load */, |
|
1136 false /* patch */, |
|
1137 NULL /* info */); |
|
1138 } |
1107 |
1139 |
1108 // Example: object.getClass () |
1140 // Example: object.getClass () |
1109 void LIRGenerator::do_getClass(Intrinsic* x) { |
1141 void LIRGenerator::do_getClass(Intrinsic* x) { |
1110 assert(x->number_of_arguments() == 1, "wrong type"); |
1142 assert(x->number_of_arguments() == 1, "wrong type"); |
1111 |
1143 |
1244 return result; |
1276 return result; |
1245 } |
1277 } |
1246 |
1278 |
1247 // Various barriers |
1279 // Various barriers |
1248 |
1280 |
1249 void LIRGenerator::pre_barrier(LIR_Opr addr_opr, bool patch, CodeEmitInfo* info) { |
1281 void LIRGenerator::pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val, |
|
1282 bool do_load, bool patch, CodeEmitInfo* info) { |
1250 // Do the pre-write barrier, if any. |
1283 // Do the pre-write barrier, if any. |
1251 switch (_bs->kind()) { |
1284 switch (_bs->kind()) { |
1252 #ifndef SERIALGC |
1285 #ifndef SERIALGC |
1253 case BarrierSet::G1SATBCT: |
1286 case BarrierSet::G1SATBCT: |
1254 case BarrierSet::G1SATBCTLogging: |
1287 case BarrierSet::G1SATBCTLogging: |
1255 G1SATBCardTableModRef_pre_barrier(addr_opr, patch, info); |
1288 G1SATBCardTableModRef_pre_barrier(addr_opr, pre_val, do_load, patch, info); |
1256 break; |
1289 break; |
1257 #endif // SERIALGC |
1290 #endif // SERIALGC |
1258 case BarrierSet::CardTableModRef: |
1291 case BarrierSet::CardTableModRef: |
1259 case BarrierSet::CardTableExtension: |
1292 case BarrierSet::CardTableExtension: |
1260 // No pre barriers |
1293 // No pre barriers |
1312 PtrQueue::byte_offset_of_active()), |
1344 PtrQueue::byte_offset_of_active()), |
1313 flag_type); |
1345 flag_type); |
1314 // Read the marking-in-progress flag. |
1346 // Read the marking-in-progress flag. |
1315 LIR_Opr flag_val = new_register(T_INT); |
1347 LIR_Opr flag_val = new_register(T_INT); |
1316 __ load(mark_active_flag_addr, flag_val); |
1348 __ load(mark_active_flag_addr, flag_val); |
1317 |
|
1318 LIR_PatchCode pre_val_patch_code = |
|
1319 patch ? lir_patch_normal : lir_patch_none; |
|
1320 |
|
1321 LIR_Opr pre_val = new_register(T_OBJECT); |
|
1322 |
|
1323 __ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0)); |
1349 __ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0)); |
1324 if (!addr_opr->is_address()) { |
1350 |
1325 assert(addr_opr->is_register(), "must be"); |
1351 LIR_PatchCode pre_val_patch_code = lir_patch_none; |
1326 addr_opr = LIR_OprFact::address(new LIR_Address(addr_opr, T_OBJECT)); |
1352 |
1327 } |
1353 CodeStub* slow; |
1328 CodeStub* slow = new G1PreBarrierStub(addr_opr, pre_val, pre_val_patch_code, |
1354 |
1329 info); |
1355 if (do_load) { |
|
1356 assert(pre_val == LIR_OprFact::illegalOpr, "sanity"); |
|
1357 assert(addr_opr != LIR_OprFact::illegalOpr, "sanity"); |
|
1358 |
|
1359 if (patch) |
|
1360 pre_val_patch_code = lir_patch_normal; |
|
1361 |
|
1362 pre_val = new_register(T_OBJECT); |
|
1363 |
|
1364 if (!addr_opr->is_address()) { |
|
1365 assert(addr_opr->is_register(), "must be"); |
|
1366 addr_opr = LIR_OprFact::address(new LIR_Address(addr_opr, T_OBJECT)); |
|
1367 } |
|
1368 slow = new G1PreBarrierStub(addr_opr, pre_val, pre_val_patch_code, info); |
|
1369 } else { |
|
1370 assert(addr_opr == LIR_OprFact::illegalOpr, "sanity"); |
|
1371 assert(pre_val->is_register(), "must be"); |
|
1372 assert(pre_val->type() == T_OBJECT, "must be an object"); |
|
1373 assert(info == NULL, "sanity"); |
|
1374 |
|
1375 slow = new G1PreBarrierStub(pre_val); |
|
1376 } |
|
1377 |
1330 __ branch(lir_cond_notEqual, T_INT, slow); |
1378 __ branch(lir_cond_notEqual, T_INT, slow); |
1331 __ branch_destination(slow->continuation()); |
1379 __ branch_destination(slow->continuation()); |
1332 } |
1380 } |
1333 |
1381 |
1334 void LIRGenerator::G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) { |
1382 void LIRGenerator::G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) { |
1335 if (G1DisablePostBarrier) return; |
|
1336 |
|
1337 // If the "new_val" is a constant NULL, no barrier is necessary. |
1383 // If the "new_val" is a constant NULL, no barrier is necessary. |
1338 if (new_val->is_constant() && |
1384 if (new_val->is_constant() && |
1339 new_val->as_constant_ptr()->as_jobject() == NULL) return; |
1385 new_val->as_constant_ptr()->as_jobject() == NULL) return; |
1340 |
1386 |
1341 if (!new_val->is_register()) { |
1387 if (!new_val->is_register()) { |
1982 LIRItem off(x->offset(), this); |
2030 LIRItem off(x->offset(), this); |
1983 |
2031 |
1984 off.load_item(); |
2032 off.load_item(); |
1985 src.load_item(); |
2033 src.load_item(); |
1986 |
2034 |
1987 LIR_Opr reg = reg = rlock_result(x, x->basic_type()); |
2035 LIR_Opr reg = rlock_result(x, x->basic_type()); |
1988 |
2036 |
1989 get_Object_unsafe(reg, src.result(), off.result(), type, x->is_volatile()); |
2037 get_Object_unsafe(reg, src.result(), off.result(), type, x->is_volatile()); |
|
2038 |
|
2039 #ifndef SERIALGC |
|
2040 // We might be reading the value of the referent field of a |
|
2041 // Reference object in order to attach it back to the live |
|
2042 // object graph. If G1 is enabled then we need to record |
|
2043 // the value that is being returned in an SATB log buffer. |
|
2044 // |
|
2045 // We need to generate code similar to the following... |
|
2046 // |
|
2047 // if (offset == java_lang_ref_Reference::referent_offset) { |
|
2048 // if (src != NULL) { |
|
2049 // if (klass(src)->reference_type() != REF_NONE) { |
|
2050 // pre_barrier(..., reg, ...); |
|
2051 // } |
|
2052 // } |
|
2053 // } |
|
2054 // |
|
2055 // The first non-constant check of either the offset or |
|
2056 // the src operand will be done here; the remainder |
|
2057 // will take place in the generated code stub. |
|
2058 |
|
2059 if (UseG1GC && type == T_OBJECT) { |
|
2060 bool gen_code_stub = true; // Assume we need to generate the slow code stub. |
|
2061 bool gen_offset_check = true; // Assume the code stub has to generate the offset guard. |
|
2062 bool gen_source_check = true; // Assume the code stub has to check the src object for null. |
|
2063 |
|
2064 if (off.is_constant()) { |
|
2065 jint off_con = off.get_jint_constant(); |
|
2066 |
|
2067 if (off_con != java_lang_ref_Reference::referent_offset) { |
|
2068 // The constant offset is something other than referent_offset. |
|
2069 // We can skip generating/checking the remaining guards and |
|
2070 // skip generation of the code stub. |
|
2071 gen_code_stub = false; |
|
2072 } else { |
|
2073 // The constant offset is the same as referent_offset - |
|
2074 // we do not need to generate a runtime offset check. |
|
2075 gen_offset_check = false; |
|
2076 } |
|
2077 } |
|
2078 |
|
2079 // We don't need to generate stub if the source object is an array |
|
2080 if (gen_code_stub && src.type()->is_array()) { |
|
2081 gen_code_stub = false; |
|
2082 } |
|
2083 |
|
2084 if (gen_code_stub) { |
|
2085 // We still need to continue with the checks. |
|
2086 if (src.is_constant()) { |
|
2087 ciObject* src_con = src.get_jobject_constant(); |
|
2088 |
|
2089 if (src_con->is_null_object()) { |
|
2090 // The constant src object is null - We can skip |
|
2091 // generating the code stub. |
|
2092 gen_code_stub = false; |
|
2093 } else { |
|
2094 // Non-null constant source object. We still have to generate |
|
2095 // the slow stub - but we don't need to generate the runtime |
|
2096 // null object check. |
|
2097 gen_source_check = false; |
|
2098 } |
|
2099 } |
|
2100 } |
|
2101 |
|
2102 if (gen_code_stub) { |
|
2103 // Temoraries. |
|
2104 LIR_Opr src_klass = new_register(T_OBJECT); |
|
2105 |
|
2106 // Get the thread pointer for the pre-barrier |
|
2107 LIR_Opr thread = getThreadPointer(); |
|
2108 |
|
2109 CodeStub* stub; |
|
2110 |
|
2111 // We can have generate one runtime check here. Let's start with |
|
2112 // the offset check. |
|
2113 if (gen_offset_check) { |
|
2114 // if (offset == referent_offset) -> slow code stub |
|
2115 __ cmp(lir_cond_equal, off.result(), |
|
2116 LIR_OprFact::intConst(java_lang_ref_Reference::referent_offset)); |
|
2117 |
|
2118 // Optionally generate "src == null" check. |
|
2119 stub = new G1UnsafeGetObjSATBBarrierStub(reg, src.result(), |
|
2120 src_klass, thread, |
|
2121 gen_source_check); |
|
2122 |
|
2123 __ branch(lir_cond_equal, T_INT, stub); |
|
2124 } else { |
|
2125 if (gen_source_check) { |
|
2126 // offset is a const and equals referent offset |
|
2127 // if (source != null) -> slow code stub |
|
2128 __ cmp(lir_cond_notEqual, src.result(), LIR_OprFact::oopConst(NULL)); |
|
2129 |
|
2130 // Since we are generating the "if src == null" guard here, |
|
2131 // there is no need to generate the "src == null" check again. |
|
2132 stub = new G1UnsafeGetObjSATBBarrierStub(reg, src.result(), |
|
2133 src_klass, thread, |
|
2134 false); |
|
2135 |
|
2136 __ branch(lir_cond_notEqual, T_OBJECT, stub); |
|
2137 } else { |
|
2138 // We have statically determined that offset == referent_offset |
|
2139 // && src != null so we unconditionally branch to code stub |
|
2140 // to perform the guards and record reg in the SATB log buffer. |
|
2141 |
|
2142 stub = new G1UnsafeGetObjSATBBarrierStub(reg, src.result(), |
|
2143 src_klass, thread, |
|
2144 false); |
|
2145 |
|
2146 __ branch(lir_cond_always, T_ILLEGAL, stub); |
|
2147 } |
|
2148 } |
|
2149 |
|
2150 // Continuation point |
|
2151 __ branch_destination(stub->continuation()); |
|
2152 } |
|
2153 } |
|
2154 #endif // SERIALGC |
|
2155 |
1990 if (x->is_volatile() && os::is_MP()) __ membar_acquire(); |
2156 if (x->is_volatile() && os::is_MP()) __ membar_acquire(); |
1991 } |
2157 } |
1992 |
2158 |
1993 |
2159 |
1994 void LIRGenerator::do_UnsafePutObject(UnsafePutObject* x) { |
2160 void LIRGenerator::do_UnsafePutObject(UnsafePutObject* x) { |