NOT_TENURED, JS_OBJECT_TYPE);
for (int i = 0; i < object_size; i += kPointerSize) {
- HObjectAccess access = HObjectAccess::ForJSObjectOffset(i);
+ HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(i);
Add<HStoreNamedField>(
object, access, Add<HLoadNamedField>(
- boilerplate, static_cast<HValue*>(NULL), access),
- INITIALIZING_STORE);
+ boilerplate, static_cast<HValue*>(NULL), access));
}
ASSERT(FLAG_allocation_site_pretenuring || (size == object_size));
Add<HStoreNamedField>(object,
HObjectAccess::ForAllocationSiteOffset(
AllocationSite::kTransitionInfoOffset),
- initial_elements_kind,
- INITIALIZING_STORE);
+ initial_elements_kind);
// Unlike literals, constructed arrays don't have nested sites
Add<HStoreNamedField>(object,
HObjectAccess::ForAllocationSiteOffset(
AllocationSite::kNestedSiteOffset),
- graph()->GetConstant0(),
- INITIALIZING_STORE);
+ graph()->GetConstant0());
// Pretenuring calculation field.
Add<HStoreNamedField>(object,
HObjectAccess::ForAllocationSiteOffset(
AllocationSite::kPretenureDataOffset),
- graph()->GetConstant0(),
- INITIALIZING_STORE);
+ graph()->GetConstant0());
// Pretenuring memento creation count field.
Add<HStoreNamedField>(object,
HObjectAccess::ForAllocationSiteOffset(
AllocationSite::kPretenureCreateCountOffset),
- graph()->GetConstant0(),
- INITIALIZING_STORE);
+ graph()->GetConstant0());
// Store an empty fixed array for the code dependency.
HConstant* empty_fixed_array =
object,
HObjectAccess::ForAllocationSiteOffset(
AllocationSite::kDependentCodeOffset),
- empty_fixed_array,
- INITIALIZING_STORE);
+ empty_fixed_array);
// Link the object to the allocation site list
HValue* site_list = Add<HConstant>(
HObjectAccess::ForAllocationSiteList());
store = Add<HStoreNamedField>(object,
HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset),
- site, INITIALIZING_STORE);
+ site);
store->SkipWriteBarrier();
Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(),
- object, INITIALIZING_STORE);
+ object);
// We use a hammer (SkipWriteBarrier()) to indicate that we know the input
// cell is really a Cell, and so no write barrier is needed.
// a cell. (perhaps with a new instruction, HAssert).
HInstruction* cell = GetParameter(0);
HObjectAccess access = HObjectAccess::ForCellValue();
- store = Add<HStoreNamedField>(cell, access, object, INITIALIZING_STORE);
+ store = Add<HStoreNamedField>(cell, access, object);
store->SkipWriteBarrier();
return cell;
}
template<>
HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() {
Representation rep = casted_stub()->representation();
+ int offset = casted_stub()->offset();
HObjectAccess access = casted_stub()->is_inobject() ?
- HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
- HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
+ HObjectAccess::ForObservableJSObjectOffset(offset, rep) :
+ HObjectAccess::ForBackingStoreOffset(offset, rep);
return AddLoadNamedField(GetParameter(0), access);
}
template<>
HValue* CodeStubGraphBuilder<KeyedLoadFieldStub>::BuildCodeStub() {
Representation rep = casted_stub()->representation();
+ int offset = casted_stub()->offset();
HObjectAccess access = casted_stub()->is_inobject() ?
- HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
- HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
+ HObjectAccess::ForObservableJSObjectOffset(offset, rep) :
+ HObjectAccess::ForBackingStoreOffset(offset, rep);
return AddLoadNamedField(GetParameter(0), access);
}
HInstruction* argument = Add<HAccessArgumentsAt>(
argument_elements, checked_length, key);
- Add<HStoreKeyed>(elements, key, argument, kind, INITIALIZING_STORE);
+ Add<HStoreKeyed>(elements, key, argument, kind);
builder.EndBody();
return new_object;
}
IfBuilder if_heap_number(this);
if_heap_number.IfNot<HIsSmiAndBranch>(operand);
if_heap_number.Then();
- Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result,
- INITIALIZING_STORE);
+ Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result);
Push(operand);
if_heap_number.Else();
Push(result);
builder.Then();
builder.Deopt("Unexpected cell contents in global store");
builder.Else();
- Add<HStoreNamedField>(cell, access, value, INITIALIZING_STORE);
+ Add<HStoreNamedField>(cell, access, value);
builder.End();
}
HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST));
Add<HStoreNamedField>(js_function,
HObjectAccess::ForNextFunctionLinkPointer(),
- optimized_functions_list, INITIALIZING_STORE);
+ optimized_functions_list);
// This store is the only one that should have a write barrier.
Add<HStoreNamedField>(native_context,
HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST),
- js_function, INITIALIZING_STORE);
+ js_function);
}
HValue* shared_info) {
Add<HStoreNamedField>(js_function,
HObjectAccess::ForNextFunctionLinkPointer(),
- graph()->GetConstantUndefined(),
- INITIALIZING_STORE);
+ graph()->GetConstantUndefined());
HValue* code_object = Add<HLoadNamedField>(
shared_info, static_cast<HValue*>(NULL), HObjectAccess::ForCodeOffset());
Add<HStoreCodeEntry>(js_function, code_object);
HInstruction* map_slot_value = Add<HLoadNamedField>(
native_context, static_cast<HValue*>(NULL),
HObjectAccess::ForContextSlot(map_index));
- Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value,
- INITIALIZING_STORE);
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value);
// Initialize the rest of the function.
Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(),
- empty_fixed_array, INITIALIZING_STORE);
+ empty_fixed_array);
Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(),
- empty_fixed_array, INITIALIZING_STORE);
+ empty_fixed_array);
Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
- empty_fixed_array, INITIALIZING_STORE);
+ empty_fixed_array);
Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(),
- graph()->GetConstantHole(), INITIALIZING_STORE);
+ graph()->GetConstantHole());
Add<HStoreNamedField>(js_function,
HObjectAccess::ForSharedFunctionInfoPointer(),
- shared_info, INITIALIZING_STORE);
+ shared_info);
Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
- context(), INITIALIZING_STORE);
+ context());
// Initialize the code pointer in the function to be the one
// found in the shared function info object.
isolate()->factory()->function_context_map());
Add<HStoreNamedField>(function_context,
HObjectAccess::ForFixedArrayLength(),
- Add<HConstant>(length), INITIALIZING_STORE);
+ Add<HConstant>(length));
// Set up the fixed slots.
Add<HStoreNamedField>(function_context,
HObjectAccess::ForContextSlot(Context::CLOSURE_INDEX),
- function, INITIALIZING_STORE);
+ function);
Add<HStoreNamedField>(function_context,
HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX),
- context(), INITIALIZING_STORE);
+ context());
Add<HStoreNamedField>(function_context,
HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX),
- graph()->GetConstant0(), INITIALIZING_STORE);
+ graph()->GetConstant0());
// Copy the global object from the previous context.
HValue* global_object = Add<HLoadNamedField>(
Add<HStoreNamedField>(function_context,
HObjectAccess::ForContextSlot(
Context::GLOBAL_OBJECT_INDEX),
- global_object,
- INITIALIZING_STORE);
+ global_object);
// Initialize the rest of the slots to undefined.
for (int i = Context::MIN_CONTEXT_SLOTS; i < length; ++i) {
Add<HStoreNamedField>(function_context,
HObjectAccess::ForContextSlot(i),
- graph()->GetConstantUndefined(),
- INITIALIZING_STORE);
+ graph()->GetConstantUndefined());
}
return function_context;
filler_map->FinalizeUniqueness(); // TODO(titzer): should be init'd a'ready
filler_map->InsertAfter(free_space_instr);
HInstruction* store_map = HStoreNamedField::New(zone, context(),
- free_space_instr, HObjectAccess::ForMap(), filler_map,
- INITIALIZING_STORE);
+ free_space_instr, HObjectAccess::ForMap(), filler_map);
store_map->SetFlag(HValue::kHasNoObservableSideEffects);
store_map->InsertAfter(filler_map);
zone, context(), free_space_size, Representation::Smi(), store_map);
// Must force Smi representation for x64 (see comment above).
HObjectAccess access =
- HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset,
- Representation::Smi());
+ HObjectAccess::ForMapAndOffset(isolate()->factory()->free_space_map(),
+ FreeSpace::kSizeOffset,
+ Representation::Smi());
HStoreNamedField* store_size = HStoreNamedField::New(zone, context(),
- free_space_instr, access, filler_size, INITIALIZING_STORE);
+ free_space_instr, access, filler_size);
store_size->SetFlag(HValue::kHasNoObservableSideEffects);
store_size->InsertAfter(filler_size);
filler_free_space_size_ = store_size;
void HAllocate::ClearNextMapWord(int offset) {
if (MustClearNextMapWord()) {
Zone* zone = block()->zone();
- HObjectAccess access = HObjectAccess::ForJSObjectOffset(offset);
+ HObjectAccess access =
+ HObjectAccess::ForObservableJSObjectOffset(offset);
HStoreNamedField* clear_next_map =
HStoreNamedField::New(zone, context(), this, access,
- block()->graph()->GetConstant0(), INITIALIZING_STORE);
+ block()->graph()->GetConstant0());
clear_next_map->ClearAllSideEffects();
clear_next_map->InsertAfter(this);
}
}
-HObjectAccess HObjectAccess::ForJSObjectOffset(int offset,
+HObjectAccess HObjectAccess::ForMapAndOffset(Handle<Map> map, int offset,
Representation representation) {
ASSERT(offset >= 0);
Portion portion = kInobject;
} else if (offset == JSObject::kMapOffset) {
portion = kMaps;
}
- return HObjectAccess(portion, offset, representation);
+ bool existing_inobject_property = true;
+ if (!map.is_null()) {
+ existing_inobject_property = (offset <
+ map->instance_size() - map->unused_property_fields() * kPointerSize);
+ }
+ return HObjectAccess(portion, offset, representation, Handle<String>::null(),
+ false, existing_inobject_property);
}
HObjectAccess HObjectAccess::ForBackingStoreOffset(int offset,
Representation representation) {
ASSERT(offset >= 0);
- return HObjectAccess(kBackingStore, offset, representation);
+ return HObjectAccess(kBackingStore, offset, representation,
+ Handle<String>::null(), false, false);
}
// Negative property indices are in-object properties, indexed
// from the end of the fixed part of the object.
int offset = (index * kPointerSize) + map->instance_size();
- return HObjectAccess(kInobject, offset, representation, name);
+ return HObjectAccess(kInobject, offset, representation, name, false, true);
} else {
// Non-negative property indices are in the properties array.
int offset = (index * kPointerSize) + FixedArray::kHeaderSize;
- return HObjectAccess(kBackingStore, offset, representation, name);
+ return HObjectAccess(kBackingStore, offset, representation, name,
+ false, false);
}
}
return ImmutableField::decode(value_);
}
+ // Returns true if access is being made to an in-object property that
+ // was already added to the object.
+ inline bool existing_inobject_property() const {
+ return ExistingInobjectPropertyField::decode(value_);
+ }
+
inline HObjectAccess WithRepresentation(Representation representation) {
- return HObjectAccess(portion(), offset(), representation, name());
+ return HObjectAccess(portion(), offset(), representation, name(),
+ immutable(), existing_inobject_property());
}
static HObjectAccess ForHeapNumberValue() {
static HObjectAccess ForAllocationSiteOffset(int offset);
static HObjectAccess ForAllocationSiteList() {
- return HObjectAccess(kExternalMemory, 0, Representation::Tagged());
+ return HObjectAccess(kExternalMemory, 0, Representation::Tagged(),
+ Handle<String>::null(), false, false);
}
static HObjectAccess ForFixedArrayLength() {
}
static HObjectAccess ForCounter() {
- return HObjectAccess(kExternalMemory, 0, Representation::Integer32());
+ return HObjectAccess(kExternalMemory, 0, Representation::Integer32(),
+ Handle<String>::null(), false, false);
}
// Create an access to an offset in a fixed array header.
static HObjectAccess ForFixedArrayHeader(int offset);
// Create an access to an in-object property in a JSObject.
- static HObjectAccess ForJSObjectOffset(int offset,
+ // This kind of access must be used when the object |map| is known and
+ // in-object properties are being accessed. Accesses of the in-object
+ // properties can have different semantics depending on whether corresponding
+ // property was added to the map or not.
+ static HObjectAccess ForMapAndOffset(Handle<Map> map, int offset,
Representation representation = Representation::Tagged());
+ // Create an access to an in-object property in a JSObject.
+ // This kind of access can be used for accessing object header fields or
+ // in-object properties if the map of the object is not known.
+ static HObjectAccess ForObservableJSObjectOffset(int offset,
+ Representation representation = Representation::Tagged()) {
+ return ForMapAndOffset(Handle<Map>::null(), offset, representation);
+ }
+
// Create an access to an in-object property in a JSArray.
static HObjectAccess ForJSArrayOffset(int offset);
static HObjectAccess ForCellPayload(Isolate* isolate);
static HObjectAccess ForJSTypedArrayLength() {
- return HObjectAccess::ForJSObjectOffset(JSTypedArray::kLengthOffset);
+ return HObjectAccess::ForObservableJSObjectOffset(
+ JSTypedArray::kLengthOffset);
}
static HObjectAccess ForJSArrayBufferBackingStore() {
- return HObjectAccess::ForJSObjectOffset(
+ return HObjectAccess::ForObservableJSObjectOffset(
JSArrayBuffer::kBackingStoreOffset, Representation::External());
}
static HObjectAccess ForExternalArrayExternalPointer() {
- return HObjectAccess::ForJSObjectOffset(
+ return HObjectAccess::ForObservableJSObjectOffset(
ExternalArray::kExternalPointerOffset, Representation::External());
}
static HObjectAccess ForJSArrayBufferViewWeakNext() {
- return HObjectAccess::ForJSObjectOffset(JSArrayBufferView::kWeakNextOffset);
+ return HObjectAccess::ForObservableJSObjectOffset(
+ JSArrayBufferView::kWeakNextOffset);
}
static HObjectAccess ForJSArrayBufferWeakFirstView() {
- return HObjectAccess::ForJSObjectOffset(
+ return HObjectAccess::ForObservableJSObjectOffset(
JSArrayBuffer::kWeakFirstViewOffset);
}
static HObjectAccess ForJSArrayBufferViewBuffer() {
- return HObjectAccess::ForJSObjectOffset(JSArrayBufferView::kBufferOffset);
+ return HObjectAccess::ForObservableJSObjectOffset(
+ JSArrayBufferView::kBufferOffset);
}
static HObjectAccess ForJSArrayBufferViewByteOffset() {
- return HObjectAccess::ForJSObjectOffset(
+ return HObjectAccess::ForObservableJSObjectOffset(
JSArrayBufferView::kByteOffsetOffset);
}
static HObjectAccess ForJSArrayBufferViewByteLength() {
- return HObjectAccess::ForJSObjectOffset(
+ return HObjectAccess::ForObservableJSObjectOffset(
JSArrayBufferView::kByteLengthOffset);
}
HObjectAccess(Portion portion, int offset,
Representation representation = Representation::Tagged(),
Handle<String> name = Handle<String>::null(),
- bool immutable = false)
+ bool immutable = false,
+ bool existing_inobject_property = true)
: value_(PortionField::encode(portion) |
RepresentationField::encode(representation.kind()) |
ImmutableField::encode(immutable ? 1 : 0) |
+ ExistingInobjectPropertyField::encode(
+ existing_inobject_property ? 1 : 0) |
OffsetField::encode(offset)),
name_(name) {
// assert that the fields decode correctly
ASSERT(this->offset() == offset);
ASSERT(this->portion() == portion);
ASSERT(this->immutable() == immutable);
+ ASSERT(this->existing_inobject_property() == existing_inobject_property);
ASSERT(RepresentationField::decode(value_) == representation.kind());
+ ASSERT(!this->existing_inobject_property() || IsInobject());
}
class PortionField : public BitField<Portion, 0, 3> {};
class RepresentationField : public BitField<Representation::Kind, 3, 4> {};
class ImmutableField : public BitField<bool, 7, 1> {};
- class OffsetField : public BitField<int, 8, 24> {};
+ class ExistingInobjectPropertyField : public BitField<bool, 8, 1> {};
+ class OffsetField : public BitField<int, 9, 23> {};
uint32_t value_; // encodes portion, representation, immutable, and offset
Handle<String> name_;
// Indicates whether the store is a store to an entry that was previously
// initialized or not.
enum StoreFieldOrKeyedMode {
- // This is a store of either an undefined value to a field or a hole/NaN to
- // an entry of a newly allocated object.
- PREINITIALIZING_STORE,
// The entry could be either previously initialized or not.
INITIALIZING_STORE,
// At the time of this store it is guaranteed that the entry is already
class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
public:
+ DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*,
+ HObjectAccess, HValue*);
DECLARE_INSTRUCTION_FACTORY_P4(HStoreNamedField, HValue*,
HObjectAccess, HValue*, StoreFieldOrKeyedMode);
HStoreNamedField(HValue* obj,
HObjectAccess access,
HValue* val,
- StoreFieldOrKeyedMode store_mode)
+ StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
: access_(access),
new_space_dominator_(NULL),
write_barrier_mode_(UPDATE_WRITE_BARRIER),
has_transition_(false),
store_mode_(store_mode) {
- // PREINITIALIZING_STORE is only used to mark stores that initialize a
- // memory region resulting from HAllocate (possibly through an
- // HInnerAllocatedObject).
- ASSERT(store_mode != PREINITIALIZING_STORE ||
+ // Stores to a non existing in-object property are allowed only to the
+ // newly allocated objects (via HAllocate or HInnerAllocatedObject).
+ ASSERT(!access.IsInobject() || access.existing_inobject_property() ||
obj->IsAllocate() || obj->IsInnerAllocatedObject());
SetOperandAt(0, obj);
SetOperandAt(1, val);
HValue* new_space_dominator_;
WriteBarrierMode write_barrier_mode_ : 1;
bool has_transition_ : 1;
- StoreFieldOrKeyedMode store_mode_ : 2;
+ StoreFieldOrKeyedMode store_mode_ : 1;
};
class HStoreKeyed V8_FINAL
: public HTemplateInstruction<3>, public ArrayInstructionInterface {
public:
+ DECLARE_INSTRUCTION_FACTORY_P4(HStoreKeyed, HValue*, HValue*, HValue*,
+ ElementsKind);
DECLARE_INSTRUCTION_FACTORY_P5(HStoreKeyed, HValue*, HValue*, HValue*,
ElementsKind, StoreFieldOrKeyedMode);
private:
HStoreKeyed(HValue* obj, HValue* key, HValue* val,
ElementsKind elements_kind,
- StoreFieldOrKeyedMode store_mode)
+ StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
: elements_kind_(elements_kind),
index_offset_(0),
is_dehoisted_(false),
SetOperandAt(1, key);
SetOperandAt(2, val);
- // PREINITIALIZING_STORE is only used to mark stores that initialize a
- // memory region resulting from HAllocate (possibly through an
- // HInnerAllocatedObject).
- ASSERT(store_mode != PREINITIALIZING_STORE ||
- obj->IsAllocate() || obj->IsInnerAllocatedObject());
-
ASSERT(store_mode != STORE_TO_INITIALIZED_ENTRY ||
elements_kind == FAST_SMI_ELEMENTS);
uint32_t index_offset_;
bool is_dehoisted_ : 1;
bool is_uninitialized_ : 1;
- StoreFieldOrKeyedMode store_mode_: 2;
+ StoreFieldOrKeyedMode store_mode_: 1;
HValue* new_space_dominator_;
};
// load or store for this object and field exists, return the new value with
// which the load should be replaced. Otherwise, return {instr}.
HValue* load(HLoadNamedField* instr) {
+ // There must be no loads from non observable in-object properties.
+ ASSERT(!instr->access().IsInobject() ||
+ instr->access().existing_inobject_property());
+
int field = FieldOf(instr->access());
if (field < 0) return instr;
// the stored values are the same), return NULL indicating that this store
// instruction is redundant. Otherwise, return {instr}.
HValue* store(HStoreNamedField* instr) {
- if (instr->store_mode() == PREINITIALIZING_STORE) {
- TRACE((" skipping preinitializing store\n"));
+ if (instr->access().IsInobject() &&
+ !instr->access().existing_inobject_property()) {
+ TRACE((" skipping non existing property initialization store\n"));
return instr;
}
new_length->ClearFlag(HValue::kCanOverflow);
Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind),
- new_length, INITIALIZING_STORE);
+ new_length);
}
if (is_store && kind == FAST_SMI_ELEMENTS) {
HValue* checked_elements = environment()->Top();
// Write zero to ensure that the new element is initialized with some smi.
- Add<HStoreKeyed>(checked_elements, key, graph()->GetConstant0(), kind,
- INITIALIZING_STORE);
+ Add<HStoreKeyed>(checked_elements, key, graph()->GetConstant0(), kind);
}
length_checker.Else();
if_builder.End();
}
- Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map,
- INITIALIZING_STORE);
+ Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map);
}
HObjectAccess::ForContextSlot(Context::REGEXP_RESULT_MAP_INDEX)));
Add<HStoreNamedField>(
result, HObjectAccess::ForJSArrayOffset(JSArray::kPropertiesOffset),
- Add<HConstant>(isolate()->factory()->empty_fixed_array()),
- INITIALIZING_STORE);
+ Add<HConstant>(isolate()->factory()->empty_fixed_array()));
Add<HStoreNamedField>(
result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset),
- elements, INITIALIZING_STORE);
+ elements);
Add<HStoreNamedField>(
- result, HObjectAccess::ForJSArrayOffset(JSArray::kLengthOffset),
- length, INITIALIZING_STORE);
+ result, HObjectAccess::ForJSArrayOffset(JSArray::kLengthOffset), length);
// Initialize the additional fields.
Add<HStoreNamedField>(
result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kIndexOffset),
- index, INITIALIZING_STORE);
+ index);
Add<HStoreNamedField>(
result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kInputOffset),
- input, INITIALIZING_STORE);
+ input);
// Initialize the elements header.
AddStoreMapConstantNoWriteBarrier(elements,
isolate()->factory()->fixed_array_map());
- Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(),
- length, INITIALIZING_STORE);
+ Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), length);
// Initialize the elements contents with undefined.
LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement);
index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT);
{
Add<HStoreKeyed>(elements, index, graph()->GetConstantUndefined(),
- FAST_ELEMENTS, INITIALIZING_STORE);
+ FAST_ELEMENTS);
}
loop.EndBody();
// Initialize the cons string fields.
Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(),
- Add<HConstant>(String::kEmptyHashField),
- INITIALIZING_STORE);
- Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length,
- INITIALIZING_STORE);
- Add<HStoreNamedField>(result, HObjectAccess::ForConsStringFirst(), left,
- INITIALIZING_STORE);
- Add<HStoreNamedField>(result, HObjectAccess::ForConsStringSecond(), right,
- INITIALIZING_STORE);
+ Add<HConstant>(String::kEmptyHashField));
+ Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length);
+ Add<HStoreNamedField>(result, HObjectAccess::ForConsStringFirst(), left);
+ Add<HStoreNamedField>(result, HObjectAccess::ForConsStringSecond(), right);
// Count the native string addition.
AddIncrementCounter(isolate()->counters()->string_add_native());
// Initialize the string fields.
Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(),
- Add<HConstant>(String::kEmptyHashField),
- INITIALIZING_STORE);
- Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length,
- INITIALIZING_STORE);
+ Add<HConstant>(String::kEmptyHashField));
+ Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length);
// Copy characters to the result string.
IfBuilder if_twobyte(this);
AddStoreMapConstant(elements, map);
Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(),
- capacity, INITIALIZING_STORE);
+ capacity);
}
HValue* allocation_site_payload,
HValue* length_field) {
- Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map,
- INITIALIZING_STORE);
+ Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map);
HConstant* empty_fixed_array =
Add<HConstant>(isolate()->factory()->empty_fixed_array());
HObjectAccess access = HObjectAccess::ForPropertiesPointer();
- Add<HStoreNamedField>(array, access, empty_fixed_array, INITIALIZING_STORE);
+ Add<HStoreNamedField>(array, access, empty_fixed_array);
Add<HStoreNamedField>(array, HObjectAccess::ForArrayLength(elements_kind),
- length_field, INITIALIZING_STORE);
+ length_field);
if (mode == TRACK_ALLOCATION_SITE) {
BuildCreateAllocationMemento(
HInnerAllocatedObject* elements = Add<HInnerAllocatedObject>(
array, Add<HConstant>(elements_location));
- Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements,
- INITIALIZING_STORE);
+ Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements);
return elements;
}
length, new_capacity);
Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
- new_elements, INITIALIZING_STORE);
+ new_elements);
return new_elements;
}
if (initial_capacity >= 0) {
for (int i = 0; i < initial_capacity; i++) {
HInstruction* key = Add<HConstant>(i);
- Add<HStoreKeyed>(elements, key, hole, elements_kind,
- PREINITIALIZING_STORE);
+ Add<HStoreKeyed>(elements, key, hole, elements_kind);
}
} else {
LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement);
HValue* key = builder.BeginBody(from, to, Token::LT);
- Add<HStoreKeyed>(elements, key, hole, elements_kind, PREINITIALIZING_STORE);
+ Add<HStoreKeyed>(elements, key, hole, elements_kind);
builder.EndBody();
}
HConstant* hole_constant = IsFastDoubleElementsKind(to_elements_kind)
? Add<HConstant>(FixedDoubleArray::hole_nan_as_double())
: graph()->GetConstantHole();
- Add<HStoreKeyed>(to_elements, key, hole_constant, kind,
- PREINITIALIZING_STORE);
+ Add<HStoreKeyed>(to_elements, key, hole_constant, kind);
if_hole.Else();
- HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind,
- INITIALIZING_STORE);
+ HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind);
store->SetFlag(HValue::kAllowUndefinedAsNaN);
if_hole.End();
} else {
- HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind,
- INITIALIZING_STORE);
+ HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind);
store->SetFlag(HValue::kAllowUndefinedAsNaN);
}
HObjectAccess access = HObjectAccess::ForJSArrayOffset(i);
Add<HStoreNamedField>(
object, access, Add<HLoadNamedField>(
- boilerplate, static_cast<HValue*>(NULL), access),
- INITIALIZING_STORE);
+ boilerplate, static_cast<HValue*>(NULL), access));
}
}
NOT_TENURED, FIXED_ARRAY_TYPE);
}
Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
- object_elements, INITIALIZING_STORE);
+ object_elements);
// Copy the elements array header.
for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) {
HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i);
Add<HStoreNamedField>(
object_elements, access, Add<HLoadNamedField>(
- boilerplate_elements, static_cast<HValue*>(NULL), access),
- INITIALIZING_STORE);
+ boilerplate_elements, static_cast<HValue*>(NULL), access));
}
// Copy the elements array contents.
HValue* key_constant = Add<HConstant>(i);
HInstruction* value = Add<HLoadKeyed>(boilerplate_elements, key_constant,
static_cast<HValue*>(NULL), kind);
- Add<HStoreKeyed>(object_elements, key_constant, value, kind,
- INITIALIZING_STORE);
+ Add<HStoreKeyed>(object_elements, key_constant, value, kind);
}
}
AddStoreMapConstant(
allocation_memento, isolate()->factory()->allocation_memento_map());
Add<HStoreNamedField>(
- allocation_memento, HObjectAccess::ForAllocationMementoSite(),
- allocation_site, INITIALIZING_STORE);
+ allocation_memento,
+ HObjectAccess::ForAllocationMementoSite(),
+ allocation_site);
if (FLAG_allocation_site_pretenuring) {
HValue* memento_create_count = Add<HLoadNamedField>(
allocation_site, static_cast<HValue*>(NULL),
memento_create_count->ClearFlag(HValue::kCanOverflow);
HStoreNamedField* store = Add<HStoreNamedField>(
allocation_site, HObjectAccess::ForAllocationSiteOffset(
- AllocationSite::kPretenureCreateCountOffset), memento_create_count,
- INITIALIZING_STORE);
+ AllocationSite::kPretenureCreateCountOffset), memento_create_count);
// No write barrier needed to store a smi.
store->SkipWriteBarrier();
}
HInstruction* global_object = Add<HLoadNamedField>(
context, static_cast<HValue*>(NULL),
HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
- HObjectAccess access = HObjectAccess::ForJSObjectOffset(
+ HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(
GlobalObject::kNativeContextOffset);
return Add<HLoadNamedField>(
global_object, static_cast<HValue*>(NULL), access);
HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
return Add<HLoadNamedField>(
global_object, static_cast<HValue*>(NULL),
- HObjectAccess::ForJSObjectOffset(GlobalObject::kNativeContextOffset));
+ HObjectAccess::ForObservableJSObjectOffset(
+ GlobalObject::kNativeContextOffset));
}
HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object,
Handle<Map> map) {
return Add<HStoreNamedField>(object, HObjectAccess::ForMap(),
- Add<HConstant>(map), INITIALIZING_STORE);
+ Add<HConstant>(map));
}
HValue* global_object = Add<HLoadNamedField>(
context(), static_cast<HValue*>(NULL),
HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
- HObjectAccess access = HObjectAccess::ForJSObjectOffset(
+ HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(
GlobalObject::kBuiltinsOffset);
HValue* builtins = Add<HLoadNamedField>(
global_object, static_cast<HValue*>(NULL), access);
- HObjectAccess function_access = HObjectAccess::ForJSObjectOffset(
- JSBuiltinsObject::OffsetOfFunctionWithId(builtin));
+ HObjectAccess function_access = HObjectAccess::ForObservableJSObjectOffset(
+ JSBuiltinsObject::OffsetOfFunctionWithId(builtin));
return Add<HLoadNamedField>(
builtins, static_cast<HValue*>(NULL), function_access);
}
case FAST_DOUBLE_ELEMENTS:
case FAST_HOLEY_DOUBLE_ELEMENTS: {
HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value,
- boilerplate_elements_kind,
- INITIALIZING_STORE);
+ boilerplate_elements_kind);
instr->SetUninitialized(uninitialized);
break;
}
HEAP_NUMBER_TYPE);
AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map());
Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(),
- value, INITIALIZING_STORE);
+ value);
instr = New<HStoreNamedField>(checked_object->ActualValue(),
heap_number_access,
- heap_number, INITIALIZING_STORE);
+ heap_number);
} else {
// Already holds a HeapNumber; load the box and write its value field.
HInstruction* heap_number = Add<HLoadNamedField>(
for (int i = 0; i < argument_count; i++) {
HValue* value = environment()->ExpressionStackAt(argument_count - i - 1);
HValue* constant_i = Add<HConstant>(i);
- Add<HStoreKeyed>(elements, constant_i, value, kind, INITIALIZING_STORE);
+ Add<HStoreKeyed>(elements, constant_i, value, kind);
}
}
HValue* constructor_value = Add<HConstant>(constructor);
HValue* initial_map_value =
Add<HLoadNamedField>(constructor_value, static_cast<HValue*>(NULL),
- HObjectAccess::ForJSObjectOffset(
+ HObjectAccess::ForMapAndOffset(
+ handle(constructor->map()),
JSFunction::kPrototypeOrInitialMapOffset));
// Initialize map and fields of the newly allocated object.
{ NoObservableSideEffectsScope no_effects(this);
ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
Add<HStoreNamedField>(receiver,
- HObjectAccess::ForJSObjectOffset(JSObject::kMapOffset),
- initial_map_value, INITIALIZING_STORE);
+ HObjectAccess::ForMapAndOffset(initial_map, JSObject::kMapOffset),
+ initial_map_value);
HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array());
Add<HStoreNamedField>(receiver,
- HObjectAccess::ForJSObjectOffset(JSObject::kPropertiesOffset),
- empty_fixed_array, INITIALIZING_STORE);
+ HObjectAccess::ForMapAndOffset(initial_map,
+ JSObject::kPropertiesOffset),
+ empty_fixed_array);
Add<HStoreNamedField>(receiver,
- HObjectAccess::ForJSObjectOffset(JSObject::kElementsOffset),
- empty_fixed_array, INITIALIZING_STORE);
+ HObjectAccess::ForMapAndOffset(initial_map,
+ JSObject::kElementsOffset),
+ empty_fixed_array);
if (initial_map->inobject_properties() != 0) {
HConstant* undefined = graph()->GetConstantUndefined();
for (int i = 0; i < initial_map->inobject_properties(); i++) {
- int property_offset = JSObject::kHeaderSize + i * kPointerSize;
+ int property_offset = initial_map->GetInObjectPropertyOffset(i);
Add<HStoreNamedField>(receiver,
- HObjectAccess::ForJSObjectOffset(property_offset),
- undefined, PREINITIALIZING_STORE);
+ HObjectAccess::ForMapAndOffset(initial_map, property_offset),
+ undefined);
}
}
}
offset < ViewClass::kSizeWithInternalFields;
offset += kPointerSize) {
Add<HStoreNamedField>(obj,
- HObjectAccess::ForJSObjectOffset(offset),
- graph()->GetConstant0(), INITIALIZING_STORE);
+ HObjectAccess::ForObservableJSObjectOffset(offset),
+ graph()->GetConstant0());
}
Add<HStoreNamedField>(
obj,
- HObjectAccess::ForJSArrayBufferViewBuffer(), buffer, INITIALIZING_STORE);
+ HObjectAccess::ForJSArrayBufferViewBuffer(), buffer);
Add<HStoreNamedField>(
obj,
HObjectAccess::ForJSArrayBufferViewByteOffset(),
- byte_offset, INITIALIZING_STORE);
+ byte_offset);
Add<HStoreNamedField>(
obj,
HObjectAccess::ForJSArrayBufferViewByteLength(),
- byte_length, INITIALIZING_STORE);
+ byte_length);
HObjectAccess weak_first_view_access =
HObjectAccess::ForJSArrayBufferWeakFirstView();
Add<HStoreNamedField>(obj,
HObjectAccess::ForJSArrayBufferViewWeakNext(),
Add<HLoadNamedField>(buffer, static_cast<HValue*>(NULL),
- weak_first_view_access),
- INITIALIZING_STORE);
+ weak_first_view_access));
Add<HStoreNamedField>(
- buffer, weak_first_view_access, obj, INITIALIZING_STORE);
+ buffer, weak_first_view_access, obj);
}
Add<HStoreNamedField>(obj,
HObjectAccess::ForJSTypedArrayLength(),
- length, INITIALIZING_STORE);
+ length);
HValue* elements =
Add<HAllocate>(
Handle<Map> external_array_map(
isolate()->heap()->MapForExternalArrayType(array_type));
- AddStoreMapConstant(elements, external_array_map);
+ Add<HStoreNamedField>(elements,
+ HObjectAccess::ForMap(),
+ Add<HConstant>(external_array_map));
HValue* backing_store = Add<HLoadNamedField>(
buffer, static_cast<HValue*>(NULL),
typed_array_start = external_pointer;
}
+ Add<HStoreNamedField>(elements,
+ HObjectAccess::ForExternalArrayExternalPointer(),
+ typed_array_start);
+ Add<HStoreNamedField>(elements,
+ HObjectAccess::ForFixedArrayLength(),
+ length);
Add<HStoreNamedField>(
- elements, HObjectAccess::ForExternalArrayExternalPointer(),
- typed_array_start, INITIALIZING_STORE);
- Add<HStoreNamedField>(
- elements, HObjectAccess::ForFixedArrayLength(), length,
- INITIALIZING_STORE);
- Add<HStoreNamedField>(
- obj, HObjectAccess::ForElementsPointer(), elements, INITIALIZING_STORE);
+ obj, HObjectAccess::ForElementsPointer(), elements);
}
if (!is_zero_byte_offset) {
HConstant* empty_fixed_array = Add<HConstant>(
isolate()->factory()->empty_fixed_array());
Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
- empty_fixed_array, INITIALIZING_STORE);
+ empty_fixed_array);
}
object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(),
pretenure_flag, FIXED_DOUBLE_ARRAY_TYPE, site_context->current());
ASSERT(*properties_field == isolate()->heap()->empty_fixed_array());
HInstruction* properties = Add<HConstant>(properties_field);
HObjectAccess access = HObjectAccess::ForPropertiesPointer();
- Add<HStoreNamedField>(object, access, properties, INITIALIZING_STORE);
+ Add<HStoreNamedField>(object, access, properties);
if (boilerplate_object->IsJSArray()) {
Handle<JSArray> boilerplate_array =
ASSERT(boilerplate_array->length()->IsSmi());
Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(
- boilerplate_array->GetElementsKind()), length, INITIALIZING_STORE);
+ boilerplate_array->GetElementsKind()), length);
}
}
object_elements = Add<HConstant>(elements_field);
}
Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
- object_elements, INITIALIZING_STORE);
+ object_elements);
}
HInstruction* object,
AllocationSiteUsageContext* site_context,
PretenureFlag pretenure_flag) {
- Handle<DescriptorArray> descriptors(
- boilerplate_object->map()->instance_descriptors());
- int limit = boilerplate_object->map()->NumberOfOwnDescriptors();
+ Handle<Map> boilerplate_map(boilerplate_object->map());
+ Handle<DescriptorArray> descriptors(boilerplate_map->instance_descriptors());
+ int limit = boilerplate_map->NumberOfOwnDescriptors();
int copied_fields = 0;
for (int i = 0; i < limit; i++) {
// The access for the store depends on the type of the boilerplate.
HObjectAccess access = boilerplate_object->IsJSArray() ?
HObjectAccess::ForJSArrayOffset(property_offset) :
- HObjectAccess::ForJSObjectOffset(property_offset);
+ HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset);
if (value->IsJSObject()) {
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
HInstruction* result =
BuildFastLiteral(value_object, site_context);
site_context->ExitScope(current_site, value_object);
- Add<HStoreNamedField>(object, access, result, INITIALIZING_STORE);
+ Add<HStoreNamedField>(object, access, result);
} else {
Representation representation = details.representation();
HInstruction* value_instruction;
AddStoreMapConstant(double_box,
isolate()->factory()->heap_number_map());
Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(),
- Add<HConstant>(value), INITIALIZING_STORE);
+ Add<HConstant>(value));
value_instruction = double_box;
} else if (representation.IsSmi() && value->IsUninitialized()) {
value_instruction = graph()->GetConstant0();
value_instruction = Add<HConstant>(value);
}
- Add<HStoreNamedField>(object, access, value_instruction,
- INITIALIZING_STORE);
+ Add<HStoreNamedField>(object, access, value_instruction);
}
}
for (int i = copied_fields; i < inobject_properties; i++) {
ASSERT(boilerplate_object->IsJSObject());
int property_offset = boilerplate_object->GetInObjectPropertyOffset(i);
- HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset);
- Add<HStoreNamedField>(object, access, value_instruction,
- PREINITIALIZING_STORE);
+ HObjectAccess access =
+ HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset);
+ Add<HStoreNamedField>(object, access, value_instruction);
}
}
static_cast<HValue*>(NULL), kind,
ALLOW_RETURN_HOLE);
HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant,
- value_instruction, kind,
- INITIALIZING_STORE);
+ value_instruction, kind);
store->SetFlag(HValue::kAllowUndefinedAsNaN);
}
}
HInstruction* result =
BuildFastLiteral(value_object, site_context);
site_context->ExitScope(current_site, value_object);
- Add<HStoreKeyed>(object_elements, key_constant, result, kind,
- INITIALIZING_STORE);
+ Add<HStoreKeyed>(object_elements, key_constant, result, kind);
} else {
HInstruction* value_instruction =
Add<HLoadKeyed>(boilerplate_elements, key_constant,
static_cast<HValue*>(NULL), kind,
ALLOW_RETURN_HOLE);
- Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind,
- INITIALIZING_STORE);
+ Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind);
}
}
}
// Return the actual value.
Push(Add<HLoadNamedField>(
object, objectisvalue,
- HObjectAccess::ForJSObjectOffset(JSValue::kValueOffset)));
+ HObjectAccess::ForObservableJSObjectOffset(
+ JSValue::kValueOffset)));
Add<HSimulate>(call->id(), FIXED_SIMULATE);
}
if_objectisvalue.Else();
if_objectisvalue.Then();
{
// Create in-object property store to kValueOffset.
- Add<HStoreNamedField>(
- object, HObjectAccess::ForJSObjectOffset(JSValue::kValueOffset),
- value, INITIALIZING_STORE);
+ Add<HStoreNamedField>(object,
+ HObjectAccess::ForObservableJSObjectOffset(JSValue::kValueOffset),
+ value);
Add<HSimulate>(call->id(), FIXED_SIMULATE);
}
if_objectisvalue.Else();
HInstruction* AddLoadStringLength(HValue* string);
HStoreNamedField* AddStoreMapNoWriteBarrier(HValue* object, HValue* map) {
HStoreNamedField* store_map = Add<HStoreNamedField>(
- object, HObjectAccess::ForMap(), map, INITIALIZING_STORE);
+ object, HObjectAccess::ForMap(), map);
store_map->SkipWriteBarrier();
return store_map;
}
ASSERT(name_->Equals(isolate()->heap()->length_string()));
*access = HObjectAccess::ForStringLength();
} else {
- *access = HObjectAccess::ForJSObjectOffset(offset);
+ *access = HObjectAccess::ForMapAndOffset(map(), offset);
}
return true;
}
int JSObject::GetInObjectPropertyOffset(int index) {
- // Adjust for the number of properties stored in the object.
- index -= map()->inobject_properties();
- ASSERT(index < 0);
- return map()->instance_size() + (index * kPointerSize);
+ return map()->GetInObjectPropertyOffset(index);
}
Object* JSObject::InObjectPropertyAt(int index) {
- // Adjust for the number of properties stored in the object.
- index -= map()->inobject_properties();
- ASSERT(index < 0);
- int offset = map()->instance_size() + (index * kPointerSize);
+ int offset = GetInObjectPropertyOffset(index);
return READ_FIELD(this, offset);
}
Object* value,
WriteBarrierMode mode) {
// Adjust for the number of properties stored in the object.
- index -= map()->inobject_properties();
- ASSERT(index < 0);
- int offset = map()->instance_size() + (index * kPointerSize);
+ int offset = GetInObjectPropertyOffset(index);
WRITE_FIELD(this, offset, value);
CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
return value;
}
+int Map::GetInObjectPropertyOffset(int index) {
+ // Adjust for the number of properties stored in the object.
+ index -= inobject_properties();
+ ASSERT(index < 0);
+ return instance_size() + (index * kPointerSize);
+}
+
+
int HeapObject::SizeFromMap(Map* map) {
int instance_size = map->instance_size();
if (instance_size != kVariableSizeSentinel) return instance_size;
Map* FindUpdatedMap(int verbatim, int length, DescriptorArray* descriptors);
Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
+ inline int GetInObjectPropertyOffset(int index);
+
int NumberOfFields();
bool InstancesNeedRewriting(Map* target,