Skip to content

Instantly share code, notes, and snippets.

@shipilev
Created May 10, 2019 18:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shipilev/43dc2ce3259481b32a41f83cd3c69afa to your computer and use it in GitHub Desktop.
Save shipilev/43dc2ce3259481b32a41f83cd3c69afa to your computer and use it in GitHub Desktop.
void ShenandoahBarrierSetAssembler::resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp) {
assert(ShenandoahCASBarrier || ShenandoahLoadRefBarrier, "should be enabled");
// The below loads the mark word, checks if the lowest two bits are
// set, and if so, clear the lowest two bits and copy the result
// to dst. Otherwise it leaves dst alone.
// Implementing this is surprisingly awkward. I do it here by:
// - Inverting the mark word
// - Test lowest two bits == 0
// - If so, set the lowest two bits
// - Invert the result back, and copy to dst
bool pp = (tmp == noreg);
if (pp) {
// No free registers available. Make one useful.
tmp = rscratch1;
__ push(tmp);
}
Label done;
__ movptr(tmp, Address(dst, oopDesc::mark_offset_in_bytes()));
__ notptr(tmp);
__ testb(tmp, markOopDesc::marked_value);
__ jccb(Assembler::notZero, done);
__ orptr(tmp, markOopDesc::marked_value);
__ notptr(tmp);
__ mov(dst, tmp);
__ bind(done);
if (pp) {
__ pop(tmp);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment