Separate Cell and PropertyCell spaces
This makes it possible to store additional information on property cells, for example Type and optimized Code dependencies. R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/16631002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15089 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
3be6a032d0
commit
1b89cbf817
@ -5333,7 +5333,7 @@ class Internals {
|
||||
static const int kNullValueRootIndex = 7;
|
||||
static const int kTrueValueRootIndex = 8;
|
||||
static const int kFalseValueRootIndex = 9;
|
||||
static const int kEmptyStringRootIndex = 130;
|
||||
static const int kEmptyStringRootIndex = 131;
|
||||
|
||||
static const int kNodeClassIdOffset = 1 * kApiPointerSize;
|
||||
static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3;
|
||||
@ -5343,10 +5343,10 @@ class Internals {
|
||||
static const int kNodeIsIndependentShift = 4;
|
||||
static const int kNodeIsPartiallyDependentShift = 5;
|
||||
|
||||
static const int kJSObjectType = 0xaf;
|
||||
static const int kJSObjectType = 0xb0;
|
||||
static const int kFirstNonstringType = 0x80;
|
||||
static const int kOddballType = 0x83;
|
||||
static const int kForeignType = 0x87;
|
||||
static const int kForeignType = 0x88;
|
||||
|
||||
static const int kUndefinedOddballKind = 5;
|
||||
static const int kNullOddballKind = 3;
|
||||
|
@ -183,6 +183,10 @@ 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;
|
||||
|
@ -179,24 +179,22 @@ void RelocInfo::set_target_runtime_entry(Address target,
|
||||
}
|
||||
|
||||
|
||||
Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
|
||||
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
Handle<Cell> RelocInfo::target_cell_handle() {
|
||||
ASSERT(rmode_ == RelocInfo::CELL);
|
||||
Address address = Memory::Address_at(pc_);
|
||||
return Handle<JSGlobalPropertyCell>(
|
||||
reinterpret_cast<JSGlobalPropertyCell**>(address));
|
||||
return Handle<Cell>(reinterpret_cast<Cell**>(address));
|
||||
}
|
||||
|
||||
|
||||
JSGlobalPropertyCell* RelocInfo::target_cell() {
|
||||
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
return JSGlobalPropertyCell::FromValueAddress(Memory::Address_at(pc_));
|
||||
Cell* RelocInfo::target_cell() {
|
||||
ASSERT(rmode_ == RelocInfo::CELL);
|
||||
return Cell::FromValueAddress(Memory::Address_at(pc_));
|
||||
}
|
||||
|
||||
|
||||
void RelocInfo::set_target_cell(JSGlobalPropertyCell* cell,
|
||||
WriteBarrierMode mode) {
|
||||
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
Address address = cell->address() + JSGlobalPropertyCell::kValueOffset;
|
||||
void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode mode) {
|
||||
ASSERT(rmode_ == RelocInfo::CELL);
|
||||
Address address = cell->address() + Cell::kValueOffset;
|
||||
Memory::Address_at(pc_) = address;
|
||||
if (mode == UPDATE_WRITE_BARRIER && host() != NULL) {
|
||||
// TODO(1550) We are passing NULL as a slot because cell can never be on
|
||||
@ -286,8 +284,8 @@ void RelocInfo::Visit(ObjectVisitor* visitor) {
|
||||
visitor->VisitEmbeddedPointer(this);
|
||||
} else if (RelocInfo::IsCodeTarget(mode)) {
|
||||
visitor->VisitCodeTarget(this);
|
||||
} else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
|
||||
visitor->VisitGlobalPropertyCell(this);
|
||||
} else if (mode == RelocInfo::CELL) {
|
||||
visitor->VisitCell(this);
|
||||
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
|
||||
visitor->VisitExternalReference(this);
|
||||
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
|
||||
@ -314,8 +312,8 @@ void RelocInfo::Visit(Heap* heap) {
|
||||
StaticVisitor::VisitEmbeddedPointer(heap, this);
|
||||
} else if (RelocInfo::IsCodeTarget(mode)) {
|
||||
StaticVisitor::VisitCodeTarget(heap, this);
|
||||
} else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
|
||||
StaticVisitor::VisitGlobalPropertyCell(heap, this);
|
||||
} else if (mode == RelocInfo::CELL) {
|
||||
StaticVisitor::VisitCell(heap, this);
|
||||
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
|
||||
StaticVisitor::VisitExternalReference(this);
|
||||
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
|
||||
|
@ -3504,7 +3504,7 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
|
||||
// Get the map location in scratch and patch it.
|
||||
__ GetRelocatedValueLocation(inline_site, scratch);
|
||||
__ ldr(scratch, MemOperand(scratch));
|
||||
__ str(map, FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
|
||||
__ str(map, FieldMemOperand(scratch, Cell::kValueOffset));
|
||||
}
|
||||
|
||||
// Register mapping: r3 is object map and r4 is function prototype.
|
||||
@ -4637,7 +4637,7 @@ static void GenerateRecordCallTargetNoArray(MacroAssembler* masm) {
|
||||
masm->isolate()->heap()->the_hole_value());
|
||||
|
||||
// Load the cache state into r3.
|
||||
__ ldr(r3, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
|
||||
__ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset));
|
||||
|
||||
// A monomorphic cache hit or an already megamorphic state: invoke the
|
||||
// function without changing the state.
|
||||
@ -4652,10 +4652,10 @@ static void GenerateRecordCallTargetNoArray(MacroAssembler* masm) {
|
||||
// MegamorphicSentinel is an immortal immovable object (undefined) so no
|
||||
// write-barrier is needed.
|
||||
__ LoadRoot(ip, Heap::kUndefinedValueRootIndex, ne);
|
||||
__ str(ip, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset), ne);
|
||||
__ str(ip, FieldMemOperand(r2, Cell::kValueOffset), ne);
|
||||
|
||||
// An uninitialized cache is patched with the function.
|
||||
__ str(r1, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset), eq);
|
||||
__ str(r1, FieldMemOperand(r2, Cell::kValueOffset), eq);
|
||||
// No need for a write barrier here - cells are rescanned.
|
||||
|
||||
__ bind(&done);
|
||||
@ -4677,7 +4677,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
|
||||
masm->isolate()->heap()->the_hole_value());
|
||||
|
||||
// Load the cache state into r3.
|
||||
__ ldr(r3, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
|
||||
__ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset));
|
||||
|
||||
// A monomorphic cache hit or an already megamorphic state: invoke the
|
||||
// function without changing the state.
|
||||
@ -4711,7 +4711,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
|
||||
// write-barrier is needed.
|
||||
__ bind(&megamorphic);
|
||||
__ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
|
||||
__ str(ip, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
|
||||
__ str(ip, FieldMemOperand(r2, Cell::kValueOffset));
|
||||
__ jmp(&done);
|
||||
|
||||
// An uninitialized cache is patched with the function or sentinel to
|
||||
@ -4729,11 +4729,11 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
|
||||
TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(),
|
||||
GetInitialFastElementsKind());
|
||||
__ mov(r3, Operand(initial_kind_sentinel));
|
||||
__ str(r3, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
|
||||
__ str(r3, FieldMemOperand(r2, Cell::kValueOffset));
|
||||
__ b(&done);
|
||||
|
||||
__ bind(¬_array_function);
|
||||
__ str(r1, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
|
||||
__ str(r1, FieldMemOperand(r2, Cell::kValueOffset));
|
||||
// No need for a write barrier here - cells are rescanned.
|
||||
|
||||
__ bind(&done);
|
||||
@ -4809,7 +4809,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
||||
ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()),
|
||||
masm->isolate()->heap()->undefined_value());
|
||||
__ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
|
||||
__ str(ip, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
|
||||
__ str(ip, FieldMemOperand(r2, Cell::kValueOffset));
|
||||
}
|
||||
// Check for function proxy.
|
||||
__ cmp(r3, Operand(JS_FUNCTION_PROXY_TYPE));
|
||||
@ -7332,14 +7332,13 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ CompareObjectType(r3, r3, r4, MAP_TYPE);
|
||||
__ Assert(eq, "Unexpected initial map for Array function");
|
||||
|
||||
// We should either have undefined in ebx or a valid jsglobalpropertycell
|
||||
// We should either have undefined in ebx or a valid cell
|
||||
Label okay_here;
|
||||
Handle<Map> global_property_cell_map(
|
||||
masm->isolate()->heap()->global_property_cell_map());
|
||||
Handle<Map> cell_map = masm->isolate()->factory()->cell_map();
|
||||
__ cmp(r2, Operand(undefined_sentinel));
|
||||
__ b(eq, &okay_here);
|
||||
__ ldr(r3, FieldMemOperand(r2, 0));
|
||||
__ cmp(r3, Operand(global_property_cell_map));
|
||||
__ cmp(r3, Operand(cell_map));
|
||||
__ Assert(eq, "Expected property cell in register ebx");
|
||||
__ bind(&okay_here);
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ void FullCodeGenerator::Generate() {
|
||||
CompilationInfo* info = info_;
|
||||
handler_table_ =
|
||||
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
|
||||
profiling_counter_ = isolate()->factory()->NewJSGlobalPropertyCell(
|
||||
profiling_counter_ = isolate()->factory()->NewCell(
|
||||
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
|
||||
SetFunctionPosition(function());
|
||||
Comment cmnt(masm_, "[ function compiled by full code generator");
|
||||
@ -327,9 +327,9 @@ void FullCodeGenerator::ClearAccumulator() {
|
||||
|
||||
void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
|
||||
__ mov(r2, Operand(profiling_counter_));
|
||||
__ ldr(r3, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
|
||||
__ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset));
|
||||
__ sub(r3, r3, Operand(Smi::FromInt(delta)), SetCC);
|
||||
__ str(r3, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
|
||||
__ str(r3, FieldMemOperand(r2, Cell::kValueOffset));
|
||||
}
|
||||
|
||||
|
||||
@ -345,7 +345,7 @@ void FullCodeGenerator::EmitProfilingCounterReset() {
|
||||
}
|
||||
__ mov(r2, Operand(profiling_counter_));
|
||||
__ mov(r3, Operand(Smi::FromInt(reset_value)));
|
||||
__ str(r3, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
|
||||
__ str(r3, FieldMemOperand(r2, Cell::kValueOffset));
|
||||
}
|
||||
|
||||
|
||||
@ -1164,15 +1164,13 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
Label non_proxy;
|
||||
__ bind(&fixed_array);
|
||||
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(
|
||||
Handle<Object>(
|
||||
Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(
|
||||
Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
|
||||
isolate()));
|
||||
RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell);
|
||||
__ LoadHeapObject(r1, cell);
|
||||
__ mov(r2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)));
|
||||
__ str(r2, FieldMemOperand(r1, JSGlobalPropertyCell::kValueOffset));
|
||||
__ str(r2, FieldMemOperand(r1, Cell::kValueOffset));
|
||||
|
||||
__ mov(r1, Operand(Smi::FromInt(1))); // Smi indicates slow check
|
||||
__ ldr(r2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object
|
||||
@ -2674,8 +2672,7 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
|
||||
flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
|
||||
Handle<Object> uninitialized =
|
||||
TypeFeedbackCells::UninitializedSentinel(isolate());
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized);
|
||||
RecordTypeFeedbackCell(expr->CallFeedbackId(), cell);
|
||||
__ mov(r2, Operand(cell));
|
||||
|
||||
@ -2870,8 +2867,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
// Record call targets in unoptimized code.
|
||||
Handle<Object> uninitialized =
|
||||
TypeFeedbackCells::UninitializedSentinel(isolate());
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized);
|
||||
RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell);
|
||||
__ mov(r2, Operand(cell));
|
||||
|
||||
|
@ -2762,8 +2762,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
|
||||
// root array to force relocation to be able to later patch with
|
||||
// the cached map.
|
||||
PredictableCodeSizeScope predictable(masm_, 5 * Assembler::kInstrSize);
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
|
||||
Handle<Cell> cell = factory()->NewCell(factory()->the_hole_value());
|
||||
__ mov(ip, Operand(Handle<Object>(cell)));
|
||||
__ ldr(ip, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset));
|
||||
__ cmp(map, Operand(ip));
|
||||
@ -2925,7 +2924,7 @@ void LCodeGen::DoReturn(LReturn* instr) {
|
||||
void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
|
||||
Register result = ToRegister(instr->result());
|
||||
__ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell())));
|
||||
__ ldr(result, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset));
|
||||
__ ldr(result, FieldMemOperand(ip, Cell::kValueOffset));
|
||||
if (instr->hydrogen()->RequiresHoleCheck()) {
|
||||
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
|
||||
__ cmp(result, ip);
|
||||
@ -2960,13 +2959,13 @@ void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
|
||||
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, JSGlobalPropertyCell::kValueOffset));
|
||||
__ ldr(payload, FieldMemOperand(cell, Cell::kValueOffset));
|
||||
__ CompareRoot(payload, Heap::kTheHoleValueRootIndex);
|
||||
DeoptimizeIf(eq, instr->environment());
|
||||
}
|
||||
|
||||
// Store the value.
|
||||
__ str(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
|
||||
__ str(value, FieldMemOperand(cell, Cell::kValueOffset));
|
||||
// Cells are always rescanned, so no write barrier here.
|
||||
}
|
||||
|
||||
@ -5236,10 +5235,9 @@ void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
|
||||
AllowDeferredHandleDereference smi_check;
|
||||
if (isolate()->heap()->InNewSpace(*target)) {
|
||||
Register reg = ToRegister(instr->value());
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(target);
|
||||
Handle<Cell> cell = isolate()->factory()->NewJSGlobalPropertyCell(target);
|
||||
__ mov(ip, Operand(Handle<Object>(cell)));
|
||||
__ ldr(ip, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset));
|
||||
__ ldr(ip, FieldMemOperand(ip, Cell::kValueOffset));
|
||||
__ cmp(reg, ip);
|
||||
} else {
|
||||
__ cmp(reg, Operand(target));
|
||||
|
@ -400,10 +400,9 @@ void MacroAssembler::LoadHeapObject(Register result,
|
||||
Handle<HeapObject> object) {
|
||||
AllowDeferredHandleDereference using_raw_address;
|
||||
if (isolate()->heap()->InNewSpace(*object)) {
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(object);
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(object);
|
||||
mov(result, Operand(cell));
|
||||
ldr(result, FieldMemOperand(result, JSGlobalPropertyCell::kValueOffset));
|
||||
ldr(result, FieldMemOperand(result, Cell::kValueOffset));
|
||||
} else {
|
||||
mov(result, Operand(object));
|
||||
}
|
||||
|
@ -427,12 +427,10 @@ static void GenerateCheckPropertyCell(MacroAssembler* masm,
|
||||
Handle<Name> name,
|
||||
Register scratch,
|
||||
Label* miss) {
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
GlobalObject::EnsurePropertyCell(global, name);
|
||||
Handle<Cell> cell = GlobalObject::EnsurePropertyCell(global, name);
|
||||
ASSERT(cell->value()->IsTheHole());
|
||||
__ mov(scratch, Operand(cell));
|
||||
__ ldr(scratch,
|
||||
FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
|
||||
__ ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
|
||||
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
|
||||
__ cmp(scratch, ip);
|
||||
__ b(ne, miss);
|
||||
@ -1586,12 +1584,12 @@ void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object,
|
||||
|
||||
|
||||
void CallStubCompiler::GenerateLoadFunctionFromCell(
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Label* miss) {
|
||||
// Get the value from the cell.
|
||||
__ mov(r3, Operand(cell));
|
||||
__ ldr(r1, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset));
|
||||
__ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset));
|
||||
|
||||
// Check that the cell contains the same function.
|
||||
if (heap()->InNewSpace(*function)) {
|
||||
@ -1662,7 +1660,7 @@ Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
|
||||
Handle<Code> CallStubCompiler::CompileArrayPushCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -1915,7 +1913,7 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall(
|
||||
Handle<Code> CallStubCompiler::CompileArrayPopCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -1997,7 +1995,7 @@ Handle<Code> CallStubCompiler::CompileArrayPopCall(
|
||||
Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -2079,7 +2077,7 @@ Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
|
||||
Handle<Code> CallStubCompiler::CompileStringCharAtCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -2162,7 +2160,7 @@ Handle<Code> CallStubCompiler::CompileStringCharAtCall(
|
||||
Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -2234,7 +2232,7 @@ Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
|
||||
Handle<Code> CallStubCompiler::CompileMathFloorCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -2342,7 +2340,7 @@ Handle<Code> CallStubCompiler::CompileMathFloorCall(
|
||||
Handle<Code> CallStubCompiler::CompileMathAbsCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -2441,7 +2439,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall(
|
||||
const CallOptimization& optimization,
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
Counters* counters = isolate()->counters();
|
||||
@ -2613,7 +2611,7 @@ Handle<Code> CallStubCompiler::CompileCallConstant(
|
||||
Handle<JSFunction> function) {
|
||||
if (HasCustomCallGenerator(function)) {
|
||||
Handle<Code> code = CompileCustomCall(object, holder,
|
||||
Handle<JSGlobalPropertyCell>::null(),
|
||||
Handle<Cell>::null(),
|
||||
function, Handle<String>::cast(name));
|
||||
// A null handle means bail out to the regular compiler code below.
|
||||
if (!code.is_null()) return code;
|
||||
@ -2859,14 +2857,12 @@ Handle<Code> StoreStubCompiler::CompileStoreGlobal(
|
||||
// global object. We bail out to the runtime system to do that.
|
||||
__ mov(scratch1(), Operand(cell));
|
||||
__ LoadRoot(scratch2(), Heap::kTheHoleValueRootIndex);
|
||||
__ ldr(scratch3(),
|
||||
FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset));
|
||||
__ ldr(scratch3(), FieldMemOperand(scratch1(), Cell::kValueOffset));
|
||||
__ cmp(scratch3(), scratch2());
|
||||
__ b(eq, &miss);
|
||||
|
||||
// Store the value in the cell.
|
||||
__ str(value(),
|
||||
FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset));
|
||||
__ str(value(), FieldMemOperand(scratch1(), Cell::kValueOffset));
|
||||
// Cells are always rescanned, so no write barrier here.
|
||||
|
||||
Counters* counters = isolate()->counters();
|
||||
@ -3002,7 +2998,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
|
||||
|
||||
// Get the value from the cell.
|
||||
__ mov(r3, Operand(cell));
|
||||
__ ldr(r4, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset));
|
||||
__ ldr(r4, FieldMemOperand(r3, Cell::kValueOffset));
|
||||
|
||||
// Check for deleted property if property can actually be deleted.
|
||||
if (!is_dont_delete) {
|
||||
|
@ -724,7 +724,7 @@ bool RelocInfo::RequiresRelocation(const CodeDesc& desc) {
|
||||
// generation.
|
||||
int mode_mask = RelocInfo::kCodeTargetMask |
|
||||
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
|
||||
RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) |
|
||||
RelocInfo::ModeMask(RelocInfo::CELL) |
|
||||
RelocInfo::kApplyMask;
|
||||
RelocIterator it(desc, mode_mask);
|
||||
return !it.done();
|
||||
@ -754,8 +754,8 @@ const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
|
||||
return "code target";
|
||||
case RelocInfo::CODE_TARGET_WITH_ID:
|
||||
return "code target with id";
|
||||
case RelocInfo::GLOBAL_PROPERTY_CELL:
|
||||
return "global property cell";
|
||||
case RelocInfo::CELL:
|
||||
return "property cell";
|
||||
case RelocInfo::RUNTIME_ENTRY:
|
||||
return "runtime entry";
|
||||
case RelocInfo::JS_RETURN:
|
||||
@ -830,7 +830,7 @@ void RelocInfo::Verify() {
|
||||
case EMBEDDED_OBJECT:
|
||||
Object::VerifyPointer(target_object());
|
||||
break;
|
||||
case GLOBAL_PROPERTY_CELL:
|
||||
case CELL:
|
||||
Object::VerifyPointer(target_cell());
|
||||
break;
|
||||
case DEBUG_BREAK:
|
||||
|
@ -254,7 +254,7 @@ class RelocInfo BASE_EMBEDDED {
|
||||
CODE_TARGET_CONTEXT, // Code target used for contextual loads and stores.
|
||||
DEBUG_BREAK, // Code target for the debugger statement.
|
||||
EMBEDDED_OBJECT,
|
||||
GLOBAL_PROPERTY_CELL,
|
||||
CELL,
|
||||
|
||||
// Everything after runtime_entry (inclusive) is not GC'ed.
|
||||
RUNTIME_ENTRY,
|
||||
@ -282,7 +282,7 @@ class RelocInfo BASE_EMBEDDED {
|
||||
FIRST_PSEUDO_RELOC_MODE = CODE_AGE_SEQUENCE,
|
||||
LAST_PSEUDO_RELOC_MODE = CODE_AGE_SEQUENCE,
|
||||
LAST_CODE_ENUM = DEBUG_BREAK,
|
||||
LAST_GCED_ENUM = GLOBAL_PROPERTY_CELL,
|
||||
LAST_GCED_ENUM = CELL,
|
||||
// Modes <= LAST_COMPACT_ENUM are guaranteed to have compact encoding.
|
||||
LAST_COMPACT_ENUM = CODE_TARGET_WITH_ID,
|
||||
LAST_STANDARD_NONCOMPACT_ENUM = INTERNAL_REFERENCE
|
||||
@ -386,9 +386,9 @@ class RelocInfo BASE_EMBEDDED {
|
||||
INLINE(void set_target_runtime_entry(Address target,
|
||||
WriteBarrierMode mode =
|
||||
UPDATE_WRITE_BARRIER));
|
||||
INLINE(JSGlobalPropertyCell* target_cell());
|
||||
INLINE(Handle<JSGlobalPropertyCell> target_cell_handle());
|
||||
INLINE(void set_target_cell(JSGlobalPropertyCell* cell,
|
||||
INLINE(Cell* target_cell());
|
||||
INLINE(Handle<Cell> target_cell_handle());
|
||||
INLINE(void set_target_cell(Cell* cell,
|
||||
WriteBarrierMode mode = UPDATE_WRITE_BARRIER));
|
||||
INLINE(Code* code_age_stub());
|
||||
INLINE(void set_code_age_stub(Code* stub));
|
||||
|
@ -570,11 +570,11 @@ bool Call::ComputeTarget(Handle<Map> type, Handle<String> name) {
|
||||
bool Call::ComputeGlobalTarget(Handle<GlobalObject> global,
|
||||
LookupResult* lookup) {
|
||||
target_ = Handle<JSFunction>::null();
|
||||
cell_ = Handle<JSGlobalPropertyCell>::null();
|
||||
cell_ = Handle<Cell>::null();
|
||||
ASSERT(lookup->IsFound() &&
|
||||
lookup->type() == NORMAL &&
|
||||
lookup->holder() == *global);
|
||||
cell_ = Handle<JSGlobalPropertyCell>(global->GetPropertyCell(lookup));
|
||||
cell_ = Handle<Cell>(global->GetPropertyCell(lookup));
|
||||
if (cell_->value()->IsJSFunction()) {
|
||||
Handle<JSFunction> candidate(JSFunction::cast(cell_->value()));
|
||||
// If the function is in new space we assume it's more likely to
|
||||
|
@ -1705,7 +1705,7 @@ class Call: public Expression {
|
||||
// as the holder!
|
||||
Handle<JSObject> holder() { return holder_; }
|
||||
|
||||
Handle<JSGlobalPropertyCell> cell() { return cell_; }
|
||||
Handle<Cell> cell() { return cell_; }
|
||||
|
||||
bool ComputeTarget(Handle<Map> type, Handle<String> name);
|
||||
bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
|
||||
@ -1745,7 +1745,7 @@ class Call: public Expression {
|
||||
SmallMapList receiver_types_;
|
||||
Handle<JSFunction> target_;
|
||||
Handle<JSObject> holder_;
|
||||
Handle<JSGlobalPropertyCell> cell_;
|
||||
Handle<Cell> cell_;
|
||||
|
||||
const BailoutId return_id_;
|
||||
};
|
||||
@ -1765,7 +1765,7 @@ class CallNew: public Expression {
|
||||
virtual bool IsMonomorphic() { return is_monomorphic_; }
|
||||
Handle<JSFunction> target() const { return target_; }
|
||||
ElementsKind elements_kind() const { return elements_kind_; }
|
||||
Handle<JSGlobalPropertyCell> allocation_info_cell() const {
|
||||
Handle<Cell> allocation_info_cell() const {
|
||||
return allocation_info_cell_;
|
||||
}
|
||||
|
||||
@ -1792,7 +1792,7 @@ class CallNew: public Expression {
|
||||
bool is_monomorphic_;
|
||||
Handle<JSFunction> target_;
|
||||
ElementsKind elements_kind_;
|
||||
Handle<JSGlobalPropertyCell> allocation_info_cell_;
|
||||
Handle<Cell> allocation_info_cell_;
|
||||
|
||||
const BailoutId return_id_;
|
||||
};
|
||||
|
@ -2499,6 +2499,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
|
||||
Handle<Name> key = Handle<Name>(Name::cast(raw_key));
|
||||
Handle<Object> value = Handle<Object>(properties->ValueAt(i),
|
||||
isolate());
|
||||
ASSERT(!value->IsCell());
|
||||
if (value->IsJSGlobalPropertyCell()) {
|
||||
value = Handle<Object>(JSGlobalPropertyCell::cast(*value)->value(),
|
||||
isolate());
|
||||
|
@ -133,6 +133,12 @@ void StatisticsExtension::GetCounters(
|
||||
"cell_space_available_bytes");
|
||||
AddNumber(result, heap->cell_space()->CommittedMemory(),
|
||||
"cell_space_commited_bytes");
|
||||
AddNumber(result, heap->property_cell_space()->Size(),
|
||||
"property_cell_space_live_bytes");
|
||||
AddNumber(result, heap->property_cell_space()->Available(),
|
||||
"property_cell_space_available_bytes");
|
||||
AddNumber(result, heap->property_cell_space()->CommittedMemory(),
|
||||
"property_cell_space_commited_bytes");
|
||||
AddNumber(result, heap->lo_space()->Size(),
|
||||
"lo_space_live_bytes");
|
||||
AddNumber(result, heap->lo_space()->Available(),
|
||||
|
@ -482,6 +482,15 @@ Handle<ExternalArray> Factory::NewExternalArray(int length,
|
||||
}
|
||||
|
||||
|
||||
Handle<Cell> Factory::NewCell(Handle<Object> value) {
|
||||
AllowDeferredHandleDereference convert_to_cell;
|
||||
CALL_HEAP_FUNCTION(
|
||||
isolate(),
|
||||
isolate()->heap()->AllocateCell(*value),
|
||||
Cell);
|
||||
}
|
||||
|
||||
|
||||
Handle<JSGlobalPropertyCell> Factory::NewJSGlobalPropertyCell(
|
||||
Handle<Object> value) {
|
||||
AllowDeferredHandleDereference convert_to_cell;
|
||||
|
@ -235,6 +235,8 @@ class Factory {
|
||||
void* external_pointer,
|
||||
PretenureFlag pretenure = NOT_TENURED);
|
||||
|
||||
Handle<Cell> NewCell(Handle<Object> value);
|
||||
|
||||
Handle<JSGlobalPropertyCell> NewJSGlobalPropertyCell(
|
||||
Handle<Object> value);
|
||||
|
||||
|
@ -473,7 +473,7 @@ void FullCodeGenerator::PrepareForBailoutForId(BailoutId id, State state) {
|
||||
|
||||
|
||||
void FullCodeGenerator::RecordTypeFeedbackCell(
|
||||
TypeFeedbackId id, Handle<JSGlobalPropertyCell> cell) {
|
||||
TypeFeedbackId id, Handle<Cell> cell) {
|
||||
TypeFeedbackCellEntry entry = { id, cell };
|
||||
type_feedback_cells_.Add(entry, zone());
|
||||
}
|
||||
|
@ -437,8 +437,7 @@ class FullCodeGenerator: public AstVisitor {
|
||||
|
||||
// Cache cell support. This associates AST ids with global property cells
|
||||
// that will be cleared during GC and collected by the type-feedback oracle.
|
||||
void RecordTypeFeedbackCell(TypeFeedbackId id,
|
||||
Handle<JSGlobalPropertyCell> cell);
|
||||
void RecordTypeFeedbackCell(TypeFeedbackId id, Handle<Cell> cell);
|
||||
|
||||
// Record a call's return site offset, used to rebuild the frame if the
|
||||
// called function was inlined at the site.
|
||||
@ -653,7 +652,7 @@ class FullCodeGenerator: public AstVisitor {
|
||||
|
||||
struct TypeFeedbackCellEntry {
|
||||
TypeFeedbackId ast_id;
|
||||
Handle<JSGlobalPropertyCell> cell;
|
||||
Handle<Cell> cell;
|
||||
};
|
||||
|
||||
|
||||
@ -849,7 +848,7 @@ class FullCodeGenerator: public AstVisitor {
|
||||
ZoneList<TypeFeedbackCellEntry> type_feedback_cells_;
|
||||
int ic_total_count_;
|
||||
Handle<FixedArray> handler_table_;
|
||||
Handle<JSGlobalPropertyCell> profiling_counter_;
|
||||
Handle<Cell> profiling_counter_;
|
||||
bool generate_debug_code_;
|
||||
Zone* zone_;
|
||||
|
||||
|
@ -245,6 +245,8 @@ MaybeObject* Heap::AllocateRaw(int size_in_bytes,
|
||||
result = lo_space_->AllocateRaw(size_in_bytes, NOT_EXECUTABLE);
|
||||
} else if (CELL_SPACE == space) {
|
||||
result = cell_space_->AllocateRaw(size_in_bytes);
|
||||
} else if (PROPERTY_CELL_SPACE == space) {
|
||||
result = property_cell_space_->AllocateRaw(size_in_bytes);
|
||||
} else {
|
||||
ASSERT(MAP_SPACE == space);
|
||||
result = map_space_->AllocateRaw(size_in_bytes);
|
||||
@ -305,7 +307,19 @@ MaybeObject* Heap::AllocateRawCell() {
|
||||
isolate_->counters()->objs_since_last_full()->Increment();
|
||||
isolate_->counters()->objs_since_last_young()->Increment();
|
||||
#endif
|
||||
MaybeObject* result = cell_space_->AllocateRaw(JSGlobalPropertyCell::kSize);
|
||||
MaybeObject* result = cell_space_->AllocateRaw(Cell::kSize);
|
||||
if (result->IsFailure()) old_gen_exhausted_ = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* Heap::AllocateRawJSGlobalPropertyCell() {
|
||||
#ifdef DEBUG
|
||||
isolate_->counters()->objs_since_last_full()->Increment();
|
||||
isolate_->counters()->objs_since_last_young()->Increment();
|
||||
#endif
|
||||
MaybeObject* result =
|
||||
property_cell_space_->AllocateRaw(JSGlobalPropertyCell::kSize);
|
||||
if (result->IsFailure()) old_gen_exhausted_ = true;
|
||||
return result;
|
||||
}
|
||||
@ -407,7 +421,8 @@ AllocationSpace Heap::TargetSpaceId(InstanceType type) {
|
||||
ASSERT(type != MAP_TYPE);
|
||||
ASSERT(type != CODE_TYPE);
|
||||
ASSERT(type != ODDBALL_TYPE);
|
||||
ASSERT(type != JS_GLOBAL_PROPERTY_CELL_TYPE);
|
||||
ASSERT(type != CELL_TYPE);
|
||||
ASSERT(type != PROPERTY_CELL_TYPE);
|
||||
|
||||
if (type <= LAST_NAME_TYPE) {
|
||||
if (type == SYMBOL_TYPE) return OLD_POINTER_SPACE;
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include "heap-profiler.h"
|
||||
#include "debug.h"
|
||||
#include "types.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -888,7 +889,8 @@ const char* V8HeapExplorer::GetSystemEntryName(HeapObject* object) {
|
||||
#undef MAKE_STRING_MAP_CASE
|
||||
default: return "system / Map";
|
||||
}
|
||||
case JS_GLOBAL_PROPERTY_CELL_TYPE: return "system / JSGlobalPropertyCell";
|
||||
case CELL_TYPE: return "system / Cell";
|
||||
case PROPERTY_CELL_TYPE: return "system / JSGlobalPropertyCell";
|
||||
case FOREIGN_TYPE: return "system / Foreign";
|
||||
case ODDBALL_TYPE: return "system / Oddball";
|
||||
#define MAKE_STRUCT_CASE(NAME, Name, name) \
|
||||
@ -976,6 +978,9 @@ void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
|
||||
ExtractCodeCacheReferences(entry, CodeCache::cast(obj));
|
||||
} else if (obj->IsCode()) {
|
||||
ExtractCodeReferences(entry, Code::cast(obj));
|
||||
} else if (obj->IsCell()) {
|
||||
ExtractCellReferences(entry, Cell::cast(obj));
|
||||
extract_indexed_refs = false;
|
||||
} else if (obj->IsJSGlobalPropertyCell()) {
|
||||
ExtractJSGlobalPropertyCellReferences(
|
||||
entry, JSGlobalPropertyCell::cast(obj));
|
||||
@ -1273,9 +1278,15 @@ void V8HeapExplorer::ExtractCodeReferences(int entry, Code* code) {
|
||||
}
|
||||
|
||||
|
||||
void V8HeapExplorer::ExtractCellReferences(int entry, Cell* cell) {
|
||||
SetInternalReference(cell, entry, "value", cell->value());
|
||||
}
|
||||
|
||||
|
||||
void V8HeapExplorer::ExtractJSGlobalPropertyCellReferences(
|
||||
int entry, JSGlobalPropertyCell* cell) {
|
||||
SetInternalReference(cell, entry, "value", cell->value());
|
||||
SetInternalReference(cell, entry, "type", cell->type());
|
||||
}
|
||||
|
||||
|
||||
@ -1562,6 +1573,7 @@ bool V8HeapExplorer::IsEssentialObject(Object* object) {
|
||||
&& object != heap_->empty_fixed_array()
|
||||
&& object != heap_->empty_descriptor_array()
|
||||
&& object != heap_->fixed_array_map()
|
||||
&& object != heap_->cell_map()
|
||||
&& object != heap_->global_property_cell_map()
|
||||
&& object != heap_->shared_function_info_map()
|
||||
&& object != heap_->free_space_map()
|
||||
@ -2210,6 +2222,8 @@ bool HeapSnapshotGenerator::GenerateSnapshot() {
|
||||
CHECK(!debug_heap->old_pointer_space()->was_swept_conservatively());
|
||||
CHECK(!debug_heap->code_space()->was_swept_conservatively());
|
||||
CHECK(!debug_heap->cell_space()->was_swept_conservatively());
|
||||
CHECK(!debug_heap->property_cell_space()->
|
||||
was_swept_conservatively());
|
||||
CHECK(!debug_heap->map_space()->was_swept_conservatively());
|
||||
#endif
|
||||
|
||||
|
@ -464,6 +464,7 @@ class V8HeapExplorer : public HeapEntriesAllocator {
|
||||
void ExtractScriptReferences(int entry, Script* script);
|
||||
void ExtractCodeCacheReferences(int entry, CodeCache* code_cache);
|
||||
void ExtractCodeReferences(int entry, Code* code);
|
||||
void ExtractCellReferences(int entry, Cell* cell);
|
||||
void ExtractJSGlobalPropertyCellReferences(int entry,
|
||||
JSGlobalPropertyCell* cell);
|
||||
void ExtractClosureReferences(JSObject* js_obj, int entry);
|
||||
|
98
src/heap.cc
98
src/heap.cc
@ -105,6 +105,7 @@ 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),
|
||||
@ -199,7 +200,8 @@ intptr_t Heap::Capacity() {
|
||||
old_data_space_->Capacity() +
|
||||
code_space_->Capacity() +
|
||||
map_space_->Capacity() +
|
||||
cell_space_->Capacity();
|
||||
cell_space_->Capacity() +
|
||||
property_cell_space_->Capacity();
|
||||
}
|
||||
|
||||
|
||||
@ -212,6 +214,7 @@ intptr_t Heap::CommittedMemory() {
|
||||
code_space_->CommittedMemory() +
|
||||
map_space_->CommittedMemory() +
|
||||
cell_space_->CommittedMemory() +
|
||||
property_cell_space_->CommittedMemory() +
|
||||
lo_space_->Size();
|
||||
}
|
||||
|
||||
@ -225,6 +228,7 @@ size_t Heap::CommittedPhysicalMemory() {
|
||||
code_space_->CommittedPhysicalMemory() +
|
||||
map_space_->CommittedPhysicalMemory() +
|
||||
cell_space_->CommittedPhysicalMemory() +
|
||||
property_cell_space_->CommittedPhysicalMemory() +
|
||||
lo_space_->CommittedPhysicalMemory();
|
||||
}
|
||||
|
||||
@ -244,7 +248,8 @@ intptr_t Heap::Available() {
|
||||
old_data_space_->Available() +
|
||||
code_space_->Available() +
|
||||
map_space_->Available() +
|
||||
cell_space_->Available();
|
||||
cell_space_->Available() +
|
||||
property_cell_space_->Available();
|
||||
}
|
||||
|
||||
|
||||
@ -254,6 +259,7 @@ bool Heap::HasBeenSetUp() {
|
||||
code_space_ != NULL &&
|
||||
map_space_ != NULL &&
|
||||
cell_space_ != NULL &&
|
||||
property_cell_space_ != NULL &&
|
||||
lo_space_ != NULL;
|
||||
}
|
||||
|
||||
@ -383,6 +389,12 @@ void Heap::PrintShortHeapStatistics() {
|
||||
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 "d KB"
|
||||
", committed: %6" V8_PTR_PREFIX "d KB\n",
|
||||
@ -514,6 +526,10 @@ 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_sample_total_committed()->AddSample(
|
||||
static_cast<int>(CommittedMemory() / KB));
|
||||
@ -523,6 +539,10 @@ 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));
|
||||
}
|
||||
|
||||
#define UPDATE_COUNTERS_FOR_SPACE(space) \
|
||||
@ -548,6 +568,7 @@ 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
|
||||
@ -1353,15 +1374,31 @@ void Heap::Scavenge() {
|
||||
store_buffer()->IteratePointersToNewSpace(&ScavengeObject);
|
||||
}
|
||||
|
||||
// Copy objects reachable from cells by scavenging cell values directly.
|
||||
// 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 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->IsJSGlobalPropertyCell()) {
|
||||
JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(heap_object);
|
||||
Address value_address = cell->ValueAddress();
|
||||
scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address));
|
||||
Address type_address = cell->TypeAddress();
|
||||
scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(type_address));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2634,7 +2671,12 @@ bool Heap::CreateInitialMaps() {
|
||||
}
|
||||
set_code_map(Map::cast(obj));
|
||||
|
||||
{ MaybeObject* maybe_obj = AllocateMap(JS_GLOBAL_PROPERTY_CELL_TYPE,
|
||||
{ MaybeObject* maybe_obj = AllocateMap(CELL_TYPE, Cell::kSize);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
set_cell_map(Map::cast(obj));
|
||||
|
||||
{ MaybeObject* maybe_obj = AllocateMap(PROPERTY_CELL_TYPE,
|
||||
JSGlobalPropertyCell::kSize);
|
||||
if (!maybe_obj->ToObject(&obj)) return false;
|
||||
}
|
||||
@ -2769,14 +2811,26 @@ MaybeObject* Heap::AllocateHeapNumber(double value) {
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* Heap::AllocateJSGlobalPropertyCell(Object* value) {
|
||||
MaybeObject* Heap::AllocateCell(Object* value) {
|
||||
Object* result;
|
||||
{ MaybeObject* maybe_result = AllocateRawCell();
|
||||
if (!maybe_result->ToObject(&result)) return maybe_result;
|
||||
}
|
||||
HeapObject::cast(result)->set_map_no_write_barrier(cell_map());
|
||||
Cell::cast(result)->set_value(value);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* Heap::AllocateJSGlobalPropertyCell(Object* value) {
|
||||
Object* result;
|
||||
{ MaybeObject* maybe_result = AllocateRawJSGlobalPropertyCell();
|
||||
if (!maybe_result->ToObject(&result)) return maybe_result;
|
||||
}
|
||||
HeapObject::cast(result)->set_map_no_write_barrier(
|
||||
global_property_cell_map());
|
||||
JSGlobalPropertyCell::cast(result)->set_value(value);
|
||||
JSGlobalPropertyCell::cast(result)->set_type(Type::None());
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -4440,8 +4494,7 @@ MaybeObject* Heap::AllocateJSObjectWithAllocationSite(JSFunction* constructor,
|
||||
// advice
|
||||
Map* initial_map = constructor->initial_map();
|
||||
|
||||
JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(
|
||||
*allocation_site_info_payload);
|
||||
Cell* cell = Cell::cast(*allocation_site_info_payload);
|
||||
Smi* smi = Smi::cast(cell->value());
|
||||
ElementsKind to_kind = static_cast<ElementsKind>(smi->value());
|
||||
AllocationSiteMode mode = TRACK_ALLOCATION_SITE;
|
||||
@ -6023,6 +6076,8 @@ void Heap::ReportHeapStatistics(const char* title) {
|
||||
map_space_->ReportStatistics();
|
||||
PrintF("Cell space : ");
|
||||
cell_space_->ReportStatistics();
|
||||
PrintF("JSGlobalPropertyCell space : ");
|
||||
property_cell_space_->ReportStatistics();
|
||||
PrintF("Large object space : ");
|
||||
lo_space_->ReportStatistics();
|
||||
PrintF(">>>>>> ========================================= >>>>>>\n");
|
||||
@ -6044,6 +6099,7 @@ bool Heap::Contains(Address addr) {
|
||||
code_space_->Contains(addr) ||
|
||||
map_space_->Contains(addr) ||
|
||||
cell_space_->Contains(addr) ||
|
||||
property_cell_space_->Contains(addr) ||
|
||||
lo_space_->SlowContains(addr));
|
||||
}
|
||||
|
||||
@ -6070,6 +6126,8 @@ 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);
|
||||
}
|
||||
@ -6096,6 +6154,7 @@ void Heap::Verify() {
|
||||
old_data_space_->Verify(&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();
|
||||
}
|
||||
@ -6595,6 +6654,8 @@ 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();
|
||||
@ -6623,6 +6684,7 @@ intptr_t Heap::PromotedSpaceSizeOfObjects() {
|
||||
+ code_space_->SizeOfObjects()
|
||||
+ map_space_->SizeOfObjects()
|
||||
+ cell_space_->SizeOfObjects()
|
||||
+ property_cell_space_->SizeOfObjects()
|
||||
+ lo_space_->SizeOfObjects();
|
||||
}
|
||||
|
||||
@ -6711,11 +6773,17 @@ bool Heap::SetUp() {
|
||||
if (map_space_ == NULL) return false;
|
||||
if (!map_space_->SetUp()) return false;
|
||||
|
||||
// Initialize global property cell space.
|
||||
// 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;
|
||||
|
||||
// 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.
|
||||
@ -6837,6 +6905,12 @@ 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_;
|
||||
@ -6927,6 +7001,8 @@ 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:
|
||||
@ -6947,6 +7023,8 @@ 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;
|
||||
}
|
||||
@ -7036,6 +7114,10 @@ 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;
|
||||
|
20
src/heap.h
20
src/heap.h
@ -60,6 +60,7 @@ namespace internal {
|
||||
V(Oddball, true_value, TrueValue) \
|
||||
V(Oddball, false_value, FalseValue) \
|
||||
V(Oddball, uninitialized_value, UninitializedValue) \
|
||||
V(Map, cell_map, CellMap) \
|
||||
V(Map, global_property_cell_map, GlobalPropertyCellMap) \
|
||||
V(Map, shared_function_info_map, SharedFunctionInfoMap) \
|
||||
V(Map, meta_map, MetaMap) \
|
||||
@ -588,6 +589,9 @@ 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) {
|
||||
@ -599,6 +603,8 @@ 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:
|
||||
@ -933,6 +939,12 @@ class Heap {
|
||||
// Please note this does not perform a garbage collection.
|
||||
MUST_USE_RESULT MaybeObject* AllocateSymbol();
|
||||
|
||||
// Allocate a tenured simple cell.
|
||||
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
|
||||
// failed.
|
||||
// Please note this does not perform a garbage collection.
|
||||
MUST_USE_RESULT MaybeObject* AllocateCell(Object* value);
|
||||
|
||||
// Allocate a tenured JS global property cell.
|
||||
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
|
||||
// failed.
|
||||
@ -1958,6 +1970,7 @@ 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_;
|
||||
@ -2114,9 +2127,12 @@ class Heap {
|
||||
// (since both AllocateRaw and AllocateRawMap are inlined).
|
||||
MUST_USE_RESULT inline MaybeObject* AllocateRawMap();
|
||||
|
||||
// Allocate an uninitialized object in the global property cell space.
|
||||
// Allocate an uninitialized object in the simple cell space.
|
||||
MUST_USE_RESULT inline MaybeObject* AllocateRawCell();
|
||||
|
||||
// Allocate an uninitialized object in the global property cell space.
|
||||
MUST_USE_RESULT inline MaybeObject* AllocateRawJSGlobalPropertyCell();
|
||||
|
||||
// Initializes a JSObject based on its map.
|
||||
void InitializeJSObjectFromMap(JSObject* obj,
|
||||
FixedArray* properties,
|
||||
@ -2437,6 +2453,8 @@ class HeapStats {
|
||||
int* size_per_type; // 22
|
||||
int* os_error; // 23
|
||||
int* end_marker; // 24
|
||||
intptr_t* property_cell_space_size; // 25
|
||||
intptr_t* property_cell_space_capacity; // 26
|
||||
};
|
||||
|
||||
|
||||
|
@ -2476,14 +2476,14 @@ class HCallNew: public HBinaryCall {
|
||||
class HCallNewArray: public HCallNew {
|
||||
public:
|
||||
HCallNewArray(HValue* context, HValue* constructor, int argument_count,
|
||||
Handle<JSGlobalPropertyCell> type_cell)
|
||||
Handle<Cell> type_cell)
|
||||
: HCallNew(context, constructor, argument_count),
|
||||
type_cell_(type_cell) {
|
||||
elements_kind_ = static_cast<ElementsKind>(
|
||||
Smi::cast(type_cell->value())->value());
|
||||
}
|
||||
|
||||
Handle<JSGlobalPropertyCell> property_cell() const {
|
||||
Handle<Cell> property_cell() const {
|
||||
return type_cell_;
|
||||
}
|
||||
|
||||
@ -2493,7 +2493,7 @@ class HCallNewArray: public HCallNew {
|
||||
|
||||
private:
|
||||
ElementsKind elements_kind_;
|
||||
Handle<JSGlobalPropertyCell> type_cell_;
|
||||
Handle<Cell> type_cell_;
|
||||
};
|
||||
|
||||
|
||||
@ -4853,14 +4853,14 @@ class HUnknownOSRValue: public HTemplateInstruction<0> {
|
||||
|
||||
class HLoadGlobalCell: public HTemplateInstruction<0> {
|
||||
public:
|
||||
HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, PropertyDetails details)
|
||||
HLoadGlobalCell(Handle<Cell> cell, PropertyDetails details)
|
||||
: cell_(cell), details_(details), unique_id_() {
|
||||
set_representation(Representation::Tagged());
|
||||
SetFlag(kUseGVN);
|
||||
SetGVNFlag(kDependsOnGlobalVars);
|
||||
}
|
||||
|
||||
Handle<JSGlobalPropertyCell> cell() const { return cell_; }
|
||||
Handle<Cell> cell() const { return cell_; }
|
||||
bool RequiresHoleCheck() const;
|
||||
|
||||
virtual void PrintDataTo(StringStream* stream);
|
||||
@ -4888,7 +4888,7 @@ class HLoadGlobalCell: public HTemplateInstruction<0> {
|
||||
private:
|
||||
virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
|
||||
|
||||
Handle<JSGlobalPropertyCell> cell_;
|
||||
Handle<Cell> cell_;
|
||||
PropertyDetails details_;
|
||||
UniqueValueId unique_id_;
|
||||
};
|
||||
|
@ -8932,7 +8932,7 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
|
||||
CHECK_ALIVE(VisitArgumentList(expr->arguments()));
|
||||
HCallNew* call;
|
||||
if (use_call_new_array) {
|
||||
Handle<JSGlobalPropertyCell> cell = expr->allocation_info_cell();
|
||||
Handle<Cell> cell = expr->allocation_info_cell();
|
||||
call = new(zone()) HCallNewArray(context, constructor, argument_count,
|
||||
cell);
|
||||
} else {
|
||||
|
@ -162,24 +162,22 @@ void RelocInfo::set_target_runtime_entry(Address target,
|
||||
}
|
||||
|
||||
|
||||
Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
|
||||
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
Handle<Cell> RelocInfo::target_cell_handle() {
|
||||
ASSERT(rmode_ == RelocInfo::CELL);
|
||||
Address address = Memory::Address_at(pc_);
|
||||
return Handle<JSGlobalPropertyCell>(
|
||||
reinterpret_cast<JSGlobalPropertyCell**>(address));
|
||||
return Handle<Cell>(reinterpret_cast<Cell**>(address));
|
||||
}
|
||||
|
||||
|
||||
JSGlobalPropertyCell* RelocInfo::target_cell() {
|
||||
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
return JSGlobalPropertyCell::FromValueAddress(Memory::Address_at(pc_));
|
||||
Cell* RelocInfo::target_cell() {
|
||||
ASSERT(rmode_ == RelocInfo::CELL);
|
||||
return Cell::FromValueAddress(Memory::Address_at(pc_));
|
||||
}
|
||||
|
||||
|
||||
void RelocInfo::set_target_cell(JSGlobalPropertyCell* cell,
|
||||
WriteBarrierMode mode) {
|
||||
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
Address address = cell->address() + JSGlobalPropertyCell::kValueOffset;
|
||||
void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode mode) {
|
||||
ASSERT(rmode_ == RelocInfo::CELL);
|
||||
Address address = cell->address() + Cell::kValueOffset;
|
||||
Memory::Address_at(pc_) = address;
|
||||
CPU::FlushICache(pc_, sizeof(Address));
|
||||
if (mode == UPDATE_WRITE_BARRIER && host() != NULL) {
|
||||
@ -259,8 +257,8 @@ void RelocInfo::Visit(ObjectVisitor* visitor) {
|
||||
CPU::FlushICache(pc_, sizeof(Address));
|
||||
} else if (RelocInfo::IsCodeTarget(mode)) {
|
||||
visitor->VisitCodeTarget(this);
|
||||
} else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
|
||||
visitor->VisitGlobalPropertyCell(this);
|
||||
} else if (mode == RelocInfo::CELL) {
|
||||
visitor->VisitCell(this);
|
||||
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
|
||||
visitor->VisitExternalReference(this);
|
||||
CPU::FlushICache(pc_, sizeof(Address));
|
||||
@ -289,8 +287,8 @@ void RelocInfo::Visit(Heap* heap) {
|
||||
CPU::FlushICache(pc_, sizeof(Address));
|
||||
} else if (RelocInfo::IsCodeTarget(mode)) {
|
||||
StaticVisitor::VisitCodeTarget(heap, this);
|
||||
} else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
|
||||
StaticVisitor::VisitGlobalPropertyCell(heap, this);
|
||||
} else if (mode == RelocInfo::CELL) {
|
||||
StaticVisitor::VisitCell(heap, this);
|
||||
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
|
||||
StaticVisitor::VisitExternalReference(this);
|
||||
CPU::FlushICache(pc_, sizeof(Address));
|
||||
|
@ -410,10 +410,10 @@ class Operand BASE_EMBEDDED {
|
||||
RelocInfo::EXTERNAL_REFERENCE);
|
||||
}
|
||||
|
||||
static Operand Cell(Handle<JSGlobalPropertyCell> cell) {
|
||||
static Operand Cell(Handle<Cell> cell) {
|
||||
AllowDeferredHandleDereference embedding_raw_address;
|
||||
return Operand(reinterpret_cast<int32_t>(cell.location()),
|
||||
RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
RelocInfo::CELL);
|
||||
}
|
||||
|
||||
// Returns true if this Operand is a wrapper for the specified register.
|
||||
|
@ -4703,13 +4703,13 @@ static void GenerateRecordCallTargetNoArray(MacroAssembler* masm) {
|
||||
__ j(equal, &initialize, Label::kNear);
|
||||
// MegamorphicSentinel is an immortal immovable object (undefined) so no
|
||||
// write-barrier is needed.
|
||||
__ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
|
||||
__ mov(FieldOperand(ebx, Cell::kValueOffset),
|
||||
Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate)));
|
||||
__ jmp(&done, Label::kNear);
|
||||
|
||||
// An uninitialized cache is patched with the function.
|
||||
__ bind(&initialize);
|
||||
__ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), edi);
|
||||
__ mov(FieldOperand(ebx, Cell::kValueOffset), edi);
|
||||
// No need for a write barrier here - cells are rescanned.
|
||||
|
||||
__ bind(&done);
|
||||
@ -4727,7 +4727,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
|
||||
Label initialize, done, miss, megamorphic, not_array_function;
|
||||
|
||||
// Load the cache state into ecx.
|
||||
__ mov(ecx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset));
|
||||
__ mov(ecx, FieldOperand(ebx, Cell::kValueOffset));
|
||||
|
||||
// A monomorphic cache hit or an already megamorphic state: invoke the
|
||||
// function without changing the state.
|
||||
@ -4762,7 +4762,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
|
||||
// MegamorphicSentinel is an immortal immovable object (undefined) so no
|
||||
// write-barrier is needed.
|
||||
__ bind(&megamorphic);
|
||||
__ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
|
||||
__ mov(FieldOperand(ebx, Cell::kValueOffset),
|
||||
Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate)));
|
||||
__ jmp(&done, Label::kNear);
|
||||
|
||||
@ -4781,12 +4781,12 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
|
||||
Handle<Object> initial_kind_sentinel =
|
||||
TypeFeedbackCells::MonomorphicArraySentinel(isolate,
|
||||
GetInitialFastElementsKind());
|
||||
__ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
|
||||
__ mov(FieldOperand(ebx, Cell::kValueOffset),
|
||||
Immediate(initial_kind_sentinel));
|
||||
__ jmp(&done);
|
||||
|
||||
__ bind(¬_array_function);
|
||||
__ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), edi);
|
||||
__ mov(FieldOperand(ebx, Cell::kValueOffset), edi);
|
||||
// No need for a write barrier here - cells are rescanned.
|
||||
|
||||
__ bind(&done);
|
||||
@ -4857,7 +4857,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
||||
// If there is a call target cache, mark it megamorphic in the
|
||||
// non-function case. MegamorphicSentinel is an immortal immovable
|
||||
// object (undefined) so no write barrier is needed.
|
||||
__ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
|
||||
__ mov(FieldOperand(ebx, Cell::kValueOffset),
|
||||
Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate)));
|
||||
}
|
||||
// Check for function proxy.
|
||||
@ -7930,13 +7930,12 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ CmpObjectType(ecx, MAP_TYPE, ecx);
|
||||
__ Assert(equal, "Unexpected initial map for Array function");
|
||||
|
||||
// We should either have undefined in ebx or a valid jsglobalpropertycell
|
||||
// We should either have undefined in ebx or a valid cell
|
||||
Label okay_here;
|
||||
Handle<Map> global_property_cell_map(
|
||||
masm->isolate()->heap()->global_property_cell_map());
|
||||
Handle<Map> cell_map = masm->isolate()->factory()->cell_map();
|
||||
__ cmp(ebx, Immediate(undefined_sentinel));
|
||||
__ j(equal, &okay_here);
|
||||
__ cmp(FieldOperand(ebx, 0), Immediate(global_property_cell_map));
|
||||
__ cmp(FieldOperand(ebx, 0), Immediate(cell_map));
|
||||
__ Assert(equal, "Expected property cell in register ebx");
|
||||
__ bind(&okay_here);
|
||||
}
|
||||
@ -7946,7 +7945,7 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
// Get the elements kind and case on that.
|
||||
__ cmp(ebx, Immediate(undefined_sentinel));
|
||||
__ j(equal, &no_info);
|
||||
__ mov(edx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset));
|
||||
__ mov(edx, FieldOperand(ebx, Cell::kValueOffset));
|
||||
__ JumpIfNotSmi(edx, &no_info);
|
||||
__ SmiUntag(edx);
|
||||
__ jmp(&switch_ready);
|
||||
|
@ -118,7 +118,7 @@ void FullCodeGenerator::Generate() {
|
||||
CompilationInfo* info = info_;
|
||||
handler_table_ =
|
||||
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
|
||||
profiling_counter_ = isolate()->factory()->NewJSGlobalPropertyCell(
|
||||
profiling_counter_ = isolate()->factory()->NewCell(
|
||||
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
|
||||
SetFunctionPosition(function());
|
||||
Comment cmnt(masm_, "[ function compiled by full code generator");
|
||||
@ -315,7 +315,7 @@ void FullCodeGenerator::ClearAccumulator() {
|
||||
|
||||
void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
|
||||
__ mov(ebx, Immediate(profiling_counter_));
|
||||
__ sub(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
|
||||
__ sub(FieldOperand(ebx, Cell::kValueOffset),
|
||||
Immediate(Smi::FromInt(delta)));
|
||||
}
|
||||
|
||||
@ -327,7 +327,7 @@ void FullCodeGenerator::EmitProfilingCounterReset() {
|
||||
reset_value = Smi::kMaxValue;
|
||||
}
|
||||
__ mov(ebx, Immediate(profiling_counter_));
|
||||
__ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
|
||||
__ mov(FieldOperand(ebx, Cell::kValueOffset),
|
||||
Immediate(Smi::FromInt(reset_value)));
|
||||
}
|
||||
|
||||
@ -1105,14 +1105,12 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
Label non_proxy;
|
||||
__ bind(&fixed_array);
|
||||
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(
|
||||
Handle<Object>(
|
||||
Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(
|
||||
Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
|
||||
isolate()));
|
||||
RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell);
|
||||
__ LoadHeapObject(ebx, cell);
|
||||
__ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
|
||||
__ mov(FieldOperand(ebx, Cell::kValueOffset),
|
||||
Immediate(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)));
|
||||
|
||||
__ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check
|
||||
@ -2628,8 +2626,7 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
|
||||
flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
|
||||
Handle<Object> uninitialized =
|
||||
TypeFeedbackCells::UninitializedSentinel(isolate());
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized);
|
||||
RecordTypeFeedbackCell(expr->CallFeedbackId(), cell);
|
||||
__ mov(ebx, cell);
|
||||
|
||||
@ -2813,8 +2810,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
// Record call targets in unoptimized code.
|
||||
Handle<Object> uninitialized =
|
||||
TypeFeedbackCells::UninitializedSentinel(isolate());
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized);
|
||||
RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell);
|
||||
__ mov(ebx, cell);
|
||||
|
||||
|
@ -2679,8 +2679,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
|
||||
Register map = ToRegister(instr->temp());
|
||||
__ mov(map, FieldOperand(object, HeapObject::kMapOffset));
|
||||
__ bind(deferred->map_check()); // Label for calculating code patching.
|
||||
Handle<JSGlobalPropertyCell> cache_cell =
|
||||
factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
|
||||
Handle<Cell> cache_cell = factory()->NewCell(factory()->the_hole_value());
|
||||
__ cmp(map, Operand::Cell(cache_cell)); // Patched to cached map.
|
||||
__ j(not_equal, &cache_miss, Label::kNear);
|
||||
__ mov(eax, factory()->the_hole_value()); // Patched to either true or false.
|
||||
@ -5747,8 +5746,7 @@ void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
|
||||
Handle<JSFunction> target = instr->hydrogen()->target();
|
||||
if (instr->hydrogen()->target_in_new_space()) {
|
||||
Register reg = ToRegister(instr->value());
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(target);
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(target);
|
||||
__ cmp(reg, Operand::Cell(cell));
|
||||
} else {
|
||||
Operand operand = ToOperand(instr->value());
|
||||
|
@ -2495,8 +2495,7 @@ void MacroAssembler::LoadHeapObject(Register result,
|
||||
Handle<HeapObject> object) {
|
||||
AllowDeferredHandleDereference embedding_raw_address;
|
||||
if (isolate()->heap()->InNewSpace(*object)) {
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(object);
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(object);
|
||||
mov(result, Operand::Cell(cell));
|
||||
} else {
|
||||
mov(result, object);
|
||||
@ -2507,8 +2506,7 @@ void MacroAssembler::LoadHeapObject(Register result,
|
||||
void MacroAssembler::CmpHeapObject(Register reg, Handle<HeapObject> object) {
|
||||
AllowDeferredHandleDereference using_raw_address;
|
||||
if (isolate()->heap()->InNewSpace(*object)) {
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(object);
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(object);
|
||||
cmp(reg, Operand::Cell(cell));
|
||||
} else {
|
||||
cmp(reg, object);
|
||||
@ -2519,8 +2517,7 @@ void MacroAssembler::CmpHeapObject(Register reg, Handle<HeapObject> object) {
|
||||
void MacroAssembler::PushHeapObject(Handle<HeapObject> object) {
|
||||
AllowDeferredHandleDereference using_raw_address;
|
||||
if (isolate()->heap()->InNewSpace(*object)) {
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(object);
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(object);
|
||||
push(Operand::Cell(cell));
|
||||
} else {
|
||||
Push(object);
|
||||
|
@ -1565,13 +1565,13 @@ void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object,
|
||||
|
||||
|
||||
void CallStubCompiler::GenerateLoadFunctionFromCell(
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Label* miss) {
|
||||
// Get the value from the cell.
|
||||
if (Serializer::enabled()) {
|
||||
__ mov(edi, Immediate(cell));
|
||||
__ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset));
|
||||
__ mov(edi, FieldOperand(edi, Cell::kValueOffset));
|
||||
} else {
|
||||
__ mov(edi, Operand::Cell(cell));
|
||||
}
|
||||
@ -1667,7 +1667,7 @@ Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
|
||||
Handle<Code> CallStubCompiler::CompileArrayPushCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -1925,7 +1925,7 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall(
|
||||
Handle<Code> CallStubCompiler::CompileArrayPopCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -2007,7 +2007,7 @@ Handle<Code> CallStubCompiler::CompileArrayPopCall(
|
||||
Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -2091,7 +2091,7 @@ Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
|
||||
Handle<Code> CallStubCompiler::CompileStringCharAtCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -2177,7 +2177,7 @@ Handle<Code> CallStubCompiler::CompileStringCharAtCall(
|
||||
Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -2253,7 +2253,7 @@ Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
|
||||
Handle<Code> CallStubCompiler::CompileMathFloorCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -2384,7 +2384,7 @@ Handle<Code> CallStubCompiler::CompileMathFloorCall(
|
||||
Handle<Code> CallStubCompiler::CompileMathAbsCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -2491,7 +2491,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall(
|
||||
const CallOptimization& optimization,
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
ASSERT(optimization.is_simple_api_call());
|
||||
@ -2673,7 +2673,7 @@ Handle<Code> CallStubCompiler::CompileCallConstant(
|
||||
|
||||
if (HasCustomCallGenerator(function)) {
|
||||
Handle<Code> code = CompileCustomCall(object, holder,
|
||||
Handle<JSGlobalPropertyCell>::null(),
|
||||
Handle<Cell>::null(),
|
||||
function, Handle<String>::cast(name));
|
||||
// A null handle means bail out to the regular compiler code below.
|
||||
if (!code.is_null()) return code;
|
||||
|
@ -394,6 +394,7 @@ 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);
|
||||
@ -440,6 +441,7 @@ void IncrementalMarking::DeactivateIncrementalWriteBarrier() {
|
||||
DeactivateIncrementalWriteBarrierForSpace(heap_->old_pointer_space());
|
||||
DeactivateIncrementalWriteBarrierForSpace(heap_->old_data_space());
|
||||
DeactivateIncrementalWriteBarrierForSpace(heap_->cell_space());
|
||||
DeactivateIncrementalWriteBarrierForSpace(heap_->property_cell_space());
|
||||
DeactivateIncrementalWriteBarrierForSpace(heap_->map_space());
|
||||
DeactivateIncrementalWriteBarrierForSpace(heap_->code_space());
|
||||
DeactivateIncrementalWriteBarrierForSpace(heap_->new_space());
|
||||
@ -474,6 +476,7 @@ void IncrementalMarking::ActivateIncrementalWriteBarrier() {
|
||||
ActivateIncrementalWriteBarrier(heap_->old_pointer_space());
|
||||
ActivateIncrementalWriteBarrier(heap_->old_data_space());
|
||||
ActivateIncrementalWriteBarrier(heap_->cell_space());
|
||||
ActivateIncrementalWriteBarrier(heap_->property_cell_space());
|
||||
ActivateIncrementalWriteBarrier(heap_->map_space());
|
||||
ActivateIncrementalWriteBarrier(heap_->code_space());
|
||||
ActivateIncrementalWriteBarrier(heap_->new_space());
|
||||
|
@ -148,6 +148,7 @@ static void VerifyMarking(Heap* heap) {
|
||||
VerifyMarking(heap->old_data_space());
|
||||
VerifyMarking(heap->code_space());
|
||||
VerifyMarking(heap->cell_space());
|
||||
VerifyMarking(heap->property_cell_space());
|
||||
VerifyMarking(heap->map_space());
|
||||
VerifyMarking(heap->new_space());
|
||||
|
||||
@ -229,6 +230,7 @@ static void VerifyEvacuation(Heap* heap) {
|
||||
VerifyEvacuation(heap->old_data_space());
|
||||
VerifyEvacuation(heap->code_space());
|
||||
VerifyEvacuation(heap->cell_space());
|
||||
VerifyEvacuation(heap->property_cell_space());
|
||||
VerifyEvacuation(heap->map_space());
|
||||
VerifyEvacuation(heap->new_space());
|
||||
|
||||
@ -283,7 +285,7 @@ class VerifyNativeContextSeparationVisitor: public ObjectVisitor {
|
||||
array->set_length(length);
|
||||
}
|
||||
break;
|
||||
case JS_GLOBAL_PROPERTY_CELL_TYPE:
|
||||
case CELL_TYPE:
|
||||
case JS_PROXY_TYPE:
|
||||
case JS_VALUE_TYPE:
|
||||
case TYPE_FEEDBACK_INFO_TYPE:
|
||||
@ -375,6 +377,7 @@ bool MarkCompactCollector::StartCompaction(CompactionMode mode) {
|
||||
if (FLAG_trace_fragmentation) {
|
||||
TraceFragmentation(heap()->map_space());
|
||||
TraceFragmentation(heap()->cell_space());
|
||||
TraceFragmentation(heap()->property_cell_space());
|
||||
}
|
||||
|
||||
heap()->old_pointer_space()->EvictEvacuationCandidatesFromFreeLists();
|
||||
@ -468,6 +471,7 @@ void MarkCompactCollector::VerifyMarkbitsAreClean() {
|
||||
VerifyMarkbitsAreClean(heap_->old_data_space());
|
||||
VerifyMarkbitsAreClean(heap_->code_space());
|
||||
VerifyMarkbitsAreClean(heap_->cell_space());
|
||||
VerifyMarkbitsAreClean(heap_->property_cell_space());
|
||||
VerifyMarkbitsAreClean(heap_->map_space());
|
||||
VerifyMarkbitsAreClean(heap_->new_space());
|
||||
|
||||
@ -529,6 +533,7 @@ void MarkCompactCollector::ClearMarkbits() {
|
||||
ClearMarkbitsInPagedSpace(heap_->old_pointer_space());
|
||||
ClearMarkbitsInPagedSpace(heap_->old_data_space());
|
||||
ClearMarkbitsInPagedSpace(heap_->cell_space());
|
||||
ClearMarkbitsInPagedSpace(heap_->property_cell_space());
|
||||
ClearMarkbitsInNewSpace(heap_->new_space());
|
||||
|
||||
LargeObjectIterator it(heap_->lo_space());
|
||||
@ -648,6 +653,8 @@ const char* AllocationSpaceName(AllocationSpace space) {
|
||||
case CODE_SPACE: return "CODE_SPACE";
|
||||
case MAP_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:
|
||||
UNREACHABLE();
|
||||
@ -2148,6 +2155,11 @@ void MarkCompactCollector::RefillMarkingDeque() {
|
||||
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_,
|
||||
@ -2241,12 +2253,30 @@ void MarkCompactCollector::MarkLiveObjects() {
|
||||
HeapObjectIterator cell_iterator(heap()->cell_space());
|
||||
HeapObject* cell;
|
||||
while ((cell = cell_iterator.Next()) != NULL) {
|
||||
ASSERT(cell->IsCell());
|
||||
if (IsMarked(cell)) {
|
||||
int offset = Cell::kValueOffset;
|
||||
MarkCompactMarkingVisitor::VisitPointer(
|
||||
heap(),
|
||||
reinterpret_cast<Object**>(cell->address() + offset));
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
HeapObjectIterator js_global_property_cell_iterator(
|
||||
heap()->property_cell_space());
|
||||
HeapObject* cell;
|
||||
while ((cell = js_global_property_cell_iterator.Next()) != NULL) {
|
||||
ASSERT(cell->IsJSGlobalPropertyCell());
|
||||
if (IsMarked(cell)) {
|
||||
int offset = JSGlobalPropertyCell::kValueOffset;
|
||||
MarkCompactMarkingVisitor::VisitPointer(
|
||||
heap(),
|
||||
reinterpret_cast<Object**>(cell->address() + offset));
|
||||
offset = JSGlobalPropertyCell::kTypeOffset;
|
||||
MarkCompactMarkingVisitor::VisitPointer(
|
||||
heap(),
|
||||
reinterpret_cast<Object**>(cell->address() + offset));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3389,11 +3419,27 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
|
||||
for (HeapObject* cell = cell_iterator.Next();
|
||||
cell != NULL;
|
||||
cell = cell_iterator.Next()) {
|
||||
if (cell->IsCell()) {
|
||||
Address value_address = reinterpret_cast<Address>(cell) +
|
||||
(Cell::kValueOffset - kHeapObjectTag);
|
||||
updating_visitor.VisitPointer(reinterpret_cast<Object**>(value_address));
|
||||
}
|
||||
}
|
||||
|
||||
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->IsJSGlobalPropertyCell()) {
|
||||
Address value_address =
|
||||
reinterpret_cast<Address>(cell) +
|
||||
(JSGlobalPropertyCell::kValueOffset - kHeapObjectTag);
|
||||
updating_visitor.VisitPointer(reinterpret_cast<Object**>(value_address));
|
||||
Address type_address =
|
||||
reinterpret_cast<Address>(cell) +
|
||||
(JSGlobalPropertyCell::kTypeOffset - kHeapObjectTag);
|
||||
updating_visitor.VisitPointer(reinterpret_cast<Object**>(type_address));
|
||||
}
|
||||
}
|
||||
|
||||
@ -4055,6 +4101,7 @@ void MarkCompactCollector::SweepSpaces() {
|
||||
SweepSpace(heap()->code_space(), PRECISE);
|
||||
|
||||
SweepSpace(heap()->cell_space(), PRECISE);
|
||||
SweepSpace(heap()->property_cell_space(), PRECISE);
|
||||
|
||||
EvacuateNewSpaceAndCandidates();
|
||||
|
||||
|
@ -172,7 +172,8 @@ class CppByteSink : public PartialSnapshotSink {
|
||||
int data_space_used,
|
||||
int code_space_used,
|
||||
int map_space_used,
|
||||
int cell_space_used) {
|
||||
int cell_space_used,
|
||||
int property_cell_space_used) {
|
||||
fprintf(fp_,
|
||||
"const int Snapshot::%snew_space_used_ = %d;\n",
|
||||
prefix,
|
||||
@ -197,6 +198,10 @@ class CppByteSink : public PartialSnapshotSink {
|
||||
"const int Snapshot::%scell_space_used_ = %d;\n",
|
||||
prefix,
|
||||
cell_space_used);
|
||||
fprintf(fp_,
|
||||
"const int Snapshot::%sproperty_cell_space_used_ = %d;\n",
|
||||
prefix,
|
||||
property_cell_space_used);
|
||||
}
|
||||
|
||||
void WritePartialSnapshot() {
|
||||
@ -417,7 +422,8 @@ int main(int argc, char** argv) {
|
||||
partial_ser.CurrentAllocationAddress(i::OLD_DATA_SPACE),
|
||||
partial_ser.CurrentAllocationAddress(i::CODE_SPACE),
|
||||
partial_ser.CurrentAllocationAddress(i::MAP_SPACE),
|
||||
partial_ser.CurrentAllocationAddress(i::CELL_SPACE));
|
||||
partial_ser.CurrentAllocationAddress(i::CELL_SPACE),
|
||||
partial_ser.CurrentAllocationAddress(i::PROPERTY_CELL_SPACE));
|
||||
sink.WriteSpaceUsed(
|
||||
"",
|
||||
ser.CurrentAllocationAddress(i::NEW_SPACE),
|
||||
@ -425,6 +431,7 @@ int main(int argc, char** argv) {
|
||||
ser.CurrentAllocationAddress(i::OLD_DATA_SPACE),
|
||||
ser.CurrentAllocationAddress(i::CODE_SPACE),
|
||||
ser.CurrentAllocationAddress(i::MAP_SPACE),
|
||||
ser.CurrentAllocationAddress(i::CELL_SPACE));
|
||||
ser.CurrentAllocationAddress(i::CELL_SPACE),
|
||||
ser.CurrentAllocationAddress(i::PROPERTY_CELL_SPACE));
|
||||
return 0;
|
||||
}
|
||||
|
@ -163,7 +163,10 @@ void HeapObject::HeapObjectVerify() {
|
||||
case JS_BUILTINS_OBJECT_TYPE:
|
||||
JSBuiltinsObject::cast(this)->JSBuiltinsObjectVerify();
|
||||
break;
|
||||
case JS_GLOBAL_PROPERTY_CELL_TYPE:
|
||||
case CELL_TYPE:
|
||||
Cell::cast(this)->CellVerify();
|
||||
break;
|
||||
case PROPERTY_CELL_TYPE:
|
||||
JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellVerify();
|
||||
break;
|
||||
case JS_ARRAY_TYPE:
|
||||
@ -615,9 +618,16 @@ void Oddball::OddballVerify() {
|
||||
}
|
||||
|
||||
|
||||
void Cell::CellVerify() {
|
||||
CHECK(IsCell());
|
||||
VerifyObjectField(kValueOffset);
|
||||
}
|
||||
|
||||
|
||||
void JSGlobalPropertyCell::JSGlobalPropertyCellVerify() {
|
||||
CHECK(IsJSGlobalPropertyCell());
|
||||
VerifyObjectField(kValueOffset);
|
||||
VerifyObjectField(kTypeOffset);
|
||||
}
|
||||
|
||||
|
||||
|
@ -668,7 +668,8 @@ template <> inline bool Is<JSFunction>(Object* obj) {
|
||||
|
||||
TYPE_CHECKER(Code, CODE_TYPE)
|
||||
TYPE_CHECKER(Oddball, ODDBALL_TYPE)
|
||||
TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
|
||||
TYPE_CHECKER(Cell, CELL_TYPE)
|
||||
TYPE_CHECKER(JSGlobalPropertyCell, PROPERTY_CELL_TYPE)
|
||||
TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
|
||||
TYPE_CHECKER(JSGeneratorObject, JS_GENERATOR_OBJECT_TYPE)
|
||||
TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
|
||||
@ -1621,18 +1622,28 @@ void Oddball::set_kind(byte value) {
|
||||
}
|
||||
|
||||
|
||||
Object* JSGlobalPropertyCell::value() {
|
||||
Object* Cell::value() {
|
||||
return READ_FIELD(this, kValueOffset);
|
||||
}
|
||||
|
||||
|
||||
void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
|
||||
void Cell::set_value(Object* val, WriteBarrierMode ignored) {
|
||||
// The write barrier is not used for global property cells.
|
||||
ASSERT(!val->IsJSGlobalPropertyCell());
|
||||
ASSERT(!val->IsJSGlobalPropertyCell() && !val->IsCell());
|
||||
WRITE_FIELD(this, kValueOffset, val);
|
||||
}
|
||||
|
||||
|
||||
Object* JSGlobalPropertyCell::type_raw() {
|
||||
return READ_FIELD(this, kTypeOffset);
|
||||
}
|
||||
|
||||
|
||||
void JSGlobalPropertyCell::set_type_raw(Object* val, WriteBarrierMode ignored) {
|
||||
WRITE_FIELD(this, kTypeOffset, val);
|
||||
}
|
||||
|
||||
|
||||
int JSObject::GetHeaderSize() {
|
||||
InstanceType type = map()->instance_type();
|
||||
// Check for the most common kind of JavaScript object before
|
||||
@ -2552,6 +2563,7 @@ CAST_ACCESSOR(Smi)
|
||||
CAST_ACCESSOR(HeapObject)
|
||||
CAST_ACCESSOR(HeapNumber)
|
||||
CAST_ACCESSOR(Oddball)
|
||||
CAST_ACCESSOR(Cell)
|
||||
CAST_ACCESSOR(JSGlobalPropertyCell)
|
||||
CAST_ACCESSOR(SharedFunctionInfo)
|
||||
CAST_ACCESSOR(Map)
|
||||
@ -6014,13 +6026,13 @@ TypeFeedbackId TypeFeedbackCells::AstId(int index) {
|
||||
}
|
||||
|
||||
|
||||
void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
|
||||
void TypeFeedbackCells::SetCell(int index, Cell* cell) {
|
||||
set(index * 2, cell);
|
||||
}
|
||||
|
||||
|
||||
JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
|
||||
return JSGlobalPropertyCell::cast(get(index * 2));
|
||||
Cell* TypeFeedbackCells::GetCell(int index) {
|
||||
return Cell::cast(get(index * 2));
|
||||
}
|
||||
|
||||
|
||||
|
@ -182,7 +182,10 @@ void HeapObject::HeapObjectPrint(FILE* out) {
|
||||
case JS_MESSAGE_OBJECT_TYPE:
|
||||
JSMessageObject::cast(this)->JSMessageObjectPrint(out);
|
||||
break;
|
||||
case JS_GLOBAL_PROPERTY_CELL_TYPE:
|
||||
case CELL_TYPE:
|
||||
Cell::cast(this)->CellPrint(out);
|
||||
break;
|
||||
case PROPERTY_CELL_TYPE:
|
||||
JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellPrint(out);
|
||||
break;
|
||||
case JS_ARRAY_BUFFER_TYPE:
|
||||
@ -533,7 +536,8 @@ static const char* TypeToString(InstanceType type) {
|
||||
case JS_OBJECT_TYPE: return "JS_OBJECT";
|
||||
case JS_CONTEXT_EXTENSION_OBJECT_TYPE: return "JS_CONTEXT_EXTENSION_OBJECT";
|
||||
case ODDBALL_TYPE: return "ODDBALL";
|
||||
case JS_GLOBAL_PROPERTY_CELL_TYPE: return "JS_GLOBAL_PROPERTY_CELL";
|
||||
case CELL_TYPE: return "CELL";
|
||||
case PROPERTY_CELL_TYPE: return "PROPERTY_CELL";
|
||||
case SHARED_FUNCTION_INFO_TYPE: return "SHARED_FUNCTION_INFO";
|
||||
case JS_GENERATOR_OBJECT_TYPE: return "JS_GENERATOR_OBJECT";
|
||||
case JS_MODULE_TYPE: return "JS_MODULE";
|
||||
@ -917,6 +921,11 @@ void JSBuiltinsObject::JSBuiltinsObjectPrint(FILE* out) {
|
||||
}
|
||||
|
||||
|
||||
void Cell::CellPrint(FILE* out) {
|
||||
HeapObject::PrintHeader(out, "Cell");
|
||||
}
|
||||
|
||||
|
||||
void JSGlobalPropertyCell::JSGlobalPropertyCellPrint(FILE* out) {
|
||||
HeapObject::PrintHeader(out, "JSGlobalPropertyCell");
|
||||
}
|
||||
@ -1093,8 +1102,8 @@ void TypeSwitchInfo::TypeSwitchInfoPrint(FILE* out) {
|
||||
void AllocationSiteInfo::AllocationSiteInfoPrint(FILE* out) {
|
||||
HeapObject::PrintHeader(out, "AllocationSiteInfo");
|
||||
PrintF(out, " - payload: ");
|
||||
if (payload()->IsJSGlobalPropertyCell()) {
|
||||
JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(payload());
|
||||
if (payload()->IsCell()) {
|
||||
Cell* cell = Cell::cast(payload());
|
||||
Object* cell_contents = cell->value();
|
||||
if (cell_contents->IsSmi()) {
|
||||
ElementsKind kind = static_cast<ElementsKind>(
|
||||
|
@ -196,6 +196,11 @@ void StaticMarkingVisitor<StaticVisitor>::Initialize() {
|
||||
|
||||
// Registration for kVisitJSRegExp is done by StaticVisitor.
|
||||
|
||||
table_.Register(kVisitCell,
|
||||
&FixedBodyVisitor<StaticVisitor,
|
||||
Cell::BodyDescriptor,
|
||||
void>::Visit);
|
||||
|
||||
table_.Register(kVisitPropertyCell,
|
||||
&FixedBodyVisitor<StaticVisitor,
|
||||
JSGlobalPropertyCell::BodyDescriptor,
|
||||
@ -240,10 +245,10 @@ void StaticMarkingVisitor<StaticVisitor>::VisitEmbeddedPointer(
|
||||
|
||||
|
||||
template<typename StaticVisitor>
|
||||
void StaticMarkingVisitor<StaticVisitor>::VisitGlobalPropertyCell(
|
||||
void StaticMarkingVisitor<StaticVisitor>::VisitCell(
|
||||
Heap* heap, RelocInfo* rinfo) {
|
||||
ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
JSGlobalPropertyCell* cell = rinfo->target_cell();
|
||||
ASSERT(rinfo->rmode() == RelocInfo::CELL);
|
||||
Cell* cell = rinfo->target_cell();
|
||||
StaticVisitor::MarkObject(heap, cell);
|
||||
}
|
||||
|
||||
@ -777,7 +782,7 @@ void StaticMarkingVisitor<StaticVisitor>::VisitJSFunctionWeakCode(
|
||||
void Code::CodeIterateBody(ObjectVisitor* v) {
|
||||
int mode_mask = RelocInfo::kCodeTargetMask |
|
||||
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
|
||||
RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) |
|
||||
RelocInfo::ModeMask(RelocInfo::CELL) |
|
||||
RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
|
||||
RelocInfo::ModeMask(RelocInfo::JS_RETURN) |
|
||||
RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) |
|
||||
@ -801,7 +806,7 @@ template<typename StaticVisitor>
|
||||
void Code::CodeIterateBody(Heap* heap) {
|
||||
int mode_mask = RelocInfo::kCodeTargetMask |
|
||||
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
|
||||
RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) |
|
||||
RelocInfo::ModeMask(RelocInfo::CELL) |
|
||||
RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
|
||||
RelocInfo::ModeMask(RelocInfo::JS_RETURN) |
|
||||
RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) |
|
||||
|
@ -91,7 +91,10 @@ StaticVisitorBase::VisitorId StaticVisitorBase::GetVisitorId(
|
||||
case CODE_TYPE:
|
||||
return kVisitCode;
|
||||
|
||||
case JS_GLOBAL_PROPERTY_CELL_TYPE:
|
||||
case CELL_TYPE:
|
||||
return kVisitCell;
|
||||
|
||||
case PROPERTY_CELL_TYPE:
|
||||
return kVisitPropertyCell;
|
||||
|
||||
case JS_SET_TYPE:
|
||||
|
@ -88,6 +88,7 @@ class StaticVisitorBase : public AllStatic {
|
||||
V(Oddball) \
|
||||
V(Code) \
|
||||
V(Map) \
|
||||
V(Cell) \
|
||||
V(PropertyCell) \
|
||||
V(SharedFunctionInfo) \
|
||||
V(JSFunction) \
|
||||
@ -394,7 +395,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
|
||||
|
||||
INLINE(static void VisitCodeEntry(Heap* heap, Address entry_address));
|
||||
INLINE(static void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo));
|
||||
INLINE(static void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo));
|
||||
INLINE(static void VisitCell(Heap* heap, RelocInfo* rinfo));
|
||||
INLINE(static void VisitDebugTarget(Heap* heap, RelocInfo* rinfo));
|
||||
INLINE(static void VisitCodeTarget(Heap* heap, RelocInfo* rinfo));
|
||||
INLINE(static void VisitCodeAgeSequence(Heap* heap, RelocInfo* rinfo));
|
||||
|
@ -631,7 +631,7 @@ Object* JSObject::GetNormalizedProperty(LookupResult* result) {
|
||||
if (IsGlobalObject()) {
|
||||
value = JSGlobalPropertyCell::cast(value)->value();
|
||||
}
|
||||
ASSERT(!value->IsJSGlobalPropertyCell());
|
||||
ASSERT(!value->IsJSGlobalPropertyCell() && !value->IsCell());
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -639,8 +639,7 @@ Object* JSObject::GetNormalizedProperty(LookupResult* result) {
|
||||
Object* JSObject::SetNormalizedProperty(LookupResult* result, Object* value) {
|
||||
ASSERT(!HasFastProperties());
|
||||
if (IsGlobalObject()) {
|
||||
JSGlobalPropertyCell* cell =
|
||||
JSGlobalPropertyCell::cast(
|
||||
JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(
|
||||
property_dictionary()->ValueAt(result->GetDictionaryEntry()));
|
||||
cell->set_value(value);
|
||||
} else {
|
||||
@ -1567,8 +1566,12 @@ void HeapObject::HeapObjectShortPrint(StringStream* accumulator) {
|
||||
case FOREIGN_TYPE:
|
||||
accumulator->Add("<Foreign>");
|
||||
break;
|
||||
case JS_GLOBAL_PROPERTY_CELL_TYPE:
|
||||
case CELL_TYPE:
|
||||
accumulator->Add("Cell for ");
|
||||
Cell::cast(this)->value()->ShortPrint(accumulator);
|
||||
break;
|
||||
case PROPERTY_CELL_TYPE:
|
||||
accumulator->Add("PropertyCell for ");
|
||||
JSGlobalPropertyCell::cast(this)->value()->ShortPrint(accumulator);
|
||||
break;
|
||||
default:
|
||||
@ -1661,7 +1664,10 @@ void HeapObject::IterateBody(InstanceType type, int object_size,
|
||||
case CODE_TYPE:
|
||||
reinterpret_cast<Code*>(this)->CodeIterateBody(v);
|
||||
break;
|
||||
case JS_GLOBAL_PROPERTY_CELL_TYPE:
|
||||
case CELL_TYPE:
|
||||
Cell::BodyDescriptor::IterateBody(this, v);
|
||||
break;
|
||||
case PROPERTY_CELL_TYPE:
|
||||
JSGlobalPropertyCell::BodyDescriptor::IterateBody(this, v);
|
||||
break;
|
||||
case SYMBOL_TYPE:
|
||||
@ -8905,8 +8911,8 @@ AllocationSiteInfo* AllocationSiteInfo::FindForJSObject(JSObject* object) {
|
||||
|
||||
bool AllocationSiteInfo::GetElementsKindPayload(ElementsKind* kind) {
|
||||
ASSERT(kind != NULL);
|
||||
if (payload()->IsJSGlobalPropertyCell()) {
|
||||
JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(payload());
|
||||
if (payload()->IsCell()) {
|
||||
Cell* cell = Cell::cast(payload());
|
||||
Object* cell_contents = cell->value();
|
||||
if (cell_contents->IsSmi()) {
|
||||
*kind = static_cast<ElementsKind>(
|
||||
@ -9980,13 +9986,13 @@ void ObjectVisitor::VisitCodeEntry(Address entry_address) {
|
||||
}
|
||||
|
||||
|
||||
void ObjectVisitor::VisitGlobalPropertyCell(RelocInfo* rinfo) {
|
||||
ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
void ObjectVisitor::VisitCell(RelocInfo* rinfo) {
|
||||
ASSERT(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<JSGlobalPropertyCell*>(cell));
|
||||
rinfo->set_target_cell(reinterpret_cast<Cell*>(cell));
|
||||
}
|
||||
}
|
||||
|
||||
@ -10048,7 +10054,7 @@ void Code::CopyFrom(const CodeDesc& desc) {
|
||||
intptr_t delta = instruction_start() - desc.buffer;
|
||||
int mode_mask = RelocInfo::kCodeTargetMask |
|
||||
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
|
||||
RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) |
|
||||
RelocInfo::ModeMask(RelocInfo::CELL) |
|
||||
RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
|
||||
RelocInfo::kApplyMask;
|
||||
// Needed to find target_object and runtime_entry on X64
|
||||
@ -10059,8 +10065,8 @@ void Code::CopyFrom(const CodeDesc& desc) {
|
||||
if (mode == RelocInfo::EMBEDDED_OBJECT) {
|
||||
Handle<Object> p = it.rinfo()->target_object_handle(origin);
|
||||
it.rinfo()->set_target_object(*p, SKIP_WRITE_BARRIER);
|
||||
} else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
|
||||
Handle<JSGlobalPropertyCell> cell = it.rinfo()->target_cell_handle();
|
||||
} else if (mode == RelocInfo::CELL) {
|
||||
Handle<Cell> cell = it.rinfo()->target_cell_handle();
|
||||
it.rinfo()->set_target_cell(*cell, SKIP_WRITE_BARRIER);
|
||||
} else if (RelocInfo::IsCodeTarget(mode)) {
|
||||
// rewrite code handles in inline cache targets to direct
|
||||
@ -10246,7 +10252,7 @@ void Code::ClearTypeFeedbackCells(Heap* heap) {
|
||||
TypeFeedbackCells* type_feedback_cells =
|
||||
TypeFeedbackInfo::cast(raw_info)->type_feedback_cells();
|
||||
for (int i = 0; i < type_feedback_cells->CellCount(); i++) {
|
||||
JSGlobalPropertyCell* cell = type_feedback_cells->Cell(i);
|
||||
Cell* cell = type_feedback_cells->GetCell(i);
|
||||
cell->set_value(TypeFeedbackCells::RawUninitializedSentinel(heap));
|
||||
}
|
||||
}
|
||||
@ -12330,8 +12336,8 @@ MaybeObject* JSObject::UpdateAllocationSiteInfo(ElementsKind to_kind) {
|
||||
return payload->TransitionElementsKind(to_kind);
|
||||
}
|
||||
}
|
||||
} else if (info->payload()->IsJSGlobalPropertyCell()) {
|
||||
JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(info->payload());
|
||||
} else if (info->payload()->IsCell()) {
|
||||
Cell* cell = Cell::cast(info->payload());
|
||||
Object* cell_contents = cell->value();
|
||||
if (cell_contents->IsSmi()) {
|
||||
ElementsKind kind = static_cast<ElementsKind>(
|
||||
@ -15804,4 +15810,15 @@ void JSTypedArray::Neuter() {
|
||||
set_elements(GetHeap()->EmptyExternalArrayForMap(map()));
|
||||
}
|
||||
|
||||
|
||||
Type* JSGlobalPropertyCell::type() {
|
||||
return static_cast<Type*>(type_raw());
|
||||
}
|
||||
|
||||
|
||||
void JSGlobalPropertyCell::set_type(Type* type, WriteBarrierMode ignored) {
|
||||
set_type_raw(type, ignored);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
@ -119,6 +119,8 @@
|
||||
// - ExternalTwoByteInternalizedString
|
||||
// - Symbol
|
||||
// - HeapNumber
|
||||
// - Cell
|
||||
// - JSGlobalPropertyCell
|
||||
// - Code
|
||||
// - Map
|
||||
// - Oddball
|
||||
@ -348,7 +350,8 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
|
||||
V(MAP_TYPE) \
|
||||
V(CODE_TYPE) \
|
||||
V(ODDBALL_TYPE) \
|
||||
V(JS_GLOBAL_PROPERTY_CELL_TYPE) \
|
||||
V(CELL_TYPE) \
|
||||
V(PROPERTY_CELL_TYPE) \
|
||||
V(BOX_TYPE) \
|
||||
\
|
||||
V(HEAP_NUMBER_TYPE) \
|
||||
@ -669,7 +672,8 @@ enum InstanceType {
|
||||
MAP_TYPE,
|
||||
CODE_TYPE,
|
||||
ODDBALL_TYPE,
|
||||
JS_GLOBAL_PROPERTY_CELL_TYPE,
|
||||
CELL_TYPE,
|
||||
PROPERTY_CELL_TYPE,
|
||||
BOX_TYPE,
|
||||
|
||||
// "Data", objects that cannot contain non-map-word pointers to heap
|
||||
@ -841,6 +845,7 @@ class Failure;
|
||||
class FixedArrayBase;
|
||||
class ObjectVisitor;
|
||||
class StringStream;
|
||||
class Type;
|
||||
|
||||
struct ValueInfo : public Malloced {
|
||||
ValueInfo() : type(FIRST_TYPE), ptr(NULL), str(NULL), number(0) { }
|
||||
@ -1011,6 +1016,7 @@ class MaybeObject BASE_EMBEDDED {
|
||||
V(JSGlobalProxy) \
|
||||
V(UndetectableObject) \
|
||||
V(AccessCheckNeeded) \
|
||||
V(Cell) \
|
||||
V(JSGlobalPropertyCell) \
|
||||
V(ObjectHashTable) \
|
||||
|
||||
@ -4378,6 +4384,7 @@ class DeoptimizationOutputData: public FixedArray {
|
||||
|
||||
|
||||
// Forward declaration.
|
||||
class Cell;
|
||||
class JSGlobalPropertyCell;
|
||||
|
||||
// TypeFeedbackCells is a fixed array used to hold the association between
|
||||
@ -4395,8 +4402,8 @@ class TypeFeedbackCells: public FixedArray {
|
||||
inline void SetAstId(int index, TypeFeedbackId id);
|
||||
|
||||
// Accessors for global property cells holding the cache values.
|
||||
inline JSGlobalPropertyCell* Cell(int index);
|
||||
inline void SetCell(int index, JSGlobalPropertyCell* cell);
|
||||
inline Cell* GetCell(int index);
|
||||
inline void SetCell(int index, Cell* cell);
|
||||
|
||||
// The object that indicates an uninitialized cache.
|
||||
static inline Handle<Object> UninitializedSentinel(Isolate* isolate);
|
||||
@ -5401,7 +5408,7 @@ class Map: public HeapObject {
|
||||
set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number));
|
||||
}
|
||||
|
||||
inline JSGlobalPropertyCell* RetrieveDescriptorsPointer();
|
||||
inline Cell* RetrieveDescriptorsPointer();
|
||||
|
||||
int EnumLength() {
|
||||
return EnumLengthBits::decode(bit_field3());
|
||||
@ -8553,16 +8560,18 @@ class Oddball: public HeapObject {
|
||||
};
|
||||
|
||||
|
||||
class JSGlobalPropertyCell: public HeapObject {
|
||||
class Cell: public HeapObject {
|
||||
public:
|
||||
// [value]: value of the global property.
|
||||
DECL_ACCESSORS(value, Object)
|
||||
|
||||
// Casting.
|
||||
static inline JSGlobalPropertyCell* cast(Object* obj);
|
||||
static inline Cell* cast(Object* obj);
|
||||
|
||||
static inline JSGlobalPropertyCell* FromValueAddress(Address value) {
|
||||
return cast(FromAddress(value - kValueOffset));
|
||||
static inline Cell* FromValueAddress(Address value) {
|
||||
Object* result = FromAddress(value - kValueOffset);
|
||||
ASSERT(result->IsCell() || result->IsJSGlobalPropertyCell());
|
||||
return static_cast<Cell*>(result);
|
||||
}
|
||||
|
||||
inline Address ValueAddress() {
|
||||
@ -8570,8 +8579,8 @@ class JSGlobalPropertyCell: public HeapObject {
|
||||
}
|
||||
|
||||
// Dispatched behavior.
|
||||
DECLARE_PRINTER(JSGlobalPropertyCell)
|
||||
DECLARE_VERIFIER(JSGlobalPropertyCell)
|
||||
DECLARE_PRINTER(Cell)
|
||||
DECLARE_VERIFIER(Cell)
|
||||
|
||||
// Layout description.
|
||||
static const int kValueOffset = HeapObject::kHeaderSize;
|
||||
@ -8582,6 +8591,37 @@ class JSGlobalPropertyCell: public HeapObject {
|
||||
kSize> BodyDescriptor;
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(Cell);
|
||||
};
|
||||
|
||||
|
||||
class JSGlobalPropertyCell: public Cell {
|
||||
public:
|
||||
Type* type();
|
||||
void set_type(Type* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
||||
|
||||
// Casting.
|
||||
static inline JSGlobalPropertyCell* cast(Object* obj);
|
||||
|
||||
inline Address TypeAddress() {
|
||||
return address() + kTypeOffset;
|
||||
}
|
||||
|
||||
// Dispatched behavior.
|
||||
DECLARE_PRINTER(JSGlobalPropertyCell)
|
||||
DECLARE_VERIFIER(JSGlobalPropertyCell)
|
||||
|
||||
// Layout description.
|
||||
static const int kTypeOffset = kValueOffset + kPointerSize;
|
||||
static const int kSize = kTypeOffset + kPointerSize;
|
||||
|
||||
typedef FixedBodyDescriptor<
|
||||
kValueOffset,
|
||||
kTypeOffset + kPointerSize,
|
||||
JSGlobalPropertyCell::kSize> BodyDescriptor;
|
||||
|
||||
private:
|
||||
DECL_ACCESSORS(type_raw, Object)
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalPropertyCell);
|
||||
};
|
||||
|
||||
@ -9601,7 +9641,7 @@ class ObjectVisitor BASE_EMBEDDED {
|
||||
virtual void VisitCodeEntry(Address entry_address);
|
||||
|
||||
// Visits a global property cell reference in the instruction stream.
|
||||
virtual void VisitGlobalPropertyCell(RelocInfo* rinfo);
|
||||
virtual void VisitCell(RelocInfo* rinfo);
|
||||
|
||||
// Visits a runtime entry in the instruction stream.
|
||||
virtual void VisitRuntimeEntry(RelocInfo* rinfo) {}
|
||||
|
@ -13481,9 +13481,9 @@ static MaybeObject* ArrayConstructorCommon(Isolate* isolate,
|
||||
MaybeObject* maybe_array;
|
||||
if (!type_info.is_null() &&
|
||||
*type_info != isolate->heap()->undefined_value() &&
|
||||
JSGlobalPropertyCell::cast(*type_info)->value()->IsSmi() &&
|
||||
Cell::cast(*type_info)->value()->IsSmi() &&
|
||||
can_use_type_feedback) {
|
||||
JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(*type_info);
|
||||
Cell* cell = Cell::cast(*type_info);
|
||||
Smi* smi = Smi::cast(cell->value());
|
||||
ElementsKind to_kind = static_cast<ElementsKind>(smi->value());
|
||||
if (holey && !IsFastHoleyElementsKind(to_kind)) {
|
||||
|
@ -778,6 +778,7 @@ void Deserializer::ReadChunk(Object** current,
|
||||
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 != OLD_DATA_SPACE);
|
||||
while (current < limit) {
|
||||
@ -838,8 +839,7 @@ void Deserializer::ReadChunk(Object** current,
|
||||
new_code_object->instruction_start()); \
|
||||
} else { \
|
||||
ASSERT(space_number == CODE_SPACE); \
|
||||
JSGlobalPropertyCell* cell = \
|
||||
JSGlobalPropertyCell::cast(new_object); \
|
||||
Cell* cell = Cell::cast(new_object); \
|
||||
new_object = reinterpret_cast<Object*>( \
|
||||
cell->ValueAddress()); \
|
||||
} \
|
||||
@ -879,6 +879,7 @@ void Deserializer::ReadChunk(Object** current,
|
||||
CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE) \
|
||||
CASE_STATEMENT(where, how, within, CODE_SPACE) \
|
||||
CASE_STATEMENT(where, how, within, CELL_SPACE) \
|
||||
CASE_STATEMENT(where, how, within, PROPERTY_CELL_SPACE) \
|
||||
CASE_STATEMENT(where, how, within, MAP_SPACE) \
|
||||
CASE_BODY(where, how, within, kAnyOldSpace)
|
||||
|
||||
@ -1566,10 +1567,9 @@ void Serializer::ObjectSerializer::VisitCodeEntry(Address entry_address) {
|
||||
}
|
||||
|
||||
|
||||
void Serializer::ObjectSerializer::VisitGlobalPropertyCell(RelocInfo* rinfo) {
|
||||
ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
JSGlobalPropertyCell* cell =
|
||||
JSGlobalPropertyCell::cast(rinfo->target_cell());
|
||||
void Serializer::ObjectSerializer::VisitCell(RelocInfo* rinfo) {
|
||||
ASSERT(rinfo->rmode() == RelocInfo::CELL);
|
||||
Cell* cell = Cell::cast(rinfo->target_cell());
|
||||
int skip = OutputRawData(rinfo->pc(), kCanReturnSkipInsteadOfSkipping);
|
||||
serializer_->SerializeObject(cell, kPlain, kInnerPointer, skip);
|
||||
}
|
||||
|
@ -519,7 +519,7 @@ class Serializer : public SerializerDeserializer {
|
||||
void VisitExternalReference(RelocInfo* rinfo);
|
||||
void VisitCodeTarget(RelocInfo* target);
|
||||
void VisitCodeEntry(Address entry_address);
|
||||
void VisitGlobalPropertyCell(RelocInfo* rinfo);
|
||||
void VisitCell(RelocInfo* rinfo);
|
||||
void VisitRuntimeEntry(RelocInfo* reloc);
|
||||
// Used for seralizing the external strings that hold the natives source.
|
||||
void VisitExternalAsciiString(
|
||||
|
@ -45,7 +45,8 @@ static void ReserveSpaceForSnapshot(Deserializer* deserializer,
|
||||
OS::SNPrintF(name, "%s.size", file_name);
|
||||
FILE* fp = OS::FOpen(name.start(), "r");
|
||||
CHECK_NE(NULL, fp);
|
||||
int new_size, pointer_size, data_size, code_size, map_size, cell_size;
|
||||
int new_size, pointer_size, data_size, code_size, map_size, cell_size,
|
||||
property_cell_size;
|
||||
#ifdef _MSC_VER
|
||||
// Avoid warning about unsafe fscanf from MSVC.
|
||||
// Please note that this is only fine if %c and %s are not being used.
|
||||
@ -57,6 +58,7 @@ static void ReserveSpaceForSnapshot(Deserializer* deserializer,
|
||||
CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size));
|
||||
CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size));
|
||||
CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size));
|
||||
CHECK_EQ(1, fscanf(fp, "property cell %d\n", &property_cell_size));
|
||||
#ifdef _MSC_VER
|
||||
#undef fscanf
|
||||
#endif
|
||||
@ -67,6 +69,8 @@ static void ReserveSpaceForSnapshot(Deserializer* deserializer,
|
||||
deserializer->set_reservation(CODE_SPACE, code_size);
|
||||
deserializer->set_reservation(MAP_SPACE, map_size);
|
||||
deserializer->set_reservation(CELL_SPACE, cell_size);
|
||||
deserializer->set_reservation(PROPERTY_CELL_SPACE,
|
||||
property_cell_size);
|
||||
name.Dispose();
|
||||
}
|
||||
|
||||
@ -78,6 +82,8 @@ void Snapshot::ReserveSpaceForLinkedInSnapshot(Deserializer* deserializer) {
|
||||
deserializer->set_reservation(CODE_SPACE, code_space_used_);
|
||||
deserializer->set_reservation(MAP_SPACE, map_space_used_);
|
||||
deserializer->set_reservation(CELL_SPACE, cell_space_used_);
|
||||
deserializer->set_reservation(PROPERTY_CELL_SPACE,
|
||||
property_cell_space_used_);
|
||||
}
|
||||
|
||||
|
||||
@ -124,6 +130,8 @@ Handle<Context> Snapshot::NewContextFromSnapshot() {
|
||||
deserializer.set_reservation(CODE_SPACE, context_code_space_used_);
|
||||
deserializer.set_reservation(MAP_SPACE, context_map_space_used_);
|
||||
deserializer.set_reservation(CELL_SPACE, context_cell_space_used_);
|
||||
deserializer.set_reservation(PROPERTY_CELL_SPACE,
|
||||
context_property_cell_space_used_);
|
||||
deserializer.DeserializePartial(&root);
|
||||
CHECK(root->IsContext());
|
||||
return Handle<Context>(Context::cast(root));
|
||||
|
@ -49,6 +49,7 @@ const int Snapshot::data_space_used_ = 0;
|
||||
const int Snapshot::code_space_used_ = 0;
|
||||
const int Snapshot::map_space_used_ = 0;
|
||||
const int Snapshot::cell_space_used_ = 0;
|
||||
const int Snapshot::property_cell_space_used_ = 0;
|
||||
|
||||
const int Snapshot::context_new_space_used_ = 0;
|
||||
const int Snapshot::context_pointer_space_used_ = 0;
|
||||
@ -56,5 +57,6 @@ const int Snapshot::context_data_space_used_ = 0;
|
||||
const int Snapshot::context_code_space_used_ = 0;
|
||||
const int Snapshot::context_map_space_used_ = 0;
|
||||
const int Snapshot::context_cell_space_used_ = 0;
|
||||
const int Snapshot::context_property_cell_space_used_ = 0;
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
@ -77,12 +77,14 @@ class Snapshot {
|
||||
static const int code_space_used_;
|
||||
static const int map_space_used_;
|
||||
static const int cell_space_used_;
|
||||
static const int property_cell_space_used_;
|
||||
static const int context_new_space_used_;
|
||||
static const int context_pointer_space_used_;
|
||||
static const int context_data_space_used_;
|
||||
static const int context_code_space_used_;
|
||||
static const int context_map_space_used_;
|
||||
static const int context_cell_space_used_;
|
||||
static const int context_property_cell_space_used_;
|
||||
static const int size_;
|
||||
static const int raw_size_;
|
||||
static const int context_size_;
|
||||
|
@ -72,6 +72,7 @@ HeapObjectIterator::HeapObjectIterator(Page* page,
|
||||
owner == page->heap()->old_data_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(),
|
||||
@ -1043,6 +1044,9 @@ intptr_t PagedSpace::SizeOfFirstPage() {
|
||||
case CELL_SPACE:
|
||||
size = 16 * kPointerSize * KB;
|
||||
break;
|
||||
case PROPERTY_CELL_SPACE:
|
||||
size = 8 * kPointerSize * KB;
|
||||
break;
|
||||
case CODE_SPACE:
|
||||
if (heap()->isolate()->code_range()->exists()) {
|
||||
// When code range exists, code pages are allocated in a special way
|
||||
@ -2834,12 +2838,19 @@ void MapSpace::VerifyObject(HeapObject* object) {
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// GlobalPropertyCellSpace implementation
|
||||
// CellSpace and PropertyCellSpace 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) {
|
||||
// The object should be a global object property cell or a free-list node.
|
||||
CHECK(object->IsCell() ||
|
||||
object->map() == heap()->two_pointer_filler_map());
|
||||
}
|
||||
|
||||
|
||||
void PropertyCellSpace::VerifyObject(HeapObject* object) {
|
||||
// The object should be a global object property cell or a free-list node.
|
||||
CHECK(object->IsJSGlobalPropertyCell() ||
|
||||
object->map() == heap()->two_pointer_filler_map());
|
||||
|
31
src/spaces.h
31
src/spaces.h
@ -2626,12 +2626,39 @@ class MapSpace : public FixedSpace {
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Old space for all global object property cell objects
|
||||
// Old space for simple property cell objects
|
||||
|
||||
class CellSpace : public FixedSpace {
|
||||
public:
|
||||
// Creates a property cell space object with a maximum capacity.
|
||||
CellSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id)
|
||||
: FixedSpace(heap, max_capacity, id, Cell::kSize)
|
||||
{}
|
||||
|
||||
virtual int RoundSizeDownToObjectAlignment(int size) {
|
||||
if (IsPowerOf2(Cell::kSize)) {
|
||||
return RoundDown(size, Cell::kSize);
|
||||
} else {
|
||||
return (size / Cell::kSize) * Cell::kSize;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void VerifyObject(HeapObject* obj);
|
||||
|
||||
public:
|
||||
TRACK_MEMORY("CellSpace")
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Old space for all global object property cell objects
|
||||
|
||||
class PropertyCellSpace : public FixedSpace {
|
||||
public:
|
||||
// Creates a property cell space object with a maximum capacity.
|
||||
PropertyCellSpace(Heap* heap, intptr_t max_capacity,
|
||||
AllocationSpace id)
|
||||
: FixedSpace(heap, max_capacity, id, JSGlobalPropertyCell::kSize)
|
||||
{}
|
||||
|
||||
@ -2647,7 +2674,7 @@ class CellSpace : public FixedSpace {
|
||||
virtual void VerifyObject(HeapObject* obj);
|
||||
|
||||
public:
|
||||
TRACK_MEMORY("CellSpace")
|
||||
TRACK_MEMORY("PropertyCellSpace")
|
||||
};
|
||||
|
||||
|
||||
|
@ -1977,7 +1977,7 @@ bool CallStubCompiler::HasCustomCallGenerator(Handle<JSFunction> function) {
|
||||
Handle<Code> CallStubCompiler::CompileCustomCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> fname) {
|
||||
ASSERT(HasCustomCallGenerator(function));
|
||||
|
@ -1019,14 +1019,14 @@ class CallStubCompiler: public StubCompiler {
|
||||
// given function.
|
||||
Handle<Code> CompileCustomCall(Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name);
|
||||
|
||||
#define DECLARE_CALL_GENERATOR(name) \
|
||||
Handle<Code> Compile##name##Call(Handle<Object> object, \
|
||||
Handle<JSObject> holder, \
|
||||
Handle<JSGlobalPropertyCell> cell, \
|
||||
Handle<Cell> cell, \
|
||||
Handle<JSFunction> function, \
|
||||
Handle<String> fname);
|
||||
CUSTOM_CALL_IC_GENERATORS(DECLARE_CALL_GENERATOR)
|
||||
@ -1035,7 +1035,7 @@ class CallStubCompiler: public StubCompiler {
|
||||
Handle<Code> CompileFastApiCall(const CallOptimization& optimization,
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name);
|
||||
|
||||
@ -1053,7 +1053,7 @@ class CallStubCompiler: public StubCompiler {
|
||||
|
||||
// Generates code to load the function from the cell checking that
|
||||
// it still contains the same function.
|
||||
void GenerateLoadFunctionFromCell(Handle<JSGlobalPropertyCell> cell,
|
||||
void GenerateLoadFunctionFromCell(Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Label* miss);
|
||||
|
||||
|
@ -80,8 +80,8 @@ Handle<Object> TypeFeedbackOracle::GetInfo(TypeFeedbackId ast_id) {
|
||||
int entry = dictionary_->FindEntry(IdToKey(ast_id));
|
||||
if (entry != UnseededNumberDictionary::kNotFound) {
|
||||
Object* value = dictionary_->ValueAt(entry);
|
||||
if (value->IsJSGlobalPropertyCell()) {
|
||||
JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(value);
|
||||
if (value->IsCell()) {
|
||||
Cell* cell = Cell::cast(value);
|
||||
return Handle<Object>(cell->value(), isolate_);
|
||||
} else {
|
||||
return Handle<Object>(value, isolate_);
|
||||
@ -91,15 +91,14 @@ Handle<Object> TypeFeedbackOracle::GetInfo(TypeFeedbackId ast_id) {
|
||||
}
|
||||
|
||||
|
||||
Handle<JSGlobalPropertyCell> TypeFeedbackOracle::GetInfoCell(
|
||||
Handle<Cell> TypeFeedbackOracle::GetInfoCell(
|
||||
TypeFeedbackId ast_id) {
|
||||
int entry = dictionary_->FindEntry(IdToKey(ast_id));
|
||||
if (entry != UnseededNumberDictionary::kNotFound) {
|
||||
JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(
|
||||
dictionary_->ValueAt(entry));
|
||||
return Handle<JSGlobalPropertyCell>(cell, isolate_);
|
||||
Cell* cell = Cell::cast(dictionary_->ValueAt(entry));
|
||||
return Handle<Cell>(cell, isolate_);
|
||||
}
|
||||
return Handle<JSGlobalPropertyCell>::null();
|
||||
return Handle<Cell>::null();
|
||||
}
|
||||
|
||||
|
||||
@ -335,8 +334,7 @@ Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(CallNew* expr) {
|
||||
}
|
||||
|
||||
|
||||
Handle<JSGlobalPropertyCell> TypeFeedbackOracle::GetCallNewAllocationInfoCell(
|
||||
CallNew* expr) {
|
||||
Handle<Cell> TypeFeedbackOracle::GetCallNewAllocationInfoCell(CallNew* expr) {
|
||||
return GetInfoCell(expr->CallNewFeedbackId());
|
||||
}
|
||||
|
||||
@ -759,7 +757,7 @@ void TypeFeedbackOracle::ProcessTypeFeedbackCells(Handle<Code> code) {
|
||||
TypeFeedbackInfo::cast(raw_info)->type_feedback_cells());
|
||||
for (int i = 0; i < cache->CellCount(); i++) {
|
||||
TypeFeedbackId ast_id = cache->AstId(i);
|
||||
JSGlobalPropertyCell* cell = cache->Cell(i);
|
||||
Cell* cell = cache->GetCell(i);
|
||||
Object* value = cell->value();
|
||||
if (value->IsSmi() ||
|
||||
(value->IsJSFunction() &&
|
||||
|
@ -283,7 +283,7 @@ class TypeFeedbackOracle: public ZoneObject {
|
||||
CheckType GetCallCheckType(Call* expr);
|
||||
Handle<JSFunction> GetCallTarget(Call* expr);
|
||||
Handle<JSFunction> GetCallNewTarget(CallNew* expr);
|
||||
Handle<JSGlobalPropertyCell> GetCallNewAllocationInfoCell(CallNew* expr);
|
||||
Handle<Cell> GetCallNewAllocationInfoCell(CallNew* expr);
|
||||
|
||||
Handle<Map> GetObjectLiteralStoreMap(ObjectLiteralProperty* prop);
|
||||
|
||||
@ -341,7 +341,7 @@ class TypeFeedbackOracle: public ZoneObject {
|
||||
Handle<Object> GetInfo(TypeFeedbackId ast_id);
|
||||
|
||||
// Return the cell that contains type feedback.
|
||||
Handle<JSGlobalPropertyCell> GetInfoCell(TypeFeedbackId ast_id);
|
||||
Handle<Cell> GetInfoCell(TypeFeedbackId ast_id);
|
||||
|
||||
private:
|
||||
Handle<Context> native_context_;
|
||||
|
@ -63,12 +63,16 @@ namespace internal {
|
||||
V8.MemoryExternalFragmentationMapSpace) \
|
||||
HP(external_fragmentation_cell_space, \
|
||||
V8.MemoryExternalFragmentationCellSpace) \
|
||||
HP(external_fragmentation_property_cell_space, \
|
||||
V8.MemoryExternalFragmentationPropertyCellSpace) \
|
||||
HP(external_fragmentation_lo_space, \
|
||||
V8.MemoryExternalFragmentationLoSpace) \
|
||||
HP(heap_fraction_map_space, \
|
||||
V8.MemoryHeapFractionMapSpace) \
|
||||
HP(heap_fraction_cell_space, \
|
||||
V8.MemoryHeapFractionCellSpace) \
|
||||
HP(heap_fraction_property_cell_space, \
|
||||
V8.MemoryHeapFractionPropertyCellSpace) \
|
||||
|
||||
|
||||
#define HISTOGRAM_MEMORY_LIST(HM) \
|
||||
@ -77,7 +81,9 @@ namespace internal {
|
||||
HM(heap_sample_map_space_committed, \
|
||||
V8.MemoryHeapSampleMapSpaceCommitted) \
|
||||
HM(heap_sample_cell_space_committed, \
|
||||
V8.MemoryHeapSampleCellSpaceCommitted)
|
||||
V8.MemoryHeapSampleCellSpaceCommitted) \
|
||||
HM(heap_sample_property_cell_space_committed, \
|
||||
V8.MemoryHeapSamplePropertyCellSpaceCommitted) \
|
||||
|
||||
|
||||
// WARNING: STATS_COUNTER_LIST_* is a very large macro that is causing MSVC
|
||||
@ -297,6 +303,12 @@ namespace internal {
|
||||
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)
|
||||
|
@ -180,12 +180,13 @@ enum AllocationSpace {
|
||||
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.
|
||||
|
||||
FIRST_SPACE = NEW_SPACE,
|
||||
LAST_SPACE = LO_SPACE,
|
||||
FIRST_PAGED_SPACE = OLD_POINTER_SPACE,
|
||||
LAST_PAGED_SPACE = CELL_SPACE
|
||||
LAST_PAGED_SPACE = PROPERTY_CELL_SPACE
|
||||
};
|
||||
const int kSpaceTagSize = 3;
|
||||
const int kSpaceTagMask = (1 << kSpaceTagSize) - 1;
|
||||
|
@ -332,24 +332,22 @@ void RelocInfo::set_target_runtime_entry(Address target,
|
||||
}
|
||||
|
||||
|
||||
Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
|
||||
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
Handle<Cell> RelocInfo::target_cell_handle() {
|
||||
ASSERT(rmode_ == RelocInfo::CELL);
|
||||
Address address = Memory::Address_at(pc_);
|
||||
return Handle<JSGlobalPropertyCell>(
|
||||
reinterpret_cast<JSGlobalPropertyCell**>(address));
|
||||
return Handle<Cell>(reinterpret_cast<Cell**>(address));
|
||||
}
|
||||
|
||||
|
||||
JSGlobalPropertyCell* RelocInfo::target_cell() {
|
||||
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
return JSGlobalPropertyCell::FromValueAddress(Memory::Address_at(pc_));
|
||||
Cell* RelocInfo::target_cell() {
|
||||
ASSERT(rmode_ == RelocInfo::CELL);
|
||||
return Cell::FromValueAddress(Memory::Address_at(pc_));
|
||||
}
|
||||
|
||||
|
||||
void RelocInfo::set_target_cell(JSGlobalPropertyCell* cell,
|
||||
WriteBarrierMode mode) {
|
||||
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
Address address = cell->address() + JSGlobalPropertyCell::kValueOffset;
|
||||
void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode mode) {
|
||||
ASSERT(rmode_ == RelocInfo::CELL);
|
||||
Address address = cell->address() + Cell::kValueOffset;
|
||||
Memory::Address_at(pc_) = address;
|
||||
CPU::FlushICache(pc_, sizeof(Address));
|
||||
if (mode == UPDATE_WRITE_BARRIER &&
|
||||
@ -445,8 +443,8 @@ void RelocInfo::Visit(ObjectVisitor* visitor) {
|
||||
CPU::FlushICache(pc_, sizeof(Address));
|
||||
} else if (RelocInfo::IsCodeTarget(mode)) {
|
||||
visitor->VisitCodeTarget(this);
|
||||
} else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
|
||||
visitor->VisitGlobalPropertyCell(this);
|
||||
} else if (mode == RelocInfo::CELL) {
|
||||
visitor->VisitCell(this);
|
||||
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
|
||||
visitor->VisitExternalReference(this);
|
||||
CPU::FlushICache(pc_, sizeof(Address));
|
||||
@ -475,8 +473,8 @@ void RelocInfo::Visit(Heap* heap) {
|
||||
CPU::FlushICache(pc_, sizeof(Address));
|
||||
} else if (RelocInfo::IsCodeTarget(mode)) {
|
||||
StaticVisitor::VisitCodeTarget(heap, this);
|
||||
} else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
|
||||
StaticVisitor::VisitGlobalPropertyCell(heap, this);
|
||||
} else if (mode == RelocInfo::CELL) {
|
||||
StaticVisitor::VisitCell(heap, this);
|
||||
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
|
||||
StaticVisitor::VisitExternalReference(this);
|
||||
CPU::FlushICache(pc_, sizeof(Address));
|
||||
|
@ -3727,7 +3727,7 @@ static void GenerateRecordCallTargetNoArray(MacroAssembler* masm) {
|
||||
Label initialize, done;
|
||||
|
||||
// Load the cache state into rcx.
|
||||
__ movq(rcx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset));
|
||||
__ movq(rcx, FieldOperand(rbx, Cell::kValueOffset));
|
||||
|
||||
// A monomorphic cache hit or an already megamorphic state: invoke the
|
||||
// function without changing the state.
|
||||
@ -3742,13 +3742,13 @@ static void GenerateRecordCallTargetNoArray(MacroAssembler* masm) {
|
||||
__ j(equal, &initialize, Label::kNear);
|
||||
// MegamorphicSentinel is an immortal immovable object (undefined) so no
|
||||
// write-barrier is needed.
|
||||
__ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset),
|
||||
__ Move(FieldOperand(rbx, Cell::kValueOffset),
|
||||
TypeFeedbackCells::MegamorphicSentinel(isolate));
|
||||
__ jmp(&done, Label::kNear);
|
||||
|
||||
// An uninitialized cache is patched with the function.
|
||||
__ bind(&initialize);
|
||||
__ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), rdi);
|
||||
__ movq(FieldOperand(rbx, Cell::kValueOffset), rdi);
|
||||
// No need for a write barrier here - cells are rescanned.
|
||||
|
||||
__ bind(&done);
|
||||
@ -3766,7 +3766,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
|
||||
Label initialize, done, miss, megamorphic, not_array_function;
|
||||
|
||||
// Load the cache state into rcx.
|
||||
__ movq(rcx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset));
|
||||
__ movq(rcx, FieldOperand(rbx, Cell::kValueOffset));
|
||||
|
||||
// A monomorphic cache hit or an already megamorphic state: invoke the
|
||||
// function without changing the state.
|
||||
@ -3799,7 +3799,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
|
||||
// MegamorphicSentinel is an immortal immovable object (undefined) so no
|
||||
// write-barrier is needed.
|
||||
__ bind(&megamorphic);
|
||||
__ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset),
|
||||
__ Move(FieldOperand(rbx, Cell::kValueOffset),
|
||||
TypeFeedbackCells::MegamorphicSentinel(isolate));
|
||||
__ jmp(&done, Label::kNear);
|
||||
|
||||
@ -3817,12 +3817,12 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
|
||||
Handle<Object> initial_kind_sentinel =
|
||||
TypeFeedbackCells::MonomorphicArraySentinel(isolate,
|
||||
GetInitialFastElementsKind());
|
||||
__ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset),
|
||||
__ Move(FieldOperand(rbx, Cell::kValueOffset),
|
||||
initial_kind_sentinel);
|
||||
__ jmp(&done);
|
||||
|
||||
__ bind(¬_array_function);
|
||||
__ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), rdi);
|
||||
__ movq(FieldOperand(rbx, Cell::kValueOffset), rdi);
|
||||
// No need for a write barrier here - cells are rescanned.
|
||||
|
||||
__ bind(&done);
|
||||
@ -3893,7 +3893,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
||||
// If there is a call target cache, mark it megamorphic in the
|
||||
// non-function case. MegamorphicSentinel is an immortal immovable
|
||||
// object (undefined) so no write barrier is needed.
|
||||
__ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset),
|
||||
__ Move(FieldOperand(rbx, Cell::kValueOffset),
|
||||
TypeFeedbackCells::MegamorphicSentinel(isolate));
|
||||
}
|
||||
// Check for function proxy.
|
||||
@ -6934,13 +6934,12 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ CmpObjectType(rcx, MAP_TYPE, rcx);
|
||||
__ Check(equal, "Unexpected initial map for Array function");
|
||||
|
||||
// We should either have undefined in ebx or a valid jsglobalpropertycell
|
||||
// We should either have undefined in ebx or a valid cell
|
||||
Label okay_here;
|
||||
Handle<Map> global_property_cell_map(
|
||||
masm->isolate()->heap()->global_property_cell_map());
|
||||
Handle<Map> cell_map = masm->isolate()->factory()->cell_map();
|
||||
__ Cmp(rbx, undefined_sentinel);
|
||||
__ j(equal, &okay_here);
|
||||
__ Cmp(FieldOperand(rbx, 0), global_property_cell_map);
|
||||
__ Cmp(FieldOperand(rbx, 0), cell_map);
|
||||
__ Assert(equal, "Expected property cell in register rbx");
|
||||
__ bind(&okay_here);
|
||||
}
|
||||
@ -6950,7 +6949,7 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
// Get the elements kind and case on that.
|
||||
__ Cmp(rbx, undefined_sentinel);
|
||||
__ j(equal, &no_info);
|
||||
__ movq(rdx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset));
|
||||
__ movq(rdx, FieldOperand(rbx, Cell::kValueOffset));
|
||||
__ JumpIfNotSmi(rdx, &no_info);
|
||||
__ SmiToInteger32(rdx, rdx);
|
||||
__ jmp(&switch_ready);
|
||||
|
@ -118,7 +118,7 @@ void FullCodeGenerator::Generate() {
|
||||
CompilationInfo* info = info_;
|
||||
handler_table_ =
|
||||
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
|
||||
profiling_counter_ = isolate()->factory()->NewJSGlobalPropertyCell(
|
||||
profiling_counter_ = isolate()->factory()->NewCell(
|
||||
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
|
||||
SetFunctionPosition(function());
|
||||
Comment cmnt(masm_, "[ function compiled by full code generator");
|
||||
@ -308,7 +308,7 @@ void FullCodeGenerator::ClearAccumulator() {
|
||||
|
||||
void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
|
||||
__ movq(rbx, profiling_counter_, RelocInfo::EMBEDDED_OBJECT);
|
||||
__ SmiAddConstant(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset),
|
||||
__ SmiAddConstant(FieldOperand(rbx, Cell::kValueOffset),
|
||||
Smi::FromInt(-delta));
|
||||
}
|
||||
|
||||
@ -323,8 +323,7 @@ void FullCodeGenerator::EmitProfilingCounterReset() {
|
||||
__ movq(kScratchRegister,
|
||||
reinterpret_cast<uint64_t>(Smi::FromInt(reset_value)),
|
||||
RelocInfo::NONE64);
|
||||
__ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset),
|
||||
kScratchRegister);
|
||||
__ movq(FieldOperand(rbx, Cell::kValueOffset), kScratchRegister);
|
||||
}
|
||||
|
||||
|
||||
@ -1128,14 +1127,12 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
Label non_proxy;
|
||||
__ bind(&fixed_array);
|
||||
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(
|
||||
Handle<Object>(
|
||||
Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(
|
||||
Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
|
||||
isolate()));
|
||||
RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell);
|
||||
__ LoadHeapObject(rbx, cell);
|
||||
__ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset),
|
||||
__ Move(FieldOperand(rbx, Cell::kValueOffset),
|
||||
Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker));
|
||||
|
||||
__ Move(rbx, Smi::FromInt(1)); // Smi indicates slow check
|
||||
@ -2611,8 +2608,7 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
|
||||
flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
|
||||
Handle<Object> uninitialized =
|
||||
TypeFeedbackCells::UninitializedSentinel(isolate());
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized);
|
||||
RecordTypeFeedbackCell(expr->CallFeedbackId(), cell);
|
||||
__ Move(rbx, cell);
|
||||
|
||||
@ -2795,8 +2791,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
// Record call targets in unoptimized code, but not in the snapshot.
|
||||
Handle<Object> uninitialized =
|
||||
TypeFeedbackCells::UninitializedSentinel(isolate());
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized);
|
||||
RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell);
|
||||
__ Move(rbx, cell);
|
||||
|
||||
|
@ -2450,9 +2450,8 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
|
||||
Register map = ToRegister(instr->temp());
|
||||
__ movq(map, FieldOperand(object, HeapObject::kMapOffset));
|
||||
__ bind(deferred->map_check()); // Label for calculating code patching.
|
||||
Handle<JSGlobalPropertyCell> cache_cell =
|
||||
factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
|
||||
__ movq(kScratchRegister, cache_cell, RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
Handle<Cell> cache_cell = factory()->NewCell(factory()->the_hole_value());
|
||||
__ movq(kScratchRegister, cache_cell, RelocInfo::CELL);
|
||||
__ cmpq(map, Operand(kScratchRegister, 0));
|
||||
__ j(not_equal, &cache_miss, Label::kNear);
|
||||
// Patched to load either true or false.
|
||||
@ -2621,7 +2620,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
|
||||
|
||||
void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
|
||||
Register value = ToRegister(instr->value());
|
||||
Handle<JSGlobalPropertyCell> cell_handle = instr->hydrogen()->cell();
|
||||
Handle<Cell> cell_handle = instr->hydrogen()->cell();
|
||||
|
||||
// If the cell we are storing to contains the hole it could have
|
||||
// been deleted from the property dictionary. In that case, we need
|
||||
@ -2631,14 +2630,14 @@ void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
|
||||
// We have a temp because CompareRoot might clobber kScratchRegister.
|
||||
Register cell = ToRegister(instr->temp());
|
||||
ASSERT(!value.is(cell));
|
||||
__ movq(cell, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
__ movq(cell, cell_handle, RelocInfo::CELL);
|
||||
__ CompareRoot(Operand(cell, 0), Heap::kTheHoleValueRootIndex);
|
||||
DeoptimizeIf(equal, instr->environment());
|
||||
// Store the value.
|
||||
__ movq(Operand(cell, 0), value);
|
||||
} else {
|
||||
// Store the value.
|
||||
__ movq(kScratchRegister, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
__ movq(kScratchRegister, cell_handle, RelocInfo::CELL);
|
||||
__ movq(Operand(kScratchRegister, 0), value);
|
||||
}
|
||||
// Cells are always rescanned, so no write barrier here.
|
||||
|
@ -2357,9 +2357,8 @@ void MacroAssembler::LoadHeapObject(Register result,
|
||||
Handle<HeapObject> object) {
|
||||
AllowDeferredHandleDereference using_raw_address;
|
||||
if (isolate()->heap()->InNewSpace(*object)) {
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(object);
|
||||
movq(result, cell, RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(object);
|
||||
movq(result, cell, RelocInfo::CELL);
|
||||
movq(result, Operand(result, 0));
|
||||
} else {
|
||||
Move(result, object);
|
||||
@ -2370,9 +2369,8 @@ void MacroAssembler::LoadHeapObject(Register result,
|
||||
void MacroAssembler::CmpHeapObject(Register reg, Handle<HeapObject> object) {
|
||||
AllowDeferredHandleDereference using_raw_address;
|
||||
if (isolate()->heap()->InNewSpace(*object)) {
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(object);
|
||||
movq(kScratchRegister, cell, RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(object);
|
||||
movq(kScratchRegister, cell, RelocInfo::CELL);
|
||||
cmpq(reg, Operand(kScratchRegister, 0));
|
||||
} else {
|
||||
Cmp(reg, object);
|
||||
@ -2383,9 +2381,8 @@ void MacroAssembler::CmpHeapObject(Register reg, Handle<HeapObject> object) {
|
||||
void MacroAssembler::PushHeapObject(Handle<HeapObject> object) {
|
||||
AllowDeferredHandleDereference using_raw_address;
|
||||
if (isolate()->heap()->InNewSpace(*object)) {
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(object);
|
||||
movq(kScratchRegister, cell, RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
Handle<Cell> cell = isolate()->factory()->NewCell(object);
|
||||
movq(kScratchRegister, cell, RelocInfo::CELL);
|
||||
movq(kScratchRegister, Operand(kScratchRegister, 0));
|
||||
push(kScratchRegister);
|
||||
} else {
|
||||
@ -2394,13 +2391,12 @@ void MacroAssembler::PushHeapObject(Handle<HeapObject> object) {
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::LoadGlobalCell(Register dst,
|
||||
Handle<JSGlobalPropertyCell> cell) {
|
||||
void MacroAssembler::LoadGlobalCell(Register dst, Handle<Cell> cell) {
|
||||
if (dst.is(rax)) {
|
||||
AllowDeferredHandleDereference embedding_raw_address;
|
||||
load_rax(cell.location(), RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
load_rax(cell.location(), RelocInfo::CELL);
|
||||
} else {
|
||||
movq(dst, cell, RelocInfo::GLOBAL_PROPERTY_CELL);
|
||||
movq(dst, cell, RelocInfo::CELL);
|
||||
movq(dst, Operand(dst, 0));
|
||||
}
|
||||
}
|
||||
|
@ -810,7 +810,7 @@ class MacroAssembler: public Assembler {
|
||||
}
|
||||
|
||||
// Load a global cell into a register.
|
||||
void LoadGlobalCell(Register dst, Handle<JSGlobalPropertyCell> cell);
|
||||
void LoadGlobalCell(Register dst, Handle<Cell> cell);
|
||||
|
||||
// Emit code to discard a non-negative number of pointer-sized elements
|
||||
// from the stack, clobbering only the rsp register.
|
||||
|
@ -741,7 +741,7 @@ static void GenerateCheckPropertyCell(MacroAssembler* masm,
|
||||
GlobalObject::EnsurePropertyCell(global, name);
|
||||
ASSERT(cell->value()->IsTheHole());
|
||||
__ Move(scratch, cell);
|
||||
__ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
|
||||
__ Cmp(FieldOperand(scratch, Cell::kValueOffset),
|
||||
masm->isolate()->factory()->the_hole_value());
|
||||
__ j(not_equal, miss);
|
||||
}
|
||||
@ -1485,12 +1485,12 @@ void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object,
|
||||
|
||||
|
||||
void CallStubCompiler::GenerateLoadFunctionFromCell(
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Label* miss) {
|
||||
// Get the value from the cell.
|
||||
__ Move(rdi, cell);
|
||||
__ movq(rdi, FieldOperand(rdi, JSGlobalPropertyCell::kValueOffset));
|
||||
__ movq(rdi, FieldOperand(rdi, Cell::kValueOffset));
|
||||
|
||||
// Check that the cell contains the same function.
|
||||
if (heap()->InNewSpace(*function)) {
|
||||
@ -1584,7 +1584,7 @@ Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
|
||||
Handle<Code> CallStubCompiler::CompileArrayPushCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -1834,7 +1834,7 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall(
|
||||
Handle<Code> CallStubCompiler::CompileArrayPopCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -1915,7 +1915,7 @@ Handle<Code> CallStubCompiler::CompileArrayPopCall(
|
||||
Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -1995,7 +1995,7 @@ Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
|
||||
Handle<Code> CallStubCompiler::CompileStringCharAtCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -2075,7 +2075,7 @@ Handle<Code> CallStubCompiler::CompileStringCharAtCall(
|
||||
Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -2146,7 +2146,7 @@ Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
|
||||
Handle<Code> CallStubCompiler::CompileMathFloorCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// TODO(872): implement this.
|
||||
@ -2157,7 +2157,7 @@ Handle<Code> CallStubCompiler::CompileMathFloorCall(
|
||||
Handle<Code> CallStubCompiler::CompileMathAbsCall(
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -2263,7 +2263,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall(
|
||||
const CallOptimization& optimization,
|
||||
Handle<Object> object,
|
||||
Handle<JSObject> holder,
|
||||
Handle<JSGlobalPropertyCell> cell,
|
||||
Handle<Cell> cell,
|
||||
Handle<JSFunction> function,
|
||||
Handle<String> name) {
|
||||
ASSERT(optimization.is_simple_api_call());
|
||||
|
@ -2498,15 +2498,15 @@ TEST(IncrementalMarkingClearsTypeFeedbackCells) {
|
||||
f->shared()->code()->type_feedback_info())->type_feedback_cells());
|
||||
|
||||
CHECK_EQ(2, cells->CellCount());
|
||||
CHECK(cells->Cell(0)->value()->IsJSFunction());
|
||||
CHECK(cells->Cell(1)->value()->IsJSFunction());
|
||||
CHECK(cells->GetCell(0)->value()->IsJSFunction());
|
||||
CHECK(cells->GetCell(1)->value()->IsJSFunction());
|
||||
|
||||
SimulateIncrementalMarking();
|
||||
HEAP->CollectAllGarbage(Heap::kNoGCFlags);
|
||||
|
||||
CHECK_EQ(2, cells->CellCount());
|
||||
CHECK(cells->Cell(0)->value()->IsTheHole());
|
||||
CHECK(cells->Cell(1)->value()->IsTheHole());
|
||||
CHECK(cells->GetCell(0)->value()->IsTheHole());
|
||||
CHECK(cells->GetCell(1)->value()->IsTheHole());
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user