| Index: src/hydrogen-instructions.h
|
| ===================================================================
|
| --- src/hydrogen-instructions.h (revision 7683)
|
| +++ src/hydrogen-instructions.h (working copy)
|
| @@ -104,6 +104,7 @@
|
| V(Goto) \
|
| V(HasInstanceType) \
|
| V(HasCachedArrayIndex) \
|
| + V(In) \
|
| V(InstanceOf) \
|
| V(InstanceOfKnownGlobal) \
|
| V(InvokeFunction) \
|
| @@ -403,6 +404,62 @@
|
| };
|
|
|
|
|
| +class HUseListNode: public ZoneObject {
|
| + public:
|
| + HUseListNode(HValue* value, int index, HUseListNode* tail)
|
| + : tail_(tail), value_(value), index_(index) {
|
| + }
|
| +
|
| + HUseListNode* tail() const { return tail_; }
|
| + HValue* value() const { return value_; }
|
| + int index() const { return index_; }
|
| +
|
| + void set_tail(HUseListNode* list) { tail_ = list; }
|
| +
|
| +#ifdef DEBUG
|
| + void Zap() {
|
| + tail_ = reinterpret_cast<HUseListNode*>(1);
|
| + value_ = NULL;
|
| + index_ = -1;
|
| + }
|
| +#endif
|
| +
|
| + private:
|
| + HUseListNode* tail_;
|
| + HValue* value_;
|
| + int index_;
|
| +};
|
| +
|
| +
|
| +// We reuse use list nodes behind the scenes as uses are added and deleted.
|
| +// This class is the safe way to iterate uses while deleting them.
|
| +class HUseIterator BASE_EMBEDDED {
|
| + public:
|
| + bool Done() { return current_ == NULL; }
|
| + void Advance();
|
| +
|
| + HValue* value() {
|
| + ASSERT(!Done());
|
| + return value_;
|
| + }
|
| +
|
| + int index() {
|
| + ASSERT(!Done());
|
| + return index_;
|
| + }
|
| +
|
| + private:
|
| + explicit HUseIterator(HUseListNode* head);
|
| +
|
| + HUseListNode* current_;
|
| + HUseListNode* next_;
|
| + HValue* value_;
|
| + int index_;
|
| +
|
| + friend class HValue;
|
| +};
|
| +
|
| +
|
| class HValue: public ZoneObject {
|
| public:
|
| static const int kNoNumber = -1;
|
| @@ -473,6 +530,7 @@
|
| HValue() : block_(NULL),
|
| id_(kNoNumber),
|
| type_(HType::Tagged()),
|
| + use_list_(NULL),
|
| range_(NULL),
|
| flags_(0) {}
|
| virtual ~HValue() {}
|
| @@ -483,7 +541,7 @@
|
| int id() const { return id_; }
|
| void set_id(int id) { id_ = id; }
|
|
|
| - SmallPointerList<HValue>* uses() { return &uses_; }
|
| + HUseIterator uses() const { return HUseIterator(use_list_); }
|
|
|
| virtual bool EmitAtUses() { return false; }
|
| Representation representation() const { return representation_; }
|
| @@ -498,7 +556,7 @@
|
|
|
| HType type() const { return type_; }
|
| void set_type(HType type) {
|
| - ASSERT(uses_.length() == 0);
|
| + ASSERT(HasNoUses());
|
| type_ = type;
|
| }
|
|
|
| @@ -524,16 +582,13 @@
|
| virtual HValue* OperandAt(int index) = 0;
|
| void SetOperandAt(int index, HValue* value);
|
|
|
| - int LookupOperandIndex(int occurrence_index, HValue* op);
|
| - bool UsesMultipleTimes(HValue* op);
|
| -
|
| - void ReplaceAndDelete(HValue* other);
|
| - void ReplaceValue(HValue* other);
|
| - void ReplaceAtUse(HValue* use, HValue* other);
|
| - void ReplaceFirstAtUse(HValue* use, HValue* other, Representation r);
|
| - bool HasNoUses() const { return uses_.is_empty(); }
|
| + void DeleteAndReplaceWith(HValue* other);
|
| + bool HasNoUses() const { return use_list_ == NULL; }
|
| + bool HasMultipleUses() const {
|
| + return use_list_ != NULL && use_list_->tail() != NULL;
|
| + }
|
| + int UseCount() const;
|
| void ClearOperands();
|
| - void Delete();
|
|
|
| int flags() const { return flags_; }
|
| void SetFlag(Flag f) { flags_ |= (1 << f); }
|
| @@ -611,7 +666,12 @@
|
| return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
|
| }
|
|
|
| - void InternalReplaceAtUse(HValue* use, HValue* other);
|
| + // Remove the matching use from the use list if present. Returns the
|
| + // removed list node or NULL.
|
| + HUseListNode* RemoveUse(HValue* value, int index);
|
| +
|
| + void ReplaceAllUsesWith(HValue* other);
|
| +
|
| void RegisterUse(int index, HValue* new_value);
|
|
|
| HBasicBlock* block_;
|
| @@ -622,7 +682,7 @@
|
|
|
| Representation representation_;
|
| HType type_;
|
| - SmallPointerList<HValue> uses_;
|
| + HUseListNode* use_list_;
|
| Range* range_;
|
| int flags_;
|
|
|
| @@ -2257,7 +2317,7 @@
|
| void SetInputRepresentation(Representation r);
|
|
|
| virtual bool EmitAtUses() {
|
| - return !HasSideEffects() && (uses()->length() <= 1);
|
| + return !HasSideEffects() && !HasMultipleUses();
|
| }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| @@ -2299,7 +2359,7 @@
|
| }
|
|
|
| virtual bool EmitAtUses() {
|
| - return !HasSideEffects() && (uses()->length() <= 1);
|
| + return !HasSideEffects() && !HasMultipleUses();
|
| }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| @@ -2322,7 +2382,7 @@
|
| }
|
|
|
| virtual bool EmitAtUses() {
|
| - return !HasSideEffects() && (uses()->length() <= 1);
|
| + return !HasSideEffects() && !HasMultipleUses();
|
| }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| @@ -2382,7 +2442,7 @@
|
| }
|
|
|
| virtual bool EmitAtUses() {
|
| - return !HasSideEffects() && (uses()->length() <= 1);
|
| + return !HasSideEffects() && !HasMultipleUses();
|
| }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| @@ -2504,7 +2564,7 @@
|
| HValue* right() { return OperandAt(2); }
|
|
|
| virtual bool EmitAtUses() {
|
| - return !HasSideEffects() && (uses()->length() <= 1);
|
| + return !HasSideEffects() && !HasMultipleUses();
|
| }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| @@ -3187,7 +3247,8 @@
|
| ExternalArrayType array_type)
|
| : HBinaryOperation(external_elements, key),
|
| array_type_(array_type) {
|
| - if (array_type == kExternalFloatArray) {
|
| + if (array_type == kExternalFloatArray ||
|
| + array_type == kExternalDoubleArray) {
|
| set_representation(Representation::Double());
|
| } else {
|
| set_representation(Representation::Integer32());
|
| @@ -3379,7 +3440,8 @@
|
| if (index == 0) {
|
| return Representation::External();
|
| } else {
|
| - if (index == 2 && array_type() == kExternalFloatArray) {
|
| + if (index == 2 && (array_type() == kExternalFloatArray ||
|
| + array_type() == kExternalDoubleArray)) {
|
| return Representation::Double();
|
| } else {
|
| return Representation::Integer32();
|
| @@ -3719,6 +3781,32 @@
|
| HValue* key() { return right(); }
|
| };
|
|
|
| +
|
| +class HIn: public HTemplateInstruction<2> {
|
| + public:
|
| + HIn(HValue* key, HValue* object) {
|
| + SetOperandAt(0, key);
|
| + SetOperandAt(1, object);
|
| + set_representation(Representation::Tagged());
|
| + SetAllSideEffects();
|
| + }
|
| +
|
| + HValue* key() { return OperandAt(0); }
|
| + HValue* object() { return OperandAt(1); }
|
| +
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| + virtual HType CalculateInferredType() {
|
| + return HType::Boolean();
|
| + }
|
| +
|
| + virtual void PrintDataTo(StringStream* stream);
|
| +
|
| + DECLARE_CONCRETE_INSTRUCTION(In)
|
| +};
|
| +
|
| #undef DECLARE_INSTRUCTION
|
| #undef DECLARE_CONCRETE_INSTRUCTION
|
|
|
|
|