Revision: 5231
Author: [email protected]
Date: Tue Aug 10 05:30:14 2010
Log: Fix fuzzer-found error where left and right were the same register in
bitops.
Review URL: http://codereview.chromium.org/3115004
http://code.google.com/p/v8/source/detail?r=5231
Added:
/branches/bleeding_edge/test/mjsunit/regress/bitops-register-alias.js
Modified:
/branches/bleeding_edge/src/ia32/codegen-ia32.cc
/branches/bleeding_edge/src/ia32/virtual-frame-ia32.h
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/regress/bitops-register-alias.js
Tue Aug 10 05:30:14 2010
@@ -0,0 +1,31 @@
+// Copyright 2010 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.
+
+// Test that the code generator can cope with left and right being in
+// the same register for bitops.
+function f() { for (var i = 10; i < 100; i++) { return i | i; } }
+assertEquals(10, f());
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Mon Aug 9 07:54:23
2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Tue Aug 10 05:30:14
2010
@@ -1055,6 +1055,7 @@
: op_(op), dst_(dst), left_(left), right_(right),
left_info_(left_info), right_info_(right_info), mode_(mode) {
set_comment("[ DeferredInlineBinaryOperation");
+ ASSERT(!left.is(right));
}
virtual void Generate();
@@ -1844,16 +1845,15 @@
frame_->Spill(eax);
frame_->Spill(edx);
// DeferredInlineBinaryOperation requires all the registers that it is
- // told about to be spilled.
- frame_->Spill(left->reg());
- frame_->Spill(right->reg());
+ // told about to be spilled and distinct.
+ Result distinct_right = frame_->MakeDistinctAndSpilled(left, right);
// Check that left and right are smi tagged.
DeferredInlineBinaryOperation* deferred =
new DeferredInlineBinaryOperation(op,
(op == Token::DIV) ? eax : edx,
left->reg(),
- right->reg(),
+ distinct_right.reg(),
left_type_info,
right_type_info,
overwrite_mode);
@@ -1946,7 +1946,8 @@
// We will modify right, it must be spilled.
frame_->Spill(ecx);
// DeferredInlineBinaryOperation requires all the registers that it is
told
- // about to be spilled.
+ // about to be spilled and distinct. We know that right is ecx and
left is
+ // not ecx.
frame_->Spill(left->reg());
// Use a fresh answer register to avoid spilling the left operand.
@@ -2021,8 +2022,7 @@
right->ToRegister();
// DeferredInlineBinaryOperation requires all the registers that it is
told
// about to be spilled.
- frame_->Spill(left->reg());
- frame_->Spill(right->reg());
+ Result distinct_right = frame_->MakeDistinctAndSpilled(left, right);
// A newly allocated register answer is used to hold the answer. The
// registers containing left and right are not modified so they don't
// need to be spilled in the fast case.
@@ -2034,7 +2034,7 @@
new DeferredInlineBinaryOperation(op,
answer.reg(),
left->reg(),
- right->reg(),
+ distinct_right.reg(),
left_type_info,
right_type_info,
overwrite_mode);
=======================================
--- /branches/bleeding_edge/src/ia32/virtual-frame-ia32.h Mon Jun 7
01:27:32 2010
+++ /branches/bleeding_edge/src/ia32/virtual-frame-ia32.h Tue Aug 10
05:30:14 2010
@@ -138,6 +138,22 @@
void Spill(Register reg) {
if (is_used(reg)) SpillElementAt(register_location(reg));
}
+
+ // Make the two registers distinct and spill them. Returns the second
+ // register. If the registers were not distinct then it returns the new
+ // second register.
+ Result MakeDistinctAndSpilled(Result* left, Result* right) {
+ Spill(left->reg());
+ Spill(right->reg());
+ if (left->reg().is(right->reg())) {
+ RegisterAllocator* allocator = cgen()->allocator();
+ Result fresh = allocator->Allocate();
+ ASSERT(fresh.is_valid());
+ masm()->mov(fresh.reg(), right->reg());
+ return fresh;
+ }
+ return *right;
+ }
// Spill all occurrences of an arbitrary register if possible. Return
the
// register spilled or no_reg if it was not possible to free any register
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev