ARM/ARM64: Fix smashed CODE_REG in intrinsics with InvokeMathCFunctionInstrs.

X64: Fix smashed ARGS_DESC_REG.

IA32: Remove unnecessary preservation of ICREG.

BUG=http://dartbug.com/26516
R=vegorov@google.com

Review URL: https://codereview.chromium.org/2003403003 .
This commit is contained in:
Ryan Macnak 2016-05-25 10:02:21 -07:00
parent b741e3f0df
commit df4e0d5ac6
10 changed files with 89 additions and 14 deletions

View file

@ -283,7 +283,7 @@ const Register ICREG = R9; // IC data register.
const Register ARGS_DESC_REG = R4;
const Register CODE_REG = R6;
const Register THR = R10; // Caches current thread in generated code.
const Register CALLEE_SAVED_TEMP = R6;
const Register CALLEE_SAVED_TEMP = R8;
// R15 encodes APSR in the vmrs instruction.
const Register APSR = R15;

View file

@ -93,7 +93,7 @@ const Register ICREG = RBX; // IC data register.
const Register ARGS_DESC_REG = R10; // Arguments descriptor register.
const Register CODE_REG = R12;
const Register THR = R14; // Caches current thread in generated code.
const Register CALLEE_SAVED_TEMP = R13;
const Register CALLEE_SAVED_TEMP = RBX;
// Exception object is passed in this register to the catch handlers when an
// exception is thrown.

View file

@ -5186,6 +5186,8 @@ LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(Zone* zone,
(recognized_kind() == MethodRecognizer::kMathDoublePow) ? 3 : 1;
LocationSummary* result = new(zone) LocationSummary(
zone, InputCount(), kNumTemps, LocationSummary::kCall);
ASSERT(R13 != CALLEE_SAVED_TEMP);
ASSERT(((1 << R13) & CallingConventions::kCalleeSaveCpuRegisters) != 0);
result->set_temp(0, Location::RegisterLocation(R13));
result->set_in(0, Location::FpuRegisterLocation(XMM2));
if (InputCount() == 2) {

View file

@ -33,7 +33,16 @@ namespace dart {
intptr_t Intrinsifier::ParameterSlotFromSp() { return -1; }
static bool IsABIPreservedRegister(Register reg) {
return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
}
void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
ASSERT(IsABIPreservedRegister(CODE_REG));
ASSERT(IsABIPreservedRegister(ARGS_DESC_REG));
ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
// Save LR by moving it to a callee saved temporary register.
assembler->Comment("IntrinsicCallPrologue");
assembler->mov(CALLEE_SAVED_TEMP, Operand(LR));

View file

@ -32,17 +32,31 @@ namespace dart {
intptr_t Intrinsifier::ParameterSlotFromSp() { return -1; }
static bool IsABIPreservedRegister(Register reg) {
return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
}
void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
ASSERT(IsABIPreservedRegister(CODE_REG));
ASSERT(!IsABIPreservedRegister(ARGS_DESC_REG));
ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP2));
ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
ASSERT(CALLEE_SAVED_TEMP2 != CODE_REG);
ASSERT(CALLEE_SAVED_TEMP2 != ARGS_DESC_REG);
assembler->Comment("IntrinsicCallPrologue");
assembler->mov(CALLEE_SAVED_TEMP, LR);
assembler->mov(CALLEE_SAVED_TEMP2, R4);
assembler->mov(CALLEE_SAVED_TEMP2, ARGS_DESC_REG);
}
void Intrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
assembler->Comment("IntrinsicCallEpilogue");
assembler->mov(LR, CALLEE_SAVED_TEMP);
assembler->mov(R4, CALLEE_SAVED_TEMP2);
assembler->mov(ARGS_DESC_REG, CALLEE_SAVED_TEMP2);
}

View file

