mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 20:51:19 +00:00
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:
parent
b741e3f0df
commit
df4e0d5ac6
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
23
tests/lib/math/call_cmath_box_failure_path_test.dart
Normal file
23
tests/lib/math/call_cmath_box_failure_path_test.dart
Normal 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();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue