[stubs] Add option to allow LO space allocation
Passing kAllowLargeObjectAllocation now allocates in LOS if necessary. Allow such allocations when growing fixed arrays in RegExp's @@match and @@split operations. BUG=chromium:670671 Review-Url: https://codereview.chromium.org/2555703003 Cr-Commit-Position: refs/heads/master@{#41526}
This commit is contained in:
parent
52fd3c1ec5
commit
9c9c8d7bb5
@ -1465,9 +1465,12 @@ class GrowableFixedArray {
|
||||
|
||||
const ElementsKind kind = FAST_ELEMENTS;
|
||||
const WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER;
|
||||
const CodeStubAssembler::AllocationFlags flags =
|
||||
CodeStubAssembler::kAllowLargeObjectAllocation;
|
||||
|
||||
Node* const from_array = var_array_.value();
|
||||
Node* const to_array = a->AllocateFixedArray(kind, new_capacity, mode);
|
||||
Node* const to_array =
|
||||
a->AllocateFixedArray(kind, new_capacity, mode, flags);
|
||||
a->CopyFixedArrayElements(kind, from_array, kind, to_array,
|
||||
current_capacity, new_capacity, barrier_mode,
|
||||
mode);
|
||||
|
@ -783,6 +783,22 @@ Node* CodeStubAssembler::AllocateRawUnaligned(Node* size_in_bytes,
|
||||
Label runtime_call(this, Label::kDeferred), no_runtime_call(this);
|
||||
Label merge_runtime(this, &result);
|
||||
|
||||
if (flags & kAllowLargeObjectAllocation) {
|
||||
Label next(this);
|
||||
GotoIf(IsRegularHeapObjectSize(size_in_bytes), &next);
|
||||
|
||||
Node* runtime_flags = SmiConstant(
|
||||
Smi::FromInt(AllocateDoubleAlignFlag::encode(false) |
|
||||
AllocateTargetSpace::encode(AllocationSpace::LO_SPACE)));
|
||||
Node* const runtime_result =
|
||||
CallRuntime(Runtime::kAllocateInTargetSpace, NoContextConstant(),
|
||||
SmiTag(size_in_bytes), runtime_flags);
|
||||
result.Bind(runtime_result);
|
||||
Goto(&merge_runtime);
|
||||
|
||||
Bind(&next);
|
||||
}
|
||||
|
||||
Node* new_top = IntPtrAdd(top, size_in_bytes);
|
||||
Branch(UintPtrGreaterThanOrEqual(new_top, limit), &runtime_call,
|
||||
&no_runtime_call);
|
||||
|
@ -58,7 +58,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
enum AllocationFlag : uint8_t {
|
||||
kNone = 0,
|
||||
kDoubleAlignment = 1,
|
||||
kPretenured = 1 << 1
|
||||
kPretenured = 1 << 1,
|
||||
kAllowLargeObjectAllocation = 1 << 2,
|
||||
};
|
||||
|
||||
typedef base::Flags<AllocationFlag> AllocationFlags;
|
||||
|
@ -273,9 +273,9 @@ RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) {
|
||||
CONVERT_SMI_ARG_CHECKED(flags, 1);
|
||||
CHECK(IsAligned(size, kPointerSize));
|
||||
CHECK(size > 0);
|
||||
CHECK(size <= kMaxRegularHeapObjectSize);
|
||||
bool double_align = AllocateDoubleAlignFlag::decode(flags);
|
||||
AllocationSpace space = AllocateTargetSpace::decode(flags);
|
||||
CHECK(size <= kMaxRegularHeapObjectSize || space == LO_SPACE);
|
||||
return *isolate->factory()->NewFillerObject(size, double_align, space);
|
||||
}
|
||||
|
||||
|
23
test/mjsunit/regress/regress-670671.js
Normal file
23
test/mjsunit/regress/regress-670671.js
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// Trigger an infinite loop through RegExp.prototype[@@match], which results
|
||||
// in unbounded growth of the results array.
|
||||
|
||||
// Limit the number of iterations to avoid OOM while still triggering large
|
||||
// object space allocation.
|
||||
const min_ptr_size = 4;
|
||||
const max_regular_heap_object_size = 507136;
|
||||
const num_iterations = max_regular_heap_object_size / min_ptr_size;
|
||||
|
||||
let i = 0;
|
||||
|
||||
const re = /foo.bar/;
|
||||
const RegExpPrototypeExec = RegExp.prototype.exec;
|
||||
re.exec = (str) => {
|
||||
return (i++ < num_iterations) ? RegExpPrototypeExec.call(re, str) : null;
|
||||
};
|
||||
re.__defineGetter__("global", () => true); // Triggers infinite loop.
|
||||
|
||||
"foo*bar".match(re); // Should not crash.
|
Loading…
Reference in New Issue
Block a user