comparison src/share/vm/opto/graphKit.cpp @ 851:fc4be448891f

6851742: (EA) allocation elimination doesn't work with UseG1GC Summary: Fix eliminate_card_mark() to eliminate G1 pre/post barriers. Reviewed-by: never
author kvn
date Thu, 16 Jul 2009 14:10:42 -0700
parents bf3489cc0aa0
children 9987d9d5eb0e
comparison
equal deleted inserted replaced
850:fd50a67f97d1 851:fc4be448891f
1371 record_for_igvn(st); 1371 record_for_igvn(st);
1372 1372
1373 return st; 1373 return st;
1374 } 1374 }
1375 1375
1376
1376 void GraphKit::pre_barrier(Node* ctl, 1377 void GraphKit::pre_barrier(Node* ctl,
1377 Node* obj, 1378 Node* obj,
1378 Node* adr, 1379 Node* adr,
1379 uint adr_idx, 1380 uint adr_idx,
1380 Node *val, 1381 Node* val,
1381 const TypeOopPtr* val_type, 1382 const TypeOopPtr* val_type,
1382 BasicType bt) { 1383 BasicType bt) {
1383 BarrierSet* bs = Universe::heap()->barrier_set(); 1384 BarrierSet* bs = Universe::heap()->barrier_set();
1384 set_control(ctl); 1385 set_control(ctl);
1385 switch (bs->kind()) { 1386 switch (bs->kind()) {
1386 case BarrierSet::G1SATBCT: 1387 case BarrierSet::G1SATBCT:
1387 case BarrierSet::G1SATBCTLogging: 1388 case BarrierSet::G1SATBCTLogging:
1388 g1_write_barrier_pre(obj, adr, adr_idx, val, val_type, bt); 1389 g1_write_barrier_pre(obj, adr, adr_idx, val, val_type, bt);
1389 break; 1390 break;
1390 1391
1391 case BarrierSet::CardTableModRef: 1392 case BarrierSet::CardTableModRef:
1392 case BarrierSet::CardTableExtension: 1393 case BarrierSet::CardTableExtension:
1393 case BarrierSet::ModRef: 1394 case BarrierSet::ModRef:
1402 1403
1403 void GraphKit::post_barrier(Node* ctl, 1404 void GraphKit::post_barrier(Node* ctl,
1404 Node* store, 1405 Node* store,
1405 Node* obj, 1406 Node* obj,
1406 Node* adr, 1407 Node* adr,
1407 uint adr_idx, 1408 uint adr_idx,
1408 Node *val, 1409 Node* val,
1409 BasicType bt, 1410 BasicType bt,
1410 bool use_precise) { 1411 bool use_precise) {
1411 BarrierSet* bs = Universe::heap()->barrier_set(); 1412 BarrierSet* bs = Universe::heap()->barrier_set();
1412 set_control(ctl); 1413 set_control(ctl);
1413 switch (bs->kind()) { 1414 switch (bs->kind()) {
1414 case BarrierSet::G1SATBCT: 1415 case BarrierSet::G1SATBCT:
1415 case BarrierSet::G1SATBCTLogging: 1416 case BarrierSet::G1SATBCTLogging:
1416 g1_write_barrier_post(store, obj, adr, adr_idx, val, bt, use_precise); 1417 g1_write_barrier_post(store, obj, adr, adr_idx, val, bt, use_precise);
1417 break; 1418 break;
1418 1419
1419 case BarrierSet::CardTableModRef: 1420 case BarrierSet::CardTableModRef:
1420 case BarrierSet::CardTableExtension: 1421 case BarrierSet::CardTableExtension:
1421 write_barrier_post(store, obj, adr, val, use_precise); 1422 write_barrier_post(store, obj, adr, val, use_precise);
1429 ShouldNotReachHere(); 1430 ShouldNotReachHere();
1430 1431
1431 } 1432 }
1432 } 1433 }
1433 1434
1434 Node* GraphKit::store_oop_to_object(Node* ctl, 1435 Node* GraphKit::store_oop(Node* ctl,
1435 Node* obj, 1436 Node* obj,
1436 Node* adr, 1437 Node* adr,
1437 const TypePtr* adr_type, 1438 const TypePtr* adr_type,
1438 Node *val, 1439 Node* val,
1439 const TypeOopPtr* val_type, 1440 const TypeOopPtr* val_type,
1440 BasicType bt) { 1441 BasicType bt,
1442 bool use_precise) {
1443
1444 set_control(ctl);
1445 if (stopped()) return top(); // Dead path ?
1446
1447 assert(bt == T_OBJECT, "sanity");
1448 assert(val != NULL, "not dead path");
1441 uint adr_idx = C->get_alias_index(adr_type); 1449 uint adr_idx = C->get_alias_index(adr_type);
1442 Node* store; 1450 assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
1443 pre_barrier(ctl, obj, adr, adr_idx, val, val_type, bt); 1451
1444 store = store_to_memory(control(), adr, val, bt, adr_idx); 1452 pre_barrier(control(), obj, adr, adr_idx, val, val_type, bt);
1445 post_barrier(control(), store, obj, adr, adr_idx, val, bt, false); 1453 Node* store = store_to_memory(control(), adr, val, bt, adr_idx);
1454 post_barrier(control(), store, obj, adr, adr_idx, val, bt, use_precise);
1446 return store; 1455 return store;
1447 } 1456 }
1448 1457
1449 Node* GraphKit::store_oop_to_array(Node* ctl, 1458 // Could be an array or object we don't know at compile time (unsafe ref.)
1450 Node* obj,
1451 Node* adr,
1452 const TypePtr* adr_type,
1453 Node *val,
1454 const TypeOopPtr* val_type,
1455 BasicType bt) {
1456 uint adr_idx = C->get_alias_index(adr_type);
1457 Node* store;
1458 pre_barrier(ctl, obj, adr, adr_idx, val, val_type, bt);
1459 store = store_to_memory(control(), adr, val, bt, adr_idx);
1460 post_barrier(control(), store, obj, adr, adr_idx, val, bt, true);
1461 return store;
1462 }
1463
1464 Node* GraphKit::store_oop_to_unknown(Node* ctl, 1459 Node* GraphKit::store_oop_to_unknown(Node* ctl,
1465 Node* obj, 1460 Node* obj, // containing obj
1466 Node* adr, 1461 Node* adr, // actual adress to store val at
1467 const TypePtr* adr_type, 1462 const TypePtr* adr_type,
1468 Node *val, 1463 Node* val,
1469 BasicType bt) { 1464 BasicType bt) {
1470 Compile::AliasType* at = C->alias_type(adr_type); 1465 Compile::AliasType* at = C->alias_type(adr_type);
1471 const TypeOopPtr* val_type = NULL; 1466 const TypeOopPtr* val_type = NULL;
1472 if (adr_type->isa_instptr()) { 1467 if (adr_type->isa_instptr()) {
1473 if (at->field() != NULL) { 1468 if (at->field() != NULL) {
1474 // known field. This code is a copy of the do_put_xxx logic. 1469 // known field. This code is a copy of the do_put_xxx logic.
1483 val_type = adr_type->is_aryptr()->elem()->make_oopptr(); 1478 val_type = adr_type->is_aryptr()->elem()->make_oopptr();
1484 } 1479 }
1485 if (val_type == NULL) { 1480 if (val_type == NULL) {
1486 val_type = TypeInstPtr::BOTTOM; 1481 val_type = TypeInstPtr::BOTTOM;
1487 } 1482 }
1488 1483 return store_oop(ctl, obj, adr, adr_type, val, val_type, bt, true);
1489 uint adr_idx = at->index();
1490 pre_barrier(ctl, obj, adr, adr_idx, val, val_type, bt);
1491 Node* store = store_to_memory(control(), adr, val, bt, adr_idx);
1492 post_barrier(control(), store, obj, adr, adr_idx, val, bt, true);
1493 return store;
1494 } 1484 }
1495 1485
1496 1486
1497 //-------------------------array_element_address------------------------- 1487 //-------------------------array_element_address-------------------------
1498 Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt, 1488 Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt,
1799 // it does not require card marks. 1789 // it does not require card marks.
1800 Node* GraphKit::just_allocated_object(Node* current_control) { 1790 Node* GraphKit::just_allocated_object(Node* current_control) {
1801 if (C->recent_alloc_ctl() == current_control) 1791 if (C->recent_alloc_ctl() == current_control)
1802 return C->recent_alloc_obj(); 1792 return C->recent_alloc_obj();
1803 return NULL; 1793 return NULL;
1804 }
1805
1806
1807 //------------------------------store_barrier----------------------------------
1808 // Insert a write-barrier store. This is to let generational GC work; we have
1809 // to flag all oop-stores before the next GC point.
1810 void GraphKit::write_barrier_post(Node* oop_store, Node* obj, Node* adr,
1811 Node* val, bool use_precise) {
1812 // No store check needed if we're storing a NULL or an old object
1813 // (latter case is probably a string constant). The concurrent
1814 // mark sweep garbage collector, however, needs to have all nonNull
1815 // oop updates flagged via card-marks.
1816 if (val != NULL && val->is_Con()) {
1817 // must be either an oop or NULL
1818 const Type* t = val->bottom_type();
1819 if (t == TypePtr::NULL_PTR || t == Type::TOP)
1820 // stores of null never (?) need barriers
1821 return;
1822 ciObject* con = t->is_oopptr()->const_oop();
1823 if (con != NULL
1824 && con->is_perm()
1825 && Universe::heap()->can_elide_permanent_oop_store_barriers())
1826 // no store barrier needed, because no old-to-new ref created
1827 return;
1828 }
1829
1830 if (use_ReduceInitialCardMarks()
1831 && obj == just_allocated_object(control())) {
1832 // We can skip marks on a freshly-allocated object.
1833 // Keep this code in sync with do_eager_card_mark in runtime.cpp.
1834 // That routine eagerly marks the occasional object which is produced
1835 // by the slow path, so that we don't have to do it here.
1836 return;
1837 }
1838
1839 if (!use_precise) {
1840 // All card marks for a (non-array) instance are in one place:
1841 adr = obj;
1842 }
1843 // (Else it's an array (or unknown), and we want more precise card marks.)
1844 assert(adr != NULL, "");
1845
1846 // Get the alias_index for raw card-mark memory
1847 int adr_type = Compile::AliasIdxRaw;
1848 // Convert the pointer to an int prior to doing math on it
1849 Node* cast = _gvn.transform(new (C, 2) CastP2XNode(control(), adr));
1850 // Divide by card size
1851 assert(Universe::heap()->barrier_set()->kind() == BarrierSet::CardTableModRef,
1852 "Only one we handle so far.");
1853 CardTableModRefBS* ct =
1854 (CardTableModRefBS*)(Universe::heap()->barrier_set());
1855 Node *b = _gvn.transform(new (C, 3) URShiftXNode( cast, _gvn.intcon(CardTableModRefBS::card_shift) ));
1856 // We store into a byte array, so do not bother to left-shift by zero
1857 Node *c = byte_map_base_node();
1858 // Combine
1859 Node *sb_ctl = control();
1860 Node *sb_adr = _gvn.transform(new (C, 4) AddPNode( top()/*no base ptr*/, c, b ));
1861 Node *sb_val = _gvn.intcon(0);
1862 // Smash zero into card
1863 if( !UseConcMarkSweepGC ) {
1864 BasicType bt = T_BYTE;
1865 store_to_memory(sb_ctl, sb_adr, sb_val, bt, adr_type);
1866 } else {
1867 // Specialized path for CM store barrier
1868 cms_card_mark( sb_ctl, sb_adr, sb_val, oop_store);
1869 }
1870 }
1871
1872 // Specialized path for CMS store barrier
1873 void GraphKit::cms_card_mark(Node* ctl, Node* adr, Node* val, Node *oop_store) {
1874 BasicType bt = T_BYTE;
1875 int adr_idx = Compile::AliasIdxRaw;
1876 Node* mem = memory(adr_idx);
1877
1878 // The type input is NULL in PRODUCT builds
1879 const TypePtr* type = NULL;
1880 debug_only(type = C->get_adr_type(adr_idx));
1881
1882 // Add required edge to oop_store, optimizer does not support precedence edges.
1883 // Convert required edge to precedence edge before allocation.
1884 Node *store = _gvn.transform( new (C, 5) StoreCMNode(ctl, mem, adr, type, val, oop_store) );
1885 set_memory(store, adr_idx);
1886
1887 // For CMS, back-to-back card-marks can only remove the first one
1888 // and this requires DU info. Push on worklist for optimizer.
1889 if (mem->req() > MemNode::Address && adr == mem->in(MemNode::Address))
1890 record_for_igvn(store);
1891 } 1794 }
1892 1795
1893 1796
1894 void GraphKit::round_double_arguments(ciMethod* dest_method) { 1797 void GraphKit::round_double_arguments(ciMethod* dest_method) {
1895 // (Note: TypeFunc::make has a cache that makes this fast.) 1798 // (Note: TypeFunc::make has a cache that makes this fast.)
3213 } 3116 }
3214 } 3117 }
3215 return NULL; 3118 return NULL;
3216 } 3119 }
3217 3120
3121 //----------------------------- store barriers ----------------------------
3122 #define __ ideal.
3123
3124 void GraphKit::sync_kit(IdealKit& ideal) {
3125 // Final sync IdealKit and graphKit.
3126 __ drain_delay_transform();
3127 set_all_memory(__ merged_memory());
3128 set_control(__ ctrl());
3129 }
3130
3131 // vanilla/CMS post barrier
3132 // Insert a write-barrier store. This is to let generational GC work; we have
3133 // to flag all oop-stores before the next GC point.
3134 void GraphKit::write_barrier_post(Node* oop_store,
3135 Node* obj,
3136 Node* adr,
3137 Node* val,
3138 bool use_precise) {
3139 // No store check needed if we're storing a NULL or an old object
3140 // (latter case is probably a string constant). The concurrent
3141 // mark sweep garbage collector, however, needs to have all nonNull
3142 // oop updates flagged via card-marks.
3143 if (val != NULL && val->is_Con()) {
3144 // must be either an oop or NULL
3145 const Type* t = val->bottom_type();
3146 if (t == TypePtr::NULL_PTR || t == Type::TOP)
3147 // stores of null never (?) need barriers
3148 return;
3149 ciObject* con = t->is_oopptr()->const_oop();
3150 if (con != NULL
3151 && con->is_perm()
3152 && Universe::heap()->can_elide_permanent_oop_store_barriers())
3153 // no store barrier needed, because no old-to-new ref created
3154 return;
3155 }
3156
3157 if (!use_precise) {
3158 // All card marks for a (non-array) instance are in one place:
3159 adr = obj;
3160 }
3161 // (Else it's an array (or unknown), and we want more precise card marks.)
3162 assert(adr != NULL, "");
3163
3164 IdealKit ideal(gvn(), control(), merged_memory(), true);
3165
3166 // Convert the pointer to an int prior to doing math on it
3167 Node* cast = __ CastPX(__ ctrl(), adr);
3168
3169 // Divide by card size
3170 assert(Universe::heap()->barrier_set()->kind() == BarrierSet::CardTableModRef,
3171 "Only one we handle so far.");
3172 Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) );
3173
3174 // Combine card table base and card offset
3175 Node* card_adr = __ AddP(__ top(), byte_map_base_node(), card_offset );
3176
3177 // Get the alias_index for raw card-mark memory
3178 int adr_type = Compile::AliasIdxRaw;
3179 // Smash zero into card
3180 Node* zero = __ ConI(0);
3181 BasicType bt = T_BYTE;
3182 if( !UseConcMarkSweepGC ) {
3183 __ store(__ ctrl(), card_adr, zero, bt, adr_type);
3184 } else {
3185 // Specialized path for CM store barrier
3186 __ storeCM(__ ctrl(), card_adr, zero, oop_store, bt, adr_type);
3187 }
3188
3189 // Final sync IdealKit and GraphKit.
3190 sync_kit(ideal);
3191 }
3192
3193 // G1 pre/post barriers
3218 void GraphKit::g1_write_barrier_pre(Node* obj, 3194 void GraphKit::g1_write_barrier_pre(Node* obj,
3219 Node* adr, 3195 Node* adr,
3220 uint alias_idx, 3196 uint alias_idx,
3221 Node* val, 3197 Node* val,
3222 const TypeOopPtr* val_type, 3198 const TypeOopPtr* val_type,
3223 BasicType bt) { 3199 BasicType bt) {
3224 IdealKit ideal(gvn(), control(), merged_memory(), true); 3200 IdealKit ideal(gvn(), control(), merged_memory(), true);
3225 #define __ ideal. 3201
3226 __ declares_done(); 3202 Node* tls = __ thread(); // ThreadLocalStorage
3227
3228 Node* thread = __ thread();
3229 3203
3230 Node* no_ctrl = NULL; 3204 Node* no_ctrl = NULL;
3231 Node* no_base = __ top(); 3205 Node* no_base = __ top();
3232 Node* zero = __ ConI(0); 3206 Node* zero = __ ConI(0);
3233 3207
3246 PtrQueue::byte_offset_of_buf()); 3220 PtrQueue::byte_offset_of_buf());
3247 // Now the actual pointers into the thread 3221 // Now the actual pointers into the thread
3248 3222
3249 // set_control( ctl); 3223 // set_control( ctl);
3250 3224
3251 Node* marking_adr = __ AddP(no_base, thread, __ ConX(marking_offset)); 3225 Node* marking_adr = __ AddP(no_base, tls, __ ConX(marking_offset));
3252 Node* buffer_adr = __ AddP(no_base, thread, __ ConX(buffer_offset)); 3226 Node* buffer_adr = __ AddP(no_base, tls, __ ConX(buffer_offset));
3253 Node* index_adr = __ AddP(no_base, thread, __ ConX(index_offset)); 3227 Node* index_adr = __ AddP(no_base, tls, __ ConX(index_offset));
3254 3228
3255 // Now some of the values 3229 // Now some of the values
3256 3230
3257 Node* marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw); 3231 Node* marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw);
3258 3232
3276 3250
3277 // decrement the index 3251 // decrement the index
3278 Node* next_index = __ SubI(index, __ ConI(sizeof(intptr_t))); 3252 Node* next_index = __ SubI(index, __ ConI(sizeof(intptr_t)));
3279 Node* next_indexX = next_index; 3253 Node* next_indexX = next_index;
3280 #ifdef _LP64 3254 #ifdef _LP64
3281 // We could refine the type for what it's worth 3255 // We could refine the type for what it's worth
3282 // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue); 3256 // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue);
3283 next_indexX = _gvn.transform( new (C, 2) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) ); 3257 next_indexX = _gvn.transform( new (C, 2) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) );
3284 #endif // _LP64 3258 #endif
3285 3259
3286 // Now get the buffer location we will log the original value into and store it 3260 // Now get the buffer location we will log the original value into and store it
3287
3288 Node *log_addr = __ AddP(no_base, buffer, next_indexX); 3261 Node *log_addr = __ AddP(no_base, buffer, next_indexX);
3289 // __ store(__ ctrl(), log_addr, orig, T_OBJECT, C->get_alias_index(TypeOopPtr::BOTTOM));
3290 __ store(__ ctrl(), log_addr, orig, T_OBJECT, Compile::AliasIdxRaw); 3262 __ store(__ ctrl(), log_addr, orig, T_OBJECT, Compile::AliasIdxRaw);
3291 3263
3292
3293 // update the index 3264 // update the index
3294 // __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw); 3265 __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw);
3295 // This is a hack to force this store to occur before the oop store that is coming up
3296 __ store(__ ctrl(), index_adr, next_index, T_INT, C->get_alias_index(TypeOopPtr::BOTTOM));
3297 3266
3298 } __ else_(); { 3267 } __ else_(); {
3299 3268
3300 // logging buffer is full, call the runtime 3269 // logging buffer is full, call the runtime
3301 const TypeFunc *tf = OptoRuntime::g1_wb_pre_Type(); 3270 const TypeFunc *tf = OptoRuntime::g1_wb_pre_Type();
3302 // __ make_leaf_call(tf, OptoRuntime::g1_wb_pre_Java(), "g1_wb_pre", orig, thread); 3271 __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), "g1_wb_pre", orig, tls);
3303 __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), "g1_wb_pre", orig, thread); 3272 } __ end_if(); // (!index)
3304 } __ end_if(); 3273 } __ end_if(); // (orig != NULL)
3305 } __ end_if(); 3274 } __ end_if(); // (!marking)
3306 } __ end_if(); 3275
3307 3276 // Final sync IdealKit and GraphKit.
3308 __ drain_delay_transform(); 3277 sync_kit(ideal);
3309 set_control( __ ctrl());
3310 set_all_memory( __ merged_memory());
3311
3312 #undef __
3313 } 3278 }
3314 3279
3315 // 3280 //
3316 // Update the card table and add card address to the queue 3281 // Update the card table and add card address to the queue
3317 // 3282 //
3318 void GraphKit::g1_mark_card(IdealKit* ideal, Node* card_adr, Node* store, Node* index, Node* index_adr, Node* buffer, const TypeFunc* tf) { 3283 void GraphKit::g1_mark_card(IdealKit& ideal,
3319 #define __ ideal-> 3284 Node* card_adr,
3285 Node* oop_store,
3286 Node* index,
3287 Node* index_adr,
3288 Node* buffer,
3289 const TypeFunc* tf) {
3290
3320 Node* zero = __ ConI(0); 3291 Node* zero = __ ConI(0);
3321 Node* no_base = __ top(); 3292 Node* no_base = __ top();
3322 BasicType card_bt = T_BYTE; 3293 BasicType card_bt = T_BYTE;
3323 // Smash zero into card. MUST BE ORDERED WRT TO STORE 3294 // Smash zero into card. MUST BE ORDERED WRT TO STORE
3324 __ storeCM(__ ctrl(), card_adr, zero, store, card_bt, Compile::AliasIdxRaw); 3295 __ storeCM(__ ctrl(), card_adr, zero, oop_store, card_bt, Compile::AliasIdxRaw);
3325 3296
3326 // Now do the queue work 3297 // Now do the queue work
3327 __ if_then(index, BoolTest::ne, zero); { 3298 __ if_then(index, BoolTest::ne, zero); {
3328 3299
3329 Node* next_index = __ SubI(index, __ ConI(sizeof(intptr_t))); 3300 Node* next_index = __ SubI(index, __ ConI(sizeof(intptr_t)));
3330 Node* next_indexX = next_index; 3301 Node* next_indexX = next_index;
3331 #ifdef _LP64 3302 #ifdef _LP64
3332 // We could refine the type for what it's worth 3303 // We could refine the type for what it's worth
3333 // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue); 3304 // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue);
3334 next_indexX = _gvn.transform( new (C, 2) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) ); 3305 next_indexX = _gvn.transform( new (C, 2) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) );
3339 __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw); 3310 __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw);
3340 3311
3341 } __ else_(); { 3312 } __ else_(); {
3342 __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), "g1_wb_post", card_adr, __ thread()); 3313 __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), "g1_wb_post", card_adr, __ thread());
3343 } __ end_if(); 3314 } __ end_if();
3344 #undef __ 3315
3345 } 3316 }
3346 3317
3347 void GraphKit::g1_write_barrier_post(Node* store, 3318 void GraphKit::g1_write_barrier_post(Node* oop_store,
3348 Node* obj, 3319 Node* obj,
3349 Node* adr, 3320 Node* adr,
3350 uint alias_idx, 3321 uint alias_idx,
3351 Node* val, 3322 Node* val,
3352 BasicType bt, 3323 BasicType bt,
3367 } 3338 }
3368 // (Else it's an array (or unknown), and we want more precise card marks.) 3339 // (Else it's an array (or unknown), and we want more precise card marks.)
3369 assert(adr != NULL, ""); 3340 assert(adr != NULL, "");
3370 3341
3371 IdealKit ideal(gvn(), control(), merged_memory(), true); 3342 IdealKit ideal(gvn(), control(), merged_memory(), true);
3372 #define __ ideal. 3343
3373 __ declares_done(); 3344 Node* tls = __ thread(); // ThreadLocalStorage
3374
3375 Node* thread = __ thread();
3376 3345
3377 Node* no_ctrl = NULL; 3346 Node* no_ctrl = NULL;
3378 Node* no_base = __ top(); 3347 Node* no_base = __ top();
3379 float likely = PROB_LIKELY(0.999); 3348 float likely = PROB_LIKELY(0.999);
3380 float unlikely = PROB_UNLIKELY(0.999); 3349 float unlikely = PROB_UNLIKELY(0.999);
3392 const int buffer_offset = in_bytes(JavaThread::dirty_card_queue_offset() + 3361 const int buffer_offset = in_bytes(JavaThread::dirty_card_queue_offset() +
3393 PtrQueue::byte_offset_of_buf()); 3362 PtrQueue::byte_offset_of_buf());
3394 3363
3395 // Pointers into the thread 3364 // Pointers into the thread
3396 3365
3397 Node* buffer_adr = __ AddP(no_base, thread, __ ConX(buffer_offset)); 3366 Node* buffer_adr = __ AddP(no_base, tls, __ ConX(buffer_offset));
3398 Node* index_adr = __ AddP(no_base, thread, __ ConX(index_offset)); 3367 Node* index_adr = __ AddP(no_base, tls, __ ConX(index_offset));
3399 3368
3400 // Now some values 3369 // Now some values
3401 3370
3402 Node* index = __ load(no_ctrl, index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw); 3371 Node* index = __ load(no_ctrl, index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw);
3403 Node* buffer = __ load(no_ctrl, buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw); 3372 Node* buffer = __ load(no_ctrl, buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw);
3404 3373
3405 3374
3406 // Convert the store obj pointer to an int prior to doing math on it 3375 // Convert the store obj pointer to an int prior to doing math on it
3407 // Use addr not obj gets accurate card marks
3408
3409 // Node* cast = __ CastPX(no_ctrl, adr /* obj */);
3410
3411 // Must use ctrl to prevent "integerized oop" existing across safepoint 3376 // Must use ctrl to prevent "integerized oop" existing across safepoint
3412 Node* cast = __ CastPX(__ ctrl(), ( use_precise ? adr : obj )); 3377 Node* cast = __ CastPX(__ ctrl(), adr);
3413 3378
3414 // Divide pointer by card size 3379 // Divide pointer by card size
3415 Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) ); 3380 Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) );
3416 3381
3417 // Combine card table base and card offset 3382 // Combine card table base and card offset
3418 Node *card_adr = __ AddP(no_base, byte_map_base_node(), card_offset ); 3383 Node* card_adr = __ AddP(no_base, byte_map_base_node(), card_offset );
3419 3384
3420 // If we know the value being stored does it cross regions? 3385 // If we know the value being stored does it cross regions?
3421 3386
3422 if (val != NULL) { 3387 if (val != NULL) {
3423 // Does the store cause us to cross regions? 3388 // Does the store cause us to cross regions?
3437 3402
3438 // load the original value of the card 3403 // load the original value of the card
3439 Node* card_val = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw); 3404 Node* card_val = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw);
3440 3405
3441 __ if_then(card_val, BoolTest::ne, zero); { 3406 __ if_then(card_val, BoolTest::ne, zero); {
3442 g1_mark_card(&ideal, card_adr, store, index, index_adr, buffer, tf); 3407 g1_mark_card(ideal, card_adr, oop_store, index, index_adr, buffer, tf);
3443 } __ end_if(); 3408 } __ end_if();
3444 } __ end_if(); 3409 } __ end_if();
3445 } __ end_if(); 3410 } __ end_if();
3446 } else { 3411 } else {
3447 g1_mark_card(&ideal, card_adr, store, index, index_adr, buffer, tf); 3412 // Object.clone() instrinsic uses this path.
3448 } 3413 g1_mark_card(ideal, card_adr, oop_store, index, index_adr, buffer, tf);
3449 3414 }
3450 3415
3451 __ drain_delay_transform(); 3416 // Final sync IdealKit and GraphKit.
3452 set_control( __ ctrl()); 3417 sync_kit(ideal);
3453 set_all_memory( __ merged_memory()); 3418 }
3454 #undef __ 3419 #undef __
3455 3420
3456 }