Fix fuzzer-found error where left and right were the same register in bitops.

Review URL: http://codereview.chromium.org/3115004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5231 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
erik.corry@gmail.com 2010-08-10 12:30:14 +00:00
parent 4bbf058d53
commit bdfdf8bee9
3 changed files with 55 additions and 8 deletions

View File

@ -1055,6 +1055,7 @@ class DeferredInlineBinaryOperation: public DeferredCode {
: 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 @@ Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr,
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 @@ Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr,
// 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 @@ Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr,
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 @@ Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr,
new DeferredInlineBinaryOperation(op,
answer.reg(),
left->reg(),
right->reg(),
distinct_right.reg(),
left_type_info,
right_type_info,
overwrite_mode);

View File

@ -139,6 +139,22 @@ class VirtualFrame: public ZoneObject {
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
// (ie, they all have frame-external references).

View File

@ -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());