RFR: 8374828: Save load_barrier_on_oop_field_preloaded in aot CodeCache

Stefan Karlsson stefank at openjdk.org
Mon Jan 12 14:27:53 UTC 2026


On Mon, 12 Jan 2026 14:05:38 GMT, Andrew Dinn <adinn at openjdk.org> wrote:

> Are you saying that for this specific flag combination the code generated by ZBarrierSetAssembler::load_at as currently implemented in mainline is more than just a simple load? 

Yes, that's what I'm trying to say.

If we follow the `ZBarrierSetAssembler::load_at` we see the call: `    __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), 2);`

```void ZBarrierSetAssembler::load_at(MacroAssembler* masm,
                                   DecoratorSet decorators,
                                   BasicType type,
                                   Register dst,
                                   Address src,
                                   Register tmp1,
                                   Register tmp2) {
  if (!ZBarrierSet::barrier_needed(decorators, type)) {
    // Barrier not needed
    BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp2);
    return;
  }

  assert_different_registers(tmp1, tmp2, src.base(), noreg);
  assert_different_registers(tmp1, tmp2, src.index());
  assert_different_registers(tmp1, tmp2, dst, noreg);
  assert_different_registers(tmp2, rscratch1);

  Label done;
  Label uncolor;

  // Load bad mask into scratch register.
  const bool on_non_strong =
    (decorators & ON_WEAK_OOP_REF) != 0 ||
    (decorators & ON_PHANTOM_OOP_REF) != 0;

  if (on_non_strong) {
    __ ldr(tmp1, mark_bad_mask_from_thread(rthread));
  } else {
    __ ldr(tmp1, load_bad_mask_from_thread(rthread));
  }

  __ lea(tmp2, src);
  __ ldr(dst, tmp2);

  // Test reference against bad mask. If mask bad, then we need to fix it up.
  __ tst(dst, tmp1);
  __ br(Assembler::EQ, uncolor);

  {
    // Call VM
    ZRuntimeCallSpill rcs(masm, dst);

    if (c_rarg0 != dst) {
      __ mov(c_rarg0, dst);
    }
    __ mov(c_rarg1, tmp2);

    __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), 2);
  }


> If so then this would mean that the assumption made above has been weakened and that an AOT cache generated with ZGC enabled can only be used in a production run using ZGC and vice versa.

OK. Maybe @fisk has thought about this in the context of Leyden?

-------------

PR Comment: https://git.openjdk.org/jdk/pull/29129#issuecomment-3738806713


More information about the hotspot-compiler-dev mailing list