Commit 9b6808bf authored by jgruber's avatar jgruber Committed by Commit bot

[heap] Initialize the owner on each page after lospace allocation

The least two bits of the owner field of a Page are used to determine
whether the Page is part of a large object. If these bits are not equal
to 0x11, the page is part of a large object and needs special handling
e.g. in MemoryChunk::FromAnyPointerAddress to determine which chunk it
belongs to.

This CL fixes an issue in which the store buffer overflows after
a large object space allocation but before the object has been fully
initialized. Store buffer overflow handling attempts to look up the
chunk of a page, but fails to do so correctly since the page's owner
field has not yet been initialized.

This CL ensures that the owner field of all pages belonging to a large
object allocation are initialized to a value that is interpreted
correctly.

BUG=chromium:672041

Review-Url: https://codereview.chromium.org/2565713002
Cr-Commit-Position: refs/heads/master@{#41641}
parent 222541df
...@@ -590,6 +590,14 @@ LargePage* LargePage::Initialize(Heap* heap, MemoryChunk* chunk, ...@@ -590,6 +590,14 @@ LargePage* LargePage::Initialize(Heap* heap, MemoryChunk* chunk,
FATAL("Code page is too large."); FATAL("Code page is too large.");
} }
heap->incremental_marking()->SetOldSpacePageFlags(chunk); heap->incremental_marking()->SetOldSpacePageFlags(chunk);
// Initialize the owner field for each contained page (except the first, which
// is initialized by MemoryChunk::Initialize).
for (size_t i = Page::kPageSize; i < chunk->size(); i += Page::kPageSize) {
// Clear out kPageHeaderTag.
Memory::Address_at(chunk->address() + i + Page::kOwnerOffset) = 0;
}
return static_cast<LargePage*>(chunk); return static_cast<LargePage*>(chunk);
} }
......
...@@ -317,8 +317,11 @@ class MemoryChunk { ...@@ -317,8 +317,11 @@ class MemoryChunk {
static const intptr_t kAlignmentMask = kAlignment - 1; static const intptr_t kAlignmentMask = kAlignment - 1;
static const intptr_t kSizeOffset = 0; static const intptr_t kSizeOffset = 0;
static const intptr_t kFlagsOffset = kSizeOffset + kSizetSize;
static const intptr_t kFlagsOffset = kSizeOffset + kPointerSize; static const intptr_t kAreaStartOffset = kFlagsOffset + kIntptrSize;
static const intptr_t kAreaEndOffset = kAreaStartOffset + kPointerSize;
static const intptr_t kReservationOffset = kAreaEndOffset + kPointerSize;
static const intptr_t kOwnerOffset = kReservationOffset + 2 * kPointerSize;
static const size_t kMinHeaderSize = static const size_t kMinHeaderSize =
kSizeOffset + kSizetSize // size_t size kSizeOffset + kSizetSize // size_t size
......
// 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;
const RegExpPrototypeExec = RegExp.prototype.exec;
let i = 0;
RegExp.prototype.__defineGetter__("global", () => true);
RegExp.prototype.exec = function(str) {
return (i++ < num_iterations) ? RegExpPrototypeExec.call(this, str) : null;
};
"a".match();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment