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:
danno@chromium.org 2013-06-12 15:03:44 +00:00
parent 3be6a032d0
commit 1b89cbf817
65 changed files with 666 additions and 339 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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)) {

View File

@ -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(&not_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);
}

View File

@ -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));

View File

@ -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));

View File

@ -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));
}

View File

@ -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) {

View File

@ -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:

View File

@ -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));

View File

@ -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

View File

@ -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_;
};

View File

@ -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());

View File

@ -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(),

View File

@ -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;

View File

@ -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);

View File

@ -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());
}

View File

@ -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_;

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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
};

View File

@ -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_;
};

View File

@ -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 {

View File

@ -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));

View File

@ -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.

View File

@ -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(&not_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);

View File

@ -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);

View File

@ -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());

View File

@ -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);

View File

@ -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;

View File

@ -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());

View File

@ -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();

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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>(

View File

@ -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) |

View File

@ -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:

View File

@ -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));

View File

@ -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

View File

@ -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) {}

View File

@ -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)) {

View File

@ -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);
}

View File

@ -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(

View File

@ -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));

View File

@ -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

View File

@ -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_;

View File

@ -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());

View File

@ -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")
};

View File

@ -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));

View File

@ -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);

View File

@ -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() &&

View File

@ -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_;

View File

@ -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)

View File

@ -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;

View File

@ -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));

View File

@ -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(&not_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);

View File

@ -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);

View File

@ -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.

View File

@ -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));
}
}

View File

@ -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.

View File

@ -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());

View File

@ -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());
}