Commit 66964395 authored by yangguo's avatar yangguo Committed by Commit bot

Only use FreeSpace objects in the free list.

This solves an issue with the custom startup snapshot, in cases where
deserializing the isolate requires more than one page per space.

R=hpayer@chromium.org

Review URL: https://codereview.chromium.org/876613002

Cr-Commit-Position: refs/heads/master@{#26285}
parent 3c17b3b3
......@@ -227,9 +227,7 @@ void AllocationTracker::AllocationEvent(Address addr, int size) {
// Mark the new block as FreeSpace to make sure the heap is iterable
// while we are capturing stack trace.
FreeListNode::FromAddress(addr)->set_size(heap, size);
DCHECK_EQ(HeapObject::FromAddress(addr)->Size(), size);
DCHECK(FreeListNode::IsFreeListNode(HeapObject::FromAddress(addr)));
heap->CreateFillerObjectAt(addr, size);
Isolate* isolate = heap->isolate();
int length = 0;
......
......@@ -27,6 +27,7 @@
#include "src/debug.h"
#include "src/deoptimizer.h"
#include "src/execution.h"
#include "src/full-codegen.h"
#include "src/global-handles.h"
#include "src/heap-profiler.h"
#include "src/heap-snapshot-generator-inl.h"
......@@ -220,6 +221,54 @@ bool RunExtraCode(Isolate* isolate, char* utf8_source) {
}
void CheckDefaultReservationSizes(const i::StartupSerializer& startup_ser,
const i::PartialSerializer& context_ser) {
#ifdef DEBUG
i::List<i::SerializedData::Reservation> startup_reservations;
i::List<i::SerializedData::Reservation> context_reservations;
startup_ser.EncodeReservations(&startup_reservations);
context_ser.EncodeReservations(&context_reservations);
for (int space = 0; space < i::Serializer::kNumberOfSpaces; space++) {
// Exactly one chunk per space.
CHECK(startup_reservations[space].is_last());
CHECK(startup_reservations[space].is_last());
uint32_t sum = startup_reservations[space].chunk_size() +
context_reservations[space].chunk_size();
uint32_t limit = 0;
const int constant_pool_delta = i::FLAG_enable_ool_constant_pool ? 48 : 0;
switch (space) {
case i::NEW_SPACE:
limit = 3 * i::kPointerSize;
break;
case i::OLD_POINTER_SPACE:
limit = (128 + constant_pool_delta) * i::kPointerSize * i::KB;
break;
case i::OLD_DATA_SPACE:
limit = 192 * i::KB;
break;
case i::MAP_SPACE:
limit = 16 * i::kPointerSize * i::KB;
break;
case i::CELL_SPACE:
limit = 16 * i::kPointerSize * i::KB;
break;
case i::PROPERTY_CELL_SPACE:
limit = 8 * i::kPointerSize * i::KB;
break;
case i::CODE_SPACE:
limit = RoundUp((480 - constant_pool_delta) * i::KB *
i::FullCodeGenerator::kBootCodeSizeMultiplier / 100,
i::kPointerSize);
break;
default:
break;
}
CHECK_LE(sum, limit);
}
#endif // DEBUG
}
StartupData V8::CreateSnapshotDataBlob(char* custom_source) {
Isolate::CreateParams params;
params.enable_serializer = true;
......@@ -266,6 +315,8 @@ StartupData V8::CreateSnapshotDataBlob(char* custom_source) {
i::SnapshotData sd(snapshot_sink, ser);
i::SnapshotData csd(context_sink, context_ser);
if (custom_source == NULL) CheckDefaultReservationSizes(ser, context_ser);
result = i::Snapshot::CreateSnapshotBlob(sd.RawData(), csd.RawData(),
metadata);
}
......
......@@ -124,7 +124,7 @@ class FullCodeGenerator: public AstVisitor {
static const int kBootCodeSizeMultiplier = 120;
#elif V8_TARGET_ARCH_MIPS64
static const int kCodeSizeMultiplier = 149;
static const int kBootCodeSizeMultiplier = 120;
static const int kBootCodeSizeMultiplier = 170;
#else
#error Unsupported target architecture.
#endif
......
......@@ -495,11 +495,11 @@ void Heap::ClearAllICsByKind(Code::Kind kind) {
}
void Heap::RepairFreeListsAfterBoot() {
void Heap::RepairFreeListsAfterDeserialization() {
PagedSpaces spaces(this);
for (PagedSpace* space = spaces.next(); space != NULL;
space = spaces.next()) {
space->RepairFreeListsAfterBoot();
space->RepairFreeListsAfterDeserialization();
}
}
......@@ -952,14 +952,15 @@ bool Heap::ReserveSpace(Reservation* reservations) {
} else {
allocation = paged_space(space)->AllocateRaw(size);
}
FreeListNode* node;
if (allocation.To(&node)) {
HeapObject* free_space;
if (allocation.To(&free_space)) {
// Mark with a free list node, in case we have a GC before
// deserializing.
node->set_size(this, size);
Address free_space_address = free_space->address();
CreateFillerObjectAt(free_space_address, size);
DCHECK(space < Serializer::kNumberOfPreallocatedSpaces);
chunk.start = node->address();
chunk.end = node->address() + size;
chunk.start = free_space_address;
chunk.end = free_space_address + size;
} else {
perform_gc = true;
break;
......@@ -3392,12 +3393,17 @@ AllocationResult Heap::AllocateByteArray(int length, PretenureFlag pretenure) {
void Heap::CreateFillerObjectAt(Address addr, int size) {
if (size == 0) return;
HeapObject* filler = HeapObject::FromAddress(addr);
// At this point, we may be deserializing the heap from a snapshot, and
// none of the maps have been created yet and are NULL.
if (size == kPointerSize) {
filler->set_map_no_write_barrier(one_pointer_filler_map());
filler->set_map_no_write_barrier(raw_unchecked_one_pointer_filler_map());
DCHECK(filler->map() == NULL || filler->map() == one_pointer_filler_map());
} else if (size == 2 * kPointerSize) {
filler->set_map_no_write_barrier(two_pointer_filler_map());
filler->set_map_no_write_barrier(raw_unchecked_two_pointer_filler_map());
DCHECK(filler->map() == NULL || filler->map() == two_pointer_filler_map());
} else {
filler->set_map_no_write_barrier(free_space_map());
filler->set_map_no_write_barrier(raw_unchecked_free_space_map());
DCHECK(filler->map() == NULL || filler->map() == free_space_map());
FreeSpace::cast(filler)->set_size(size);
}
}
......
......@@ -692,8 +692,8 @@ class Heap {
// Iterates the whole code space to clear all ICs of the given kind.
void ClearAllICsByKind(Code::Kind kind);
// For use during bootup.
void RepairFreeListsAfterBoot();
// FreeSpace objects have a null map after deserialization. Update the map.
void RepairFreeListsAfterDeserialization();
template <typename T>
static inline bool IsOneByte(T t, int chars);
......
......@@ -305,14 +305,6 @@ intptr_t LargeObjectSpace::Available() {
return ObjectSizeFor(heap()->isolate()->memory_allocator()->Available());
}
bool FreeListNode::IsFreeListNode(HeapObject* object) {
Map* map = object->map();
Heap* heap = object->GetHeap();
return map == heap->raw_unchecked_free_space_map() ||
map == heap->raw_unchecked_one_pointer_filler_map() ||
map == heap->raw_unchecked_two_pointer_filler_map();
}
}
} // namespace v8::internal
......
This diff is collapsed.
......@@ -1411,45 +1411,6 @@ class AllocationStats BASE_EMBEDDED {
// -----------------------------------------------------------------------------
// Free lists for old object spaces
//
// Free-list nodes are free blocks in the heap. They look like heap objects
// (free-list node pointers have the heap object tag, and they have a map like
// a heap object). They have a size and a next pointer. The next pointer is
// the raw address of the next free list node (or NULL).
class FreeListNode : public HeapObject {
public:
// Obtain a free-list node from a raw address. This is not a cast because
// it does not check nor require that the first word at the address is a map
// pointer.
static FreeListNode* FromAddress(Address address) {
return reinterpret_cast<FreeListNode*>(HeapObject::FromAddress(address));
}
static inline bool IsFreeListNode(HeapObject* object);
// Set the size in bytes, which can be read with HeapObject::Size(). This
// function also writes a map to the first word of the block so that it
// looks like a heap object to the garbage collector and heap iteration
// functions.
void set_size(Heap* heap, int size_in_bytes);
// Accessors for the next field.
inline FreeListNode* next();
inline FreeListNode** next_address();
inline void set_next(FreeListNode* next);
inline void Zap();
static inline FreeListNode* cast(Object* object) {
return reinterpret_cast<FreeListNode*>(object);
}
private:
static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize);
DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode);
};
// The free list category holds a pointer to the top element and a pointer to
// the end element of the linked list of free memory blocks.
......@@ -1461,27 +1422,26 @@ class FreeListCategory {
void Reset();
void Free(FreeListNode* node, int size_in_bytes);
void Free(FreeSpace* node, int size_in_bytes);
FreeListNode* PickNodeFromList(int* node_size);
FreeListNode* PickNodeFromList(int size_in_bytes, int* node_size);
FreeSpace* PickNodeFromList(int* node_size);
FreeSpace* PickNodeFromList(int size_in_bytes, int* node_size);
intptr_t EvictFreeListItemsInList(Page* p);
bool ContainsPageFreeListItemsInList(Page* p);
void RepairFreeList(Heap* heap);
FreeListNode* top() const {
return reinterpret_cast<FreeListNode*>(base::NoBarrier_Load(&top_));
FreeSpace* top() const {
return reinterpret_cast<FreeSpace*>(base::NoBarrier_Load(&top_));
}
void set_top(FreeListNode* top) {
void set_top(FreeSpace* top) {
base::NoBarrier_Store(&top_, reinterpret_cast<base::AtomicWord>(top));
}
FreeListNode** GetEndAddress() { return &end_; }
FreeListNode* end() const { return end_; }
void set_end(FreeListNode* end) { end_ = end; }
FreeSpace* end() const { return end_; }
void set_end(FreeSpace* end) { end_ = end; }
int* GetAvailableAddress() { return &available_; }
int available() const { return available_; }
......@@ -1497,9 +1457,9 @@ class FreeListCategory {
#endif
private:
// top_ points to the top FreeListNode* in the free list category.
// top_ points to the top FreeSpace* in the free list category.
base::AtomicWord top_;
FreeListNode* end_;
FreeSpace* end_;
base::Mutex mutex_;
// Total available bytes in all blocks of this free list category.
......@@ -1596,17 +1556,18 @@ class FreeList {
FreeListCategory* large_list() { return &large_list_; }
FreeListCategory* huge_list() { return &huge_list_; }
static const int kSmallListMin = 0x20 * kPointerSize;
private:
// The size range of blocks, in bytes.
static const int kMinBlockSize = 3 * kPointerSize;
static const int kMaxBlockSize = Page::kMaxRegularHeapObjectSize;
FreeListNode* FindNodeFor(int size_in_bytes, int* node_size);
FreeSpace* FindNodeFor(int size_in_bytes, int* node_size);
PagedSpace* owner_;
Heap* heap_;
static const int kSmallListMin = 0x20 * kPointerSize;
static const int kSmallListMax = 0xff * kPointerSize;
static const int kMediumListMax = 0x7ff * kPointerSize;
static const int kLargeListMax = 0x3fff * kPointerSize;
......@@ -1702,7 +1663,7 @@ class PagedSpace : public Space {
// During boot the free_space_map is created, and afterwards we may need
// to write it into the free list nodes that were already created.
void RepairFreeListsAfterBoot();
void RepairFreeListsAfterDeserialization();
// Prepares for a mark-compact GC.
void PrepareForMarkCompact();
......@@ -1909,8 +1870,6 @@ class PagedSpace : public Space {
// Maximum capacity of this space.
intptr_t max_capacity_;
intptr_t SizeOfFirstPage();
// Accounting information for this space.
AllocationStats accounting_stats_;
......
......@@ -1362,7 +1362,6 @@ class Isolate {
friend class ExecutionAccess;
friend class HandleScopeImplementer;
friend class IsolateInitializer;
friend class OptimizingCompilerThread;
friend class SweeperThread;
friend class ThreadManager;
......
......@@ -3334,7 +3334,6 @@ CAST_ACCESSOR(FixedArrayBase)
CAST_ACCESSOR(FixedDoubleArray)
CAST_ACCESSOR(FixedTypedArrayBase)
CAST_ACCESSOR(Foreign)
CAST_ACCESSOR(FreeSpace)
CAST_ACCESSOR(GlobalObject)
CAST_ACCESSOR(HeapObject)
CAST_ACCESSOR(JSArray)
......@@ -3443,6 +3442,39 @@ SMI_ACCESSORS(String, length, kLengthOffset)
SYNCHRONIZED_SMI_ACCESSORS(String, length, kLengthOffset)
FreeSpace* FreeSpace::next() {
DCHECK(map() == GetHeap()->raw_unchecked_free_space_map() ||
(!GetHeap()->deserialization_complete() && map() == NULL));
DCHECK_LE(kNextOffset + kPointerSize, nobarrier_size());
return reinterpret_cast<FreeSpace*>(
Memory::Address_at(address() + kNextOffset));
}
FreeSpace** FreeSpace::next_address() {
DCHECK(map() == GetHeap()->raw_unchecked_free_space_map() ||
(!GetHeap()->deserialization_complete() && map() == NULL));
DCHECK_LE(kNextOffset + kPointerSize, nobarrier_size());
return reinterpret_cast<FreeSpace**>(address() + kNextOffset);
}
void FreeSpace::set_next(FreeSpace* next) {
DCHECK(map() == GetHeap()->raw_unchecked_free_space_map() ||
(!GetHeap()->deserialization_complete() && map() == NULL));
DCHECK_LE(kNextOffset + kPointerSize, nobarrier_size());
base::NoBarrier_Store(
reinterpret_cast<base::AtomicWord*>(address() + kNextOffset),
reinterpret_cast<base::AtomicWord>(next));
}
FreeSpace* FreeSpace::cast(HeapObject* o) {
SLOW_DCHECK(!o->GetHeap()->deserialization_complete() || o->IsFreeSpace());
return reinterpret_cast<FreeSpace*>(o);
}
uint32_t Name::hash_field() {
return READ_UINT32_FIELD(this, kHashFieldOffset);
}
......
......@@ -4448,8 +4448,11 @@ class ByteArray: public FixedArrayBase {
};
// FreeSpace represents fixed sized areas of the heap that are not currently in
// use. Used by the heap and GC.
// FreeSpace are fixed-size free memory blocks used by the heap and GC.
// They look like heap objects (are heap object tagged and have a map) so that
// the heap remains iterable. They have a size and a next pointer.
// The next pointer is the raw address of the next FreeSpace object (or NULL)
// in the free list.
class FreeSpace: public HeapObject {
public:
// [size]: size of the free space including the header.
......@@ -4461,7 +4464,12 @@ class FreeSpace: public HeapObject {
inline int Size() { return size(); }
DECLARE_CAST(FreeSpace)
// Accessors for the next field.
inline FreeSpace* next();
inline FreeSpace** next_address();
inline void set_next(FreeSpace* next);
inline static FreeSpace* cast(HeapObject* obj);
// Dispatched behavior.
DECLARE_PRINTER(FreeSpace)
......@@ -4470,9 +4478,7 @@ class FreeSpace: public HeapObject {
// Layout description.
// Size is smi tagged when it is stored.
static const int kSizeOffset = HeapObject::kHeaderSize;
static const int kHeaderSize = kSizeOffset + kPointerSize;
static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
static const int kNextOffset = POINTER_SIZE_ALIGN(kSizeOffset + kPointerSize);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(FreeSpace);
......
......@@ -664,7 +664,7 @@ void Deserializer::Deserialize(Isolate* isolate) {
DCHECK(isolate_->handle_scope_implementer()->blocks()->is_empty());
isolate_->heap()->IterateSmiRoots(this);
isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG);
isolate_->heap()->RepairFreeListsAfterBoot();
isolate_->heap()->RepairFreeListsAfterDeserialization();
isolate_->heap()->IterateWeakRoots(this, VISIT_ALL);
isolate_->heap()->set_native_contexts_list(
......
......@@ -486,27 +486,39 @@ static inline bool FillUpOnePage(v8::internal::NewSpace* space) {
v8::internal::AllocationResult allocation =
space->AllocateRaw(v8::internal::Page::kMaxRegularHeapObjectSize);
if (allocation.IsRetry()) return false;
v8::internal::FreeListNode* node =
v8::internal::FreeListNode::cast(allocation.ToObjectChecked());
node->set_size(space->heap(), v8::internal::Page::kMaxRegularHeapObjectSize);
v8::internal::HeapObject* free_space;
CHECK(allocation.To(&free_space));
space->heap()->CreateFillerObjectAt(
free_space->address(), v8::internal::Page::kMaxRegularHeapObjectSize);
return true;
}
static inline void SimulateFullSpace(v8::internal::NewSpace* space) {
int new_linear_size = static_cast<int>(*space->allocation_limit_address() -
// Helper function that simulates a fill new-space in the heap.
static inline void AllocateAllButNBytes(v8::internal::NewSpace* space,
int extra_bytes) {
int space_remaining = static_cast<int>(*space->allocation_limit_address() -
*space->allocation_top_address());
if (new_linear_size > 0) {
// Fill up the current page.
v8::internal::AllocationResult allocation =
space->AllocateRaw(new_linear_size);
v8::internal::FreeListNode* node =
v8::internal::FreeListNode::cast(allocation.ToObjectChecked());
node->set_size(space->heap(), new_linear_size);
CHECK(space_remaining >= extra_bytes);
int new_linear_size = space_remaining - extra_bytes;
if (new_linear_size == 0) return;
v8::internal::AllocationResult allocation =
space->AllocateRaw(new_linear_size);
v8::internal::HeapObject* free_space;
CHECK(allocation.To(&free_space));
space->heap()->CreateFillerObjectAt(free_space->address(), new_linear_size);
}
static inline void FillCurrentPage(v8::internal::NewSpace* space) {
AllocateAllButNBytes(space, 0);
}
static inline void SimulateFullSpace(v8::internal::NewSpace* space) {
FillCurrentPage(space);
while (FillUpOnePage(space)) {
}
// Fill up all remaining pages.
while (FillUpOnePage(space))
;
}
......
......@@ -3872,21 +3872,6 @@ TEST(Regress169209) {
}
// Helper function that simulates a fill new-space in the heap.
static inline void AllocateAllButNBytes(v8::internal::NewSpace* space,
int extra_bytes) {
int space_remaining = static_cast<int>(
*space->allocation_limit_address() - *space->allocation_top_address());
CHECK(space_remaining >= extra_bytes);
int new_linear_size = space_remaining - extra_bytes;
v8::internal::AllocationResult allocation =
space->AllocateRaw(new_linear_size);
v8::internal::FreeListNode* node =
v8::internal::FreeListNode::cast(allocation.ToObjectChecked());
node->set_size(space->heap(), new_linear_size);
}
TEST(Regress169928) {
i::FLAG_allow_natives_syntax = true;
i::FLAG_crankshaft = false;
......
......@@ -156,6 +156,23 @@ static void Serialize(v8::Isolate* isolate) {
}
Vector<const uint8_t> ConstructSource(Vector<const uint8_t> head,
Vector<const uint8_t> body,
Vector<const uint8_t> tail, int repeats) {
int source_length = head.length() + body.length() * repeats + tail.length();
uint8_t* source = NewArray<uint8_t>(static_cast<size_t>(source_length));
CopyChars(source, head.start(), head.length());
for (int i = 0; i < repeats; i++) {
CopyChars(source + head.length() + i * body.length(), body.start(),
body.length());
}
CopyChars(source + head.length() + repeats * body.length(), tail.start(),
tail.length());
return Vector<const uint8_t>(const_cast<const uint8_t*>(source),
source_length);
}
// Test that the whole heap can be serialized.
UNINITIALIZED_TEST(Serialize) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
......@@ -300,6 +317,32 @@ UNINITIALIZED_DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
}
// Test that the whole heap can be serialized.
UNINITIALIZED_TEST(SerializeMultiplePages) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
v8::Isolate::CreateParams params;
params.enable_serializer = true;
v8::Isolate* isolate = v8::Isolate::New(params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
Vector<const uint8_t> source = ConstructSource(
STATIC_CHAR_VECTOR("var s='"), STATIC_CHAR_VECTOR("A"),
STATIC_CHAR_VECTOR("';"), Page::kMaxRegularHeapObjectSize - 100);
v8::Handle<v8::String> source_str = v8::String::NewFromOneByte(
isolate, source.start(), v8::String::kNormalString, source.length());
CompileRun(source_str);
}
Isolate* internal_isolate = reinterpret_cast<Isolate*>(isolate);
internal_isolate->heap()->CollectAllAvailableGarbage("serialize");
WriteToFile(internal_isolate, FLAG_testing_serialization_file);
}
}
UNINITIALIZED_TEST(PartialSerialization) {
if (!Snapshot::HaveASnapshotToStartFrom()) {
v8::Isolate::CreateParams params;
......@@ -546,7 +589,6 @@ UNINITIALIZED_TEST(CustomContextSerialization) {
params.enable_serializer = true;
v8::Isolate* v8_isolate = v8::Isolate::New(params);
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
Heap* heap = isolate->heap();
{
v8::Isolate::Scope isolate_scope(v8_isolate);
......@@ -569,6 +611,16 @@ UNINITIALIZED_TEST(CustomContextSerialization) {
"var r = Math.random() + Math.cos(0);"
"var f = (function(a, b) { return a + b; }).bind(1, 2, 3);"
"var s = parseInt('12345');");
Vector<const uint8_t> source = ConstructSource(
STATIC_CHAR_VECTOR("function g() { return [,"),
STATIC_CHAR_VECTOR("1,"),
STATIC_CHAR_VECTOR("];} a = g(); b = g(); b.push(1);"), 100000);
v8::Handle<v8::String> source_str = v8::String::NewFromOneByte(
v8_isolate, source.start(), v8::String::kNormalString,
source.length());
CompileRun(source_str);
source.Dispose();
}
// Make sure all builtin scripts are cached.
{
......@@ -579,7 +631,7 @@ UNINITIALIZED_TEST(CustomContextSerialization) {
}
// If we don't do this then we end up with a stray root pointing at the
// context even after we have disposed of env.
heap->CollectAllGarbage(Heap::kNoGCFlags);
isolate->heap()->CollectAllAvailableGarbage("snapshotting");
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
......@@ -667,6 +719,10 @@ UNINITIALIZED_DEPENDENT_TEST(CustomContextDeserialization,
CHECK_EQ(5, f);
v8::Handle<v8::String> s = CompileRun("s")->ToString(v8_isolate);
CHECK(s->Equals(v8_str("12345")));
int a = CompileRun("a.length")->ToNumber(v8_isolate)->Int32Value();
CHECK_EQ(100001, a);
int b = CompileRun("b.length")->ToNumber(v8_isolate)->Int32Value();
CHECK_EQ(100002, b);
}
}
v8_isolate->Dispose();
......@@ -819,23 +875,6 @@ TEST(SerializeToplevelInternalizedString) {
}
Vector<const uint8_t> ConstructSource(Vector<const uint8_t> head,
Vector<const uint8_t> body,
Vector<const uint8_t> tail, int repeats) {
int source_length = head.length() + body.length() * repeats + tail.length();
uint8_t* source = NewArray<uint8_t>(static_cast<size_t>(source_length));
CopyChars(source, head.start(), head.length());
for (int i = 0; i < repeats; i++) {
CopyChars(source + head.length() + i * body.length(), body.start(),
body.length());
}
CopyChars(source + head.length() + repeats * body.length(), tail.start(),
tail.length());
return Vector<const uint8_t>(const_cast<const uint8_t*>(source),
source_length);
}
TEST(SerializeToplevelLargeCodeObject) {
FLAG_serialize_toplevel = true;
LocalContext context;
......
......@@ -459,18 +459,6 @@ TEST(SizeOfFirstPageIsLargeEnough) {
}
static inline void FillCurrentPage(v8::internal::NewSpace* space) {
int new_linear_size = static_cast<int>(*space->allocation_limit_address() -
*space->allocation_top_address());
if (new_linear_size == 0) return;
v8::internal::AllocationResult allocation =
space->AllocateRaw(new_linear_size);
v8::internal::FreeListNode* node =
v8::internal::FreeListNode::cast(allocation.ToObjectChecked());
node->set_size(space->heap(), new_linear_size);
}
UNINITIALIZED_TEST(NewSpaceGrowsToTargetCapacity) {
FLAG_target_semi_space_size = 2;
if (FLAG_optimize_for_size) return;
......@@ -502,9 +490,9 @@ UNINITIALIZED_TEST(NewSpaceGrowsToTargetCapacity) {
// Turn the allocation into a proper object so isolate teardown won't
// crash.
v8::internal::FreeListNode* node =
v8::internal::FreeListNode::cast(allocation.ToObjectChecked());
node->set_size(new_space->heap(), 80);
HeapObject* free_space;
CHECK(allocation.To(&free_space));
new_space->heap()->CreateFillerObjectAt(free_space->address(), 80);
}
}
isolate->Dispose();
......
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