Index: src/hydrogen-instructions.h |
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h |
index 2d57537596b612ffff8aa628dac5b0bac9cb8027..ace5f8783e435d61a4bb707b810957be615ecdbb 100644 |
--- a/src/hydrogen-instructions.h |
+++ b/src/hydrogen-instructions.h |
@@ -64,6 +64,7 @@ class LChunkBuilder; |
V(AbnormalExit) \ |
V(AccessArgumentsAt) \ |
V(Add) \ |
+ V(Allocate) \ |
V(AllocateObject) \ |
V(ApplyArguments) \ |
V(ArgumentsElements) \ |
@@ -179,6 +180,7 @@ class LChunkBuilder; |
V(Throw) \ |
V(ToFastProperties) \ |
V(TransitionElementsKind) \ |
+ V(TrapAllocationMemento) \ |
V(Typeof) \ |
V(TypeofIsAndBranch) \ |
V(UnaryMathOperation) \ |
@@ -4127,7 +4129,8 @@ inline bool StoringValueNeedsWriteBarrier(HValue* value) { |
inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, |
HValue* new_space_dominator) { |
- return (!object->IsAllocateObject() && !object->IsFastLiteral()) || |
+ return (!object->IsAllocateObject() && !object->IsAllocate() && |
Michael Starzinger
2013/01/31 13:15:10
This only holds if HAllocate guarantees that it al
danno
2013/01/31 15:53:25
Done.
|
+ !object->IsFastLiteral()) || |
(object != new_space_dominator); |
} |
@@ -4460,15 +4463,23 @@ class ArrayInstructionInterface { |
}; |
+enum LoadKeyedHoleMode { |
+ NEVER_RETURN_HOLE, |
+ ALLOW_RETURN_HOLE |
+}; |
+ |
+ |
class HLoadKeyed |
: public HTemplateInstruction<3>, public ArrayInstructionInterface { |
public: |
HLoadKeyed(HValue* obj, |
HValue* key, |
HValue* dependency, |
- ElementsKind elements_kind) |
+ ElementsKind elements_kind, |
+ LoadKeyedHoleMode mode = NEVER_RETURN_HOLE) |
: bit_field_(0) { |
- bit_field_ = ElementsKindField::encode(elements_kind); |
+ bit_field_ = ElementsKindField::encode(elements_kind) | |
+ HoleModeField::encode(mode); |
SetOperandAt(0, obj); |
SetOperandAt(1, key); |
@@ -4481,8 +4492,7 @@ class HLoadKeyed |
IsFastDoubleElementsKind(elements_kind)); |
if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
- if (IsFastSmiElementsKind(elements_kind) && |
- IsFastPackedElementsKind(elements_kind)) { |
+ if (IsFastSmiElementsKind(elements_kind)) { |
set_type(HType::Smi()); |
} |
@@ -4531,6 +4541,9 @@ class HLoadKeyed |
ElementsKind elements_kind() const { |
return ElementsKindField::decode(bit_field_); |
} |
+ LoadKeyedHoleMode hole_mode() const { |
+ return HoleModeField::decode(bit_field_); |
+ } |
virtual Representation RequiredInputRepresentation(int index) { |
// kind_fast: tagged[int32] (none) |
@@ -4553,6 +4566,7 @@ class HLoadKeyed |
virtual void PrintDataTo(StringStream* stream); |
+ bool CanReturnHole() const; |
bool RequiresHoleCheck() const; |
virtual Range* InferRange(Zone* zone); |
@@ -4577,11 +4591,13 @@ class HLoadKeyed |
// Establish some checks around our packed fields |
enum LoadKeyedBits { |
kBitsForElementsKind = 5, |
- kBitsForIndexOffset = 26, |
+ kBitsForHoleMode = 1, |
+ kBitsForIndexOffset = 25, |
kBitsForIsDehoisted = 1, |
kStartElementsKind = 0, |
- kStartIndexOffset = kStartElementsKind + kBitsForElementsKind, |
+ kStartHoleMode = kStartElementsKind + kBitsForElementsKind, |
+ kStartIndexOffset = kStartHoleMode + kBitsForHoleMode, |
kStartIsDehoisted = kStartIndexOffset + kBitsForIndexOffset |
}; |
@@ -4591,6 +4607,9 @@ class HLoadKeyed |
class ElementsKindField: |
public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind> |
{}; // NOLINT |
+ class HoleModeField: |
+ public BitField<LoadKeyedHoleMode, kStartHoleMode, kBitsForHoleMode> |
+ {}; // NOLINT |
class IndexOffsetField: |
public BitField<uint32_t, kStartIndexOffset, kBitsForIndexOffset> |
{}; // NOLINT |
@@ -4729,11 +4748,18 @@ class HStoreKeyed |
public: |
HStoreKeyed(HValue* obj, HValue* key, HValue* val, |
ElementsKind elements_kind) |
- : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { |
+ : elements_kind_(elements_kind), |
+ index_offset_(0), |
+ is_dehoisted_(false), |
+ new_space_dominator_(NULL) { |
SetOperandAt(0, obj); |
SetOperandAt(1, key); |
SetOperandAt(2, val); |
+ if (IsFastObjectElementsKind(elements_kind)) { |
+ SetFlag(kTrackSideEffectDominators); |
+ SetGVNFlag(kDependsOnNewSpacePromotion); |
+ } |
if (is_external()) { |
SetGVNFlag(kChangesSpecializedArrayElements); |
} else if (IsFastDoubleElementsKind(elements_kind)) { |
@@ -4801,11 +4827,19 @@ class HStoreKeyed |
bool IsDehoisted() { return is_dehoisted_; } |
void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } |
+ virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { |
+ ASSERT(side_effect == kChangesNewSpacePromotion); |
+ new_space_dominator_ = dominator; |
+ } |
+ |
+ HValue* new_space_dominator() const { return new_space_dominator_; } |
+ |
bool NeedsWriteBarrier() { |
if (value_is_smi()) { |
return false; |
} else { |
- return StoringValueNeedsWriteBarrier(value()); |
+ return StoringValueNeedsWriteBarrier(value()) && |
+ ReceiverObjectNeedsWriteBarrier(elements(), new_space_dominator()); |
} |
} |
@@ -4819,6 +4853,7 @@ class HStoreKeyed |
ElementsKind elements_kind_; |
uint32_t index_offset_; |
bool is_dehoisted_; |
+ HValue* new_space_dominator_; |
}; |
@@ -4857,9 +4892,10 @@ class HStoreKeyedGeneric: public HTemplateInstruction<4> { |
}; |
-class HTransitionElementsKind: public HTemplateInstruction<1> { |
+class HTransitionElementsKind: public HTemplateInstruction<2> { |
public: |
- HTransitionElementsKind(HValue* object, |
+ HTransitionElementsKind(HValue* context, |
+ HValue* object, |
Handle<Map> original_map, |
Handle<Map> transitioned_map) |
: original_map_(original_map), |
@@ -4867,6 +4903,7 @@ class HTransitionElementsKind: public HTemplateInstruction<1> { |
from_kind_(original_map->elements_kind()), |
to_kind_(transitioned_map->elements_kind()) { |
SetOperandAt(0, object); |
+ SetOperandAt(1, context); |
SetFlag(kUseGVN); |
SetGVNFlag(kChangesElementsKind); |
if (original_map->has_fast_double_elements()) { |
@@ -4885,6 +4922,7 @@ class HTransitionElementsKind: public HTemplateInstruction<1> { |
} |
HValue* object() { return OperandAt(0); } |
+ HValue* context() { return OperandAt(1); } |
Handle<Map> original_map() { return original_map_; } |
Handle<Map> transitioned_map() { return transitioned_map_; } |
ElementsKind from_kind() { return from_kind_; } |
@@ -5071,6 +5109,59 @@ class HAllocateObject: public HTemplateInstruction<1> { |
}; |
+class HAllocate: public HTemplateInstruction<2> { |
+ public: |
+ enum Flags { |
+ CAN_ALLOCATE_IN_NEW_SPACE = 1 << 0, |
+ CAN_ALLOCATE_IN_OLD_SPACE = 1 << 1, |
Michael Starzinger
2013/01/31 13:15:10
The old-space flag will need to indicate which old
danno
2013/01/31 15:53:25
Done.
|
+ ALLOCATE_DOUBLE_ALIGNED = 1 << 2, |
+ ALLOCATE_IN_ANY_SPACE = CAN_ALLOCATE_IN_NEW_SPACE | |
+ CAN_ALLOCATE_IN_OLD_SPACE |
+ }; |
+ |
+ HAllocate(HValue* context, HValue* size, HType type, Flags flags) |
+ : type_(type), |
+ flags_(flags) { |
+ ASSERT((flags & CAN_ALLOCATE_IN_OLD_SPACE) == 0); // unimplemented |
+ SetOperandAt(0, context); |
+ SetOperandAt(1, size); |
+ set_representation(Representation::Tagged()); |
+ SetGVNFlag(kChangesNewSpacePromotion); |
+ } |
+ |
+ HValue* context() { return OperandAt(0); } |
+ HValue* size() { return OperandAt(1); } |
+ |
+ virtual Representation RequiredInputRepresentation(int index) { |
+ if (index == 0) { |
+ return Representation::Tagged(); |
+ } else { |
+ return Representation::Integer32(); |
+ } |
+ } |
+ |
+ virtual HType CalculateInferredType(); |
+ |
+ bool CanAllocateInNewSpace() const { |
+ return (flags_ & CAN_ALLOCATE_IN_NEW_SPACE) != 0; |
+ } |
+ |
+ bool CanAllocateInOldSpace() const { |
+ return (flags_ & CAN_ALLOCATE_IN_OLD_SPACE) != 0; |
+ } |
+ |
+ bool MustAllocateDoubleAligned() const { |
+ return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0; |
+ } |
+ |
+ DECLARE_CONCRETE_INSTRUCTION(Allocate) |
+ |
+ private: |
+ HType type_; |
+ Flags flags_; |
+}; |
+ |
+ |
template <int V> |
class HMaterializedLiteral: public HTemplateInstruction<V> { |
public: |
@@ -5304,6 +5395,22 @@ class HTypeof: public HTemplateInstruction<2> { |
}; |
+class HTrapAllocationMemento : public HTemplateInstruction<2> { |
+ public: |
+ explicit HTrapAllocationMemento(HValue* obj) { |
+ SetOperandAt(0, obj); |
+ } |
+ |
+ virtual Representation RequiredInputRepresentation(int index) { |
+ return Representation::Tagged(); |
+ } |
+ |
+ HValue* object() { return OperandAt(0); } |
+ |
+ DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento) |
+}; |
+ |
+ |
class HToFastProperties: public HUnaryOperation { |
public: |
explicit HToFastProperties(HValue* value) : HUnaryOperation(value) { |