MIPS: Separate Cell and PropertyCell spaces

Port r15089 (5c28e4e7)

Original commit message:
This makes it possible to store additional information on property cells, for example Type and optimized Code dependencies.

BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15103 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
palfia@homejinni.com 2013-06-12 23:39:22 +00:00
parent ba15460ce6
commit f5461d3c8a
6 changed files with 60 additions and 74 deletions

View File

@ -232,24 +232,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
@ -345,8 +343,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)) {
@ -373,8 +371,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)) {

View File

@ -3860,7 +3860,7 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
__ Subu(inline_site, ra, scratch);
// Get the map location in scratch and patch it.
__ GetRelocatedValue(inline_site, scratch, v1); // v1 used as scratch.
__ sw(map, FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
__ sw(map, FieldMemOperand(scratch, Cell::kValueOffset));
}
// Register mapping: a3 is object map and t0 is function prototype.
@ -5043,7 +5043,7 @@ static void GenerateRecordCallTargetNoArray(MacroAssembler* masm) {
masm->isolate()->heap()->the_hole_value());
// Load the cache state into a3.
__ lw(a3, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset));
__ lw(a3, FieldMemOperand(a2, Cell::kValueOffset));
// A monomorphic cache hit or an already megamorphic state: invoke the
// function without changing the state.
@ -5059,13 +5059,13 @@ static void GenerateRecordCallTargetNoArray(MacroAssembler* masm) {
// An uninitialized cache is patched with the function.
// Store a1 in the delay slot. This may or may not get overwritten depending
// on the result of the comparison.
__ sw(a1, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset));
__ sw(a1, FieldMemOperand(a2, Cell::kValueOffset));
// No need for a write barrier here - cells are rescanned.
// MegamorphicSentinel is an immortal immovable object (undefined) so no
// write-barrier is needed.
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
__ sw(at, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset));
__ sw(at, FieldMemOperand(a2, Cell::kValueOffset));
__ bind(&done);
}
@ -5086,7 +5086,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
masm->isolate()->heap()->the_hole_value());
// Load the cache state into a3.
__ lw(a3, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset));
__ lw(a3, FieldMemOperand(a2, Cell::kValueOffset));
// A monomorphic cache hit or an already megamorphic state: invoke the
// function without changing the state.
@ -5117,7 +5117,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// write-barrier is needed.
__ bind(&megamorphic);
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
__ sw(at, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset));
__ sw(at, FieldMemOperand(a2, Cell::kValueOffset));
__ jmp(&done);
// An uninitialized cache is patched with the function or sentinel to
@ -5134,11 +5134,11 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(),
GetInitialFastElementsKind());
__ li(a3, Operand(initial_kind_sentinel));
__ sw(a3, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset));
__ sw(a3, FieldMemOperand(a2, Cell::kValueOffset));
__ Branch(&done);
__ bind(&not_array_function);
__ sw(a1, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset));
__ sw(a1, FieldMemOperand(a2, Cell::kValueOffset));
// No need for a write barrier here - cells are rescanned.
__ bind(&done);
@ -5214,7 +5214,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()),
masm->isolate()->heap()->undefined_value());
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
__ sw(at, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset));
__ sw(at, FieldMemOperand(a2, Cell::kValueOffset));
}
// Check for function proxy.
__ Branch(&non_function, ne, a3, Operand(JS_FUNCTION_PROXY_TYPE));
@ -7776,14 +7776,13 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
__ Assert(eq, "Unexpected initial map for Array function",
t0, Operand(MAP_TYPE));
// We should either have undefined in ebx or a valid jsglobalpropertycell
// We should either have undefined in a2 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();
__ Branch(&okay_here, eq, a2, Operand(undefined_sentinel));
__ lw(a3, FieldMemOperand(a2, 0));
__ Assert(eq, "Expected property cell in register ebx",
a3, Operand(global_property_cell_map));
__ Assert(eq, "Expected property cell in register a2",
a3, Operand(cell_map));
__ bind(&okay_here);
}

View File

@ -138,7 +138,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");
@ -326,9 +326,9 @@ void FullCodeGenerator::ClearAccumulator() {
void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
__ li(a2, Operand(profiling_counter_));
__ lw(a3, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset));
__ lw(a3, FieldMemOperand(a2, Cell::kValueOffset));
__ Subu(a3, a3, Operand(Smi::FromInt(delta)));
__ sw(a3, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset));
__ sw(a3, FieldMemOperand(a2, Cell::kValueOffset));
}
@ -344,7 +344,7 @@ void FullCodeGenerator::EmitProfilingCounterReset() {
}
__ li(a2, Operand(profiling_counter_));
__ li(a3, Operand(Smi::FromInt(reset_value)));
__ sw(a3, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset));
__ sw(a3, FieldMemOperand(a2, 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),
isolate()));
Handle<Cell> cell = isolate()->factory()->NewCell(
Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
isolate()));
RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell);
__ LoadHeapObject(a1, cell);
__ li(a2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)));
__ sw(a2, FieldMemOperand(a1, JSGlobalPropertyCell::kValueOffset));
__ sw(a2, FieldMemOperand(a1, Cell::kValueOffset));
__ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check
__ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object
@ -2702,8 +2700,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);
__ li(a2, Operand(cell));
@ -2897,8 +2894,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);
__ li(a2, Operand(cell));

