Revision: 13634
Author: [email protected]
Date: Mon Feb 11 01:00:07 2013
Log: Merged r13617, r13622 into trunk branch.
Fix DoubleStackSlot-to-DoubleStackSlot moves on ia32. Unify
platform-independent code.
Add regression test for r13617
BUG=173907,173907
[email protected]
Review URL: https://codereview.chromium.org/12210108
http://code.google.com/p/v8/source/detail?r=13634
Added:
/trunk/test/mjsunit/regress/regress-crbug-173907.js
Modified:
/trunk/src/arm/lithium-codegen-arm.cc
/trunk/src/ia32/lithium-codegen-ia32.cc
/trunk/src/lithium.cc
/trunk/src/lithium.h
/trunk/src/mips/lithium-codegen-mips.cc
/trunk/src/version.cc
/trunk/src/x64/lithium-codegen-x64.cc
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-crbug-173907.js Mon Feb 11 01:00:07
2013
@@ -0,0 +1,88 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+var X = 1.1;
+var K = 0.5;
+
+var O = 0;
+var result = new Float64Array(2);
+
+function spill() {
+ try { } catch (e) { }
+}
+
+function buggy() {
+ var v = X;
+ var phi1 = v + K;
+ var phi2 = v - K;
+
+ spill(); // At this point initial values for phi1 and phi2 are spilled.
+
+ var xmm1 = v;
+ var xmm2 = v*v*v;
+ var xmm3 = v*v*v*v;
+ var xmm4 = v*v*v*v*v;
+ var xmm5 = v*v*v*v*v*v;
+ var xmm6 = v*v*v*v*v*v*v;
+ var xmm7 = v*v*v*v*v*v*v*v;
+ var xmm8 = v*v*v*v*v*v*v*v*v;
+
+ // All registers are blocked and phis for phi1 and phi2 are spilled
because
+ // their left (incoming) value is spilled, there are no free registers,
+ // and phis themselves have only ANY-policy uses.
+
+ for (var x = 0; x < 2; x++) {
+ xmm1 += xmm1 * xmm6;
+ xmm2 += xmm1 * xmm5;
+ xmm3 += xmm1 * xmm4;
+ xmm4 += xmm1 * xmm3;
+ xmm5 += xmm1 * xmm2;
+
+ // Now swap values of phi1 and phi2 to create cycle between phis.
+ var t = phi1;
+ phi1 = phi2;
+ phi2 = t;
+ }
+
+ // Now we want to get values of phi1 and phi2. However we would like to
+ // do it in a way that does not produce any uses of phi1&phi2 that have
+ // a register beneficial policy. How? We just hide these uses behind
phis.
+ result[0] = (O === 0) ? phi1 : phi2;
+ result[1] = (O !== 0) ? phi1 : phi2;
+}
+
+function test() {
+ buggy();
+ assertArrayEquals([X + K, X - K], result);
+}
+
+test();
+test();
+%OptimizeFunctionOnNextCall(buggy);
+test();
=======================================
--- /trunk/src/arm/lithium-codegen-arm.cc Mon Feb 4 05:33:20 2013
+++ /trunk/src/arm/lithium-codegen-arm.cc Mon Feb 11 01:00:07 2013
@@ -568,30 +568,13 @@
ASSERT(!op->IsRegister());
ASSERT(!op->IsDoubleRegister());
ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot());
- int index = op->index();
- if (index >= 0) {
- // Local or spill slot. Skip the frame pointer, function, and
- // context in the fixed part of the frame.
- return MemOperand(fp, -(index + 3) * kPointerSize);
- } else {
- // Incoming parameter. Skip the return address.
- return MemOperand(fp, -(index - 1) * kPointerSize);
- }
+ return MemOperand(fp, StackSlotOffset(op->index()));
}
MemOperand LCodeGen::ToHighMemOperand(LOperand* op) const {
ASSERT(op->IsDoubleStackSlot());
- int index = op->index();
- if (index >= 0) {
- // Local or spill slot. Skip the frame pointer, function, context,
- // and the first word of the double in the fixed part of the frame.
- return MemOperand(fp, -(index + 3) * kPointerSize + kPointerSize);
- } else {
- // Incoming parameter. Skip the return address and the first word of
- // the double.
- return MemOperand(fp, -(index - 1) * kPointerSize + kPointerSize);
- }
+ return MemOperand(fp, StackSlotOffset(op->index()) + kPointerSize);
}
=======================================
--- /trunk/src/ia32/lithium-codegen-ia32.cc Mon Feb 4 05:33:20 2013
+++ /trunk/src/ia32/lithium-codegen-ia32.cc Mon Feb 11 01:00:07 2013
@@ -549,23 +549,13 @@
if (op->IsRegister()) return Operand(ToRegister(op));
if (op->IsDoubleRegister()) return Operand(ToDoubleRegister(op));
ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot());
- int index = op->index();
- if (index >= 0) {
- // Local or spill slot. Skip the frame pointer, function, and
- // context in the fixed part of the frame.
- return Operand(ebp, -(index + 3) * kPointerSize);
- } else {
- // Incoming parameter. Skip the return address.
- return Operand(ebp, -(index - 1) * kPointerSize);
- }
+ return Operand(ebp, StackSlotOffset(op->index()));
}
Operand LCodeGen::HighOperand(LOperand* op) {
ASSERT(op->IsDoubleStackSlot());
- int index = op->index();
- int offset = (index >= 0) ? index + 3 : index - 1;
- return Operand(ebp, -offset * kPointerSize);
+ return Operand(ebp, StackSlotOffset(op->index()) + kPointerSize);
}
=======================================
--- /trunk/src/lithium.cc Mon Feb 4 05:33:20 2013
+++ /trunk/src/lithium.cc Mon Feb 11 01:00:07 2013
@@ -255,6 +255,18 @@
UNREACHABLE();
return 0;
}
+
+
+int StackSlotOffset(int index) {
+ if (index >= 0) {
+ // Local or spill slot. Skip the frame pointer, function, and
+ // context in the fixed part of the frame.
+ return -(index + 3) * kPointerSize;
+ } else {
+ // Incoming parameter. Skip the return address.
+ return -(index - 1) * kPointerSize;
+ }
+}
LChunk::LChunk(CompilationInfo* info, HGraph* graph)
=======================================
--- /trunk/src/lithium.h Mon Feb 4 05:33:20 2013
+++ /trunk/src/lithium.h Mon Feb 11 01:00:07 2013
@@ -709,6 +709,7 @@
int ElementsKindToShiftSize(ElementsKind elements_kind);
+int StackSlotOffset(int index);
enum NumberUntagDMode {
NUMBER_CANDIDATE_IS_SMI,
=======================================
--- /trunk/src/mips/lithium-codegen-mips.cc Fri Feb 1 01:06:41 2013
+++ /trunk/src/mips/lithium-codegen-mips.cc Mon Feb 11 01:00:07 2013
@@ -528,30 +528,13 @@
ASSERT(!op->IsRegister());
ASSERT(!op->IsDoubleRegister());
ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot());
- int index = op->index();
- if (index >= 0) {
- // Local or spill slot. Skip the frame pointer, function, and
- // context in the fixed part of the frame.
- return MemOperand(fp, -(index + 3) * kPointerSize);
- } else {
- // Incoming parameter. Skip the return address.
- return MemOperand(fp, -(index - 1) * kPointerSize);
- }
+ return MemOperand(fp, StackSlotOffset(op->index()));
}
MemOperand LCodeGen::ToHighMemOperand(LOperand* op) const {
ASSERT(op->IsDoubleStackSlot());
- int index = op->index();
- if (index >= 0) {
- // Local or spill slot. Skip the frame pointer, function, context,
- // and the first word of the double in the fixed part of the frame.
- return MemOperand(fp, -(index + 3) * kPointerSize + kPointerSize);
- } else {
- // Incoming parameter. Skip the return address and the first word of
- // the double.
- return MemOperand(fp, -(index - 1) * kPointerSize + kPointerSize);
- }
+ return MemOperand(fp, StackSlotOffset(op->index()) + kPointerSize);
}
=======================================
--- /trunk/src/version.cc Wed Feb 6 06:12:58 2013
+++ /trunk/src/version.cc Mon Feb 11 01:00:07 2013
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 16
#define BUILD_NUMBER 14
-#define PATCH_LEVEL 0
+#define PATCH_LEVEL 1
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
=======================================
--- /trunk/src/x64/lithium-codegen-x64.cc Mon Feb 4 05:33:20 2013
+++ /trunk/src/x64/lithium-codegen-x64.cc Mon Feb 11 01:00:07 2013
@@ -464,15 +464,7 @@
// Does not handle registers. In X64 assembler, plain registers are not
// representable as an Operand.
ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot());
- int index = op->index();
- if (index >= 0) {
- // Local or spill slot. Skip the frame pointer, function, and
- // context in the fixed part of the frame.
- return Operand(rbp, -(index + 3) * kPointerSize);
- } else {
- // Incoming parameter. Skip the return address.
- return Operand(rbp, -(index - 1) * kPointerSize);
- }
+ return Operand(rbp, StackSlotOffset(op->index()));
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.