Skip to content

Commit

Permalink
[vm, compiler] Make register allocator instead of assembler put the w…
Browse files Browse the repository at this point in the history
…rite barrier value into a fixed register.

Unlike the assembler, the register allocator is in a position to avoid a move. Use the call result register since it is the most popular value source.

This pattern will also be needed to get the write barrier slot into a fixed register for card-marking, since X64 and ARM don't have a TMP2.

dart2js aot product:
X64 Instructions(CodeSize): 9049952 -> 8994240 (-0.62%)
ARM Instructions(CodeSize): 9772096 -> 9711696 (-0.62%)
ARM64 Instructions(CodeSize): 10185056 -> 10122496 (-0.61%)

Bug: dart-lang/sdk#34002
Change-Id: Id2e9dd7b3d86069a9da3ba4e141720511ce6399e
Reviewed-on: https://dart-review.googlesource.com/76307
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
  • Loading branch information
rmacnak-google authored and commit-bot@chromium.org committed Sep 26, 2018
1 parent 2f25dcd commit 808ed62
Show file tree
Hide file tree
Showing 14 changed files with 205 additions and 111 deletions.
39 changes: 32 additions & 7 deletions runtime/vm/compiler/assembler/assembler_arm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1615,9 +1615,34 @@ void Assembler::StoreIntoObject(Register object,
and_(TMP, LR, Operand(TMP, LSR, RawObject::kBarrierOverlapShift));
ldr(LR, Address(THR, Thread::write_barrier_mask_offset()));
tst(TMP, Operand(LR));
mov(TMP, Operand(value), NE);
ldr(LR, Address(THR, Thread::write_barrier_wrappers_offset(object)), NE);
blx(LR, NE);
if (value != kWriteBarrierValueReg) {
// Unlikely. Only non-graph intrinsics.
// TODO(rmacnak): Shuffle registers in intrinsics.
Label restore_and_done;
b(&restore_and_done, ZERO);
Register objectForCall = object;
if (object != kWriteBarrierValueReg) {
Push(kWriteBarrierValueReg);
} else {
COMPILE_ASSERT(R2 != kWriteBarrierValueReg);
COMPILE_ASSERT(R3 != kWriteBarrierValueReg);
objectForCall = (value == R2) ? R3 : R2;
PushList((1 << kWriteBarrierValueReg) | (1 << objectForCall));
mov(objectForCall, Operand(object));
}
mov(kWriteBarrierValueReg, Operand(value));
ldr(LR, Address(THR, Thread::write_barrier_wrappers_offset(objectForCall)));
blx(LR);
if (object != kWriteBarrierValueReg) {
Pop(kWriteBarrierValueReg);
} else {
PopList((1 << kWriteBarrierValueReg) | (1 << objectForCall));
}
Bind(&restore_and_done);
} else {
ldr(LR, Address(THR, Thread::write_barrier_wrappers_offset(object)), NE);
blx(LR, NE);
}
if (!lr_reserved) Pop(LR);
Bind(&done);
#else
Expand All @@ -1632,12 +1657,12 @@ void Assembler::StoreIntoObject(Register object,
StoreIntoObjectFilter(object, value, &done, can_be_smi, kJumpToNoUpdate);
RegList regs = 0;
regs |= (1 << LR);
if (value != R0) {
regs |= (1 << R0); // Preserve R0.
if (value != kWriteBarrierObjectReg) {
regs |= (1 << kWriteBarrierObjectReg);
}
PushList(regs);
if (object != R0) {
mov(R0, Operand(object));
if (object != kWriteBarrierObjectReg) {
mov(kWriteBarrierObjectReg, Operand(object));
}
ldr(LR, Address(THR, Thread::write_barrier_entry_point_offset()));
blx(LR);
Expand Down
27 changes: 24 additions & 3 deletions runtime/vm/compiler/assembler/assembler_arm64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1004,12 +1004,33 @@ void Assembler::StoreIntoObject(Register object,
ldr(TMP2, FieldAddress(value, Object::tags_offset()), kUnsignedByte);
and_(TMP, TMP2, Operand(TMP, LSR, RawObject::kBarrierOverlapShift));
tst(TMP, Operand(BARRIER_MASK));
b(&done, EQ);
b(&done, ZERO);

if (!lr_reserved) Push(LR);
mov(TMP2, value);
ldr(LR, Address(THR, Thread::write_barrier_wrappers_offset(object)));
Register objectForCall = object;
if (value != kWriteBarrierValueReg) {
// Unlikely. Only non-graph intrinsics.
// TODO(rmacnak): Shuffle registers in intrinsics.
if (object != kWriteBarrierValueReg) {
Push(kWriteBarrierValueReg);
} else {
COMPILE_ASSERT(R2 != kWriteBarrierValueReg);
COMPILE_ASSERT(R3 != kWriteBarrierValueReg);
objectForCall = (value == R2) ? R3 : R2;
PushPair(kWriteBarrierValueReg, objectForCall);
mov(objectForCall, object);
}
mov(kWriteBarrierValueReg, value);
}
ldr(LR, Address(THR, Thread::write_barrier_wrappers_offset(objectForCall)));
blr(LR);
if (value != kWriteBarrierValueReg) {
if (object != kWriteBarrierValueReg) {
Pop(kWriteBarrierValueReg);
} else {
PopPair(kWriteBarrierValueReg, objectForCall);
}
}
if (!lr_reserved) Pop(LR);
Bind(&done);
#else
Expand Down
24 changes: 22 additions & 2 deletions runtime/vm/compiler/assembler/assembler_x64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1298,8 +1298,28 @@ void Assembler::StoreIntoObject(Register object,
andl(TMP, Address(THR, Thread::write_barrier_mask_offset()));
testb(FieldAddress(value, Object::tags_offset()), TMP);
j(ZERO, &done, kNearJump);
movq(TMP, value);
call(Address(THR, Thread::write_barrier_wrappers_offset(object)));

Register objectForCall = object;
if (value != kWriteBarrierValueReg) {
// Unlikely. Only non-graph intrinsics.
// TODO(rmacnak): Shuffle registers in intrinsics.
pushq(kWriteBarrierValueReg);
if (object == kWriteBarrierValueReg) {
COMPILE_ASSERT(RBX != kWriteBarrierValueReg);
COMPILE_ASSERT(RCX != kWriteBarrierValueReg);
objectForCall = (value == RBX) ? RCX : RBX;
pushq(objectForCall);
movq(objectForCall, object);
}
movq(kWriteBarrierValueReg, value);
}
call(Address(THR, Thread::write_barrier_wrappers_offset(objectForCall)));
if (value != kWriteBarrierValueReg) {
if (object == kWriteBarrierValueReg) {
popq(objectForCall);
}
popq(kWriteBarrierValueReg);
}
Bind(&done);
#else
movq(dest, value);
Expand Down
10 changes: 8 additions & 2 deletions runtime/vm/compiler/backend/il_arm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1523,9 +1523,15 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,

switch (class_id()) {
case kArrayCid:
#if defined(CONCURRENT_MARKING)
locs->set_in(2, ShouldEmitStoreBarrier()
? Location::RegisterLocation(kWriteBarrierValueReg)
: Location::RegisterOrConstant(value()));
#else
locs->set_in(2, ShouldEmitStoreBarrier()
? Location::WritableRegister()
: Location::RegisterOrConstant(value()));
#endif
break;
case kExternalTypedDataUint8ArrayCid:
case kExternalTypedDataUint8ClampedArrayCid:
Expand Down Expand Up @@ -2212,7 +2218,7 @@ LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Zone* zone,
} else {
#if defined(CONCURRENT_MARKING)
summary->set_in(1, ShouldEmitStoreBarrier()
? Location::RequiresRegister()
? Location::RegisterLocation(kWriteBarrierValueReg)
: Location::RegisterOrConstant(value()));
#else
summary->set_in(1, ShouldEmitStoreBarrier()
Expand Down Expand Up @@ -2426,7 +2432,7 @@ LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(Zone* zone,
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
#if defined(CONCURRENT_MARKING)
locs->set_in(0, Location::RequiresRegister());
locs->set_in(0, Location::RegisterLocation(kWriteBarrierValueReg));
#else
locs->set_in(0, value()->NeedsWriteBarrier() ? Location::WritableRegister()
: Location::RequiresRegister());
Expand Down
10 changes: 8 additions & 2 deletions runtime/vm/compiler/backend/il_arm64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1366,9 +1366,15 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,
}
switch (class_id()) {
case kArrayCid:
#if defined(CONCURRENT_MARKING)
locs->set_in(2, ShouldEmitStoreBarrier()
? Location::RegisterLocation(kWriteBarrierValueReg)
: Location::RegisterOrConstant(value()));
#else
locs->set_in(2, ShouldEmitStoreBarrier()
? Location::WritableRegister()
: Location::RegisterOrConstant(value()));
#endif
break;
case kExternalTypedDataUint8ArrayCid:
case kExternalTypedDataUint8ClampedArrayCid:
Expand Down Expand Up @@ -1932,7 +1938,7 @@ LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Zone* zone,
} else {
#if defined(CONCURRENT_MARKING)
summary->set_in(1, ShouldEmitStoreBarrier()
? Location::RequiresRegister()
? Location::RegisterLocation(kWriteBarrierValueReg)
: Location::RegisterOrConstant(value()));
#else
summary->set_in(1, ShouldEmitStoreBarrier()
Expand Down Expand Up @@ -2129,7 +2135,7 @@ LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(Zone* zone,
LocationSummary* locs =
new (zone) LocationSummary(zone, 1, 1, LocationSummary::kNoCall);
#if defined(CONCURRENT_MARKING)
locs->set_in(0, Location::RequiresRegister());
locs->set_in(0, Location::RegisterLocation(kWriteBarrierValueReg));
#else
locs->set_in(0, value()->NeedsWriteBarrier() ? Location::WritableRegister()
: Location::RequiresRegister());
Expand Down
10 changes: 8 additions & 2 deletions runtime/vm/compiler/backend/il_x64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1405,9 +1405,15 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,
}
switch (class_id()) {
case kArrayCid:
#if defined(CONCURRENT_MARKING)
locs->set_in(2, ShouldEmitStoreBarrier()
? Location::RegisterLocation(kWriteBarrierValueReg)
: Location::RegisterOrConstant(value()));
#else
locs->set_in(2, ShouldEmitStoreBarrier()
? Location::WritableRegister()
: Location::RegisterOrConstant(value()));
#endif
break;
case kExternalTypedDataUint8ArrayCid:
case kExternalTypedDataUint8ClampedArrayCid:
Expand Down Expand Up @@ -1921,7 +1927,7 @@ LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Zone* zone,
} else {
#if defined(CONCURRENT_MARKING)
summary->set_in(1, ShouldEmitStoreBarrier()
? Location::RequiresRegister()
? Location::RegisterLocation(kWriteBarrierValueReg)
: Location::RegisterOrConstant(value()));
#else
summary->set_in(1, ShouldEmitStoreBarrier()
Expand Down Expand Up @@ -2130,7 +2136,7 @@ LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(Zone* zone,
LocationSummary* locs =
new (zone) LocationSummary(zone, 1, 1, LocationSummary::kNoCall);
#if defined(CONCURRENT_MARKING)
locs->set_in(0, Location::RequiresRegister());
locs->set_in(0, Location::RegisterLocation(kWriteBarrierValueReg));
#else
locs->set_in(0, value()->NeedsWriteBarrier() ? Location::WritableRegister()
: Location::RequiresRegister());
Expand Down
10 changes: 5 additions & 5 deletions runtime/vm/constants_arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,14 +276,14 @@ const Register CALLEE_SAVED_TEMP = R8;
// R15 encodes APSR in the vmrs instruction.
const Register APSR = R15;

// Exception object is passed in this register to the catch handlers when an
// exception is thrown.
// ABI for catch-clause entry point.
const Register kExceptionObjectReg = R0;

// Stack trace object is passed in this register to the catch handlers when
// an exception is thrown.
const Register kStackTraceObjectReg = R1;

// ABI for write barrier stub.
const Register kWriteBarrierObjectReg = R1;
const Register kWriteBarrierValueReg = R0;

// List of registers used in load/store multiple.
typedef uint16_t RegList;
const RegList kAllCpuRegistersList = 0xFFFF;
Expand Down
10 changes: 5 additions & 5 deletions runtime/vm/constants_arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,14 @@ const Register CALLEE_SAVED_TEMP = R19;
const Register CALLEE_SAVED_TEMP2 = R20;
const Register BARRIER_MASK = R28;

// Exception object is passed in this register to the catch handlers when an
// exception is thrown.
// ABI for catch-clause entry point.
const Register kExceptionObjectReg = R0;

// Stack trace object is passed in this register to the catch handlers when
// an exception is thrown.
const Register kStackTraceObjectReg = R1;

// ABI for write barrier stub.
const Register kWriteBarrierObjectReg = R1;
const Register kWriteBarrierValueReg = R0;

// Masks, sizes, etc.
const int kXRegSizeInBits = 64;
const int kWRegSizeInBits = 32;
Expand Down
10 changes: 5 additions & 5 deletions runtime/vm/constants_ia32.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ const Register THR = ESI; // Caches current thread in generated code.
const Register CALLEE_SAVED_TEMP = EBX;
const Register CALLEE_SAVED_TEMP2 = EDI;

// Exception object is passed in this register to the catch handlers when an
// exception is thrown.
// ABI for catch-clause entry point.
const Register kExceptionObjectReg = EAX;

// Stack trace object is passed in this register to the catch handlers when
// an exception is thrown.
const Register kStackTraceObjectReg = EDX;

// ABI for write barrier stub.
const Register kWriteBarrierObjectReg = EDX;
const Register kWriteBarrierValueReg = kNoRegister;

typedef uint32_t RegList;
const RegList kAllCpuRegistersList = 0xFF;

Expand Down
10 changes: 5 additions & 5 deletions runtime/vm/constants_x64.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,14 @@ const Register CODE_REG = R12;
const Register THR = R14; // Caches current thread in generated code.
const Register CALLEE_SAVED_TEMP = RBX;

// Exception object is passed in this register to the catch handlers when an
// exception is thrown.
// ABI for catch-clause entry point.
const Register kExceptionObjectReg = RAX;

// Stack trace object is passed in this register to the catch handlers when
// an exception is thrown.
const Register kStackTraceObjectReg = RDX;

// ABI for write barrier stub.
const Register kWriteBarrierObjectReg = RDX;
const Register kWriteBarrierValueReg = RAX;

typedef uint32_t RegList;
const RegList kAllCpuRegistersList = 0xFFFF;
const RegList kAllFpuRegistersList = 0xFFFF;
Expand Down
Loading

0 comments on commit 808ed62

Please sign in to comment.