449 }
450 }
451
452 void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, Register dst) {
453 if (ShenandoahLoadRefBarrier) {
454 Label done;
455 __ testptr(dst, dst);
456 __ jcc(Assembler::zero, done);
457 load_reference_barrier_not_null(masm, dst);
458 __ bind(done);
459 }
460 }
461
462 void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
463 Register dst, Address src, Register tmp1, Register tmp_thread) {
464 bool on_oop = type == T_OBJECT || type == T_ARRAY;
465 bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
466 bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
467 bool not_in_heap = (decorators & IN_NATIVE) != 0;
468 bool on_reference = on_weak || on_phantom;
469 bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0;
470
471 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
472 if (on_oop) {
473 if (not_in_heap) {
474 if (ShenandoahHeap::heap()->is_traversal_mode()) {
475 load_reference_barrier(masm, dst);
476 keep_alive = true;
477 } else {
478 load_reference_barrier_native(masm, dst);
479 }
480 } else {
481 load_reference_barrier(masm, dst);
482 }
483
484 if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) {
485 const Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
486 assert_different_registers(dst, tmp1, tmp_thread);
487 NOT_LP64(__ get_thread(thread));
488 // Generate the SATB pre-barrier code to log the value of
489 // the referent field in an SATB buffer.
490 shenandoah_write_barrier_pre(masm /* masm */,
491 noreg /* obj */,
492 dst /* pre_val */,
493 thread /* thread */,
494 tmp1 /* tmp */,
495 true /* tosca_live */,
496 true /* expand_call */);
497 }
498 }
499 }
|
449 }
450 }
451
452 void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, Register dst) {
453 if (ShenandoahLoadRefBarrier) {
454 Label done;
455 __ testptr(dst, dst);
456 __ jcc(Assembler::zero, done);
457 load_reference_barrier_not_null(masm, dst);
458 __ bind(done);
459 }
460 }
461
462 void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
463 Register dst, Address src, Register tmp1, Register tmp_thread) {
464 bool on_oop = type == T_OBJECT || type == T_ARRAY;
465 bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
466 bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
467 bool not_in_heap = (decorators & IN_NATIVE) != 0;
468 bool on_reference = on_weak || on_phantom;
469 bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode();
470 bool keep_alive = ((decorators & AS_NO_KEEPALIVE) == 0) || is_traversal_mode;
471
472 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
473 if (on_oop) {
474 if (not_in_heap && !is_traversal_mode) {
475 load_reference_barrier_native(masm, dst);
476 } else {
477 load_reference_barrier(masm, dst);
478 }
479
480 if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) {
481 const Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
482 assert_different_registers(dst, tmp1, tmp_thread);
483 NOT_LP64(__ get_thread(thread));
484 // Generate the SATB pre-barrier code to log the value of
485 // the referent field in an SATB buffer.
486 shenandoah_write_barrier_pre(masm /* masm */,
487 noreg /* obj */,
488 dst /* pre_val */,
489 thread /* thread */,
490 tmp1 /* tmp */,
491 true /* tosca_live */,
492 true /* expand_call */);
493 }
494 }
495 }
|