Fix embedded new-space pointer in LCmpObjectEqAndBranch.
R=mvstanton@chromium.org BUG=chromium:240032 TEST=mjsunit/regress/regress-crbug-240032 Review URL: https://codereview.chromium.org/15779004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14777 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
6a806b9917
commit
8fb2086847
@ -2325,10 +2325,11 @@ void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
|
||||
int true_block = chunk_->LookupDestination(instr->true_block_id());
|
||||
|
||||
if (instr->right()->IsConstantOperand()) {
|
||||
__ cmp(left, ToHandle(LConstantOperand::cast(instr->right())));
|
||||
Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
|
||||
__ CmpObject(left, right);
|
||||
} else {
|
||||
Operand right = ToOperand(instr->right());
|
||||
__ cmp(left, Operand(right));
|
||||
__ cmp(left, right);
|
||||
}
|
||||
EmitBranch(true_block, false_block, equal);
|
||||
}
|
||||
|
@ -2504,6 +2504,18 @@ void MacroAssembler::LoadHeapObject(Register result,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::CmpHeapObject(Register reg, Handle<HeapObject> object) {
|
||||
ALLOW_HANDLE_DEREF(isolate(), "using raw address");
|
||||
if (isolate()->heap()->InNewSpace(*object)) {
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(object);
|
||||
cmp(reg, Operand::Cell(cell));
|
||||
} else {
|
||||
cmp(reg, object);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::PushHeapObject(Handle<HeapObject> object) {
|
||||
ALLOW_HANDLE_DEREF(isolate(), "using raw address");
|
||||
if (isolate()->heap()->InNewSpace(*object)) {
|
||||
|
@ -272,6 +272,7 @@ class MacroAssembler: public Assembler {
|
||||
void LoadFromSafepointRegisterSlot(Register dst, Register src);
|
||||
|
||||
void LoadHeapObject(Register result, Handle<HeapObject> object);
|
||||
void CmpHeapObject(Register reg, Handle<HeapObject> object);
|
||||
void PushHeapObject(Handle<HeapObject> object);
|
||||
|
||||
void LoadObject(Register result, Handle<Object> object) {
|
||||
@ -283,6 +284,15 @@ class MacroAssembler: public Assembler {
|
||||
}
|
||||
}
|
||||
|
||||
void CmpObject(Register reg, Handle<Object> object) {
|
||||
ALLOW_HANDLE_DEREF(isolate(), "heap object check");
|
||||
if (object->IsHeapObject()) {
|
||||
CmpHeapObject(reg, Handle<HeapObject>::cast(object));
|
||||
} else {
|
||||
cmp(reg, Immediate(object));
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// JavaScript invokes
|
||||
|
||||
|
@ -2103,9 +2103,11 @@ void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
|
||||
int true_block = chunk_->LookupDestination(instr->true_block_id());
|
||||
|
||||
if (instr->right()->IsConstantOperand()) {
|
||||
__ Cmp(left, ToHandle(LConstantOperand::cast(instr->right())));
|
||||
Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
|
||||
__ CmpObject(left, right);
|
||||
} else {
|
||||
__ cmpq(left, ToRegister(instr->right()));
|
||||
Register right = ToRegister(instr->right());
|
||||
__ cmpq(left, right);
|
||||
}
|
||||
EmitBranch(true_block, false_block, equal);
|
||||
}
|
||||
@ -4974,15 +4976,7 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
|
||||
void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
|
||||
Register reg = ToRegister(instr->value());
|
||||
Handle<JSFunction> target = instr->hydrogen()->target();
|
||||
ALLOW_HANDLE_DEREF(isolate(), "using raw address");
|
||||
if (isolate()->heap()->InNewSpace(*target)) {
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(target);
|
||||
__ movq(kScratchRegister, cell, RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
__ cmpq(reg, Operand(kScratchRegister, 0));
|
||||
} else {
|
||||
__ Cmp(reg, target);
|
||||
}
|
||||
__ CmpHeapObject(reg, target);
|
||||
DeoptimizeIf(not_equal, instr->environment());
|
||||
}
|
||||
|
||||
|
@ -2299,6 +2299,7 @@ void MacroAssembler::Move(Register dst, Handle<Object> source) {
|
||||
if (source->IsSmi()) {
|
||||
Move(dst, Smi::cast(*source));
|
||||
} else {
|
||||
ASSERT(source->IsHeapObject());
|
||||
movq(dst, source, RelocInfo::EMBEDDED_OBJECT);
|
||||
}
|
||||
}
|
||||
@ -2309,6 +2310,7 @@ void MacroAssembler::Move(const Operand& dst, Handle<Object> source) {
|
||||
if (source->IsSmi()) {
|
||||
Move(dst, Smi::cast(*source));
|
||||
} else {
|
||||
ASSERT(source->IsHeapObject());
|
||||
movq(kScratchRegister, source, RelocInfo::EMBEDDED_OBJECT);
|
||||
movq(dst, kScratchRegister);
|
||||
}
|
||||
@ -2320,7 +2322,8 @@ void MacroAssembler::Cmp(Register dst, Handle<Object> source) {
|
||||
if (source->IsSmi()) {
|
||||
Cmp(dst, Smi::cast(*source));
|
||||
} else {
|
||||
Move(kScratchRegister, source);
|
||||
ASSERT(source->IsHeapObject());
|
||||
movq(kScratchRegister, source, RelocInfo::EMBEDDED_OBJECT);
|
||||
cmpq(dst, kScratchRegister);
|
||||
}
|
||||
}
|
||||
@ -2364,6 +2367,19 @@ void MacroAssembler::LoadHeapObject(Register result,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::CmpHeapObject(Register reg, Handle<HeapObject> object) {
|
||||
ALLOW_HANDLE_DEREF(isolate(), "using raw address");
|
||||
if (isolate()->heap()->InNewSpace(*object)) {
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(object);
|
||||
movq(kScratchRegister, cell, RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
cmpq(reg, Operand(kScratchRegister, 0));
|
||||
} else {
|
||||
Cmp(reg, object);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::PushHeapObject(Handle<HeapObject> object) {
|
||||
ALLOW_HANDLE_DEREF(isolate(), "using raw address");
|
||||
if (isolate()->heap()->InNewSpace(*object)) {
|
||||
|
@ -788,6 +788,7 @@ class MacroAssembler: public Assembler {
|
||||
// Load a heap object and handle the case of new-space objects by
|
||||
// indirecting via a global cell.
|
||||
void LoadHeapObject(Register result, Handle<HeapObject> object);
|
||||
void CmpHeapObject(Register reg, Handle<HeapObject> object);
|
||||
void PushHeapObject(Handle<HeapObject> object);
|
||||
|
||||
void LoadObject(Register result, Handle<Object> object) {
|
||||
@ -799,6 +800,15 @@ class MacroAssembler: public Assembler {
|
||||
}
|
||||
}
|
||||
|
||||
void CmpObject(Register reg, Handle<Object> object) {
|
||||
ALLOW_HANDLE_DEREF(isolate(), "heap object check");
|
||||
if (object->IsHeapObject()) {
|
||||
CmpHeapObject(reg, Handle<HeapObject>::cast(object));
|
||||
} else {
|
||||
Cmp(reg, object);
|
||||
}
|
||||
}
|
||||
|
||||
// Load a global cell into a register.
|
||||
void LoadGlobalCell(Register dst, Handle<JSGlobalPropertyCell> cell);
|
||||
|
||||
|
48
test/mjsunit/regress/regress-crbug-240032.js
Normal file
48
test/mjsunit/regress/regress-crbug-240032.js
Normal file
@ -0,0 +1,48 @@
|
||||
// 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
|
||||
|
||||
// Generate closures in that live in new-space.
|
||||
function mk() {
|
||||
return function() {};
|
||||
}
|
||||
assertInstanceof(mk(), Function);
|
||||
assertInstanceof(mk(), Function);
|
||||
|
||||
// Setup constant function using above closures.
|
||||
var o = {};
|
||||
o.func = mk();
|
||||
|
||||
// Optimize object comparison with new-space RHS.
|
||||
function cmp(o, f) {
|
||||
return f === o.func;
|
||||
}
|
||||
assertTrue(cmp(o, o.func));
|
||||
assertTrue(cmp(o, o.func));
|
||||
%OptimizeFunctionOnNextCall(cmp);
|
||||
assertTrue(cmp(o, o.func));
|
Loading…
Reference in New Issue
Block a user