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