Remove PropertyCell space
Replaces StoreGlobalCell / LoadGlobalCell with NamedField variants that use write barriers. BUG= Review URL: https://codereview.chromium.org/1016803002 Cr-Commit-Position: refs/heads/master@{#27269}
This commit is contained in:
parent
9118b2fa87
commit
16c8485a35
@ -6619,7 +6619,7 @@ class Internals {
|
||||
static const int kJSObjectType = 0xbd;
|
||||
static const int kFirstNonstringType = 0x80;
|
||||
static const int kOddballType = 0x83;
|
||||
static const int kForeignType = 0x88;
|
||||
static const int kForeignType = 0x87;
|
||||
|
||||
static const int kUndefinedOddballKind = 5;
|
||||
static const int kNullOddballKind = 3;
|
||||
|
@ -249,10 +249,6 @@ void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
|
||||
heap_stats.cell_space_size = &cell_space_size;
|
||||
intptr_t cell_space_capacity;
|
||||
heap_stats.cell_space_capacity = &cell_space_capacity;
|
||||
intptr_t property_cell_space_size;
|
||||
heap_stats.property_cell_space_size = &property_cell_space_size;
|
||||
intptr_t property_cell_space_capacity;
|
||||
heap_stats.property_cell_space_capacity = &property_cell_space_capacity;
|
||||
intptr_t lo_space_size;
|
||||
heap_stats.lo_space_size = &lo_space_size;
|
||||
int global_handle_count;
|
||||
|
@ -2140,14 +2140,6 @@ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
|
||||
LLoadGlobalCell* result = new(zone()) LLoadGlobalCell;
|
||||
return instr->RequiresHoleCheck()
|
||||
? AssignEnvironment(DefineAsRegister(result))
|
||||
: DefineAsRegister(result);
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
|
||||
LOperand* context = UseFixed(instr->context(), cp);
|
||||
LOperand* global_object =
|
||||
@ -2162,16 +2154,6 @@ LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
|
||||
LOperand* value = UseRegister(instr->value());
|
||||
// Use a temp to check the value in the cell in the case where we perform
|
||||
// a hole check.
|
||||
return instr->RequiresHoleCheck()
|
||||
? AssignEnvironment(new(zone()) LStoreGlobalCell(value, TempRegister()))
|
||||
: new(zone()) LStoreGlobalCell(value, NULL);
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
|
||||
LOperand* context = UseRegisterAtStart(instr->value());
|
||||
LInstruction* result =
|
||||
|
@ -100,7 +100,6 @@ class LCodeGen;
|
||||
V(LoadRoot) \
|
||||
V(LoadFieldByIndex) \
|
||||
V(LoadFunctionPrototype) \
|
||||
V(LoadGlobalCell) \
|
||||
V(LoadGlobalGeneric) \
|
||||
V(LoadKeyed) \
|
||||
V(LoadKeyedGeneric) \
|
||||
@ -142,7 +141,6 @@ class LCodeGen;
|
||||
V(StoreCodeEntry) \
|
||||
V(StoreContextSlot) \
|
||||
V(StoreFrameContext) \
|
||||
V(StoreGlobalCell) \
|
||||
V(StoreKeyed) \
|
||||
V(StoreKeyedGeneric) \
|
||||
V(StoreNamedField) \
|
||||
@ -1704,13 +1702,6 @@ class LLoadKeyedGeneric FINAL : public LTemplateInstruction<1, 3, 1> {
|
||||
};
|
||||
|
||||
|
||||
class LLoadGlobalCell FINAL : public LTemplateInstruction<1, 0, 0> {
|
||||
public:
|
||||
DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load-global-cell")
|
||||
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalCell)
|
||||
};
|
||||
|
||||
|
||||
class LLoadGlobalGeneric FINAL : public LTemplateInstruction<1, 2, 1> {
|
||||
public:
|
||||
LLoadGlobalGeneric(LOperand* context, LOperand* global_object,
|
||||
@ -1732,21 +1723,6 @@ class LLoadGlobalGeneric FINAL : public LTemplateInstruction<1, 2, 1> {
|
||||
};
|
||||
|
||||
|
||||
class LStoreGlobalCell FINAL : public LTemplateInstruction<0, 1, 1> {
|
||||
public:
|
||||
LStoreGlobalCell(LOperand* value, LOperand* temp) {
|
||||
inputs_[0] = value;
|
||||
temps_[0] = temp;
|
||||
}
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
|
||||
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
|
||||
};
|
||||
|
||||
|
||||
class LLoadContextSlot FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LLoadContextSlot(LOperand* context) {
|
||||
|
@ -2982,18 +2982,6 @@ void LCodeGen::DoReturn(LReturn* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
|
||||
Register result = ToRegister(instr->result());
|
||||
__ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell().handle())));
|
||||
__ ldr(result, FieldMemOperand(ip, Cell::kValueOffset));
|
||||
if (instr->hydrogen()->RequiresHoleCheck()) {
|
||||
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
|
||||
__ cmp(result, ip);
|
||||
DeoptimizeIf(eq, instr, Deoptimizer::kHole);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
|
||||
DCHECK(FLAG_vector_ics);
|
||||
@ -3029,31 +3017,6 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
|
||||
Register value = ToRegister(instr->value());
|
||||
Register cell = scratch0();
|
||||
|
||||
// Load the cell.
|
||||
__ mov(cell, Operand(instr->hydrogen()->cell().handle()));
|
||||
|
||||
// If the cell we are storing to contains the hole it could have
|
||||
// been deleted from the property dictionary. In that case, we need
|
||||
// to update the property details in the property dictionary to mark
|
||||
// it as no longer deleted.
|
||||
if (instr->hydrogen()->RequiresHoleCheck()) {
|
||||
// We use a temp to check the payload (CompareRoot might clobber ip).
|
||||
Register payload = ToRegister(instr->temp());
|
||||
__ ldr(payload, FieldMemOperand(cell, Cell::kValueOffset));
|
||||
__ CompareRoot(payload, Heap::kTheHoleValueRootIndex);
|
||||
DeoptimizeIf(eq, instr, Deoptimizer::kHole);
|
||||
}
|
||||
|
||||
// Store the value.
|
||||
__ str(value, FieldMemOperand(cell, Cell::kValueOffset));
|
||||
// Cells are always rescanned, so no write barrier here.
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
|
||||
Register context = ToRegister(instr->context());
|
||||
Register result = ToRegister(instr->result());
|
||||
|
@ -1692,14 +1692,6 @@ LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
|
||||
LLoadGlobalCell* result = new(zone()) LLoadGlobalCell();
|
||||
return instr->RequiresHoleCheck()
|
||||
? AssignEnvironment(DefineAsRegister(result))
|
||||
: DefineAsRegister(result);
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
|
||||
LOperand* context = UseFixed(instr->context(), cp);
|
||||
LOperand* global_object =
|
||||
@ -2351,18 +2343,6 @@ LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
|
||||
LOperand* value = UseRegister(instr->value());
|
||||
if (instr->RequiresHoleCheck()) {
|
||||
return AssignEnvironment(new(zone()) LStoreGlobalCell(value,
|
||||
TempRegister(),
|
||||
TempRegister()));
|
||||
} else {
|
||||
return new(zone()) LStoreGlobalCell(value, TempRegister(), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
|
||||
LOperand* key = UseRegisterOrConstant(instr->key());
|
||||
LOperand* temp = NULL;
|
||||
|
@ -102,7 +102,6 @@ class LCodeGen;
|
||||
V(LoadContextSlot) \
|
||||
V(LoadFieldByIndex) \
|
||||
V(LoadFunctionPrototype) \
|
||||
V(LoadGlobalCell) \
|
||||
V(LoadGlobalGeneric) \
|
||||
V(LoadKeyedExternal) \
|
||||
V(LoadKeyedFixed) \
|
||||
@ -151,7 +150,6 @@ class LCodeGen;
|
||||
V(StoreCodeEntry) \
|
||||
V(StoreContextSlot) \
|
||||
V(StoreFrameContext) \
|
||||
V(StoreGlobalCell) \
|
||||
V(StoreKeyedExternal) \
|
||||
V(StoreKeyedFixed) \
|
||||
V(StoreKeyedFixedDouble) \
|
||||
@ -1731,13 +1729,6 @@ class LLoadFunctionPrototype FINAL : public LTemplateInstruction<1, 1, 1> {
|
||||
};
|
||||
|
||||
|
||||
class LLoadGlobalCell FINAL : public LTemplateInstruction<1, 0, 0> {
|
||||
public:
|
||||
DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load-global-cell")
|
||||
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalCell)
|
||||
};
|
||||
|
||||
|
||||
class LLoadGlobalGeneric FINAL : public LTemplateInstruction<1, 2, 1> {
|
||||
public:
|
||||
LLoadGlobalGeneric(LOperand* context, LOperand* global_object,
|
||||
@ -2809,23 +2800,6 @@ class LStoreContextSlot FINAL : public LTemplateInstruction<0, 2, 1> {
|
||||
};
|
||||
|
||||
|
||||
class LStoreGlobalCell FINAL : public LTemplateInstruction<0, 1, 2> {
|
||||
public:
|
||||
LStoreGlobalCell(LOperand* value, LOperand* temp1, LOperand* temp2) {
|
||||
inputs_[0] = value;
|
||||
temps_[0] = temp1;
|
||||
temps_[1] = temp2;
|
||||
}
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
LOperand* temp1() { return temps_[0]; }
|
||||
LOperand* temp2() { return temps_[1]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
|
||||
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
|
||||
};
|
||||
|
||||
|
||||
class LSubI FINAL : public LTemplateInstruction<1, 2, 0> {
|
||||
public:
|
||||
LSubI(LOperand* left, LOperand* right)
|
||||
|
@ -3395,17 +3395,6 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
|
||||
Register result = ToRegister(instr->result());
|
||||
__ Mov(result, Operand(Handle<Object>(instr->hydrogen()->cell().handle())));
|
||||
__ Ldr(result, FieldMemOperand(result, Cell::kValueOffset));
|
||||
if (instr->hydrogen()->RequiresHoleCheck()) {
|
||||
DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr,
|
||||
Deoptimizer::kHole);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
|
||||
DCHECK(FLAG_vector_ics);
|
||||
@ -5182,30 +5171,6 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
|
||||
Register value = ToRegister(instr->value());
|
||||
Register cell = ToRegister(instr->temp1());
|
||||
|
||||
// Load the cell.
|
||||
__ Mov(cell, Operand(instr->hydrogen()->cell().handle()));
|
||||
|
||||
// If the cell we are storing to contains the hole it could have
|
||||
// been deleted from the property dictionary. In that case, we need
|
||||
// to update the property details in the property dictionary to mark
|
||||
// it as no longer deleted. We deoptimize in that case.
|
||||
if (instr->hydrogen()->RequiresHoleCheck()) {
|
||||
Register payload = ToRegister(instr->temp2());
|
||||
__ Ldr(payload, FieldMemOperand(cell, Cell::kValueOffset));
|
||||
DeoptimizeIfRoot(payload, Heap::kTheHoleValueRootIndex, instr,
|
||||
Deoptimizer::kHole);
|
||||
}
|
||||
|
||||
// Store the value.
|
||||
__ Str(value, FieldMemOperand(cell, Cell::kValueOffset));
|
||||
// Cells are always rescanned, so no write barrier here.
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoStoreKeyedExternal(LStoreKeyedExternal* instr) {
|
||||
Register ext_ptr = ToRegister(instr->elements());
|
||||
Register key = no_reg;
|
||||
|
@ -1360,8 +1360,7 @@ HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() {
|
||||
builder.Then();
|
||||
builder.Deopt(Deoptimizer::kUnexpectedCellContentsInGlobalStore);
|
||||
builder.Else();
|
||||
HStoreNamedField* store = Add<HStoreNamedField>(cell, access, value);
|
||||
store->MarkReceiverAsCell();
|
||||
Add<HStoreNamedField>(cell, access, value);
|
||||
builder.End();
|
||||
}
|
||||
|
||||
|
@ -405,8 +405,6 @@ class AggregatedHistogramTimerScope {
|
||||
HP(external_fragmentation_map_space, V8.MemoryExternalFragmentationMapSpace) \
|
||||
HP(external_fragmentation_cell_space, \
|
||||
V8.MemoryExternalFragmentationCellSpace) \
|
||||
HP(external_fragmentation_property_cell_space, \
|
||||
V8.MemoryExternalFragmentationPropertyCellSpace) \
|
||||
HP(external_fragmentation_lo_space, V8.MemoryExternalFragmentationLoSpace) \
|
||||
/* Percentages of heap committed to each space. */ \
|
||||
HP(heap_fraction_new_space, V8.MemoryHeapFractionNewSpace) \
|
||||
@ -414,8 +412,6 @@ class AggregatedHistogramTimerScope {
|
||||
HP(heap_fraction_code_space, V8.MemoryHeapFractionCodeSpace) \
|
||||
HP(heap_fraction_map_space, V8.MemoryHeapFractionMapSpace) \
|
||||
HP(heap_fraction_cell_space, V8.MemoryHeapFractionCellSpace) \
|
||||
HP(heap_fraction_property_cell_space, \
|
||||
V8.MemoryHeapFractionPropertyCellSpace) \
|
||||
HP(heap_fraction_lo_space, V8.MemoryHeapFractionLoSpace) \
|
||||
/* Percentage of crankshafted codegen. */ \
|
||||
HP(codegen_fraction_crankshaft, V8.CodegenFractionCrankshaft)
|
||||
@ -428,8 +424,6 @@ class AggregatedHistogramTimerScope {
|
||||
V8.MemoryHeapSampleMapSpaceCommitted) \
|
||||
HM(heap_sample_cell_space_committed, \
|
||||
V8.MemoryHeapSampleCellSpaceCommitted) \
|
||||
HM(heap_sample_property_cell_space_committed, \
|
||||
V8.MemoryHeapSamplePropertyCellSpaceCommitted) \
|
||||
HM(heap_sample_code_space_committed, \
|
||||
V8.MemoryHeapSampleCodeSpaceCommitted) \
|
||||
HM(heap_sample_maximum_committed, \
|
||||
@ -603,11 +597,6 @@ class AggregatedHistogramTimerScope {
|
||||
SC(cell_space_bytes_available, V8.MemoryCellSpaceBytesAvailable) \
|
||||
SC(cell_space_bytes_committed, V8.MemoryCellSpaceBytesCommitted) \
|
||||
SC(cell_space_bytes_used, V8.MemoryCellSpaceBytesUsed) \
|
||||
SC(property_cell_space_bytes_available, \
|
||||
V8.MemoryPropertyCellSpaceBytesAvailable) \
|
||||
SC(property_cell_space_bytes_committed, \
|
||||
V8.MemoryPropertyCellSpaceBytesCommitted) \
|
||||
SC(property_cell_space_bytes_used, V8.MemoryPropertyCellSpaceBytesUsed) \
|
||||
SC(lo_space_bytes_available, V8.MemoryLoSpaceBytesAvailable) \
|
||||
SC(lo_space_bytes_committed, V8.MemoryLoSpaceBytesCommitted) \
|
||||
SC(lo_space_bytes_used, V8.MemoryLoSpaceBytesUsed)
|
||||
|
@ -117,11 +117,6 @@ void StatisticsExtension::GetCounters(
|
||||
{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->property_cell_space()->Size(), "property_cell_space_live_bytes"},
|
||||
{heap->property_cell_space()->Available(),
|
||||
"property_cell_space_available_bytes"},
|
||||
{heap->property_cell_space()->CommittedMemory(),
|
||||
"property_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"},
|
||||
|
@ -408,18 +408,17 @@ typedef bool (*WeakSlotCallbackWithHeap)(Heap* heap, Object** pointer);
|
||||
// consecutive.
|
||||
// Keep this enum in sync with the ObjectSpace enum in v8.h
|
||||
enum AllocationSpace {
|
||||
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.
|
||||
CELL_SPACE, // Only and all cell objects.
|
||||
PROPERTY_CELL_SPACE, // Only and all global property cell objects.
|
||||
LO_SPACE, // Promoted large 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.
|
||||
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 = PROPERTY_CELL_SPACE
|
||||
LAST_PAGED_SPACE = CELL_SPACE
|
||||
};
|
||||
const int kSpaceTagSize = 3;
|
||||
const int kSpaceTagMask = (1 << kSpaceTagSize) - 1;
|
||||
|
@ -196,8 +196,6 @@ AllocationResult Heap::AllocateRaw(int size_in_bytes, AllocationSpace space,
|
||||
allocation = lo_space_->AllocateRaw(size_in_bytes, NOT_EXECUTABLE);
|
||||
} else if (CELL_SPACE == space) {
|
||||
allocation = cell_space_->AllocateRaw(size_in_bytes);
|
||||
} else if (PROPERTY_CELL_SPACE == space) {
|
||||
allocation = property_cell_space_->AllocateRaw(size_in_bytes);
|
||||
} else {
|
||||
DCHECK(MAP_SPACE == space);
|
||||
allocation = map_space_->AllocateRaw(size_in_bytes);
|
||||
@ -390,7 +388,6 @@ bool Heap::AllowedToBeMigrated(HeapObject* obj, AllocationSpace dst) {
|
||||
return dst == src && type == CODE_TYPE;
|
||||
case MAP_SPACE:
|
||||
case CELL_SPACE:
|
||||
case PROPERTY_CELL_SPACE:
|
||||
case LO_SPACE:
|
||||
return false;
|
||||
}
|
||||
|
@ -88,7 +88,6 @@ Heap::Heap()
|
||||
code_space_(NULL),
|
||||
map_space_(NULL),
|
||||
cell_space_(NULL),
|
||||
property_cell_space_(NULL),
|
||||
lo_space_(NULL),
|
||||
gc_state_(NOT_IN_GC),
|
||||
gc_post_processing_depth_(0),
|
||||
@ -174,7 +173,7 @@ intptr_t Heap::Capacity() {
|
||||
|
||||
return new_space_.Capacity() + old_space_->Capacity() +
|
||||
code_space_->Capacity() + map_space_->Capacity() +
|
||||
cell_space_->Capacity() + property_cell_space_->Capacity();
|
||||
cell_space_->Capacity();
|
||||
}
|
||||
|
||||
|
||||
@ -183,7 +182,7 @@ intptr_t Heap::CommittedOldGenerationMemory() {
|
||||
|
||||
return old_space_->CommittedMemory() + code_space_->CommittedMemory() +
|
||||
map_space_->CommittedMemory() + cell_space_->CommittedMemory() +
|
||||
property_cell_space_->CommittedMemory() + lo_space_->Size();
|
||||
lo_space_->Size();
|
||||
}
|
||||
|
||||
|
||||
@ -202,7 +201,6 @@ size_t Heap::CommittedPhysicalMemory() {
|
||||
code_space_->CommittedPhysicalMemory() +
|
||||
map_space_->CommittedPhysicalMemory() +
|
||||
cell_space_->CommittedPhysicalMemory() +
|
||||
property_cell_space_->CommittedPhysicalMemory() +
|
||||
lo_space_->CommittedPhysicalMemory();
|
||||
}
|
||||
|
||||
@ -229,14 +227,13 @@ intptr_t Heap::Available() {
|
||||
|
||||
return new_space_.Available() + old_space_->Available() +
|
||||
code_space_->Available() + map_space_->Available() +
|
||||
cell_space_->Available() + property_cell_space_->Available();
|
||||
cell_space_->Available();
|
||||
}
|
||||
|
||||
|
||||
bool Heap::HasBeenSetUp() {
|
||||
return old_space_ != NULL && code_space_ != NULL && map_space_ != NULL &&
|
||||
cell_space_ != NULL && property_cell_space_ != NULL &&
|
||||
lo_space_ != NULL;
|
||||
cell_space_ != NULL && lo_space_ != NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -367,14 +364,6 @@ void Heap::PrintShortHeapStatistics() {
|
||||
", committed: %6" V8_PTR_PREFIX "d KB\n",
|
||||
cell_space_->SizeOfObjects() / KB, cell_space_->Available() / KB,
|
||||
cell_space_->CommittedMemory() / KB);
|
||||
PrintPID("PropertyCell space, used: %6" V8_PTR_PREFIX
|
||||
"d KB"
|
||||
", available: %6" V8_PTR_PREFIX
|
||||
"d KB"
|
||||
", committed: %6" V8_PTR_PREFIX "d KB\n",
|
||||
property_cell_space_->SizeOfObjects() / KB,
|
||||
property_cell_space_->Available() / KB,
|
||||
property_cell_space_->CommittedMemory() / KB);
|
||||
PrintPID("Large object space, used: %6" V8_PTR_PREFIX
|
||||
"d KB"
|
||||
", available: %6" V8_PTR_PREFIX
|
||||
@ -659,9 +648,6 @@ void Heap::GarbageCollectionEpilogue() {
|
||||
isolate_->counters()->heap_fraction_cell_space()->AddSample(
|
||||
static_cast<int>((cell_space()->CommittedMemory() * 100.0) /
|
||||
CommittedMemory()));
|
||||
isolate_->counters()->heap_fraction_property_cell_space()->AddSample(
|
||||
static_cast<int>((property_cell_space()->CommittedMemory() * 100.0) /
|
||||
CommittedMemory()));
|
||||
isolate_->counters()->heap_fraction_lo_space()->AddSample(static_cast<int>(
|
||||
(lo_space()->CommittedMemory() * 100.0) / CommittedMemory()));
|
||||
|
||||
@ -673,10 +659,6 @@ void Heap::GarbageCollectionEpilogue() {
|
||||
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_property_cell_space_committed()
|
||||
->AddSample(
|
||||
static_cast<int>(property_cell_space()->CommittedMemory() / KB));
|
||||
isolate_->counters()->heap_sample_code_space_committed()->AddSample(
|
||||
static_cast<int>(code_space()->CommittedMemory() / KB));
|
||||
|
||||
@ -707,7 +689,6 @@ void Heap::GarbageCollectionEpilogue() {
|
||||
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(property_cell_space)
|
||||
UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(lo_space)
|
||||
#undef UPDATE_COUNTERS_FOR_SPACE
|
||||
#undef UPDATE_FRAGMENTATION_FOR_SPACE
|
||||
@ -1578,19 +1559,6 @@ void Heap::Scavenge() {
|
||||
}
|
||||
}
|
||||
|
||||
// Copy objects reachable from global property cells by scavenging global
|
||||
// property cell values directly.
|
||||
HeapObjectIterator js_global_property_cell_iterator(property_cell_space_);
|
||||
for (HeapObject* heap_object = js_global_property_cell_iterator.Next();
|
||||
heap_object != NULL;
|
||||
heap_object = js_global_property_cell_iterator.Next()) {
|
||||
if (heap_object->IsPropertyCell()) {
|
||||
PropertyCell* cell = PropertyCell::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.
|
||||
@ -2853,8 +2821,7 @@ AllocationResult Heap::AllocatePropertyCell() {
|
||||
STATIC_ASSERT(PropertyCell::kSize <= Page::kMaxRegularHeapObjectSize);
|
||||
|
||||
HeapObject* result;
|
||||
AllocationResult allocation =
|
||||
AllocateRaw(size, PROPERTY_CELL_SPACE, PROPERTY_CELL_SPACE);
|
||||
AllocationResult allocation = AllocateRaw(size, OLD_SPACE, OLD_SPACE);
|
||||
if (!allocation.To(&result)) return allocation;
|
||||
|
||||
result->set_map_no_write_barrier(global_property_cell_map());
|
||||
@ -4766,8 +4733,6 @@ void Heap::ReportHeapStatistics(const char* title) {
|
||||
map_space_->ReportStatistics();
|
||||
PrintF("Cell space : ");
|
||||
cell_space_->ReportStatistics();
|
||||
PrintF("PropertyCell space : ");
|
||||
property_cell_space_->ReportStatistics();
|
||||
PrintF("Large object space : ");
|
||||
lo_space_->ReportStatistics();
|
||||
PrintF(">>>>>> ========================================= >>>>>>\n");
|
||||
@ -4783,8 +4748,7 @@ bool Heap::Contains(Address addr) {
|
||||
return HasBeenSetUp() &&
|
||||
(new_space_.ToSpaceContains(addr) || old_space_->Contains(addr) ||
|
||||
code_space_->Contains(addr) || map_space_->Contains(addr) ||
|
||||
cell_space_->Contains(addr) || property_cell_space_->Contains(addr) ||
|
||||
lo_space_->SlowContains(addr));
|
||||
cell_space_->Contains(addr) || lo_space_->SlowContains(addr));
|
||||
}
|
||||
|
||||
|
||||
@ -4808,8 +4772,6 @@ bool Heap::InSpace(Address addr, AllocationSpace space) {
|
||||
return map_space_->Contains(addr);
|
||||
case CELL_SPACE:
|
||||
return cell_space_->Contains(addr);
|
||||
case PROPERTY_CELL_SPACE:
|
||||
return property_cell_space_->Contains(addr);
|
||||
case LO_SPACE:
|
||||
return lo_space_->SlowContains(addr);
|
||||
}
|
||||
@ -4857,7 +4819,6 @@ void Heap::Verify() {
|
||||
VerifyPointersVisitor no_dirty_regions_visitor;
|
||||
code_space_->Verify(&no_dirty_regions_visitor);
|
||||
cell_space_->Verify(&no_dirty_regions_visitor);
|
||||
property_cell_space_->Verify(&no_dirty_regions_visitor);
|
||||
|
||||
lo_space_->Verify();
|
||||
}
|
||||
@ -5180,8 +5141,6 @@ void Heap::RecordStats(HeapStats* stats, bool take_snapshot) {
|
||||
*stats->map_space_capacity = map_space_->Capacity();
|
||||
*stats->cell_space_size = cell_space_->SizeOfObjects();
|
||||
*stats->cell_space_capacity = cell_space_->Capacity();
|
||||
*stats->property_cell_space_size = property_cell_space_->SizeOfObjects();
|
||||
*stats->property_cell_space_capacity = property_cell_space_->Capacity();
|
||||
*stats->lo_space_size = lo_space_->Size();
|
||||
isolate_->global_handles()->RecordStats(stats);
|
||||
*stats->memory_allocator_size = isolate()->memory_allocator()->Size();
|
||||
@ -5206,7 +5165,7 @@ void Heap::RecordStats(HeapStats* stats, bool take_snapshot) {
|
||||
intptr_t Heap::PromotedSpaceSizeOfObjects() {
|
||||
return old_space_->SizeOfObjects() + code_space_->SizeOfObjects() +
|
||||
map_space_->SizeOfObjects() + cell_space_->SizeOfObjects() +
|
||||
property_cell_space_->SizeOfObjects() + lo_space_->SizeOfObjects();
|
||||
lo_space_->SizeOfObjects();
|
||||
}
|
||||
|
||||
|
||||
@ -5353,12 +5312,6 @@ bool Heap::SetUp() {
|
||||
if (cell_space_ == NULL) return false;
|
||||
if (!cell_space_->SetUp()) return false;
|
||||
|
||||
// Initialize global property cell space.
|
||||
property_cell_space_ = new PropertyCellSpace(this, max_old_generation_size_,
|
||||
PROPERTY_CELL_SPACE);
|
||||
if (property_cell_space_ == NULL) return false;
|
||||
if (!property_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.
|
||||
@ -5469,8 +5422,6 @@ void Heap::TearDown() {
|
||||
map_space_->MaximumCommittedMemory());
|
||||
PrintF("maximum_committed_by_cell_space=%" V8_PTR_PREFIX "d ",
|
||||
cell_space_->MaximumCommittedMemory());
|
||||
PrintF("maximum_committed_by_property_space=%" V8_PTR_PREFIX "d ",
|
||||
property_cell_space_->MaximumCommittedMemory());
|
||||
PrintF("maximum_committed_by_lo_space=%" V8_PTR_PREFIX "d ",
|
||||
lo_space_->MaximumCommittedMemory());
|
||||
PrintF("\n\n");
|
||||
@ -5514,12 +5465,6 @@ void Heap::TearDown() {
|
||||
cell_space_ = NULL;
|
||||
}
|
||||
|
||||
if (property_cell_space_ != NULL) {
|
||||
property_cell_space_->TearDown();
|
||||
delete property_cell_space_;
|
||||
property_cell_space_ = NULL;
|
||||
}
|
||||
|
||||
if (lo_space_ != NULL) {
|
||||
lo_space_->TearDown();
|
||||
delete lo_space_;
|
||||
@ -5643,8 +5588,6 @@ Space* AllSpaces::next() {
|
||||
return heap_->map_space();
|
||||
case CELL_SPACE:
|
||||
return heap_->cell_space();
|
||||
case PROPERTY_CELL_SPACE:
|
||||
return heap_->property_cell_space();
|
||||
case LO_SPACE:
|
||||
return heap_->lo_space();
|
||||
default:
|
||||
@ -5663,8 +5606,6 @@ PagedSpace* PagedSpaces::next() {
|
||||
return heap_->map_space();
|
||||
case CELL_SPACE:
|
||||
return heap_->cell_space();
|
||||
case PROPERTY_CELL_SPACE:
|
||||
return heap_->property_cell_space();
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@ -5745,10 +5686,6 @@ ObjectIterator* SpaceIterator::CreateIterator() {
|
||||
case CELL_SPACE:
|
||||
iterator_ = new HeapObjectIterator(heap_->cell_space(), size_func_);
|
||||
break;
|
||||
case PROPERTY_CELL_SPACE:
|
||||
iterator_ =
|
||||
new HeapObjectIterator(heap_->property_cell_space(), size_func_);
|
||||
break;
|
||||
case LO_SPACE:
|
||||
iterator_ = new LargeObjectIterator(heap_->lo_space(), size_func_);
|
||||
break;
|
||||
|
@ -645,7 +645,6 @@ class Heap {
|
||||
OldSpace* code_space() { return code_space_; }
|
||||
MapSpace* map_space() { return map_space_; }
|
||||
CellSpace* cell_space() { return cell_space_; }
|
||||
PropertyCellSpace* property_cell_space() { return property_cell_space_; }
|
||||
LargeObjectSpace* lo_space() { return lo_space_; }
|
||||
PagedSpace* paged_space(int idx) {
|
||||
switch (idx) {
|
||||
@ -655,8 +654,6 @@ class Heap {
|
||||
return map_space();
|
||||
case CELL_SPACE:
|
||||
return cell_space();
|
||||
case PROPERTY_CELL_SPACE:
|
||||
return property_cell_space();
|
||||
case CODE_SPACE:
|
||||
return code_space();
|
||||
case NEW_SPACE:
|
||||
@ -1566,7 +1563,6 @@ class Heap {
|
||||
OldSpace* code_space_;
|
||||
MapSpace* map_space_;
|
||||
CellSpace* cell_space_;
|
||||
PropertyCellSpace* property_cell_space_;
|
||||
LargeObjectSpace* lo_space_;
|
||||
HeapState gc_state_;
|
||||
int gc_post_processing_depth_;
|
||||
@ -2185,8 +2181,6 @@ class HeapStats {
|
||||
int* size_per_type; // 20
|
||||
int* os_error; // 21
|
||||
int* end_marker; // 22
|
||||
intptr_t* property_cell_space_size; // 23
|
||||
intptr_t* property_cell_space_capacity; // 24
|
||||
};
|
||||
|
||||
|
||||
|
@ -303,7 +303,6 @@ void IncrementalMarking::SetOldSpacePageFlags(MemoryChunk* chunk,
|
||||
chunk->SetFlag(MemoryChunk::RESCAN_ON_EVACUATION);
|
||||
}
|
||||
} else if (chunk->owner()->identity() == CELL_SPACE ||
|
||||
chunk->owner()->identity() == PROPERTY_CELL_SPACE ||
|
||||
chunk->scan_on_scavenge()) {
|
||||
chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING);
|
||||
chunk->ClearFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING);
|
||||
@ -349,7 +348,6 @@ void IncrementalMarking::DeactivateIncrementalWriteBarrierForSpace(
|
||||
void IncrementalMarking::DeactivateIncrementalWriteBarrier() {
|
||||
DeactivateIncrementalWriteBarrierForSpace(heap_->old_space());
|
||||
DeactivateIncrementalWriteBarrierForSpace(heap_->cell_space());
|
||||
DeactivateIncrementalWriteBarrierForSpace(heap_->property_cell_space());
|
||||
DeactivateIncrementalWriteBarrierForSpace(heap_->map_space());
|
||||
DeactivateIncrementalWriteBarrierForSpace(heap_->code_space());
|
||||
DeactivateIncrementalWriteBarrierForSpace(heap_->new_space());
|
||||
@ -383,7 +381,6 @@ void IncrementalMarking::ActivateIncrementalWriteBarrier(NewSpace* space) {
|
||||
void IncrementalMarking::ActivateIncrementalWriteBarrier() {
|
||||
ActivateIncrementalWriteBarrier(heap_->old_space());
|
||||
ActivateIncrementalWriteBarrier(heap_->cell_space());
|
||||
ActivateIncrementalWriteBarrier(heap_->property_cell_space());
|
||||
ActivateIncrementalWriteBarrier(heap_->map_space());
|
||||
ActivateIncrementalWriteBarrier(heap_->code_space());
|
||||
ActivateIncrementalWriteBarrier(heap_->new_space());
|
||||
|
@ -138,7 +138,6 @@ static void VerifyMarking(Heap* heap) {
|
||||
VerifyMarking(heap->old_space());
|
||||
VerifyMarking(heap->code_space());
|
||||
VerifyMarking(heap->cell_space());
|
||||
VerifyMarking(heap->property_cell_space());
|
||||
VerifyMarking(heap->map_space());
|
||||
VerifyMarking(heap->new_space());
|
||||
|
||||
@ -217,7 +216,6 @@ static void VerifyEvacuation(Heap* heap) {
|
||||
VerifyEvacuation(heap, heap->old_space());
|
||||
VerifyEvacuation(heap, heap->code_space());
|
||||
VerifyEvacuation(heap, heap->cell_space());
|
||||
VerifyEvacuation(heap, heap->property_cell_space());
|
||||
VerifyEvacuation(heap, heap->map_space());
|
||||
VerifyEvacuation(heap->new_space());
|
||||
|
||||
@ -271,7 +269,6 @@ bool MarkCompactCollector::StartCompaction(CompactionMode mode) {
|
||||
if (FLAG_trace_fragmentation) {
|
||||
TraceFragmentation(heap()->map_space());
|
||||
TraceFragmentation(heap()->cell_space());
|
||||
TraceFragmentation(heap()->property_cell_space());
|
||||
}
|
||||
|
||||
heap()->old_space()->EvictEvacuationCandidatesFromFreeLists();
|
||||
@ -364,7 +361,6 @@ void MarkCompactCollector::VerifyMarkbitsAreClean() {
|
||||
VerifyMarkbitsAreClean(heap_->old_space());
|
||||
VerifyMarkbitsAreClean(heap_->code_space());
|
||||
VerifyMarkbitsAreClean(heap_->cell_space());
|
||||
VerifyMarkbitsAreClean(heap_->property_cell_space());
|
||||
VerifyMarkbitsAreClean(heap_->map_space());
|
||||
VerifyMarkbitsAreClean(heap_->new_space());
|
||||
|
||||
@ -422,7 +418,6 @@ void MarkCompactCollector::ClearMarkbits() {
|
||||
ClearMarkbitsInPagedSpace(heap_->map_space());
|
||||
ClearMarkbitsInPagedSpace(heap_->old_space());
|
||||
ClearMarkbitsInPagedSpace(heap_->cell_space());
|
||||
ClearMarkbitsInPagedSpace(heap_->property_cell_space());
|
||||
ClearMarkbitsInNewSpace(heap_->new_space());
|
||||
|
||||
LargeObjectIterator it(heap_->lo_space());
|
||||
@ -568,8 +563,6 @@ const char* AllocationSpaceName(AllocationSpace space) {
|
||||
return "MAP_SPACE";
|
||||
case CELL_SPACE:
|
||||
return "CELL_SPACE";
|
||||
case PROPERTY_CELL_SPACE:
|
||||
return "PROPERTY_CELL_SPACE";
|
||||
case LO_SPACE:
|
||||
return "LO_SPACE";
|
||||
default:
|
||||
@ -2034,10 +2027,6 @@ void MarkCompactCollector::RefillMarkingDeque() {
|
||||
DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space());
|
||||
if (marking_deque_.IsFull()) return;
|
||||
|
||||
DiscoverGreyObjectsInSpace(heap(), &marking_deque_,
|
||||
heap()->property_cell_space());
|
||||
if (marking_deque_.IsFull()) return;
|
||||
|
||||
LargeObjectIterator lo_it(heap()->lo_space());
|
||||
DiscoverGreyObjectsWithIterator(heap(), &marking_deque_, &lo_it);
|
||||
if (marking_deque_.IsFull()) return;
|
||||
@ -2242,17 +2231,6 @@ void MarkCompactCollector::MarkLiveObjects() {
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
HeapObjectIterator js_global_property_cell_iterator(
|
||||
heap()->property_cell_space());
|
||||
HeapObject* cell;
|
||||
while ((cell = js_global_property_cell_iterator.Next()) != NULL) {
|
||||
DCHECK(cell->IsPropertyCell());
|
||||
if (IsMarked(cell)) {
|
||||
MarkCompactMarkingVisitor::VisitPropertyCell(cell->map(), cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RootMarkingVisitor root_visitor(heap());
|
||||
@ -2909,11 +2887,9 @@ void PointersUpdatingVisitor::CheckLayoutDescriptorAndDie(Heap* heap,
|
||||
space_owner_id = 5;
|
||||
} else if (heap->cell_space()->ContainsSafe(slot_address)) {
|
||||
space_owner_id = 6;
|
||||
} else if (heap->property_cell_space()->ContainsSafe(slot_address)) {
|
||||
space_owner_id = 7;
|
||||
} else {
|
||||
// Lo space or other.
|
||||
space_owner_id = 8;
|
||||
space_owner_id = 7;
|
||||
}
|
||||
data[index++] = space_owner_id;
|
||||
data[index++] = 0x20aaaaaaaaUL;
|
||||
@ -3710,15 +3686,6 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
|
||||
}
|
||||
}
|
||||
|
||||
HeapObjectIterator js_global_property_cell_iterator(
|
||||
heap_->property_cell_space());
|
||||
for (HeapObject* cell = js_global_property_cell_iterator.Next(); cell != NULL;
|
||||
cell = js_global_property_cell_iterator.Next()) {
|
||||
if (cell->IsPropertyCell()) {
|
||||
PropertyCell::BodyDescriptor::IterateBody(cell, &updating_visitor);
|
||||
}
|
||||
}
|
||||
|
||||
heap_->string_table()->Iterate(&updating_visitor);
|
||||
|
||||
// Update pointers from external string table.
|
||||
@ -4337,7 +4304,6 @@ void MarkCompactCollector::SweepSpaces() {
|
||||
GCTracer::Scope sweep_scope(heap()->tracer(),
|
||||
GCTracer::Scope::MC_SWEEP_CELL);
|
||||
SweepSpace(heap()->cell_space(), SEQUENTIAL_SWEEPING);
|
||||
SweepSpace(heap()->property_cell_space(), SEQUENTIAL_SWEEPING);
|
||||
}
|
||||
|
||||
EvacuateNewSpaceAndCandidates();
|
||||
|
@ -44,7 +44,6 @@ HeapObjectIterator::HeapObjectIterator(Page* page,
|
||||
DCHECK(owner == page->heap()->old_space() ||
|
||||
owner == page->heap()->map_space() ||
|
||||
owner == page->heap()->cell_space() ||
|
||||
owner == page->heap()->property_cell_space() ||
|
||||
owner == page->heap()->code_space());
|
||||
Initialize(reinterpret_cast<PagedSpace*>(owner), page->area_start(),
|
||||
page->area_end(), kOnePageOnly, size_func);
|
||||
@ -927,9 +926,6 @@ 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::PROPERTY_CELL_SPACE) ==
|
||||
ObjectSpace::kObjectSpacePropertyCellSpace);
|
||||
STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::MAP_SPACE) ==
|
||||
ObjectSpace::kObjectSpaceMapSpace);
|
||||
|
||||
@ -2783,7 +2779,7 @@ void MapSpace::VerifyObject(HeapObject* object) { CHECK(object->IsMap()); }
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// CellSpace and PropertyCellSpace implementation
|
||||
// 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.
|
||||
@ -2791,11 +2787,6 @@ void MapSpace::VerifyObject(HeapObject* object) { CHECK(object->IsMap()); }
|
||||
void CellSpace::VerifyObject(HeapObject* object) { CHECK(object->IsCell()); }
|
||||
|
||||
|
||||
void PropertyCellSpace::VerifyObject(HeapObject* object) {
|
||||
CHECK(object->IsPropertyCell());
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// LargeObjectIterator
|
||||
|
||||
|
@ -2674,31 +2674,6 @@ class CellSpace : public PagedSpace {
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Old space for all global object property cell objects
|
||||
|
||||
class PropertyCellSpace : public PagedSpace {
|
||||
public:
|
||||
// Creates a property cell space object with a maximum capacity.
|
||||
PropertyCellSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id)
|
||||
: PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE) {}
|
||||
|
||||
virtual int RoundSizeDownToObjectAlignment(int size) {
|
||||
if (base::bits::IsPowerOfTwo32(PropertyCell::kSize)) {
|
||||
return RoundDown(size, PropertyCell::kSize);
|
||||
} else {
|
||||
return (size / PropertyCell::kSize) * PropertyCell::kSize;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void VerifyObject(HeapObject* obj);
|
||||
|
||||
public:
|
||||
TRACK_MEMORY("PropertyCellSpace")
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Large objects ( > Page::kMaxHeapObjectSize ) are allocated and managed by
|
||||
// the large object space. A large object is allocated from OS heap with
|
||||
|
@ -346,17 +346,20 @@ SideEffects SideEffectsTracker::ComputeChanges(HInstruction* instr) {
|
||||
int index;
|
||||
SideEffects result(instr->ChangesFlags());
|
||||
if (result.ContainsFlag(kGlobalVars)) {
|
||||
if (instr->IsStoreGlobalCell() &&
|
||||
ComputeGlobalVar(HStoreGlobalCell::cast(instr)->cell(), &index)) {
|
||||
result.RemoveFlag(kGlobalVars);
|
||||
result.AddSpecial(GlobalVar(index));
|
||||
} else {
|
||||
for (index = 0; index < kNumberOfGlobalVars; ++index) {
|
||||
if (instr->IsStoreNamedField()) {
|
||||
HStoreNamedField* store = HStoreNamedField::cast(instr);
|
||||
HConstant* target = HConstant::cast(store->object());
|
||||
if (ComputeGlobalVar(Unique<PropertyCell>::cast(target->GetUnique()),
|
||||
&index)) {
|
||||
result.RemoveFlag(kGlobalVars);
|
||||
result.AddSpecial(GlobalVar(index));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result.ContainsFlag(kInobjectFields)) {
|
||||
for (index = 0; index < kNumberOfGlobalVars; ++index) {
|
||||
result.AddSpecial(GlobalVar(index));
|
||||
}
|
||||
} else if (result.ContainsFlag(kInobjectFields)) {
|
||||
if (instr->IsStoreNamedField() &&
|
||||
ComputeInobjectField(HStoreNamedField::cast(instr)->access(), &index)) {
|
||||
result.RemoveFlag(kInobjectFields);
|
||||
@ -375,17 +378,20 @@ SideEffects SideEffectsTracker::ComputeDependsOn(HInstruction* instr) {
|
||||
int index;
|
||||
SideEffects result(instr->DependsOnFlags());
|
||||
if (result.ContainsFlag(kGlobalVars)) {
|
||||
if (instr->IsLoadGlobalCell() &&
|
||||
ComputeGlobalVar(HLoadGlobalCell::cast(instr)->cell(), &index)) {
|
||||
result.RemoveFlag(kGlobalVars);
|
||||
result.AddSpecial(GlobalVar(index));
|
||||
} else {
|
||||
for (index = 0; index < kNumberOfGlobalVars; ++index) {
|
||||
if (instr->IsLoadNamedField()) {
|
||||
HLoadNamedField* load = HLoadNamedField::cast(instr);
|
||||
HConstant* target = HConstant::cast(load->object());
|
||||
if (ComputeGlobalVar(Unique<PropertyCell>::cast(target->GetUnique()),
|
||||
&index)) {
|
||||
result.RemoveFlag(kGlobalVars);
|
||||
result.AddSpecial(GlobalVar(index));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result.ContainsFlag(kInobjectFields)) {
|
||||
for (index = 0; index < kNumberOfGlobalVars; ++index) {
|
||||
result.AddSpecial(GlobalVar(index));
|
||||
}
|
||||
} else if (result.ContainsFlag(kInobjectFields)) {
|
||||
if (instr->IsLoadNamedField() &&
|
||||
ComputeInobjectField(HLoadNamedField::cast(instr)->access(), &index)) {
|
||||
result.RemoveFlag(kInobjectFields);
|
||||
@ -439,7 +445,8 @@ GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
|
||||
}
|
||||
|
||||
|
||||
bool SideEffectsTracker::ComputeGlobalVar(Unique<Cell> cell, int* index) {
|
||||
bool SideEffectsTracker::ComputeGlobalVar(Unique<PropertyCell> cell,
|
||||
int* index) {
|
||||
for (int i = 0; i < num_global_vars_; ++i) {
|
||||
if (cell == global_vars_[i]) {
|
||||
*index = i;
|
||||
|
@ -70,7 +70,7 @@ class SideEffectsTracker FINAL BASE_EMBEDDED {
|
||||
|
||||
private:
|
||||
friend std::ostream& operator<<(std::ostream& os, const TrackedEffects& f);
|
||||
bool ComputeGlobalVar(Unique<Cell> cell, int* index);
|
||||
bool ComputeGlobalVar(Unique<PropertyCell> cell, int* index);
|
||||
bool ComputeInobjectField(HObjectAccess access, int* index);
|
||||
|
||||
static int GlobalVar(int index) {
|
||||
@ -86,7 +86,7 @@ class SideEffectsTracker FINAL BASE_EMBEDDED {
|
||||
|
||||
// Track up to four global vars.
|
||||
static const int kNumberOfGlobalVars = 4;
|
||||
Unique<Cell> global_vars_[kNumberOfGlobalVars];
|
||||
Unique<PropertyCell> global_vars_[kNumberOfGlobalVars];
|
||||
int num_global_vars_;
|
||||
|
||||
// Track up to n inobject fields.
|
||||
|
@ -871,7 +871,6 @@ bool HInstruction::CanDeoptimize() {
|
||||
case HValue::kInvokeFunction:
|
||||
case HValue::kLoadContextSlot:
|
||||
case HValue::kLoadFunctionPrototype:
|
||||
case HValue::kLoadGlobalCell:
|
||||
case HValue::kLoadKeyed:
|
||||
case HValue::kLoadKeyedGeneric:
|
||||
case HValue::kMathFloorOfDiv:
|
||||
@ -887,7 +886,6 @@ bool HInstruction::CanDeoptimize() {
|
||||
case HValue::kSimulate:
|
||||
case HValue::kStackCheck:
|
||||
case HValue::kStoreContextSlot:
|
||||
case HValue::kStoreGlobalCell:
|
||||
case HValue::kStoreKeyedGeneric:
|
||||
case HValue::kStringAdd:
|
||||
case HValue::kStringCompareAndBranch:
|
||||
@ -3624,14 +3622,6 @@ std::ostream& HTransitionElementsKind::PrintDataTo(
|
||||
}
|
||||
|
||||
|
||||
std::ostream& HLoadGlobalCell::PrintDataTo(std::ostream& os) const { // NOLINT
|
||||
os << "[" << *cell().handle() << "]";
|
||||
if (details_.IsConfigurable()) os << " (configurable)";
|
||||
if (details_.IsReadOnly()) os << " (read-only)";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& HLoadGlobalGeneric::PrintDataTo(
|
||||
std::ostream& os) const { // NOLINT
|
||||
return os << name()->ToCString().get() << " ";
|
||||
@ -3645,14 +3635,6 @@ std::ostream& HInnerAllocatedObject::PrintDataTo(
|
||||
}
|
||||
|
||||
|
||||
std::ostream& HStoreGlobalCell::PrintDataTo(std::ostream& os) const { // NOLINT
|
||||
os << "[" << *cell().handle() << "] = " << NameOf(value());
|
||||
if (details_.IsConfigurable()) os << " (configurable)";
|
||||
if (details_.IsReadOnly()) os << " (read-only)";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& HLoadContextSlot::PrintDataTo(std::ostream& os) const { // NOLINT
|
||||
return os << NameOf(value()) << "[" << slot_index() << "]";
|
||||
}
|
||||
|
@ -117,7 +117,6 @@ class LChunkBuilder;
|
||||
V(LoadContextSlot) \
|
||||
V(LoadFieldByIndex) \
|
||||
V(LoadFunctionPrototype) \
|
||||
V(LoadGlobalCell) \
|
||||
V(LoadGlobalGeneric) \
|
||||
V(LoadKeyed) \
|
||||
V(LoadKeyedGeneric) \
|
||||
@ -146,7 +145,6 @@ class LChunkBuilder;
|
||||
V(StoreCodeEntry) \
|
||||
V(StoreContextSlot) \
|
||||
V(StoreFrameContext) \
|
||||
V(StoreGlobalCell) \
|
||||
V(StoreKeyed) \
|
||||
V(StoreKeyedGeneric) \
|
||||
V(StoreNamedField) \
|
||||
@ -3501,7 +3499,7 @@ class HConstant FINAL : public HTemplateInstruction<0> {
|
||||
|
||||
bool IsCell() const {
|
||||
InstanceType instance_type = GetInstanceType();
|
||||
return instance_type == CELL_TYPE || instance_type == PROPERTY_CELL_TYPE;
|
||||
return instance_type == CELL_TYPE;
|
||||
}
|
||||
|
||||
Representation RequiredInputRepresentation(int index) OVERRIDE {
|
||||
@ -5414,47 +5412,6 @@ class HUnknownOSRValue FINAL : public HTemplateInstruction<0> {
|
||||
};
|
||||
|
||||
|
||||
class HLoadGlobalCell FINAL : public HTemplateInstruction<0> {
|
||||
public:
|
||||
DECLARE_INSTRUCTION_FACTORY_P2(HLoadGlobalCell, Handle<Cell>,
|
||||
PropertyDetails);
|
||||
|
||||
Unique<Cell> cell() const { return cell_; }
|
||||
// TODO(dcarney): remove this.
|
||||
bool RequiresHoleCheck() const { return false; }
|
||||
|
||||
std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE; // NOLINT
|
||||
|
||||
intptr_t Hashcode() OVERRIDE { return cell_.Hashcode(); }
|
||||
|
||||
void FinalizeUniqueness() OVERRIDE { cell_ = Unique<Cell>(cell_.handle()); }
|
||||
|
||||
Representation RequiredInputRepresentation(int index) OVERRIDE {
|
||||
return Representation::None();
|
||||
}
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
|
||||
|
||||
protected:
|
||||
bool DataEquals(HValue* other) OVERRIDE {
|
||||
return cell_ == HLoadGlobalCell::cast(other)->cell_;
|
||||
}
|
||||
|
||||
private:
|
||||
HLoadGlobalCell(Handle<Cell> cell, PropertyDetails details)
|
||||
: cell_(Unique<Cell>::CreateUninitialized(cell)), details_(details) {
|
||||
set_representation(Representation::Tagged());
|
||||
SetFlag(kUseGVN);
|
||||
SetDependsOnFlag(kGlobalVars);
|
||||
}
|
||||
|
||||
bool IsDeletable() const OVERRIDE { return true; }
|
||||
|
||||
Unique<Cell> cell_;
|
||||
PropertyDetails details_;
|
||||
};
|
||||
|
||||
|
||||
class HLoadGlobalGeneric FINAL : public HTemplateInstruction<2> {
|
||||
public:
|
||||
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HLoadGlobalGeneric, HValue*,
|
||||
@ -5797,44 +5754,6 @@ inline PointersToHereCheck PointersToHereCheckForObject(HValue* object,
|
||||
}
|
||||
|
||||
|
||||
class HStoreGlobalCell FINAL : public HUnaryOperation {
|
||||
public:
|
||||
DECLARE_INSTRUCTION_FACTORY_P3(HStoreGlobalCell, HValue*,
|
||||
Handle<PropertyCell>, PropertyDetails);
|
||||
|
||||
Unique<PropertyCell> cell() const { return cell_; }
|
||||
// TODO(dcarney): remove
|
||||
bool RequiresHoleCheck() const { return false; }
|
||||
bool NeedsWriteBarrier() {
|
||||
return StoringValueNeedsWriteBarrier(value());
|
||||
}
|
||||
|
||||
void FinalizeUniqueness() OVERRIDE {
|
||||
cell_ = Unique<PropertyCell>(cell_.handle());
|
||||
}
|
||||
|
||||
Representation RequiredInputRepresentation(int index) OVERRIDE {
|
||||
return Representation::Tagged();
|
||||
}
|
||||
std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE; // NOLINT
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
|
||||
|
||||
private:
|
||||
HStoreGlobalCell(HValue* value,
|
||||
Handle<PropertyCell> cell,
|
||||
PropertyDetails details)
|
||||
: HUnaryOperation(value),
|
||||
cell_(Unique<PropertyCell>::CreateUninitialized(cell)),
|
||||
details_(details) {
|
||||
SetChangesFlag(kGlobalVars);
|
||||
}
|
||||
|
||||
Unique<PropertyCell> cell_;
|
||||
PropertyDetails details_;
|
||||
};
|
||||
|
||||
|
||||
class HLoadContextSlot FINAL : public HUnaryOperation {
|
||||
public:
|
||||
enum Mode {
|
||||
@ -6925,14 +6844,6 @@ class HStoreNamedField FINAL : public HTemplateInstruction<3> {
|
||||
SetChangesFlag(kMaps);
|
||||
}
|
||||
|
||||
void MarkReceiverAsCell() {
|
||||
bit_field_ = ReceiverIsCellField::update(bit_field_, true);
|
||||
}
|
||||
|
||||
bool receiver_is_cell() const {
|
||||
return ReceiverIsCellField::decode(bit_field_);
|
||||
}
|
||||
|
||||
bool NeedsWriteBarrier() const {
|
||||
DCHECK(!field_representation().IsDouble() ||
|
||||
(FLAG_unbox_double_fields && access_.IsInobject()) ||
|
||||
@ -6941,7 +6852,6 @@ class HStoreNamedField FINAL : public HTemplateInstruction<3> {
|
||||
if (field_representation().IsSmi()) return false;
|
||||
if (field_representation().IsInteger32()) return false;
|
||||
if (field_representation().IsExternal()) return false;
|
||||
if (receiver_is_cell()) return false;
|
||||
return StoringValueNeedsWriteBarrier(value()) &&
|
||||
ReceiverObjectNeedsWriteBarrier(object(), value(), dominator());
|
||||
}
|
||||
@ -7001,7 +6911,6 @@ class HStoreNamedField FINAL : public HTemplateInstruction<3> {
|
||||
|
||||
class HasTransitionField : public BitField<bool, 0, 1> {};
|
||||
class StoreModeField : public BitField<StoreFieldOrKeyedMode, 1, 1> {};
|
||||
class ReceiverIsCellField : public BitField<bool, 2, 1> {};
|
||||
|
||||
HObjectAccess access_;
|
||||
HValue* dominator_;
|
||||
|
@ -5358,8 +5358,11 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
|
||||
HConstant* constant = New<HConstant>(constant_object);
|
||||
return ast_context()->ReturnInstruction(constant, expr->id());
|
||||
} else {
|
||||
HLoadGlobalCell* instr =
|
||||
New<HLoadGlobalCell>(cell, it.property_details());
|
||||
HConstant* cell_constant = Add<HConstant>(cell);
|
||||
HLoadNamedField* instr = New<HLoadNamedField>(
|
||||
cell_constant, nullptr, HObjectAccess::ForPropertyCellValue());
|
||||
instr->ClearDependsOnFlag(kInobjectFields);
|
||||
instr->SetDependsOnFlag(kGlobalVars);
|
||||
return ast_context()->ReturnInstruction(instr, expr->id());
|
||||
}
|
||||
} else {
|
||||
@ -6538,8 +6541,11 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
|
||||
builder.End();
|
||||
}
|
||||
}
|
||||
HInstruction* instr =
|
||||
Add<HStoreGlobalCell>(value, cell, it.property_details());
|
||||
HConstant* cell_constant = Add<HConstant>(cell);
|
||||
HInstruction* instr = Add<HStoreNamedField>(
|
||||
cell_constant, HObjectAccess::ForPropertyCellValue(), value);
|
||||
instr->ClearChangesFlag(kInobjectFields);
|
||||
instr->SetChangesFlag(kGlobalVars);
|
||||
if (instr->HasObservableSideEffects()) {
|
||||
Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
|
||||
}
|
||||
|
@ -2863,16 +2863,6 @@ void LCodeGen::DoReturn(LReturn* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
|
||||
Register result = ToRegister(instr->result());
|
||||
__ mov(result, Operand::ForCell(instr->hydrogen()->cell().handle()));
|
||||
if (instr->hydrogen()->RequiresHoleCheck()) {
|
||||
__ cmp(result, factory()->the_hole_value());
|
||||
DeoptimizeIf(equal, instr, Deoptimizer::kHole);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
|
||||
DCHECK(FLAG_vector_ics);
|
||||
@ -2908,25 +2898,6 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
|
||||
Register value = ToRegister(instr->value());
|
||||
Handle<PropertyCell> cell_handle = instr->hydrogen()->cell().handle();
|
||||
|
||||
// If the cell we are storing to contains the hole it could have
|
||||
// been deleted from the property dictionary. In that case, we need
|
||||
// to update the property details in the property dictionary to mark
|
||||
// it as no longer deleted. We deoptimize in that case.
|
||||
if (instr->hydrogen()->RequiresHoleCheck()) {
|
||||
__ cmp(Operand::ForCell(cell_handle), factory()->the_hole_value());
|
||||
DeoptimizeIf(equal, instr, Deoptimizer::kHole);
|
||||
}
|
||||
|
||||
// Store the value.
|
||||
__ mov(Operand::ForCell(cell_handle), value);
|
||||
// Cells are always rescanned, so no write barrier here.
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
|
||||
Register context = ToRegister(instr->context());
|
||||
Register result = ToRegister(instr->result());
|
||||
|
@ -2132,14 +2132,6 @@ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
|
||||
LLoadGlobalCell* result = new(zone()) LLoadGlobalCell;
|
||||
return instr->RequiresHoleCheck()
|
||||
? AssignEnvironment(DefineAsRegister(result))
|
||||
: DefineAsRegister(result);
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
|
||||
LOperand* context = UseFixed(instr->context(), esi);
|
||||
LOperand* global_object =
|
||||
@ -2155,13 +2147,6 @@ LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
|
||||
LStoreGlobalCell* result =
|
||||
new(zone()) LStoreGlobalCell(UseRegister(instr->value()));
|
||||
return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
|
||||
LOperand* context = UseRegisterAtStart(instr->value());
|
||||
LInstruction* result =
|
||||
|
@ -103,7 +103,6 @@ class LCodeGen;
|
||||
V(LoadContextSlot) \
|
||||
V(LoadFieldByIndex) \
|
||||
V(LoadFunctionPrototype) \
|
||||
V(LoadGlobalCell) \
|
||||
V(LoadGlobalGeneric) \
|
||||
V(LoadKeyed) \
|
||||
V(LoadKeyedGeneric) \
|
||||
@ -144,7 +143,6 @@ class LCodeGen;
|
||||
V(StoreCodeEntry) \
|
||||
V(StoreContextSlot) \
|
||||
V(StoreFrameContext) \
|
||||
V(StoreGlobalCell) \
|
||||
V(StoreKeyed) \
|
||||
V(StoreKeyedGeneric) \
|
||||
V(StoreNamedField) \
|
||||
@ -1718,13 +1716,6 @@ class LLoadKeyedGeneric FINAL : public LTemplateInstruction<1, 3, 1> {
|
||||
};
|
||||
|
||||
|
||||
class LLoadGlobalCell FINAL : public LTemplateInstruction<1, 0, 0> {
|
||||
public:
|
||||
DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load-global-cell")
|
||||
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalCell)
|
||||
};
|
||||
|
||||
|
||||
class LLoadGlobalGeneric FINAL : public LTemplateInstruction<1, 2, 1> {
|
||||
public:
|
||||
LLoadGlobalGeneric(LOperand* context, LOperand* global_object,
|
||||
@ -1746,19 +1737,6 @@ class LLoadGlobalGeneric FINAL : public LTemplateInstruction<1, 2, 1> {
|
||||
};
|
||||
|
||||
|
||||
class LStoreGlobalCell FINAL : public LTemplateInstruction<0, 1, 0> {
|
||||
public:
|
||||
explicit LStoreGlobalCell(LOperand* value) {
|
||||
inputs_[0] = value;
|
||||
}
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
|
||||
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
|
||||
};
|
||||
|
||||
|
||||
class LLoadContextSlot FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LLoadContextSlot(LOperand* context) {
|
||||
|
@ -104,12 +104,12 @@ class IC {
|
||||
|
||||
static bool IsCleared(Code* code) {
|
||||
InlineCacheState state = code->ic_state();
|
||||
return state == UNINITIALIZED || state == PREMONOMORPHIC;
|
||||
return !FLAG_use_ic || state == UNINITIALIZED || state == PREMONOMORPHIC;
|
||||
}
|
||||
|
||||
static bool IsCleared(FeedbackNexus* nexus) {
|
||||
InlineCacheState state = nexus->StateFromFeedback();
|
||||
return state == UNINITIALIZED || state == PREMONOMORPHIC;
|
||||
return !FLAG_use_ic || state == UNINITIALIZED || state == PREMONOMORPHIC;
|
||||
}
|
||||
|
||||
static bool ICUseVector(Code::Kind kind) {
|
||||
|
@ -1900,7 +1900,7 @@ void Cell::set_value(Object* val, WriteBarrierMode ignored) {
|
||||
}
|
||||
|
||||
ACCESSORS(PropertyCell, dependent_code, DependentCode, kDependentCodeOffset)
|
||||
|
||||
ACCESSORS(PropertyCell, value, Object, kValueOffset)
|
||||
|
||||
Object* WeakCell::value() const { return READ_FIELD(this, kValueOffset); }
|
||||
|
||||
|
@ -662,7 +662,6 @@ enum InstanceType {
|
||||
CODE_TYPE,
|
||||
ODDBALL_TYPE,
|
||||
CELL_TYPE,
|
||||
PROPERTY_CELL_TYPE,
|
||||
|
||||
// "Data", objects that cannot contain non-map-word pointers to heap
|
||||
// objects.
|
||||
@ -718,6 +717,7 @@ enum InstanceType {
|
||||
CONSTANT_POOL_ARRAY_TYPE,
|
||||
SHARED_FUNCTION_INFO_TYPE,
|
||||
WEAK_CELL_TYPE,
|
||||
PROPERTY_CELL_TYPE,
|
||||
|
||||
// All the following types are subtypes of JSReceiver, which corresponds to
|
||||
// objects in the JS sense. The first and the last type in this range are
|
||||
@ -9692,7 +9692,7 @@ class Oddball: public HeapObject {
|
||||
|
||||
class Cell: public HeapObject {
|
||||
public:
|
||||
// [value]: value of the global property.
|
||||
// [value]: value of the cell.
|
||||
DECL_ACCESSORS(value, Object)
|
||||
|
||||
DECLARE_CAST(Cell)
|
||||
@ -9726,6 +9726,8 @@ class Cell: public HeapObject {
|
||||
|
||||
class PropertyCell: public Cell {
|
||||
public:
|
||||
// [value]: value of the global property.
|
||||
DECL_ACCESSORS(value, Object)
|
||||
// [dependent_code]: dependent code that depends on the type of the global
|
||||
// property.
|
||||
DECL_ACCESSORS(dependent_code, DependentCode)
|
||||
|
@ -846,8 +846,7 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
||||
// but that may change.
|
||||
bool write_barrier_needed =
|
||||
(current_object_address != NULL && source_space != NEW_SPACE &&
|
||||
source_space != CELL_SPACE && source_space != PROPERTY_CELL_SPACE &&
|
||||
source_space != CODE_SPACE);
|
||||
source_space != CELL_SPACE && source_space != CODE_SPACE);
|
||||
while (current < limit) {
|
||||
byte data = source_.Get();
|
||||
switch (data) {
|
||||
@ -948,8 +947,8 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
||||
}
|
||||
|
||||
// This generates a case and a body for the new space (which has to do extra
|
||||
// write barrier handling) and handles the other spaces with 8 fall-through
|
||||
// cases and one body.
|
||||
// write barrier handling) and handles the other spaces with fall-through cases
|
||||
// and one body.
|
||||
#define ALL_SPACES(where, how, within) \
|
||||
CASE_STATEMENT(where, how, within, NEW_SPACE) \
|
||||
CASE_BODY(where, how, within, NEW_SPACE) \
|
||||
@ -957,7 +956,6 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_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, PROPERTY_CELL_SPACE) \
|
||||
CASE_STATEMENT(where, how, within, LO_SPACE) \
|
||||
CASE_BODY(where, how, within, kAnyOldSpace)
|
||||
|
||||
|
@ -306,8 +306,8 @@ class SerializerDeserializer: public ObjectVisitor {
|
||||
// Where the pointed-to object can be found:
|
||||
enum Where {
|
||||
kNewObject = 0, // Object is next in snapshot.
|
||||
// 1-7 One per space.
|
||||
// 0x8 Unused.
|
||||
// 1-6 One per space.
|
||||
// 0x7, 0x8 Unused.
|
||||
kRootArray = 0x9, // Object is found in root array.
|
||||
kPartialSnapshotCache = 0xa, // Object is in the cache.
|
||||
kExternalReference = 0xb, // Pointer to an external reference.
|
||||
@ -316,9 +316,11 @@ class SerializerDeserializer: public ObjectVisitor {
|
||||
kAttachedReference = 0xe, // Object is described in an attached list.
|
||||
// 0xf Used by misc. See below.
|
||||
kBackref = 0x10, // Object is described relative to end.
|
||||
// 0x11-0x17 One per space.
|
||||
// 0x11-0x16 One per space.
|
||||
// 0x17 Unused.
|
||||
kBackrefWithSkip = 0x18, // Object is described relative to end.
|
||||
// 0x19-0x1f One per space.
|
||||
// 0x19-0x1e One per space.
|
||||
// 0x1f Unused.
|
||||
// 0x20-0x3f Used by misc. See below.
|
||||
kPointedToMask = 0x3f
|
||||
};
|
||||
|
@ -2884,16 +2884,6 @@ void LCodeGen::DoReturn(LReturn* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
|
||||
Register result = ToRegister(instr->result());
|
||||
__ LoadGlobalCell(result, instr->hydrogen()->cell().handle());
|
||||
if (instr->hydrogen()->RequiresHoleCheck()) {
|
||||
__ CompareRoot(result, Heap::kTheHoleValueRootIndex);
|
||||
DeoptimizeIf(equal, instr, Deoptimizer::kHole);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
|
||||
DCHECK(FLAG_vector_ics);
|
||||
@ -2929,32 +2919,6 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
|
||||
Register value = ToRegister(instr->value());
|
||||
Handle<Cell> cell_handle = instr->hydrogen()->cell().handle();
|
||||
|
||||
// If the cell we are storing to contains the hole it could have
|
||||
// been deleted from the property dictionary. In that case, we need
|
||||
// to update the property details in the property dictionary to mark
|
||||
// it as no longer deleted. We deoptimize in that case.
|
||||
if (instr->hydrogen()->RequiresHoleCheck()) {
|
||||
// We have a temp because CompareRoot might clobber kScratchRegister.
|
||||
Register cell = ToRegister(instr->temp());
|
||||
DCHECK(!value.is(cell));
|
||||
__ Move(cell, cell_handle, RelocInfo::CELL);
|
||||
__ CompareRoot(Operand(cell, 0), Heap::kTheHoleValueRootIndex);
|
||||
DeoptimizeIf(equal, instr, Deoptimizer::kHole);
|
||||
// Store the value.
|
||||
__ movp(Operand(cell, 0), value);
|
||||
} else {
|
||||
// Store the value.
|
||||
__ Move(kScratchRegister, cell_handle, RelocInfo::CELL);
|
||||
__ movp(Operand(kScratchRegister, 0), value);
|
||||
}
|
||||
// Cells are always rescanned, so no write barrier here.
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
|
||||
Register context = ToRegister(instr->context());
|
||||
Register result = ToRegister(instr->result());
|
||||
|
@ -2083,14 +2083,6 @@ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
|
||||
LLoadGlobalCell* result = new(zone()) LLoadGlobalCell;
|
||||
return instr->RequiresHoleCheck()
|
||||
? AssignEnvironment(DefineAsRegister(result))
|
||||
: DefineAsRegister(result);
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
|
||||
LOperand* context = UseFixed(instr->context(), rsi);
|
||||
LOperand* global_object =
|
||||
@ -2106,16 +2098,6 @@ LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
|
||||
LOperand* value = UseRegister(instr->value());
|
||||
// Use a temp to avoid reloading the cell value address in the case where
|
||||
// we perform a hole check.
|
||||
return instr->RequiresHoleCheck()
|
||||
? AssignEnvironment(new(zone()) LStoreGlobalCell(value, TempRegister()))
|
||||
: new(zone()) LStoreGlobalCell(value, NULL);
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
|
||||
LOperand* context = UseRegisterAtStart(instr->value());
|
||||
LInstruction* result =
|
||||
|
@ -100,7 +100,6 @@ class LCodeGen;
|
||||
V(LoadRoot) \
|
||||
V(LoadFieldByIndex) \
|
||||
V(LoadFunctionPrototype) \
|
||||
V(LoadGlobalCell) \
|
||||
V(LoadGlobalGeneric) \
|
||||
V(LoadKeyed) \
|
||||
V(LoadKeyedGeneric) \
|
||||
@ -140,7 +139,6 @@ class LCodeGen;
|
||||
V(StoreCodeEntry) \
|
||||
V(StoreContextSlot) \
|
||||
V(StoreFrameContext) \
|
||||
V(StoreGlobalCell) \
|
||||
V(StoreKeyed) \
|
||||
V(StoreKeyedGeneric) \
|
||||
V(StoreNamedField) \
|
||||
@ -1695,13 +1693,6 @@ class LLoadKeyedGeneric FINAL : public LTemplateInstruction<1, 3, 1> {
|
||||
};
|
||||
|
||||
|
||||
class LLoadGlobalCell FINAL : public LTemplateInstruction<1, 0, 0> {
|
||||
public:
|
||||
DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load-global-cell")
|
||||
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalCell)
|
||||
};
|
||||
|
||||
|
||||
class LLoadGlobalGeneric FINAL : public LTemplateInstruction<1, 2, 1> {
|
||||
public:
|
||||
explicit LLoadGlobalGeneric(LOperand* context, LOperand* global_object,
|
||||
@ -1723,21 +1714,6 @@ class LLoadGlobalGeneric FINAL : public LTemplateInstruction<1, 2, 1> {
|
||||
};
|
||||
|
||||
|
||||
class LStoreGlobalCell FINAL : public LTemplateInstruction<0, 1, 1> {
|
||||
public:
|
||||
explicit LStoreGlobalCell(LOperand* value, LOperand* temp) {
|
||||
inputs_[0] = value;
|
||||
temps_[0] = temp;
|
||||
}
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
|
||||
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
|
||||
};
|
||||
|
||||
|
||||
class LLoadContextSlot FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LLoadContextSlot(LOperand* context) {
|
||||
|
Loading…
Reference in New Issue
Block a user