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:
parent
4bbf058d53
commit
bdfdf8bee9
@ -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);
|
||||
|
@ -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).
|
||||
|
31
test/mjsunit/regress/bitops-register-alias.js
Normal file
31
test/mjsunit/regress/bitops-register-alias.js
Normal 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());
|
Loading…
Reference in New Issue
Block a user