@ -41,16 +41,16 @@ intptr_t Intrinsifier::ParameterSlotFromSp() { return 0; }
void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
COMPILE_ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
assembler->Comment("IntrinsicCallPrologue");
assembler->movl(CALLEE_SAVED_TEMP, ICREG);
assembler->movl(CALLEE_SAVED_TEMP2, ARGS_DESC_REG);
assembler->movl(CALLEE_SAVED_TEMP, ARGS_DESC_REG);
}
void Intrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
assembler->Comment("IntrinsicCallEpilogue");
assembler->movl(ICREG, CALLEE_SAVED_TEMP);
assembler->movl(ARGS_DESC_REG, CALLEE_SAVED_TEMP2);
assembler->movl(ARGS_DESC_REG, CALLEE_SAVED_TEMP);
}

View file

@ -32,15 +32,25 @@ namespace dart {
intptr_t Intrinsifier::ParameterSlotFromSp() { return -1; }
static bool IsABIPreservedRegister(Register reg) {
return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
}
void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
ASSERT(IsABIPreservedRegister(CODE_REG));
ASSERT(IsABIPreservedRegister(ARGS_DESC_REG));
ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
assembler->Comment("IntrinsicCallPrologue");
assembler->mov(CALLEE_SAVED_TEMP, RA);
assembler->mov(CALLEE_SAVED_TEMP, LRREG);
}
void Intrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
assembler->Comment("IntrinsicCallEpilogue");
assembler->mov(RA, CALLEE_SAVED_TEMP);
assembler->mov(LRREG, CALLEE_SAVED_TEMP);
}

View file

@ -32,15 +32,26 @@ namespace dart {
intptr_t Intrinsifier::ParameterSlotFromSp() { return 0; }
static bool IsABIPreservedRegister(Register reg) {
return ((1 << reg) & CallingConventions::kCalleeSaveCpuRegisters) != 0;
}
void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
ASSERT(IsABIPreservedRegister(CODE_REG));
ASSERT(!IsABIPreservedRegister(ARGS_DESC_REG));
ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
assembler->Comment("IntrinsicCallPrologue");
assembler->movq(CALLEE_SAVED_TEMP, R10);
assembler->movq(CALLEE_SAVED_TEMP, ARGS_DESC_REG);
}
void Intrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
assembler->Comment("IntrinsicCallEpilogue");
assembler->movq(R10, CALLEE_SAVED_TEMP);
assembler->movq(ARGS_DESC_REG, CALLEE_SAVED_TEMP);
}

View file

@ -52,14 +52,20 @@ void RuntimeEntry::Call(Assembler* assembler, intptr_t argument_count) const {
// We cache the Dart stack pointer and the stack limit in callee-saved
// registers, then align and call, restoring CSP and SP on return from the
// call.
__ mov(R24, CSP);
// This sequence may occur in an intrinsic, so don't use registers an
// intrinsic must preserve.
COMPILE_ASSERT(R23 != CODE_REG);
COMPILE_ASSERT(R25 != CODE_REG);
COMPILE_ASSERT(R23 != ARGS_DESC_REG);
COMPILE_ASSERT(R25 != ARGS_DESC_REG);
__ mov(R23, CSP);
__ mov(R25, SP);
__ ReserveAlignedFrameSpace(0);
__ mov(CSP, SP);
__ ldr(TMP, Address(THR, Thread::OffsetFromThread(this)));
__ blr(TMP);
__ mov(SP, R25);
__ mov(CSP, R24);
__ mov(CSP, R23);
} else {
// Argument count is not checked here, but in the runtime entry for a more
// informative error message.

View file

@ -0,0 +1,23 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// VMOptions=--optimization-counter-threshold=-1 --new_gen_semi_max_size=2
import 'dart:math';
main() {
// 2MB / 16 bytes = 125000 allocations
for (var i = 0; i < 500000; i++) {
sin(i);
}
for (var i = 0; i < 500000; i++) {
cos(i);
}
for (var i = 0; i < 500000; i++) {
i.toDouble().truncateToDouble();
}
}