View File

@ -2439,8 +2439,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
// We use Factory::the_hole_value() on purpose instead of loading from the
// root array to force relocation to be able to later patch with
// the cached map.
Handle<JSGlobalPropertyCell> cell =
factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
Handle<Cell> cell = factory()->NewCell(factory()->the_hole_value());
__ li(at, Operand(Handle<Object>(cell)));
__ lw(at, FieldMemOperand(at, JSGlobalPropertyCell::kValueOffset));
__ Branch(&cache_miss, ne, map, Operand(at));
@ -2596,7 +2595,7 @@ void LCodeGen::DoReturn(LReturn* instr) {
void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
Register result = ToRegister(instr->result());
__ li(at, Operand(Handle<Object>(instr->hydrogen()->cell())));
__ lw(result, FieldMemOperand(at, JSGlobalPropertyCell::kValueOffset));
__ lw(result, FieldMemOperand(at, Cell::kValueOffset));
if (instr->hydrogen()->RequiresHoleCheck()) {
__ LoadRoot(at, Heap::kTheHoleValueRootIndex);
DeoptimizeIf(eq, instr->environment(), result, Operand(at));
@ -2630,13 +2629,13 @@ void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
if (instr->hydrogen()->RequiresHoleCheck()) {
// We use a temp to check the payload.
Register payload = ToRegister(instr->temp());
__ lw(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
__ lw(payload, FieldMemOperand(cell, Cell::kValueOffset));
__ LoadRoot(at, Heap::kTheHoleValueRootIndex);
DeoptimizeIf(eq, instr->environment(), payload, Operand(at));
}
// Store the value.
__ sw(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
__ sw(value, FieldMemOperand(cell, Cell::kValueOffset));
// Cells are always rescanned, so no write barrier here.
}
@ -5001,10 +5000,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);
__ li(at, Operand(Handle<Object>(cell)));
__ lw(at, FieldMemOperand(at, JSGlobalPropertyCell::kValueOffset));
__ lw(at, FieldMemOperand(at, Cell::kValueOffset));
DeoptimizeIf(ne, instr->environment(), reg,
Operand(at));
} else {

View File

@ -85,10 +85,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);
li(result, Operand(cell));
lw(result, FieldMemOperand(result, JSGlobalPropertyCell::kValueOffset));
lw(result, FieldMemOperand(result, Cell::kValueOffset));
} else {
li(result, Operand(object));
}

View File

@ -420,12 +420,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());
__ li(scratch, Operand(cell));
__ lw(scratch,
FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
__ lw(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
__ LoadRoot(at, Heap::kTheHoleValueRootIndex);
__ Branch(miss, ne, scratch, Operand(at));
}
@ -1600,12 +1598,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.
__ li(a3, Operand(cell));
__ lw(a1, FieldMemOperand(a3, JSGlobalPropertyCell::kValueOffset));
__ lw(a1, FieldMemOperand(a3, Cell::kValueOffset));
// Check that the cell contains the same function.
if (heap()->InNewSpace(*function)) {
@ -1675,7 +1673,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 -------------
@ -1929,7 +1927,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 -------------
@ -2011,7 +2009,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 -------------
@ -2093,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 -------------
@ -2174,7 +2172,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 -------------
@ -2247,7 +2245,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 -------------
@ -2376,7 +2374,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 -------------
@ -2476,7 +2474,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) {
@ -2649,7 +2647,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;
@ -2899,13 +2897,11 @@ Handle<Code> StoreStubCompiler::CompileStoreGlobal(
// global object. We bail out to the runtime system to do that.
__ li(scratch1(), Operand(cell));
__ LoadRoot(scratch2(), Heap::kTheHoleValueRootIndex);
__ lw(scratch3(),
FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset));
__ lw(scratch3(), FieldMemOperand(scratch1(), Cell::kValueOffset));
__ Branch(&miss, eq, scratch3(), Operand(scratch2()));
// Store the value in the cell.
__ sw(value(),
FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset));
__ sw(value(), FieldMemOperand(scratch1(), Cell::kValueOffset));
__ mov(v0, a0); // Stored value must be returned in v0.
// Cells are always rescanned, so no write barrier here.
@ -3039,7 +3035,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
// Get the value from the cell.
__ li(a3, Operand(cell));
__ lw(t0, FieldMemOperand(a3, JSGlobalPropertyCell::kValueOffset));
__ lw(t0, FieldMemOperand(a3, Cell::kValueOffset));
// Check for deleted property if property can actually be deleted.
if (!is_dont_delete) {