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;
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;
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;
}
-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
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)) {
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)) {
// 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.
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.
// 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);
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.
// 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
TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(),
GetInitialFastElementsKind());
__ mov(r3, Operand(initial_kind_sentinel));
- __ str(r3, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
+ __ str(r3, FieldMemOperand(r2, Cell::kValueOffset));
__ b(&done);
__ bind(¬_array_function);
- __ str(r1, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
+ __ str(r1, FieldMemOperand(r2, Cell::kValueOffset));
// No need for a write barrier here - cells are rescanned.
__ bind(&done);
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));
__ 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);
}
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");
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));
}
}
__ mov(r2, Operand(profiling_counter_));
__ mov(r3, Operand(Smi::FromInt(reset_value)));
- __ str(r3, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
+ __ str(r3, FieldMemOperand(r2, Cell::kValueOffset));
}
Label non_proxy;
__ bind(&fixed_array);
- Handle<JSGlobalPropertyCell> cell =
- isolate()->factory()->NewJSGlobalPropertyCell(
- Handle<Object>(
- Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
- isolate()));
+ Handle<Cell> cell = isolate()->factory()->NewCell(
+ Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
+ isolate()));
RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell);
__ LoadHeapObject(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
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));
// 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));
// 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));
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);
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.
}
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));
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));
}
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);
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)) {
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 -------------
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 -------------
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 -------------
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 -------------
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 -------------
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 -------------
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 -------------
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();
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;
// 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();
// 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) {
// 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();
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:
case EMBEDDED_OBJECT:
Object::VerifyPointer(target_object());
break;
- case GLOBAL_PROPERTY_CELL:
+ case CELL:
Object::VerifyPointer(target_cell());
break;
case DEBUG_BREAK:
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,
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
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));
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
// 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);
SmallMapList receiver_types_;
Handle<JSFunction> target_;
Handle<JSObject> holder_;
- Handle<JSGlobalPropertyCell> cell_;
+ Handle<Cell> cell_;
const BailoutId return_id_;
};
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_;
}
bool is_monomorphic_;
Handle<JSFunction> target_;
ElementsKind elements_kind_;
- Handle<JSGlobalPropertyCell> allocation_info_cell_;
+ Handle<Cell> allocation_info_cell_;
const BailoutId return_id_;
};
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());
"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(),
}
+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;
void* external_pointer,
PretenureFlag pretenure = NOT_TENURED);
+ Handle<Cell> NewCell(Handle<Object> value);
+
Handle<JSGlobalPropertyCell> NewJSGlobalPropertyCell(
Handle<Object> value);
void FullCodeGenerator::RecordTypeFeedbackCell(
- TypeFeedbackId id, Handle<JSGlobalPropertyCell> cell) {
+ TypeFeedbackId id, Handle<Cell> cell) {
TypeFeedbackCellEntry entry = { id, cell };
type_feedback_cells_.Add(entry, zone());
}
// 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.
struct TypeFeedbackCellEntry {
TypeFeedbackId ast_id;
- Handle<JSGlobalPropertyCell> cell;
+ Handle<Cell> cell;
};
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_;
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);
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;
}
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;
#include "heap-profiler.h"
#include "debug.h"
+#include "types.h"
namespace v8 {
namespace internal {
#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) \
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));
}
+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());
}
&& 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()
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
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);
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),
old_data_space_->Capacity() +
code_space_->Capacity() +
map_space_->Capacity() +
- cell_space_->Capacity();
+ cell_space_->Capacity() +
+ property_cell_space_->Capacity();
}
code_space_->CommittedMemory() +
map_space_->CommittedMemory() +
cell_space_->CommittedMemory() +
+ property_cell_space_->CommittedMemory() +
lo_space_->Size();
}
code_space_->CommittedPhysicalMemory() +
map_space_->CommittedPhysicalMemory() +
cell_space_->CommittedPhysicalMemory() +
+ property_cell_space_->CommittedPhysicalMemory() +
lo_space_->CommittedPhysicalMemory();
}
old_data_space_->Available() +
code_space_->Available() +
map_space_->Available() +
- cell_space_->Available();
+ cell_space_->Available() +
+ property_cell_space_->Available();
}
code_space_ != NULL &&
map_space_ != NULL &&
cell_space_ != NULL &&
+ property_cell_space_ != NULL &&
lo_space_ != NULL;
}
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",
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));
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) \
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
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));
}
}
}
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;
}
}
-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;
}
// 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;
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");
code_space_->Contains(addr) ||
map_space_->Contains(addr) ||
cell_space_->Contains(addr) ||
+ property_cell_space_->Contains(addr) ||
lo_space_->SlowContains(addr));
}
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);
}
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();
}
*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();
+ code_space_->SizeOfObjects()
+ map_space_->SizeOfObjects()
+ cell_space_->SizeOfObjects()
+ + property_cell_space_->SizeOfObjects()
+ lo_space_->SizeOfObjects();
}
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.
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_;
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:
return heap_->map_space();
case CELL_SPACE:
return heap_->cell_space();
+ case PROPERTY_CELL_SPACE:
+ return heap_->property_cell_space();
default:
return NULL;
}
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;
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) \
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) {
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:
// 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.
OldSpace* code_space_;
MapSpace* map_space_;
CellSpace* cell_space_;
+ PropertyCellSpace* property_cell_space_;
LargeObjectSpace* lo_space_;
HeapState gc_state_;
int gc_post_processing_depth_;
// (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,
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
};
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_;
}
private:
ElementsKind elements_kind_;
- Handle<JSGlobalPropertyCell> type_cell_;
+ Handle<Cell> type_cell_;
};
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);
private:
virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
- Handle<JSGlobalPropertyCell> cell_;
+ Handle<Cell> cell_;
PropertyDetails details_;
UniqueValueId unique_id_;
};
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 {
}
-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) {
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));
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));
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.
__ 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);
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.
// 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);
Handle<Object> initial_kind_sentinel =
TypeFeedbackCells::MonomorphicArraySentinel(isolate,
GetInitialFastElementsKind());
- __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
+ __ mov(FieldOperand(ebx, Cell::kValueOffset),
Immediate(initial_kind_sentinel));
__ jmp(&done);
__ bind(¬_array_function);
- __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), edi);
+ __ mov(FieldOperand(ebx, Cell::kValueOffset), edi);
// No need for a write barrier here - cells are rescanned.
__ bind(&done);
// 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.
__ 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);
}
// 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);
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");
void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
__ mov(ebx, Immediate(profiling_counter_));
- __ sub(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
+ __ sub(FieldOperand(ebx, Cell::kValueOffset),
Immediate(Smi::FromInt(delta)));
}
reset_value = Smi::kMaxValue;
}
__ mov(ebx, Immediate(profiling_counter_));
- __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
+ __ mov(FieldOperand(ebx, Cell::kValueOffset),
Immediate(Smi::FromInt(reset_value)));
}
Label non_proxy;
__ bind(&fixed_array);
- Handle<JSGlobalPropertyCell> cell =
- isolate()->factory()->NewJSGlobalPropertyCell(
- Handle<Object>(
- Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
- isolate()));
+ Handle<Cell> cell = isolate()->factory()->NewCell(
+ Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
+ isolate()));
RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell);
__ LoadHeapObject(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
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);
// 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);
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.
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());
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);
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);
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);
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));
}
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 -------------
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 -------------
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 -------------
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 -------------
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 -------------
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 -------------
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 -------------
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());
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;
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);
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());
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());
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());
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());
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:
if (FLAG_trace_fragmentation) {
TraceFragmentation(heap()->map_space());
TraceFragmentation(heap()->cell_space());
+ TraceFragmentation(heap()->property_cell_space());
}
heap()->old_pointer_space()->EvictEvacuationCandidatesFromFreeLists();
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());
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());
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();
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_,
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));
}
}
}
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));
}
}
SweepSpace(heap()->code_space(), PRECISE);
SweepSpace(heap()->cell_space(), PRECISE);
+ SweepSpace(heap()->property_cell_space(), PRECISE);
EvacuateNewSpaceAndCandidates();
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,
"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() {
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),
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;
}
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:
}
+void Cell::CellVerify() {
+ CHECK(IsCell());
+ VerifyObjectField(kValueOffset);
+}
+
+
void JSGlobalPropertyCell::JSGlobalPropertyCellVerify() {
CHECK(IsJSGlobalPropertyCell());
VerifyObjectField(kValueOffset);
+ VerifyObjectField(kTypeOffset);
}
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)
}
-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
CAST_ACCESSOR(HeapObject)
CAST_ACCESSOR(HeapNumber)
CAST_ACCESSOR(Oddball)
+CAST_ACCESSOR(Cell)
CAST_ACCESSOR(JSGlobalPropertyCell)
CAST_ACCESSOR(SharedFunctionInfo)
CAST_ACCESSOR(Map)
}
-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));
}
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:
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";
}
+void Cell::CellPrint(FILE* out) {
+ HeapObject::PrintHeader(out, "Cell");
+}
+
+
void JSGlobalPropertyCell::JSGlobalPropertyCellPrint(FILE* out) {
HeapObject::PrintHeader(out, "JSGlobalPropertyCell");
}
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>(
// Registration for kVisitJSRegExp is done by StaticVisitor.
+ table_.Register(kVisitCell,
+ &FixedBodyVisitor<StaticVisitor,
+ Cell::BodyDescriptor,
+ void>::Visit);
+
table_.Register(kVisitPropertyCell,
&FixedBodyVisitor<StaticVisitor,
JSGlobalPropertyCell::BodyDescriptor,
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);
}
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) |
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) |
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:
V(Oddball) \
V(Code) \
V(Map) \
+ V(Cell) \
V(PropertyCell) \
V(SharedFunctionInfo) \
V(JSFunction) \
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));
if (IsGlobalObject()) {
value = JSGlobalPropertyCell::cast(value)->value();
}
- ASSERT(!value->IsJSGlobalPropertyCell());
+ ASSERT(!value->IsJSGlobalPropertyCell() && !value->IsCell());
return value;
}
Object* JSObject::SetNormalizedProperty(LookupResult* result, Object* value) {
ASSERT(!HasFastProperties());
if (IsGlobalObject()) {
- JSGlobalPropertyCell* cell =
- JSGlobalPropertyCell::cast(
- property_dictionary()->ValueAt(result->GetDictionaryEntry()));
+ JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(
+ property_dictionary()->ValueAt(result->GetDictionaryEntry()));
cell->set_value(value);
} else {
property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value);
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:
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:
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>(
}
-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));
}
}
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
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
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));
}
}
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>(
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
// - ExternalTwoByteInternalizedString
// - Symbol
// - HeapNumber
+// - Cell
+// - JSGlobalPropertyCell
// - Code
// - Map
// - Oddball
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) \
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
class FixedArrayBase;
class ObjectVisitor;
class StringStream;
+class Type;
struct ValueInfo : public Malloced {
ValueInfo() : type(FIRST_TYPE), ptr(NULL), str(NULL), number(0) { }
V(JSGlobalProxy) \
V(UndetectableObject) \
V(AccessCheckNeeded) \
+ V(Cell) \
V(JSGlobalPropertyCell) \
V(ObjectHashTable) \
// Forward declaration.
+class Cell;
class JSGlobalPropertyCell;
// TypeFeedbackCells is a fixed array used to hold the association between
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);
set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number));
}
- inline JSGlobalPropertyCell* RetrieveDescriptorsPointer();
+ inline Cell* RetrieveDescriptorsPointer();
int EnumLength() {
return EnumLengthBits::decode(bit_field3());
};
-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() {
}
// Dispatched behavior.
- DECLARE_PRINTER(JSGlobalPropertyCell)
- DECLARE_VERIFIER(JSGlobalPropertyCell)
+ DECLARE_PRINTER(Cell)
+ DECLARE_VERIFIER(Cell)
// Layout description.
static const int kValueOffset = HeapObject::kHeaderSize;
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);
};
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) {}
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)) {
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) {
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()); \
} \
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)
}
-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);
}
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(
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.
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
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();
}
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_);
}
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));
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;
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
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_;
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(),
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
// -----------------------------------------------------------------------------
-// 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());
// -----------------------------------------------------------------------------
-// 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)
{}
virtual void VerifyObject(HeapObject* obj);
public:
- TRACK_MEMORY("CellSpace")
+ TRACK_MEMORY("PropertyCellSpace")
};
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));
// 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)
Handle<Code> CompileFastApiCall(const CallOptimization& optimization,
Handle<Object> object,
Handle<JSObject> holder,
- Handle<JSGlobalPropertyCell> cell,
+ Handle<Cell> cell,
Handle<JSFunction> function,
Handle<String> name);
// 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);
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_);
}
-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();
}
}
-Handle<JSGlobalPropertyCell> TypeFeedbackOracle::GetCallNewAllocationInfoCell(
- CallNew* expr) {
+Handle<Cell> TypeFeedbackOracle::GetCallNewAllocationInfoCell(CallNew* expr) {
return GetInfoCell(expr->CallNewFeedbackId());
}
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() &&
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);
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_;
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) \
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
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)
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;
}
-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 &&
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));
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));
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.
__ 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);
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.
// 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);
Handle<Object> initial_kind_sentinel =
TypeFeedbackCells::MonomorphicArraySentinel(isolate,
GetInitialFastElementsKind());
- __ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset),
+ __ Move(FieldOperand(rbx, Cell::kValueOffset),
initial_kind_sentinel);
__ jmp(&done);
__ bind(¬_array_function);
- __ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), rdi);
+ __ movq(FieldOperand(rbx, Cell::kValueOffset), rdi);
// No need for a write barrier here - cells are rescanned.
__ bind(&done);
// 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.
__ 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);
}
// 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);
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");
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));
}
__ movq(kScratchRegister,
reinterpret_cast<uint64_t>(Smi::FromInt(reset_value)),
RelocInfo::NONE64);
- __ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset),
- kScratchRegister);
+ __ movq(FieldOperand(rbx, Cell::kValueOffset), kScratchRegister);
}
Label non_proxy;
__ bind(&fixed_array);
- Handle<JSGlobalPropertyCell> cell =
- isolate()->factory()->NewJSGlobalPropertyCell(
- Handle<Object>(
- Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
- isolate()));
+ Handle<Cell> cell = isolate()->factory()->NewCell(
+ Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
+ isolate()));
RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell);
__ LoadHeapObject(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
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);
// 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);
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.
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
// 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.
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);
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);
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 {
}
-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));
}
}
}
// 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.
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);
}
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)) {
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 -------------
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 -------------
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 -------------
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 -------------
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 -------------
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.
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 -------------
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());
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());
}