Fix for issue 351261.
This relands the following fix: "HAllocate should never generate allocation code if the requested size does not fit into page. Regression test included. (bug 347543)" along with additional fixes to KeyedStoreIC. BUG=351261 LOG=N R=verwaest@chromium.org Review URL: https://codereview.chromium.org/200113002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19926 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
6923d84785
commit
11df4b8815
@ -1507,7 +1507,11 @@ void LCodeGen::DoAllocate(LAllocate* instr) {
|
||||
|
||||
if (instr->size()->IsConstantOperand()) {
|
||||
int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
|
||||
__ Allocate(size, result, temp1, temp2, deferred->entry(), flags);
|
||||
if (size <= Page::kMaxRegularHeapObjectSize) {
|
||||
__ Allocate(size, result, temp1, temp2, deferred->entry(), flags);
|
||||
} else {
|
||||
__ B(deferred->entry());
|
||||
}
|
||||
} else {
|
||||
Register size = ToRegister32(instr->size());
|
||||
__ Sxtw(size.X(), size);
|
||||
|
@ -5220,7 +5220,11 @@ void LCodeGen::DoAllocate(LAllocate* instr) {
|
||||
|
||||
if (instr->size()->IsConstantOperand()) {
|
||||
int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
|
||||
__ Allocate(size, result, scratch, scratch2, deferred->entry(), flags);
|
||||
if (size <= Page::kMaxRegularHeapObjectSize) {
|
||||
__ Allocate(size, result, scratch, scratch2, deferred->entry(), flags);
|
||||
} else {
|
||||
__ jmp(deferred->entry());
|
||||
}
|
||||
} else {
|
||||
Register size = ToRegister(instr->size());
|
||||
__ Allocate(size,
|
||||
|
@ -5845,7 +5845,11 @@ void LCodeGen::DoAllocate(LAllocate* instr) {
|
||||
|
||||
if (instr->size()->IsConstantOperand()) {
|
||||
int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
|
||||
__ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
|
||||
if (size <= Page::kMaxRegularHeapObjectSize) {
|
||||
__ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
|
||||
} else {
|
||||
__ jmp(deferred->entry());
|
||||
}
|
||||
} else {
|
||||
Register size = ToRegister(instr->size());
|
||||
__ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
|
||||
|
12
src/ic.cc
12
src/ic.cc
@ -1599,7 +1599,10 @@ KeyedAccessStoreMode KeyedStoreIC::GetStoreMode(Handle<JSObject> receiver,
|
||||
key->ToSmi()->To(&smi_key);
|
||||
int index = smi_key->value();
|
||||
bool oob_access = IsOutOfBoundsAccess(receiver, index);
|
||||
bool allow_growth = receiver->IsJSArray() && oob_access;
|
||||
// Don't consider this a growing store if the store would send the receiver to
|
||||
// dictionary mode.
|
||||
bool allow_growth = receiver->IsJSArray() && oob_access &&
|
||||
!receiver->WouldConvertToSlowElements(key);
|
||||
if (allow_growth) {
|
||||
// Handle growing array in stub if necessary.
|
||||
if (receiver->HasFastSmiElements()) {
|
||||
@ -1724,12 +1727,7 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
|
||||
if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) {
|
||||
KeyedAccessStoreMode store_mode =
|
||||
GetStoreMode(receiver, key, value);
|
||||
// Use the generic stub if the store would send the receiver to
|
||||
// dictionary mode.
|
||||
if (!IsGrowStoreMode(store_mode) ||
|
||||
!receiver->WouldConvertToSlowElements(key)) {
|
||||
stub = StoreElementStub(receiver, store_mode);
|
||||
}
|
||||
stub = StoreElementStub(receiver, store_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5184,7 +5184,11 @@ void LCodeGen::DoAllocate(LAllocate* instr) {
|
||||
}
|
||||
if (instr->size()->IsConstantOperand()) {
|
||||
int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
|
||||
__ Allocate(size, result, scratch, scratch2, deferred->entry(), flags);
|
||||
if (size <= Page::kMaxRegularHeapObjectSize) {
|
||||
__ Allocate(size, result, scratch, scratch2, deferred->entry(), flags);
|
||||
} else {
|
||||
__ jmp(deferred->entry());
|
||||
}
|
||||
} else {
|
||||
Register size = ToRegister(instr->size());
|
||||
__ Allocate(size,
|
||||
|
@ -5144,7 +5144,11 @@ void LCodeGen::DoAllocate(LAllocate* instr) {
|
||||
|
||||
if (instr->size()->IsConstantOperand()) {
|
||||
int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
|
||||
__ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
|
||||
if (size <= Page::kMaxRegularHeapObjectSize) {
|
||||
__ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
|
||||
} else {
|
||||
__ jmp(deferred->entry());
|
||||
}
|
||||
} else {
|
||||
Register size = ToRegister(instr->size());
|
||||
__ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
|
||||
|
19
test/mjsunit/regress/regress-351261.js
Normal file
19
test/mjsunit/regress/regress-351261.js
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2014 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax --fold-constants
|
||||
|
||||
function store(a) {
|
||||
a[5000000] = 1;
|
||||
}
|
||||
|
||||
function foo() {
|
||||
var __v_8 = new Object;
|
||||
var __v_7 = new Array(4999990);
|
||||
store(__v_8);
|
||||
store(__v_7);
|
||||
}
|
||||
foo();
|
||||
%OptimizeFunctionOnNextCall(foo);
|
||||
foo();
|
Loading…
Reference in New Issue
Block a user