Skip to content

Commit

Permalink
Reland "[heap] Adds a young generation large object space"
Browse files Browse the repository at this point in the history
Bug: chromium:852420
Change-Id: I44d0bde25283ac8c00155344f879eb1143b43bc9
Reviewed-on: https://chromium-review.googlesource.com/1119688
Reviewed-by: Ulan Degenbaev <[email protected]>
Reviewed-by: Yang Guo <[email protected]>
Commit-Queue: Hannes Payer <[email protected]>
Cr-Commit-Position: refs/heads/master@{#54130}
  • Loading branch information
hannespayer authored and Commit Bot committed Jul 2, 2018
1 parent 83f5b8d commit a383aa3
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 10 deletions.
4 changes: 4 additions & 0 deletions src/flag-definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,10 @@ DEFINE_NEG_NEG_IMPLICATION(optimize_ephemerons, parallel_ephemeron_visiting)

DEFINE_BOOL(clear_free_memory, true, "initialize free memory with 0")

DEFINE_BOOL(young_generation_large_objects, false,
"allocates large objects by default in the young generation large "
"object space")

// assembler-ia32.cc / assembler-arm.cc / assembler-x64.cc
DEFINE_BOOL(debug_code, DEBUG_BOOL,
"generate extra code (assertions) for debugging")
Expand Down
15 changes: 9 additions & 6 deletions src/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@ class MapSpace;
class MarkCompactCollector;
class MaybeObject;
class NewSpace;
class NewLargeObjectSpace;
class Object;
class OldSpace;
class ParameterCount;
Expand Down Expand Up @@ -570,14 +571,16 @@ typedef bool (*WeakSlotCallbackWithHeap)(Heap* heap, Object** pointer);
enum AllocationSpace {
// TODO(v8:7464): Actually map this space's memory as read-only.
RO_SPACE, // Immortal, immovable and immutable objects,
NEW_SPACE, // Semispaces collected with copying collector.
OLD_SPACE, // May contain pointers to new space.
CODE_SPACE, // No pointers to new space, marked executable.
MAP_SPACE, // Only and all map objects.
LO_SPACE, // Promoted large objects.
NEW_SPACE, // Young generation semispaces for regular objects collected with
// Scavenger.
OLD_SPACE, // Old generation regular object space.
CODE_SPACE, // Old generation code object space, marked executable.
MAP_SPACE, // Old generation map object space, non-movable.
LO_SPACE, // Old generation large object space.
NEW_LO_SPACE, // Young generation large object space.

FIRST_SPACE = RO_SPACE,
LAST_SPACE = LO_SPACE,
LAST_SPACE = NEW_LO_SPACE,
FIRST_GROWABLE_PAGED_SPACE = OLD_SPACE,
LAST_GROWABLE_PAGED_SPACE = MAP_SPACE
};
Expand Down
6 changes: 5 additions & 1 deletion src/heap/heap-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,11 @@ AllocationResult Heap::AllocateRaw(int size_in_bytes, AllocationSpace space,
}
} else if (LO_SPACE == space) {
DCHECK(large_object);
allocation = lo_space_->AllocateRaw(size_in_bytes, NOT_EXECUTABLE);
if (FLAG_young_generation_large_objects) {
allocation = new_lo_space_->AllocateRaw(size_in_bytes, NOT_EXECUTABLE);
} else {
allocation = lo_space_->AllocateRaw(size_in_bytes, NOT_EXECUTABLE);
}
} else if (MAP_SPACE == space) {
allocation = map_space_->AllocateRawUnaligned(size_in_bytes);
} else if (RO_SPACE == space) {
Expand Down
13 changes: 12 additions & 1 deletion src/heap/heap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ Heap::Heap()
code_space_(nullptr),
map_space_(nullptr),
lo_space_(nullptr),
new_lo_space_(nullptr),
read_only_space_(nullptr),
write_protect_code_memory_(false),
code_space_memory_modification_scope_depth_(0),
Expand Down Expand Up @@ -673,6 +674,8 @@ const char* Heap::GetSpaceName(int idx) {
return "code_space";
case LO_SPACE:
return "large_object_space";
case NEW_LO_SPACE:
return "new_large_object_space";
case RO_SPACE:
return "read_only_space";
default:
Expand Down Expand Up @@ -3646,6 +3649,8 @@ bool Heap::InSpace(HeapObject* value, AllocationSpace space) {
return map_space_->Contains(value);
case LO_SPACE:
return lo_space_->Contains(value);
case NEW_LO_SPACE:
return new_lo_space_->Contains(value);
case RO_SPACE:
return read_only_space_->Contains(value);
}
Expand All @@ -3669,20 +3674,22 @@ bool Heap::InSpaceSlow(Address addr, AllocationSpace space) {
return map_space_->ContainsSlow(addr);
case LO_SPACE:
return lo_space_->ContainsSlow(addr);
case NEW_LO_SPACE:
return new_lo_space_->ContainsSlow(addr);
case RO_SPACE:
return read_only_space_->ContainsSlow(addr);
}
UNREACHABLE();
}


bool Heap::IsValidAllocationSpace(AllocationSpace space) {
switch (space) {
case NEW_SPACE:
case OLD_SPACE:
case CODE_SPACE:
case MAP_SPACE:
case LO_SPACE:
case NEW_LO_SPACE:
case RO_SPACE:
return true;
default:
Expand Down Expand Up @@ -4591,6 +4598,7 @@ void Heap::SetUp() {
space_[CODE_SPACE] = code_space_ = new CodeSpace(this);
space_[MAP_SPACE] = map_space_ = new MapSpace(this);
space_[LO_SPACE] = lo_space_ = new LargeObjectSpace(this);
space_[NEW_LO_SPACE] = new_lo_space_ = new NewLargeObjectSpace(this);

// Set up the seed that is used to randomize the string hash function.
DCHECK_EQ(Smi::kZero, hash_seed());
Expand Down Expand Up @@ -5525,6 +5533,8 @@ const char* AllocationSpaceName(AllocationSpace space) {
return "MAP_SPACE";
case LO_SPACE:
return "LO_SPACE";
case NEW_LO_SPACE:
return "NEW_LO_SPACE";
case RO_SPACE:
return "RO_SPACE";
default:
Expand Down Expand Up @@ -5598,6 +5608,7 @@ bool Heap::AllowedToBeMigrated(HeapObject* obj, AllocationSpace dst) {
return dst == CODE_SPACE && type == CODE_TYPE;
case MAP_SPACE:
case LO_SPACE:
case NEW_LO_SPACE:
case RO_SPACE:
return false;
}
Expand Down
2 changes: 2 additions & 0 deletions src/heap/heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,7 @@ class Heap {
CodeSpace* code_space() { return code_space_; }
MapSpace* map_space() { return map_space_; }
LargeObjectSpace* lo_space() { return lo_space_; }
NewLargeObjectSpace* new_lo_space() { return new_lo_space_; }
ReadOnlySpace* read_only_space() { return read_only_space_; }

inline PagedSpace* paged_space(int idx);
Expand Down Expand Up @@ -2294,6 +2295,7 @@ class Heap {
CodeSpace* code_space_;
MapSpace* map_space_;
LargeObjectSpace* lo_space_;
NewLargeObjectSpace* new_lo_space_;
ReadOnlySpace* read_only_space_;
// Map from the space id to the space.
Space* space_[LAST_SPACE + 1];
Expand Down
13 changes: 12 additions & 1 deletion src/heap/spaces.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3340,7 +3340,10 @@ HeapObject* LargeObjectIterator::Next() {
// LargeObjectSpace

LargeObjectSpace::LargeObjectSpace(Heap* heap)
: Space(heap, LO_SPACE), // Managed on a per-allocation basis
: LargeObjectSpace(heap, LO_SPACE) {}

LargeObjectSpace::LargeObjectSpace(Heap* heap, AllocationSpace id)
: Space(heap, id),
size_(0),
page_count_(0),
objects_size_(0),
Expand Down Expand Up @@ -3651,5 +3654,13 @@ void Page::Print() {
}

#endif // DEBUG

NewLargeObjectSpace::NewLargeObjectSpace(Heap* heap)
: LargeObjectSpace(heap, NEW_LO_SPACE) {}

size_t NewLargeObjectSpace::Available() {
// TODO(hpayer): Update as soon as we have a growing strategy.
return 0;
}
} // namespace internal
} // namespace v8
9 changes: 9 additions & 0 deletions src/heap/spaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -2941,6 +2941,8 @@ class LargeObjectSpace : public Space {
typedef LargePageIterator iterator;

explicit LargeObjectSpace(Heap* heap);
LargeObjectSpace(Heap* heap, AllocationSpace id);

~LargeObjectSpace() override { TearDown(); }

// Releases internal resources, frees objects in this space.
Expand Down Expand Up @@ -3034,6 +3036,13 @@ class LargeObjectSpace : public Space {
friend class LargeObjectIterator;
};

class NewLargeObjectSpace : public LargeObjectSpace {
public:
explicit NewLargeObjectSpace(Heap* heap);

// Available bytes for objects in this space.
size_t Available() override;
};

class LargeObjectIterator : public ObjectIterator {
public:
Expand Down
6 changes: 5 additions & 1 deletion src/snapshot/serializer-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,12 @@ class SerializerDeserializer : public RootVisitor {
// No reservation for large object space necessary.
// We also handle map space differenly.
STATIC_ASSERT(MAP_SPACE == CODE_SPACE + 1);

// We do not support young generation large objects.
STATIC_ASSERT(LAST_SPACE == NEW_LO_SPACE);
STATIC_ASSERT(LAST_SPACE - 1 == LO_SPACE);
static const int kNumberOfPreallocatedSpaces = CODE_SPACE + 1;
static const int kNumberOfSpaces = LAST_SPACE + 1;
static const int kNumberOfSpaces = LO_SPACE + 1;

protected:
static bool CanBeDeferred(HeapObject* o);
Expand Down
1 change: 1 addition & 0 deletions src/snapshot/serializer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,7 @@ void Serializer<AllocatorT>::ObjectSerializer::SerializeObject() {
Map* map = object_->map();
AllocationSpace space =
MemoryChunk::FromAddress(object_->address())->owner()->identity();
DCHECK(space != NEW_LO_SPACE);
SerializePrologue(space, size, map);

// Serialize the rest of the object.
Expand Down
12 changes: 12 additions & 0 deletions test/cctest/heap/test-heap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5656,6 +5656,18 @@ TEST(Regress618958) {
!heap->incremental_marking()->IsStopped()));
}

TEST(YoungGenerationLargeObjectAllocation) {
FLAG_young_generation_large_objects = true;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Heap* heap = CcTest::heap();
Isolate* isolate = heap->isolate();

Handle<FixedArray> array = isolate->factory()->NewFixedArray(200000);
MemoryChunk* chunk = MemoryChunk::FromAddress(array->address());
CHECK(chunk->owner()->identity() == NEW_LO_SPACE);
}

TEST(UncommitUnusedLargeObjectMemory) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Expand Down
3 changes: 3 additions & 0 deletions test/cctest/test-api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18922,6 +18922,9 @@ TEST(GetHeapSpaceStatistics) {
v8::HeapSpaceStatistics space_statistics;
isolate->GetHeapSpaceStatistics(&space_statistics, i);
CHECK_NOT_NULL(space_statistics.space_name());
if (strcmp(space_statistics.space_name(), "new_large_object_space") == 0) {
continue;
}
CHECK_GT(space_statistics.space_size(), 0u);
total_size += space_statistics.space_size();
CHECK_GT(space_statistics.space_used_size(), 0u);
Expand Down

0 comments on commit a383aa3

Please sign in to comment.