kObjectSpaceOldSpace = 1 << 1,
kObjectSpaceCodeSpace = 1 << 2,
kObjectSpaceMapSpace = 1 << 3,
- kObjectSpaceCellSpace = 1 << 4,
- kObjectSpaceLoSpace = 1 << 5,
+ kObjectSpaceLoSpace = 1 << 4,
kObjectSpaceAll = kObjectSpaceNewSpace | kObjectSpaceOldSpace |
kObjectSpaceCodeSpace | kObjectSpaceMapSpace |
kObjectSpaceLoSpace
static const int kJSObjectType = 0xbe;
static const int kFirstNonstringType = 0x80;
static const int kOddballType = 0x83;
- static const int kForeignType = 0x87;
+ static const int kForeignType = 0x86;
static const int kUndefinedOddballKind = 5;
static const int kNullOddballKind = 3;
heap_stats.map_space_size = &map_space_size;
intptr_t map_space_capacity;
heap_stats.map_space_capacity = &map_space_capacity;
- intptr_t cell_space_size;
- heap_stats.cell_space_size = &cell_space_size;
- intptr_t cell_space_capacity;
- heap_stats.cell_space_capacity = &cell_space_capacity;
intptr_t lo_space_size;
heap_stats.lo_space_size = &lo_space_size;
int global_handle_count;
__ GetRelocatedValueLocation(r9, map_load_offset, scratch);
__ ldr(map_load_offset, MemOperand(map_load_offset));
__ str(map, FieldMemOperand(map_load_offset, Cell::kValueOffset));
+
+ __ mov(r8, map);
+ // |map_load_offset| points at the beginning of the cell. Calculate the
+ // field containing the map.
+ __ add(function, map_load_offset, Operand(Cell::kValueOffset - 1));
+ __ RecordWriteField(map_load_offset, Cell::kValueOffset, r8, function,
+ kLRHasNotBeenSaved, kDontSaveFPRegs,
+ OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
}
// Register mapping: r3 is object map and r4 is function prototype.
// We have a cell, so need another level of dereferencing.
__ Ldr(scratch1, MemOperand(scratch1));
__ Str(map, FieldMemOperand(scratch1, Cell::kValueOffset));
+
+ __ Mov(x14, map);
+ // |scratch1| points at the beginning of the cell. Calculate the
+ // field containing the map.
+ __ Add(function, scratch1, Operand(Cell::kValueOffset - 1));
+ __ RecordWriteField(scratch1, Cell::kValueOffset, x14, function,
+ kLRHasNotBeenSaved, kDontSaveFPRegs,
+ OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
} else {
__ StoreRoot(function, Heap::kInstanceofCacheFunctionRootIndex);
__ StoreRoot(map, Heap::kInstanceofCacheMapRootIndex);
static inline bool IsEmbeddedObject(Mode mode) {
return mode == EMBEDDED_OBJECT;
}
+ static inline bool IsCell(Mode mode) { return mode == CELL; }
static inline bool IsRuntimeEntry(Mode mode) {
return mode == RUNTIME_ENTRY;
}
HP(external_fragmentation_code_space, \
V8.MemoryExternalFragmentationCodeSpace) \
HP(external_fragmentation_map_space, V8.MemoryExternalFragmentationMapSpace) \
- HP(external_fragmentation_cell_space, \
- V8.MemoryExternalFragmentationCellSpace) \
HP(external_fragmentation_lo_space, V8.MemoryExternalFragmentationLoSpace) \
/* Percentages of heap committed to each space. */ \
HP(heap_fraction_new_space, V8.MemoryHeapFractionNewSpace) \
HP(heap_fraction_old_space, V8.MemoryHeapFractionOldSpace) \
HP(heap_fraction_code_space, V8.MemoryHeapFractionCodeSpace) \
HP(heap_fraction_map_space, V8.MemoryHeapFractionMapSpace) \
- HP(heap_fraction_cell_space, V8.MemoryHeapFractionCellSpace) \
HP(heap_fraction_lo_space, V8.MemoryHeapFractionLoSpace) \
/* Percentage of crankshafted codegen. */ \
HP(codegen_fraction_crankshaft, V8.CodegenFractionCrankshaft)
HM(heap_sample_total_used, V8.MemoryHeapSampleTotalUsed) \
HM(heap_sample_map_space_committed, \
V8.MemoryHeapSampleMapSpaceCommitted) \
- HM(heap_sample_cell_space_committed, \
- V8.MemoryHeapSampleCellSpaceCommitted) \
HM(heap_sample_code_space_committed, \
V8.MemoryHeapSampleCodeSpaceCommitted) \
HM(heap_sample_maximum_committed, \
SC(map_space_bytes_available, V8.MemoryMapSpaceBytesAvailable) \
SC(map_space_bytes_committed, V8.MemoryMapSpaceBytesCommitted) \
SC(map_space_bytes_used, V8.MemoryMapSpaceBytesUsed) \
- SC(cell_space_bytes_available, V8.MemoryCellSpaceBytesAvailable) \
- SC(cell_space_bytes_committed, V8.MemoryCellSpaceBytesCommitted) \
- SC(cell_space_bytes_used, V8.MemoryCellSpaceBytesUsed) \
SC(lo_space_bytes_available, V8.MemoryLoSpaceBytesAvailable) \
SC(lo_space_bytes_committed, V8.MemoryLoSpaceBytesCommitted) \
SC(lo_space_bytes_used, V8.MemoryLoSpaceBytesUsed)
{heap->code_space()->Size(), "code_space_live_bytes"},
{heap->code_space()->Available(), "code_space_available_bytes"},
{heap->code_space()->CommittedMemory(), "code_space_commited_bytes"},
- {heap->cell_space()->Size(), "cell_space_live_bytes"},
- {heap->cell_space()->Available(), "cell_space_available_bytes"},
- {heap->cell_space()->CommittedMemory(), "cell_space_commited_bytes"},
{heap->lo_space()->Size(), "lo_space_live_bytes"},
{heap->lo_space()->Available(), "lo_space_available_bytes"},
{heap->lo_space()->CommittedMemory(), "lo_space_commited_bytes"},
OLD_SPACE, // May contain pointers to new space.
CODE_SPACE, // No pointers to new space, marked executable.
MAP_SPACE, // Only and all map objects.
- CELL_SPACE, // Only and all cell objects.
LO_SPACE, // Promoted large objects.
FIRST_SPACE = NEW_SPACE,
LAST_SPACE = LO_SPACE,
FIRST_PAGED_SPACE = OLD_SPACE,
- LAST_PAGED_SPACE = CELL_SPACE
+ LAST_PAGED_SPACE = MAP_SPACE
};
const int kSpaceTagSize = 3;
const int kSpaceTagMask = (1 << kSpaceTagSize) - 1;
}
} else if (LO_SPACE == space) {
allocation = lo_space_->AllocateRaw(size_in_bytes, NOT_EXECUTABLE);
- } else if (CELL_SPACE == space) {
- allocation = cell_space_->AllocateRaw(size_in_bytes);
} else {
DCHECK(MAP_SPACE == space);
allocation = map_space_->AllocateRaw(size_in_bytes);
case CODE_SPACE:
return dst == src && type == CODE_TYPE;
case MAP_SPACE:
- case CELL_SPACE:
case LO_SPACE:
return false;
}
old_space_(NULL),
code_space_(NULL),
map_space_(NULL),
- cell_space_(NULL),
lo_space_(NULL),
gc_state_(NOT_IN_GC),
gc_post_processing_depth_(0),
if (!HasBeenSetUp()) return 0;
return new_space_.Capacity() + old_space_->Capacity() +
- code_space_->Capacity() + map_space_->Capacity() +
- cell_space_->Capacity();
+ code_space_->Capacity() + map_space_->Capacity();
}
if (!HasBeenSetUp()) return 0;
return old_space_->CommittedMemory() + code_space_->CommittedMemory() +
- map_space_->CommittedMemory() + cell_space_->CommittedMemory() +
- lo_space_->Size();
+ map_space_->CommittedMemory() + lo_space_->Size();
}
old_space_->CommittedPhysicalMemory() +
code_space_->CommittedPhysicalMemory() +
map_space_->CommittedPhysicalMemory() +
- cell_space_->CommittedPhysicalMemory() +
lo_space_->CommittedPhysicalMemory();
}
if (!HasBeenSetUp()) return 0;
return new_space_.Available() + old_space_->Available() +
- code_space_->Available() + map_space_->Available() +
- cell_space_->Available();
+ code_space_->Available() + map_space_->Available();
}
bool Heap::HasBeenSetUp() {
return old_space_ != NULL && code_space_ != NULL && map_space_ != NULL &&
- cell_space_ != NULL && lo_space_ != NULL;
+ lo_space_ != NULL;
}
", committed: %6" V8_PTR_PREFIX "d KB\n",
map_space_->SizeOfObjects() / KB, map_space_->Available() / KB,
map_space_->CommittedMemory() / KB);
- PrintPID("Cell space, used: %6" V8_PTR_PREFIX
- "d KB"
- ", available: %6" V8_PTR_PREFIX
- "d KB"
- ", committed: %6" V8_PTR_PREFIX "d KB\n",
- cell_space_->SizeOfObjects() / KB, cell_space_->Available() / KB,
- cell_space_->CommittedMemory() / KB);
PrintPID("Large object space, used: %6" V8_PTR_PREFIX
"d KB"
", available: %6" V8_PTR_PREFIX
CommittedMemory()));
isolate_->counters()->heap_fraction_map_space()->AddSample(static_cast<int>(
(map_space()->CommittedMemory() * 100.0) / CommittedMemory()));
- isolate_->counters()->heap_fraction_cell_space()->AddSample(
- static_cast<int>((cell_space()->CommittedMemory() * 100.0) /
- CommittedMemory()));
isolate_->counters()->heap_fraction_lo_space()->AddSample(static_cast<int>(
(lo_space()->CommittedMemory() * 100.0) / CommittedMemory()));
static_cast<int>(SizeOfObjects() / KB));
isolate_->counters()->heap_sample_map_space_committed()->AddSample(
static_cast<int>(map_space()->CommittedMemory() / KB));
- isolate_->counters()->heap_sample_cell_space_committed()->AddSample(
- static_cast<int>(cell_space()->CommittedMemory() / KB));
isolate_->counters()->heap_sample_code_space_committed()->AddSample(
static_cast<int>(code_space()->CommittedMemory() / KB));
UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(old_space)
UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(code_space)
UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(map_space)
- UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(cell_space)
UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(lo_space)
#undef UPDATE_COUNTERS_FOR_SPACE
#undef UPDATE_FRAGMENTATION_FOR_SPACE
store_buffer()->IteratePointersToNewSpace(&ScavengeObject);
}
- // Copy objects reachable from simple cells by scavenging cell values
- // directly.
- HeapObjectIterator cell_iterator(cell_space_);
- for (HeapObject* heap_object = cell_iterator.Next(); heap_object != NULL;
- heap_object = cell_iterator.Next()) {
- if (heap_object->IsCell()) {
- Cell* cell = Cell::cast(heap_object);
- Address value_address = cell->ValueAddress();
- scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address));
- }
- }
-
// Copy objects reachable from the encountered weak collections list.
scavenge_visitor.VisitPointer(&encountered_weak_collections_);
// Copy objects reachable from the encountered weak cells.
HeapObject* result;
{
- AllocationResult allocation = AllocateRaw(size, CELL_SPACE, CELL_SPACE);
+ AllocationResult allocation = AllocateRaw(size, OLD_SPACE, OLD_SPACE);
if (!allocation.To(&result)) return allocation;
}
result->set_map_no_write_barrier(cell_map());
code_space_->ReportStatistics();
PrintF("Map space : ");
map_space_->ReportStatistics();
- PrintF("Cell space : ");
- cell_space_->ReportStatistics();
PrintF("Large object space : ");
lo_space_->ReportStatistics();
PrintF(">>>>>> ========================================= >>>>>>\n");
return HasBeenSetUp() &&
(new_space_.ToSpaceContains(addr) || old_space_->Contains(addr) ||
code_space_->Contains(addr) || map_space_->Contains(addr) ||
- cell_space_->Contains(addr) || lo_space_->SlowContains(addr));
+ lo_space_->SlowContains(addr));
}
return code_space_->Contains(addr);
case MAP_SPACE:
return map_space_->Contains(addr);
- case CELL_SPACE:
- return cell_space_->Contains(addr);
case LO_SPACE:
return lo_space_->SlowContains(addr);
}
VerifyPointersVisitor no_dirty_regions_visitor;
code_space_->Verify(&no_dirty_regions_visitor);
- cell_space_->Verify(&no_dirty_regions_visitor);
lo_space_->Verify();
}
*stats->code_space_capacity = code_space_->Capacity();
*stats->map_space_size = map_space_->SizeOfObjects();
*stats->map_space_capacity = map_space_->Capacity();
- *stats->cell_space_size = cell_space_->SizeOfObjects();
- *stats->cell_space_capacity = cell_space_->Capacity();
*stats->lo_space_size = lo_space_->Size();
isolate_->global_handles()->RecordStats(stats);
*stats->memory_allocator_size = isolate()->memory_allocator()->Size();
intptr_t Heap::PromotedSpaceSizeOfObjects() {
return old_space_->SizeOfObjects() + code_space_->SizeOfObjects() +
- map_space_->SizeOfObjects() + cell_space_->SizeOfObjects() +
- lo_space_->SizeOfObjects();
+ map_space_->SizeOfObjects() + lo_space_->SizeOfObjects();
}
if (map_space_ == NULL) return false;
if (!map_space_->SetUp()) return false;
- // Initialize simple cell space.
- cell_space_ = new CellSpace(this, max_old_generation_size_, CELL_SPACE);
- if (cell_space_ == NULL) return false;
- if (!cell_space_->SetUp()) return false;
-
// The large object code space may contain code or data. We set the memory
// to be non-executable here for safety, but this means we need to enable it
// explicitly when allocating large code objects.
code_space_->MaximumCommittedMemory());
PrintF("maximum_committed_by_map_space=%" V8_PTR_PREFIX "d ",
map_space_->MaximumCommittedMemory());
- PrintF("maximum_committed_by_cell_space=%" V8_PTR_PREFIX "d ",
- cell_space_->MaximumCommittedMemory());
PrintF("maximum_committed_by_lo_space=%" V8_PTR_PREFIX "d ",
lo_space_->MaximumCommittedMemory());
PrintF("\n\n");
map_space_ = NULL;
}
- if (cell_space_ != NULL) {
- cell_space_->TearDown();
- delete cell_space_;
- cell_space_ = NULL;
- }
-
if (lo_space_ != NULL) {
lo_space_->TearDown();
delete lo_space_;
return heap_->code_space();
case MAP_SPACE:
return heap_->map_space();
- case CELL_SPACE:
- return heap_->cell_space();
case LO_SPACE:
return heap_->lo_space();
default:
return heap_->code_space();
case MAP_SPACE:
return heap_->map_space();
- case CELL_SPACE:
- return heap_->cell_space();
default:
return NULL;
}
case MAP_SPACE:
iterator_ = new HeapObjectIterator(heap_->map_space(), size_func_);
break;
- case CELL_SPACE:
- iterator_ = new HeapObjectIterator(heap_->cell_space(), size_func_);
- break;
case LO_SPACE:
iterator_ = new LargeObjectIterator(heap_->lo_space(), size_func_);
break;
OldSpace* old_space() { return old_space_; }
OldSpace* code_space() { return code_space_; }
MapSpace* map_space() { return map_space_; }
- CellSpace* cell_space() { return cell_space_; }
LargeObjectSpace* lo_space() { return lo_space_; }
PagedSpace* paged_space(int idx) {
switch (idx) {
return old_space();
case MAP_SPACE:
return map_space();
- case CELL_SPACE:
- return cell_space();
case CODE_SPACE:
return code_space();
case NEW_SPACE:
OldSpace* old_space_;
OldSpace* code_space_;
MapSpace* map_space_;
- CellSpace* cell_space_;
LargeObjectSpace* lo_space_;
HeapState gc_state_;
int gc_post_processing_depth_;
intptr_t* code_space_capacity; // 6
intptr_t* map_space_size; // 7
intptr_t* map_space_capacity; // 8
- intptr_t* cell_space_size; // 9
- intptr_t* cell_space_capacity; // 10
- intptr_t* lo_space_size; // 11
- int* global_handle_count; // 12
- int* weak_global_handle_count; // 13
- int* pending_global_handle_count; // 14
- int* near_death_global_handle_count; // 15
- int* free_global_handle_count; // 16
- intptr_t* memory_allocator_size; // 17
- intptr_t* memory_allocator_capacity; // 18
- int* objects_per_type; // 19
- int* size_per_type; // 20
- int* os_error; // 21
- int* end_marker; // 22
+ intptr_t* lo_space_size; // 9
+ int* global_handle_count; // 10
+ int* weak_global_handle_count; // 11
+ int* pending_global_handle_count; // 12
+ int* near_death_global_handle_count; // 13
+ int* free_global_handle_count; // 14
+ intptr_t* memory_allocator_size; // 15
+ intptr_t* memory_allocator_capacity; // 16
+ int* objects_per_type; // 17
+ int* size_per_type; // 18
+ int* os_error; // 19
+ int* end_marker; // 20
};
chunk->size() > static_cast<size_t>(Page::kPageSize) && is_compacting) {
chunk->SetFlag(MemoryChunk::RESCAN_ON_EVACUATION);
}
- } else if (chunk->owner()->identity() == CELL_SPACE ||
- chunk->scan_on_scavenge()) {
- chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING);
- chunk->ClearFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING);
} else {
chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING);
chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING);
void IncrementalMarking::DeactivateIncrementalWriteBarrier() {
DeactivateIncrementalWriteBarrierForSpace(heap_->old_space());
- DeactivateIncrementalWriteBarrierForSpace(heap_->cell_space());
DeactivateIncrementalWriteBarrierForSpace(heap_->map_space());
DeactivateIncrementalWriteBarrierForSpace(heap_->code_space());
DeactivateIncrementalWriteBarrierForSpace(heap_->new_space());
void IncrementalMarking::ActivateIncrementalWriteBarrier() {
ActivateIncrementalWriteBarrier(heap_->old_space());
- ActivateIncrementalWriteBarrier(heap_->cell_space());
ActivateIncrementalWriteBarrier(heap_->map_space());
ActivateIncrementalWriteBarrier(heap_->code_space());
ActivateIncrementalWriteBarrier(heap_->new_space());
static void VerifyMarking(Heap* heap) {
VerifyMarking(heap->old_space());
VerifyMarking(heap->code_space());
- VerifyMarking(heap->cell_space());
VerifyMarking(heap->map_space());
VerifyMarking(heap->new_space());
static void VerifyEvacuation(Heap* heap) {
VerifyEvacuation(heap, heap->old_space());
VerifyEvacuation(heap, heap->code_space());
- VerifyEvacuation(heap, heap->cell_space());
VerifyEvacuation(heap, heap->map_space());
VerifyEvacuation(heap->new_space());
if (FLAG_trace_fragmentation) {
TraceFragmentation(heap()->map_space());
- TraceFragmentation(heap()->cell_space());
}
heap()->old_space()->EvictEvacuationCandidatesFromFreeLists();
ClearInvalidSlotsBufferEntries(heap_->old_space());
ClearInvalidSlotsBufferEntries(heap_->code_space());
- ClearInvalidSlotsBufferEntries(heap_->cell_space());
ClearInvalidSlotsBufferEntries(heap_->map_space());
LargeObjectIterator it(heap_->lo_space());
VerifyValidSlotsBufferEntries(heap, heap->old_space());
VerifyValidSlotsBufferEntries(heap, heap->code_space());
- VerifyValidSlotsBufferEntries(heap, heap->cell_space());
VerifyValidSlotsBufferEntries(heap, heap->map_space());
LargeObjectIterator it(heap->lo_space());
void MarkCompactCollector::VerifyMarkbitsAreClean() {
VerifyMarkbitsAreClean(heap_->old_space());
VerifyMarkbitsAreClean(heap_->code_space());
- VerifyMarkbitsAreClean(heap_->cell_space());
VerifyMarkbitsAreClean(heap_->map_space());
VerifyMarkbitsAreClean(heap_->new_space());
ClearMarkbitsInPagedSpace(heap_->code_space());
ClearMarkbitsInPagedSpace(heap_->map_space());
ClearMarkbitsInPagedSpace(heap_->old_space());
- ClearMarkbitsInPagedSpace(heap_->cell_space());
ClearMarkbitsInNewSpace(heap_->new_space());
LargeObjectIterator it(heap_->lo_space());
return "CODE_SPACE";
case MAP_SPACE:
return "MAP_SPACE";
- case CELL_SPACE:
- return "CELL_SPACE";
case LO_SPACE:
return "LO_SPACE";
default:
DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space());
if (marking_deque_.IsFull()) return;
- DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space());
- if (marking_deque_.IsFull()) return;
-
LargeObjectIterator lo_it(heap()->lo_space());
DiscoverGreyObjectsWithIterator(heap(), &marking_deque_, &lo_it);
if (marking_deque_.IsFull()) return;
PrepareForCodeFlushing();
- if (was_marked_incrementally_) {
- // There is no write barrier on cells so we have to scan them now at the end
- // of the incremental marking.
- {
- HeapObjectIterator cell_iterator(heap()->cell_space());
- HeapObject* cell;
- while ((cell = cell_iterator.Next()) != NULL) {
- DCHECK(cell->IsCell());
- if (IsMarked(cell)) {
- int offset = Cell::kValueOffset;
- MarkCompactMarkingVisitor::VisitPointer(
- heap(), reinterpret_cast<Object**>(cell->address() + offset));
- }
- }
- }
- }
-
RootMarkingVisitor root_visitor(heap());
MarkRoots(&root_visitor);
for (Object** p = start; p < end; p++) UpdatePointer(p);
}
+ void VisitCell(RelocInfo* rinfo) {
+ DCHECK(rinfo->rmode() == RelocInfo::CELL);
+ Object* cell = rinfo->target_cell();
+ Object* old_cell = cell;
+ VisitPointer(&cell);
+ if (cell != old_cell) {
+ rinfo->set_target_cell(reinterpret_cast<Cell*>(cell));
+ }
+ }
+
void VisitEmbeddedPointer(RelocInfo* rinfo) {
DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
Object* target = rinfo->target_object();
space_owner_id = 4;
} else if (heap->map_space()->ContainsSafe(slot_address)) {
space_owner_id = 5;
- } else if (heap->cell_space()->ContainsSafe(slot_address)) {
- space_owner_id = 6;
} else {
// Lo space or other.
- space_owner_id = 7;
+ space_owner_id = 6;
}
data[index++] = space_owner_id;
data[index++] = 0x20aaaaaaaaUL;
rinfo.Visit(isolate, v);
break;
}
+ case SlotsBuffer::CELL_TARGET_SLOT: {
+ RelocInfo rinfo(addr, RelocInfo::CELL, 0, NULL);
+ rinfo.Visit(isolate, v);
+ break;
+ }
case SlotsBuffer::CODE_ENTRY_SLOT: {
v->VisitCodeEntry(addr);
break;
GCTracer::Scope gc_scope(heap()->tracer(),
GCTracer::Scope::MC_UPDATE_MISC_POINTERS);
- // Update pointers from cells.
- HeapObjectIterator cell_iterator(heap_->cell_space());
- for (HeapObject* cell = cell_iterator.Next(); cell != NULL;
- cell = cell_iterator.Next()) {
- if (cell->IsCell()) {
- Cell::BodyDescriptor::IterateBody(cell, &updating_visitor);
- }
- }
-
heap_->string_table()->Iterate(&updating_visitor);
// Update pointers from external string table.
SweepSpace(heap()->code_space(), SEQUENTIAL_SWEEPING);
}
- {
- GCTracer::Scope sweep_scope(heap()->tracer(),
- GCTracer::Scope::MC_SWEEP_CELL);
- SweepSpace(heap()->cell_space(), SEQUENTIAL_SWEEPING);
- }
-
EvacuateNewSpaceAndCandidates();
// ClearNonLiveReferences depends on precise sweeping of map space to
static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) {
if (RelocInfo::IsCodeTarget(rmode)) {
return SlotsBuffer::CODE_TARGET_SLOT;
+ } else if (RelocInfo::IsCell(rmode)) {
+ return SlotsBuffer::CELL_TARGET_SLOT;
} else if (RelocInfo::IsEmbeddedObject(rmode)) {
return SlotsBuffer::EMBEDDED_OBJECT_SLOT;
} else if (RelocInfo::IsDebugBreakSlot(rmode)) {
enum SlotType {
EMBEDDED_OBJECT_SLOT,
RELOCATED_CODE_OBJECT,
+ CELL_TARGET_SLOT,
CODE_TARGET_SLOT,
CODE_ENTRY_SLOT,
DEBUG_TARGET_SLOT,
return "EMBEDDED_OBJECT_SLOT";
case RELOCATED_CODE_OBJECT:
return "RELOCATED_CODE_OBJECT";
+ case CELL_TARGET_SLOT:
+ return "CELL_TARGET_SLOT";
case CODE_TARGET_SLOT:
return "CODE_TARGET_SLOT";
case CODE_ENTRY_SLOT:
RelocInfo* rinfo) {
DCHECK(rinfo->rmode() == RelocInfo::CELL);
Cell* cell = rinfo->target_cell();
- // No need to record slots because the cell space is not compacted during GC.
+ heap->mark_compact_collector()->RecordRelocSlot(rinfo, cell);
if (!rinfo->host()->IsWeakObject(cell)) {
StaticVisitor::MarkObject(heap, cell);
}
Space* owner = page->owner();
DCHECK(owner == page->heap()->old_space() ||
owner == page->heap()->map_space() ||
- owner == page->heap()->cell_space() ||
owner == page->heap()->code_space());
Initialize(reinterpret_cast<PagedSpace*>(owner), page->area_start(),
page->area_end(), kOnePageOnly, size_func);
ObjectSpace::kObjectSpaceOldSpace);
STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::CODE_SPACE) ==
ObjectSpace::kObjectSpaceCodeSpace);
-STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::CELL_SPACE) ==
- ObjectSpace::kObjectSpaceCellSpace);
STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::MAP_SPACE) ==
ObjectSpace::kObjectSpaceMapSpace);
// -----------------------------------------------------------------------------
-// CellSpace implementation
-// TODO(mvstanton): this is weird...the compiler can't make a vtable unless
-// there is at least one non-inlined virtual function. I would prefer to hide
-// the VerifyObject definition behind VERIFY_HEAP.
-
-void CellSpace::VerifyObject(HeapObject* object) { CHECK(object->IsCell()); }
-
-
-// -----------------------------------------------------------------------------
// LargeObjectIterator
LargeObjectIterator::LargeObjectIterator(LargeObjectSpace* space) {
// -----------------------------------------------------------------------------
-// Old space for simple property cell objects
-
-class CellSpace : public PagedSpace {
- public:
- // Creates a property cell space object with a maximum capacity.
- CellSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id)
- : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE) {}
-
- virtual int RoundSizeDownToObjectAlignment(int size) {
- if (base::bits::IsPowerOfTwo32(Cell::kSize)) {
- return RoundDown(size, Cell::kSize);
- } else {
- return (size / Cell::kSize) * Cell::kSize;
- }
- }
-
- protected:
- virtual void VerifyObject(HeapObject* obj);
-
- public:
- TRACK_MEMORY("CellSpace")
-};
-
-
-// -----------------------------------------------------------------------------
// Large objects ( > Page::kMaxHeapObjectSize ) are allocated and managed by
// the large object space. A large object is allocated from OS heap with
// extra padding bytes (Page::kPageSize + Page::kObjectStartOffset).
void StoreBuffer::Mark(Address addr) {
- DCHECK(!heap_->cell_space()->Contains(addr));
DCHECK(!heap_->code_space()->Contains(addr));
Address* top = reinterpret_cast<Address*>(heap_->store_buffer_top());
*top++ = addr;
void StoreBuffer::EnterDirectlyIntoStoreBuffer(Address addr) {
if (store_buffer_rebuilding_enabled_) {
- SLOW_DCHECK(!heap_->cell_space()->Contains(addr) &&
- !heap_->code_space()->Contains(addr) &&
+ SLOW_DCHECK(!heap_->code_space()->Contains(addr) &&
!heap_->new_space()->Contains(addr));
Address* top = old_top_;
*top++ = addr;
// functions to reduce the number of unnecessary clashes.
hash_sets_are_empty_ = false; // Hash sets are in use.
for (Address* current = start_; current < top; current++) {
- DCHECK(!heap_->cell_space()->Contains(*current));
DCHECK(!heap_->code_space()->Contains(*current));
uintptr_t int_addr = reinterpret_cast<uintptr_t>(*current);
// Shift out the last bits including any tags.
while (object->IsInnerAllocatedObject()) {
object = HInnerAllocatedObject::cast(object)->base_object();
}
- if (object->IsConstant() && HConstant::cast(object)->IsCell()) {
- return false;
- }
if (object->IsConstant() &&
HConstant::cast(object)->HasExternalReferenceValue()) {
// Stores to external references require no write barriers
void RelocInfo::set_target_cell(Cell* cell,
WriteBarrierMode write_barrier_mode,
ICacheFlushMode icache_flush_mode) {
+ DCHECK(cell->IsCell());
DCHECK(rmode_ == RelocInfo::CELL);
Address address = cell->address() + Cell::kValueOffset;
Memory::Address_at(pc_) = address;
}
__ mov(scratch, Operand(scratch, kDeltaToCmpImmediate));
__ mov(Operand(scratch, 0), map);
+ __ push(map);
+ // Scratch points at the cell payload. Calculate the start of the object.
+ __ sub(scratch, Immediate(Cell::kValueOffset - 1));
+ __ RecordWriteField(scratch, Cell::kValueOffset, map, function,
+ kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+ __ pop(map);
}
// Loop through the prototype chain of the object looking for the function
// Get the map location in scratch and patch it.
__ GetRelocatedValue(inline_site, scratch, v1); // v1 used as scratch.
__ sw(map, FieldMemOperand(scratch, Cell::kValueOffset));
+
+ __ mov(t4, map);
+ // |scratch| points at the beginning of the cell. Calculate the field
+ // containing the map.
+ __ Addu(function, scratch, Operand(Cell::kValueOffset - 1));
+ __ RecordWriteField(scratch, Cell::kValueOffset, t4, function,
+ kRAHasNotBeenSaved, kDontSaveFPRegs,
+ OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
}
// Register mapping: a3 is object map and t0 is function prototype.
// Get the map location in scratch and patch it.
__ GetRelocatedValue(inline_site, scratch, v1); // v1 used as scratch.
__ sd(map, FieldMemOperand(scratch, Cell::kValueOffset));
+
+ __ mov(t0, map);
+ // |scratch| points at the beginning of the cell. Calculate the
+ // field containing the map.
+ __ Daddu(function, scratch, Operand(Cell::kValueOffset - 1));
+ __ RecordWriteField(scratch, Cell::kValueOffset, t0, function,
+ kRAHasNotBeenSaved, kDontSaveFPRegs,
+ OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
}
// Register mapping: a3 is object map and a4 is function prototype.
}
-Object* Cell::value() const {
- return READ_FIELD(this, kValueOffset);
-}
-
-
-void Cell::set_value(Object* val, WriteBarrierMode ignored) {
- // The write barrier is not used for global property cells.
- DCHECK(!val->IsPropertyCell() && !val->IsCell());
- WRITE_FIELD(this, kValueOffset, val);
-}
-
+ACCESSORS(Cell, value, Object, kValueOffset)
ACCESSORS(PropertyCell, dependent_code, DependentCode, kDependentCodeOffset)
ACCESSORS(PropertyCell, value, Object, kValueOffset)
MAP_TYPE,
CODE_TYPE,
ODDBALL_TYPE,
- CELL_TYPE,
// "Data", objects that cannot contain non-map-word pointers to heap
// objects.
FIXED_ARRAY_TYPE,
CONSTANT_POOL_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
+ CELL_TYPE,
WEAK_CELL_TYPE,
PROPERTY_CELL_TYPE,
PROTOTYPE_INFO_TYPE,
static inline Cell* FromValueAddress(Address value) {
Object* result = FromAddress(value - kValueOffset);
- DCHECK(result->IsCell());
return static_cast<Cell*>(result);
}
// but that may change.
bool write_barrier_needed =
(current_object_address != NULL && source_space != NEW_SPACE &&
- source_space != CELL_SPACE && source_space != CODE_SPACE);
+ source_space != CODE_SPACE);
while (current < limit) {
byte data = source_.Get();
switch (data) {
CASE_STATEMENT(where, how, within, OLD_SPACE) \
CASE_STATEMENT(where, how, within, CODE_SPACE) \
CASE_STATEMENT(where, how, within, MAP_SPACE) \
- CASE_STATEMENT(where, how, within, CELL_SPACE) \
CASE_STATEMENT(where, how, within, LO_SPACE) \
CASE_BODY(where, how, within, kAnyOldSpace)
static int nop() { return kNop; }
// No reservation for large object space necessary.
- static const int kNumberOfPreallocatedSpaces = LO_SPACE;
+ static const int kNumberOfPreallocatedSpaces = LAST_PAGED_SPACE + 1;
static const int kNumberOfSpaces = LAST_SPACE + 1;
protected:
// ---------- byte code range 0x00..0x7f ----------
// Byte codes in this range represent Where, HowToCode and WhereToPoint.
// Where the pointed-to object can be found:
+ // The static assert below will trigger when the number of preallocated spaces
+ // changed. If that happens, update the bytecode ranges in the comments below.
+ STATIC_ASSERT(5 == kNumberOfSpaces);
enum Where {
- // 0x00..0x05 Allocate new object, in specified space.
+ // 0x00..0x04 Allocate new object, in specified space.
kNewObject = 0,
+ // 0x05 Unused (including 0x25, 0x45, 0x65).
// 0x06 Unused (including 0x26, 0x46, 0x66).
// 0x07 Unused (including 0x27, 0x47, 0x67).
- // 0x08..0x0d Reference to previous object from space.
+ // 0x08..0x0c Reference to previous object from space.
kBackref = 0x08,
// 0x0e Unused (including 0x2e, 0x4e, 0x6e).
// 0x0f Unused (including 0x2f, 0x4f, 0x6f).
- // 0x10..0x15 Reference to previous object from space after skip.
+ // 0x10..0x14 Reference to previous object from space after skip.
kBackrefWithSkip = 0x10,
// 0x16 Unused (including 0x36, 0x56, 0x76).
// 0x17 Unused (including 0x37, 0x57, 0x77).
__ movp(kScratchRegister,
Operand(kScratchRegister, kOffsetToMapCheckValue));
__ movp(Operand(kScratchRegister, 0), map);
+
+ __ movp(r8, map);
+ // Scratch points at the cell payload. Calculate the start of the object.
+ __ subp(kScratchRegister, Immediate(Cell::kValueOffset - 1));
+ __ RecordWriteField(kScratchRegister, Cell::kValueOffset, r8, function,
+ kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
}
// Loop through the prototype chain looking for the function prototype.