Chromium Code Reviews| Index: src/hydrogen-instructions.h |
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h |
| index e5290783d5a858aef51c860bb5fdc2e19d220401..3a96612b8a4bcaefac95bd7225c5d673acde652c 100644 |
| --- a/src/hydrogen-instructions.h |
| +++ b/src/hydrogen-instructions.h |
| @@ -2256,6 +2256,8 @@ class HCheckMaps: public HTemplateInstruction<2> { |
| virtual HType CalculateInferredType(); |
| HValue* value() { return OperandAt(0); } |
| + bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } |
| + void RemoveTypeCheck() { SetOperandAt(1, OperandAt(0)); } |
| SmallMapList* map_set() { return &map_set_; } |
| DECLARE_CONCRETE_INSTRUCTION(CheckMaps) |
| @@ -4333,6 +4335,8 @@ class ArrayInstructionInterface { |
| virtual void SetIndexOffset(uint32_t index_offset) = 0; |
| virtual bool IsDehoisted() = 0; |
| virtual void SetDehoisted(bool is_dehoisted) = 0; |
| + virtual void PerformDeferredInitialization( |
| + ElementsKind new_elements_kind) = 0; |
| virtual ~ArrayInstructionInterface() { }; |
| }; |
| @@ -4343,15 +4347,42 @@ class HLoadKeyed |
| HLoadKeyed(HValue* obj, |
| HValue* key, |
| HValue* dependency, |
| - ElementsKind elements_kind) |
| + ElementsKind elements_kind, |
| + bool defer_initialization = false) |
| : bit_field_(0) { |
| bit_field_ = ElementsKindField::encode(elements_kind); |
| +#ifdef DEBUG |
| + initialized_ = !defer_initialization; |
|
danno
2012/11/28 14:42:10
Make this transparent with a single macro in Array
mvstanton
2012/12/04 11:39:58
Done.
|
| + |
| + // Deferred initialization should only be invoked for fast elements |
| + // that are not external. |
| + ASSERT(!(defer_initialization && is_external())); |
| +#endif |
| + |
| SetOperandAt(0, obj); |
| SetOperandAt(1, key); |
| SetOperandAt(2, dependency); |
| - if (!is_external()) { |
| + if (is_external()) { |
| + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| + elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| + set_representation(Representation::Double()); |
| + } else { |
| + set_representation(Representation::Integer32()); |
| + } |
| + |
| + SetGVNFlag(kDependsOnSpecializedArrayElements); |
| + // Native code could change the specialized array. |
| + SetGVNFlag(kDependsOnCalls); |
| + } else if (defer_initialization) { |
| + ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || |
| + IsFastDoubleElementsKind(elements_kind)); |
| + |
| + // We don't yet know what it depends on yet, so set both flags |
| + SetGVNFlag(kDependsOnArrayElements); |
| + SetGVNFlag(kDependsOnDoubleArrayElements); |
| + } else { |
| // I can detect the case between storing double (holey and fast) and |
| // smi/object by looking at elements_kind_. |
| ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || |
| @@ -4369,22 +4400,42 @@ class HLoadKeyed |
| set_representation(Representation::Double()); |
| SetGVNFlag(kDependsOnDoubleArrayElements); |
| } |
| - } else { |
| - if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| - elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| - set_representation(Representation::Double()); |
| - } else { |
| - set_representation(Representation::Integer32()); |
| - } |
| - |
| - SetGVNFlag(kDependsOnSpecializedArrayElements); |
| - // Native code could change the specialized array. |
| - SetGVNFlag(kDependsOnCalls); |
| } |
| SetFlag(kUseGVN); |
| } |
| +#ifdef DEBUG |
| + bool Initialized() const { return initialized_; } |
| +#endif |
| + |
| + void PerformDeferredInitialization(ElementsKind new_elements_kind) { |
|
danno
2012/11/28 14:42:10
Put this in the .cc
mvstanton
2012/12/04 11:39:58
Done.
|
| +#ifdef DEBUG |
| + ASSERT(!initialized_); |
| + initialized_ = true; |
| +#endif |
| + if (new_elements_kind != elements_kind()) { |
| + bit_field_ = ElementsKindField::encode(new_elements_kind); |
| + } |
| + |
| + // Start fresh |
| + ClearGVNFlag(kDependsOnArrayElements); |
| + ClearGVNFlag(kDependsOnDoubleArrayElements); |
| + |
| + if (IsFastSmiOrObjectElementsKind(elements_kind())) { |
| + if (IsFastSmiElementsKind(elements_kind()) && |
| + IsFastPackedElementsKind(elements_kind())) { |
| + set_type(HType::Smi()); |
| + } |
| + |
| + set_representation(Representation::Tagged()); |
| + SetGVNFlag(kDependsOnArrayElements); |
| + } else { |
| + set_representation(Representation::Double()); |
| + SetGVNFlag(kDependsOnDoubleArrayElements); |
| + } |
| + } |
| + |
| bool is_external() const { |
| return IsExternalArrayElementsKind(elements_kind()); |
| } |
| @@ -4406,6 +4457,11 @@ class HLoadKeyed |
| } |
| virtual Representation RequiredInputRepresentation(int index) { |
| +#ifdef DEBUG |
| + // The idea here is that nobody should be inquiring about input |
| + // representation until we've finished a possibly deferred initialization |
| + ASSERT(initialized_); |
| +#endif |
| // kind_fast: tagged[int32] (none) |
| // kind_double: tagged[int32] (none) |
| // kind_external: external[int32] (none) |
| @@ -4468,6 +4524,9 @@ class HLoadKeyed |
| public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted> |
| {}; // NOLINT |
| uint32_t bit_field_; |
| +#ifdef DEBUG |
| + bool initialized_; |
| +#endif |
| }; |
| @@ -4598,29 +4657,66 @@ class HStoreKeyed |
| : public HTemplateInstruction<3>, public ArrayInstructionInterface { |
| public: |
| HStoreKeyed(HValue* obj, HValue* key, HValue* val, |
| - ElementsKind elements_kind) |
| + ElementsKind elements_kind, |
| + bool defer_initialization = false) |
|
danno
2012/11/28 14:42:10
can you not have to care whether this is deferred,
mvstanton
2012/12/04 11:39:58
That didn't work because there are protections aro
|
| : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { |
| SetOperandAt(0, obj); |
| SetOperandAt(1, key); |
| SetOperandAt(2, val); |
| +#ifdef DEBUG |
| + initialized_ = !defer_initialization; |
| + |
| + // Deferred initialization should only be invoked for fast elements |
| + // that are not external. |
| + ASSERT(!(defer_initialization && is_external())); |
| +#endif |
| + |
| if (is_external()) { |
| SetGVNFlag(kChangesSpecializedArrayElements); |
| + // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. |
| + if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && |
| + elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
| + SetFlag(kTruncatingToInt32); |
| + } |
| + } else if (defer_initialization) { |
| + // We don't know what we'll have later. |
| + // Initialize for the worst case |
| + SetGVNFlag(kChangesDoubleArrayElements); |
| + SetFlag(kDeoptimizeOnUndefined); |
| + SetGVNFlag(kChangesArrayElements); |
| } else if (IsFastDoubleElementsKind(elements_kind)) { |
| SetGVNFlag(kChangesDoubleArrayElements); |
| SetFlag(kDeoptimizeOnUndefined); |
| } else { |
| SetGVNFlag(kChangesArrayElements); |
| } |
| + } |
| + |
| +#ifdef DEBUG |
| + bool Initialized() const { return initialized_; } |
| +#endif |
| - // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. |
| - if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && |
| - elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
| - SetFlag(kTruncatingToInt32); |
| + void PerformDeferredInitialization(ElementsKind new_elements_kind) { |
| +#ifdef DEBUG |
| + ASSERT(!initialized_); |
| + initialized_ = true; |
| +#endif |
| + if (new_elements_kind != elements_kind_) { |
| + elements_kind_ = new_elements_kind; |
| + } |
| + |
| + // Adjust flags appropriately |
| + if (IsFastDoubleElementsKind(elements_kind())) { |
| + ClearGVNFlag(kChangesArrayElements); |
| + } else { |
| + ClearGVNFlag(kChangesDoubleArrayElements); |
| + ClearFlag(kDeoptimizeOnUndefined); |
| } |
| } |
| virtual Representation RequiredInputRepresentation(int index) { |
| + ASSERT(initialized_); |
| // kind_fast: tagged[int32] = tagged |
| // kind_double: tagged[int32] = double |
| // kind_external: external[int32] = (double | int32) |
| @@ -4679,7 +4775,6 @@ class HStoreKeyed |
| } |
| bool NeedsCanonicalization(); |
| - |
| virtual void PrintDataTo(StringStream* stream); |
| DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) |
| @@ -4688,6 +4783,9 @@ class HStoreKeyed |
| ElementsKind elements_kind_; |
| uint32_t index_offset_; |
| bool is_dehoisted_; |
| +#ifdef DEBUG |
| + bool initialized_; |
| +#endif |
| }; |