277 } __ end_if(); // (!index)
278 } __ end_if(); // (pre_val != NULL)
279 } __ end_if(); // (!marking)
280
281 // Final sync IdealKit and GraphKit.
282 kit->final_sync(ideal);
283
284 if (ShenandoahSATBBarrier && adr != NULL) {
285 Node* c = kit->control();
286 Node* call = c->in(1)->in(1)->in(1)->in(0);
287 assert(is_shenandoah_wb_pre_call(call), "shenandoah_wb_pre call expected");
288 call->add_req(adr);
289 }
290 }
291
292 bool ShenandoahBarrierSetC2::is_shenandoah_wb_pre_call(Node* call) {
293 return call->is_CallLeaf() &&
294 call->as_CallLeaf()->entry_point() == CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry);
295 }
296
297 bool ShenandoahBarrierSetC2::is_shenandoah_wb_call(Node* call) {
298 return call->is_CallLeaf() &&
299 call->as_CallLeaf()->entry_point() == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_JRT);
300 }
301
302 bool ShenandoahBarrierSetC2::is_shenandoah_marking_if(PhaseTransform *phase, Node* n) {
303 if (n->Opcode() != Op_If) {
304 return false;
305 }
306
307 Node* bol = n->in(1);
308 assert(bol->is_Bool(), "");
309 Node* cmpx = bol->in(1);
310 if (bol->as_Bool()->_test._test == BoolTest::ne &&
311 cmpx->is_Cmp() && cmpx->in(2) == phase->intcon(0) &&
312 is_shenandoah_state_load(cmpx->in(1)->in(1)) &&
313 cmpx->in(1)->in(2)->is_Con() &&
314 cmpx->in(1)->in(2) == phase->intcon(ShenandoahHeap::MARKING)) {
315 return true;
316 }
317
454
455 // create result type (range)
456 fields = TypeTuple::fields(0);
457 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
458
459 return TypeFunc::make(domain, range);
460 }
461
462 const TypeFunc* ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type() {
463 const Type **fields = TypeTuple::fields(1);
464 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
465 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
466
467 // create result type (range)
468 fields = TypeTuple::fields(0);
469 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
470
471 return TypeFunc::make(domain, range);
472 }
473
474 const TypeFunc* ShenandoahBarrierSetC2::shenandoah_write_barrier_Type() {
475 const Type **fields = TypeTuple::fields(1);
476 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
477 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
478
479 // create result type (range)
480 fields = TypeTuple::fields(1);
481 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
482 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
483
484 return TypeFunc::make(domain, range);
485 }
486
487 Node* ShenandoahBarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue& val) const {
488 DecoratorSet decorators = access.decorators();
489
490 const TypePtr* adr_type = access.addr().type();
491 Node* adr = access.addr().node();
492
493 bool anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0;
494 bool on_heap = (decorators & IN_HEAP) != 0;
|
277 } __ end_if(); // (!index)
278 } __ end_if(); // (pre_val != NULL)
279 } __ end_if(); // (!marking)
280
281 // Final sync IdealKit and GraphKit.
282 kit->final_sync(ideal);
283
284 if (ShenandoahSATBBarrier && adr != NULL) {
285 Node* c = kit->control();
286 Node* call = c->in(1)->in(1)->in(1)->in(0);
287 assert(is_shenandoah_wb_pre_call(call), "shenandoah_wb_pre call expected");
288 call->add_req(adr);
289 }
290 }
291
292 bool ShenandoahBarrierSetC2::is_shenandoah_wb_pre_call(Node* call) {
293 return call->is_CallLeaf() &&
294 call->as_CallLeaf()->entry_point() == CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry);
295 }
296
297 bool ShenandoahBarrierSetC2::is_shenandoah_lrb_call(Node* call) {
298 return call->is_CallLeaf() &&
299 call->as_CallLeaf()->entry_point() == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_JRT);
300 }
301
302 bool ShenandoahBarrierSetC2::is_shenandoah_marking_if(PhaseTransform *phase, Node* n) {
303 if (n->Opcode() != Op_If) {
304 return false;
305 }
306
307 Node* bol = n->in(1);
308 assert(bol->is_Bool(), "");
309 Node* cmpx = bol->in(1);
310 if (bol->as_Bool()->_test._test == BoolTest::ne &&
311 cmpx->is_Cmp() && cmpx->in(2) == phase->intcon(0) &&
312 is_shenandoah_state_load(cmpx->in(1)->in(1)) &&
313 cmpx->in(1)->in(2)->is_Con() &&
314 cmpx->in(1)->in(2) == phase->intcon(ShenandoahHeap::MARKING)) {
315 return true;
316 }
317
454
455 // create result type (range)
456 fields = TypeTuple::fields(0);
457 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
458
459 return TypeFunc::make(domain, range);
460 }
461
462 const TypeFunc* ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type() {
463 const Type **fields = TypeTuple::fields(1);
464 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
465 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
466
467 // create result type (range)
468 fields = TypeTuple::fields(0);
469 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
470
471 return TypeFunc::make(domain, range);
472 }
473
474 const TypeFunc* ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type() {
475 const Type **fields = TypeTuple::fields(1);
476 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
477 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
478
479 // create result type (range)
480 fields = TypeTuple::fields(1);
481 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
482 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
483
484 return TypeFunc::make(domain, range);
485 }
486
487 Node* ShenandoahBarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue& val) const {
488 DecoratorSet decorators = access.decorators();
489
490 const TypePtr* adr_type = access.addr().type();
491 Node* adr = access.addr().node();
492
493 bool anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0;
494 bool on_heap = (decorators & IN_HEAP) != 0;
|