| Index: src/hydrogen-instructions.h
|
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
|
| index 8f7d602d2e5794d49796a056912a0a86b9691749..cfd5444cd5101ccac70b895980fd9b295ae69cba 100644
|
| --- a/src/hydrogen-instructions.h
|
| +++ b/src/hydrogen-instructions.h
|
| @@ -5710,8 +5710,15 @@ class HObjectAccess V8_FINAL {
|
| 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() {
|
| @@ -5755,7 +5762,8 @@ class HObjectAccess V8_FINAL {
|
| 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() {
|
| @@ -5857,16 +5865,29 @@ class HObjectAccess V8_FINAL {
|
| }
|
|
|
| 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);
|
|
|
| @@ -5884,39 +5905,42 @@ class HObjectAccess V8_FINAL {
|
| 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);
|
| }
|
|
|
| @@ -5949,23 +5973,29 @@ class HObjectAccess V8_FINAL {
|
| 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_;
|
| @@ -6351,9 +6381,6 @@ class HLoadKeyedGeneric V8_FINAL : public HTemplateInstruction<3> {
|
| // 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
|
| @@ -6364,6 +6391,8 @@ enum StoreFieldOrKeyedMode {
|
|
|
| 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);
|
|
|
| @@ -6470,16 +6499,15 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
|
| 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);
|
| @@ -6491,7 +6519,7 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
|
| HValue* new_space_dominator_;
|
| WriteBarrierMode write_barrier_mode_ : 1;
|
| bool has_transition_ : 1;
|
| - StoreFieldOrKeyedMode store_mode_ : 2;
|
| + StoreFieldOrKeyedMode store_mode_ : 1;
|
| };
|
|
|
|
|
| @@ -6536,6 +6564,8 @@ class HStoreNamedGeneric V8_FINAL : public HTemplateInstruction<3> {
|
| 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);
|
|
|
| @@ -6655,7 +6685,7 @@ class HStoreKeyed V8_FINAL
|
| 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),
|
| @@ -6666,12 +6696,6 @@ class HStoreKeyed V8_FINAL
|
| 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);
|
|
|
| @@ -6706,7 +6730,7 @@ class HStoreKeyed V8_FINAL
|
| uint32_t index_offset_;
|
| bool is_dehoisted_ : 1;
|
| bool is_uninitialized_ : 1;
|
| - StoreFieldOrKeyedMode store_mode_: 2;
|
| + StoreFieldOrKeyedMode store_mode_: 1;
|
| HValue* new_space_dominator_;
|
| };
|
|
|
|
|