HIR refactoring.
authorfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 23 Feb 2011 11:19:50 +0000 (11:19 +0000)
committerfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 23 Feb 2011 11:19:50 +0000 (11:19 +0000)
Review URL: http://codereview.chromium.org/6538080

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6910 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/lithium-arm.cc
src/arm/lithium-arm.h
src/hydrogen-instructions.cc
src/hydrogen-instructions.h
src/hydrogen.cc
src/hydrogen.h
src/ia32/lithium-ia32.cc
src/ia32/lithium-ia32.h
src/x64/lithium-x64.cc
src/x64/lithium-x64.h

index 7847a5b..15498cb 100644 (file)
@@ -346,7 +346,7 @@ void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
 }
 
 
-void LStoreNamed::PrintDataTo(StringStream* stream) {
+void LStoreNamedField::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
   stream->Add(".");
   stream->Add(*String::cast(*name())->ToCString());
@@ -355,7 +355,25 @@ void LStoreNamed::PrintDataTo(StringStream* stream) {
 }
 
 
-void LStoreKeyed::PrintDataTo(StringStream* stream) {
+void LStoreNamedGeneric::PrintDataTo(StringStream* stream) {
+  object()->PrintTo(stream);
+  stream->Add(".");
+  stream->Add(*String::cast(*name())->ToCString());
+  stream->Add(" <- ");
+  value()->PrintTo(stream);
+}
+
+
+void LStoreKeyedFastElement::PrintDataTo(StringStream* stream) {
+  object()->PrintTo(stream);
+  stream->Add("[");
+  key()->PrintTo(stream);
+  stream->Add("] <- ");
+  value()->PrintTo(stream);
+}
+
+
+void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
   stream->Add("[");
   key()->PrintTo(stream);
index bd625aa..77d6b71 100644 (file)
@@ -42,8 +42,6 @@ class LCodeGen;
 #define LITHIUM_ALL_INSTRUCTION_LIST(V)         \
   V(ControlInstruction)                         \
   V(Call)                                       \
-  V(StoreKeyed)                                 \
-  V(StoreNamed)                                 \
   LITHIUM_CONCRETE_INSTRUCTION_LIST(V)
 
 
@@ -1523,32 +1521,22 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
 };
 
 
-class LStoreNamed: public LTemplateInstruction<0, 2, 0> {
+class LStoreNamedField: public LTemplateInstruction<0, 2, 0> {
  public:
-  LStoreNamed(LOperand* obj, LOperand* val) {
+  LStoreNamedField(LOperand* obj, LOperand* val) {
     inputs_[0] = obj;
     inputs_[1] = val;
   }
 
-  DECLARE_INSTRUCTION(StoreNamed)
-  DECLARE_HYDROGEN_ACCESSOR(StoreNamed)
+  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
+  DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
 
   virtual void PrintDataTo(StringStream* stream);
 
   LOperand* object() { return inputs_[0]; }
   LOperand* value() { return inputs_[1]; }
-  Handle<Object> name() const { return hydrogen()->name(); }
-};
-
-
-class LStoreNamedField: public LStoreNamed {
- public:
-  LStoreNamedField(LOperand* obj, LOperand* val)
-      : LStoreNamed(obj, val) { }
-
-  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
-  DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
 
+  Handle<Object> name() const { return hydrogen()->name(); }
   bool is_in_object() { return hydrogen()->is_in_object(); }
   int offset() { return hydrogen()->offset(); }
   bool needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); }
@@ -1556,25 +1544,35 @@ class LStoreNamedField: public LStoreNamed {
 };
 
 
-class LStoreNamedGeneric: public LStoreNamed {
+class LStoreNamedGeneric: public LTemplateInstruction<0, 2, 0> {
  public:
-  LStoreNamedGeneric(LOperand* obj, LOperand* val)
-      : LStoreNamed(obj, val) { }
+  LStoreNamedGeneric(LOperand* obj, LOperand* val) {
+    inputs_[0] = obj;
+    inputs_[1] = val;
+  }
 
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  LOperand* object() { return inputs_[0]; }
+  LOperand* value() { return inputs_[1]; }
+  Handle<Object> name() const { return hydrogen()->name(); }
 };
 
 
-class LStoreKeyed: public LTemplateInstruction<0, 3, 0> {
+class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> {
  public:
-  LStoreKeyed(LOperand* obj, LOperand* key, LOperand* val) {
+  LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val) {
     inputs_[0] = obj;
     inputs_[1] = key;
     inputs_[2] = val;
   }
 
-  DECLARE_INSTRUCTION(StoreKeyed)
+  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
+                               "store-keyed-fast-element")
+  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
 
   virtual void PrintDataTo(StringStream* stream);
 
@@ -1584,23 +1582,21 @@ class LStoreKeyed: public LTemplateInstruction<0, 3, 0> {
 };
 
 
-class LStoreKeyedFastElement: public LStoreKeyed {
+class LStoreKeyedGeneric: public LTemplateInstruction<0, 3, 0> {
  public:
-  LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val)
-      : LStoreKeyed(obj, key, val) {}
-
-  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
-                               "store-keyed-fast-element")
-  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
-};
+  LStoreKeyedGeneric(LOperand* obj, LOperand* key, LOperand* val) {
+    inputs_[0] = obj;
+    inputs_[1] = key;
+    inputs_[2] = val;
+  }
 
+  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
 
-class LStoreKeyedGeneric: public LStoreKeyed {
- public:
-  LStoreKeyedGeneric(LOperand* obj, LOperand* key, LOperand* val)
-      : LStoreKeyed(obj, key, val) { }
+  virtual void PrintDataTo(StringStream* stream);
 
-  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
+  LOperand* object() { return inputs_[0]; }
+  LOperand* key() { return inputs_[1]; }
+  LOperand* value() { return inputs_[2]; }
 };
 
 
index d750cb5..c5a7146 100644 (file)
@@ -284,33 +284,6 @@ void HValue::SetOperandAt(int index, HValue* value) {
 }
 
 
-void HLoadKeyedGeneric::InternalSetOperandAt(int index, HValue* value) {
-  if (index < 2) {
-    operands_[index] = value;
-  } else {
-    context_ = value;
-  }
-}
-
-
-void HStoreKeyedGeneric::InternalSetOperandAt(int index, HValue* value) {
-  if (index < 3) {
-    operands_[index] = value;
-  } else {
-    context_ = value;
-  }
-}
-
-
-void HStoreNamedGeneric::InternalSetOperandAt(int index, HValue* value) {
-  if (index < 2) {
-    operands_[index] = value;
-  } else {
-    context_ = value;
-  }
-}
-
-
 void HValue::ReplaceAndDelete(HValue* other) {
   ReplaceValue(other);
   Delete();
@@ -564,15 +537,10 @@ void HInstruction::Verify() {
 #endif
 
 
-void HCall::PrintDataTo(StringStream* stream) {
-  stream->Add("#%d", argument_count());
-}
-
-
 void HUnaryCall::PrintDataTo(StringStream* stream) {
   value()->PrintNameTo(stream);
   stream->Add(" ");
-  HCall::PrintDataTo(stream);
+  stream->Add("#%d", argument_count());
 }
 
 
@@ -581,7 +549,7 @@ void HBinaryCall::PrintDataTo(StringStream* stream) {
   stream->Add(" ");
   second()->PrintNameTo(stream);
   stream->Add(" ");
-  HCall::PrintDataTo(stream);
+  stream->Add("#%d", argument_count());
 }
 
 
@@ -591,7 +559,7 @@ void HCallConstantFunction::PrintDataTo(StringStream* stream) {
   } else {
     stream->Add("%o ", function()->shared()->DebugName());
   }
-  HCall::PrintDataTo(stream);
+  stream->Add("#%d", argument_count());
 }
 
 
@@ -609,13 +577,13 @@ void HCallGlobal::PrintDataTo(StringStream* stream) {
 
 void HCallKnownGlobal::PrintDataTo(StringStream* stream) {
   stream->Add("o ", target()->shared()->DebugName());
-  HCall::PrintDataTo(stream);
+  stream->Add("#%d", argument_count());
 }
 
 
 void HCallRuntime::PrintDataTo(StringStream* stream) {
   stream->Add("%o ", *name());
-  HCall::PrintDataTo(stream);
+  stream->Add("#%d", argument_count());
 }
 
 
@@ -1162,7 +1130,15 @@ void HLoadNamedField::PrintDataTo(StringStream* stream) {
 }
 
 
-void HLoadKeyed::PrintDataTo(StringStream* stream) {
+void HLoadKeyedFastElement::PrintDataTo(StringStream* stream) {
+  object()->PrintNameTo(stream);
+  stream->Add("[");
+  key()->PrintNameTo(stream);
+  stream->Add("]");
+}
+
+
+void HLoadKeyedGeneric::PrintDataTo(StringStream* stream) {
   object()->PrintNameTo(stream);
   stream->Add("[");
   key()->PrintNameTo(stream);
@@ -1178,7 +1154,7 @@ void HLoadPixelArrayElement::PrintDataTo(StringStream* stream) {
 }
 
 
-void HStoreNamed::PrintDataTo(StringStream* stream) {
+void HStoreNamedGeneric::PrintDataTo(StringStream* stream) {
   object()->PrintNameTo(stream);
   stream->Add(".");
   ASSERT(name()->IsString());
@@ -1189,14 +1165,28 @@ void HStoreNamed::PrintDataTo(StringStream* stream) {
 
 
 void HStoreNamedField::PrintDataTo(StringStream* stream) {
-  HStoreNamed::PrintDataTo(stream);
+  object()->PrintNameTo(stream);
+  stream->Add(".");
+  ASSERT(name()->IsString());
+  stream->Add(*String::cast(*name())->ToCString());
+  stream->Add(" = ");
+  value()->PrintNameTo(stream);
   if (!transition().is_null()) {
     stream->Add(" (transition map %p)", *transition());
   }
 }
 
 
-void HStoreKeyed::PrintDataTo(StringStream* stream) {
+void HStoreKeyedFastElement::PrintDataTo(StringStream* stream) {
+  object()->PrintNameTo(stream);
+  stream->Add("[");
+  key()->PrintNameTo(stream);
+  stream->Add("] = ");
+  value()->PrintNameTo(stream);
+}
+
+
+void HStoreKeyedGeneric::PrintDataTo(StringStream* stream) {
   object()->PrintNameTo(stream);
   stream->Add("[");
   key()->PrintNameTo(stream);
index d8fdf1d..22916f5 100644 (file)
@@ -51,14 +51,9 @@ class LChunkBuilder;
   V(BinaryCall)                                \
   V(BinaryOperation)                           \
   V(BitwiseBinaryOperation)                    \
-  V(Call)                                      \
   V(ControlInstruction)                        \
   V(Instruction)                               \
-  V(LoadKeyed)                                 \
-  V(MaterializedLiteral)                       \
   V(Phi)                                       \
-  V(StoreKeyed)                                \
-  V(StoreNamed)                                \
   V(UnaryCall)                                 \
   V(UnaryControlInstruction)                   \
   V(UnaryOperation)                            \
@@ -193,14 +188,6 @@ class LChunkBuilder;
   DECLARE_INSTRUCTION(type)
 
 
-
-template<int kSize>
-class HOperandVector : public EmbeddedVector<HValue*, kSize> {
- public:
-  HOperandVector() : EmbeddedVector<HValue*, kSize>(NULL) { }
-};
-
-
 class Range: public ZoneObject {
  public:
   Range() : lower_(kMinInt),
@@ -544,11 +531,8 @@ class HValue: public ZoneObject {
   bool IsDefinedAfter(HBasicBlock* other) const;
 
   // Operands.
-  virtual int OperandCount() { return 0; }
-  virtual HValue* OperandAt(int index) {
-    UNREACHABLE();
-    return NULL;
-  }
+  virtual int OperandCount() = 0;
+  virtual HValue* OperandAt(int index) = 0;
   void SetOperandAt(int index, HValue* value);
 
   int LookupOperandIndex(int occurrence_index, HValue* op);
@@ -626,7 +610,7 @@ class HValue: public ZoneObject {
   virtual void RepresentationChanged(Representation to) { }
   virtual Range* InferRange();
   virtual void DeleteFromGraph() = 0;
-  virtual void InternalSetOperandAt(int index, HValue* value) { UNREACHABLE(); }
+  virtual void InternalSetOperandAt(int index, HValue* value) = 0;
   void clear_block() {
     ASSERT(block_ != NULL);
     block_ = NULL;
@@ -690,6 +674,8 @@ class HInstruction: public HValue {
   // instruction.
   virtual bool IsCheckInstruction() const { return false; }
 
+  virtual bool IsCall() { return false; }
+
   DECLARE_INSTRUCTION(Instruction)
 
  protected:
@@ -716,17 +702,6 @@ class HInstruction: public HValue {
 };
 
 
-class HBlockEntry: public HInstruction {
- public:
-
-  virtual Representation RequiredInputRepresentation(int index) const {
-    return Representation::None();
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(BlockEntry, "block_entry")
-};
-
-
 class HControlInstruction: public HInstruction {
  public:
   HControlInstruction(HBasicBlock* first, HBasicBlock* second)
@@ -746,9 +721,77 @@ class HControlInstruction: public HInstruction {
 };
 
 
-class HDeoptimize: public HControlInstruction {
+template<int NumElements>
+class HOperandContainer {
  public:
-  HDeoptimize() : HControlInstruction(NULL, NULL) { }
+  HOperandContainer() : elems_() { }
+
+  int length() { return NumElements; }
+  HValue*& operator[](int i) {
+    ASSERT(i < length());
+    return elems_[i];
+  }
+
+ private:
+  HValue* elems_[NumElements];
+};
+
+
+template<>
+class HOperandContainer<0> {
+ public:
+  int length() { return 0; }
+  HValue*& operator[](int i) {
+    UNREACHABLE();
+    static HValue* t = 0;
+    return t;
+  }
+};
+
+
+template<int V>
+class HTemplateInstruction : public HInstruction {
+ public:
+  int OperandCount() { return V; }
+  HValue* OperandAt(int i) { return inputs_[i]; }
+
+ protected:
+  void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
+
+ private:
+  HOperandContainer<V> inputs_;
+};
+
+
+template<int V>
+class HTemplateControlInstruction : public HControlInstruction {
+ public:
+  HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
+    : HControlInstruction(first, second) { }
+  int OperandCount() { return V; }
+  HValue* OperandAt(int i) { return inputs_[i]; }
+
+ protected:
+  void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
+
+ private:
+  HOperandContainer<V> inputs_;
+};
+
+
+class HBlockEntry: public HTemplateInstruction<0> {
+ public:
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::None();
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(BlockEntry, "block_entry")
+};
+
+
+class HDeoptimize: public HTemplateControlInstruction<0> {
+ public:
+  HDeoptimize() : HTemplateControlInstruction<0>(NULL, NULL) { }
 
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::None();
@@ -758,11 +801,11 @@ class HDeoptimize: public HControlInstruction {
 };
 
 
-class HGoto: public HControlInstruction {
+class HGoto: public HTemplateControlInstruction<0> {
  public:
   explicit HGoto(HBasicBlock* target)
-      : HControlInstruction(target, NULL), include_stack_check_(false) {
-  }
+      : HTemplateControlInstruction<0>(target, NULL),
+        include_stack_check_(false) { }
 
   void set_include_stack_check(bool include_stack_check) {
     include_stack_check_ = include_stack_check;
@@ -780,30 +823,20 @@ class HGoto: public HControlInstruction {
 };
 
 
-class HUnaryControlInstruction: public HControlInstruction {
+class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
  public:
   explicit HUnaryControlInstruction(HValue* value,
                                     HBasicBlock* true_target,
                                     HBasicBlock* false_target)
-      : HControlInstruction(true_target, false_target) {
+      : HTemplateControlInstruction<1>(true_target, false_target) {
     SetOperandAt(0, value);
   }
 
   virtual void PrintDataTo(StringStream* stream);
 
   HValue* value() { return OperandAt(0); }
-  virtual int OperandCount() { return 1; }
-  virtual HValue* OperandAt(int index) { return operands_[index]; }
 
   DECLARE_INSTRUCTION(UnaryControlInstruction)
-
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value) {
-    operands_[index] = value;
-  }
-
- private:
-  HOperandVector<1> operands_;
 };
 
 
@@ -864,9 +897,9 @@ class HReturn: public HUnaryControlInstruction {
 };
 
 
-class HAbnormalExit: public HControlInstruction {
+class HAbnormalExit: public HTemplateControlInstruction<0> {
  public:
-  HAbnormalExit() : HControlInstruction(NULL, NULL) { }
+  HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
 
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::None();
@@ -876,7 +909,7 @@ class HAbnormalExit: public HControlInstruction {
 };
 
 
-class HUnaryOperation: public HInstruction {
+class HUnaryOperation: public HTemplateInstruction<1> {
  public:
   explicit HUnaryOperation(HValue* value) {
     SetOperandAt(0, value);
@@ -884,18 +917,8 @@ class HUnaryOperation: public HInstruction {
 
   HValue* value() { return OperandAt(0); }
   virtual void PrintDataTo(StringStream* stream);
-  virtual int OperandCount() { return 1; }
-  virtual HValue* OperandAt(int index) { return operands_[index]; }
 
   DECLARE_INSTRUCTION(UnaryOperation)
-
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value) {
-    operands_[index] = value;
-  }
-
- private:
-  HOperandVector<1> operands_;
 };
 
 
@@ -1036,7 +1059,7 @@ class HSimulate: public HInstruction {
 };
 
 
-class HStackCheck: public HInstruction {
+class HStackCheck: public HTemplateInstruction<0> {
  public:
   HStackCheck() { }
 
@@ -1048,7 +1071,7 @@ class HStackCheck: public HInstruction {
 };
 
 
-class HEnterInlined: public HInstruction {
+class HEnterInlined: public HTemplateInstruction<0> {
  public:
   HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
       : closure_(closure), function_(function) {
@@ -1071,7 +1094,7 @@ class HEnterInlined: public HInstruction {
 };
 
 
-class HLeaveInlined: public HInstruction {
+class HLeaveInlined: public HTemplateInstruction<0> {
  public:
   HLeaveInlined() {}
 
@@ -1099,7 +1122,7 @@ class HPushArgument: public HUnaryOperation {
 };
 
 
-class HContext: public HInstruction {
+class HContext: public HTemplateInstruction<0> {
  public:
   HContext() {
     set_representation(Representation::Tagged());
@@ -1172,89 +1195,70 @@ class HGlobalReceiver: public HUnaryOperation {
 };
 
 
-class HCall: public HInstruction {
+template <int V>
+class HCall: public HTemplateInstruction<V> {
  public:
   // The argument count includes the receiver.
-  explicit HCall(int argument_count) : argument_count_(argument_count) {
-    set_representation(Representation::Tagged());
-    SetAllSideEffects();
+  explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
+    this->set_representation(Representation::Tagged());
+    this->SetAllSideEffects();
   }
 
   virtual HType CalculateInferredType() { return HType::Tagged(); }
 
   virtual int argument_count() const { return argument_count_; }
 
-  virtual void PrintDataTo(StringStream* stream);
-
-  DECLARE_INSTRUCTION(Call)
+  virtual bool IsCall() { return true; }
 
  private:
   int argument_count_;
 };
 
 
-class HUnaryCall: public HCall {
+class HUnaryCall: public HCall<1> {
  public:
   HUnaryCall(HValue* value, int argument_count)
-      : HCall(argument_count), value_(NULL) {
+      : HCall<1>(argument_count) {
     SetOperandAt(0, value);
   }
 
-  virtual void PrintDataTo(StringStream* stream);
-
-  HValue* value() { return value_; }
-
-  virtual int OperandCount() { return 1; }
-  virtual HValue* OperandAt(int index) {
-    ASSERT(index == 0);
-    return value_;
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
   }
 
-  DECLARE_INSTRUCTION(UnaryCall)
+  virtual void PrintDataTo(StringStream* stream);
 
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value) {
-    ASSERT(index == 0);
-    value_ = value;
-  }
+  HValue* value() { return OperandAt(0); }
 
- private:
-  HValue* value_;
+  DECLARE_INSTRUCTION(UnaryCall)
 };
 
 
-class HBinaryCall: public HCall {
+class HBinaryCall: public HCall<2> {
  public:
   HBinaryCall(HValue* first, HValue* second, int argument_count)
-      : HCall(argument_count) {
+      : HCall<2>(argument_count) {
     SetOperandAt(0, first);
     SetOperandAt(1, second);
   }
 
   virtual void PrintDataTo(StringStream* stream);
 
-  HValue* first() const { return operands_[0]; }
-  HValue* second() const { return operands_[1]; }
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
+  }
 
-  virtual int OperandCount() { return 2; }
-  virtual HValue* OperandAt(int index) { return operands_[index]; }
+  HValue* first() { return OperandAt(0); }
+  HValue* second() { return OperandAt(1); }
 
   DECLARE_INSTRUCTION(BinaryCall)
-
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value) {
-    operands_[index] = value;
-  }
-
- private:
-  HOperandVector<2> operands_;
 };
 
 
-class HCallConstantFunction: public HCall {
+class HCallConstantFunction: public HCall<0> {
  public:
   HCallConstantFunction(Handle<JSFunction> function, int argument_count)
-      : HCall(argument_count), function_(function) { }
+      : HCall<0>(argument_count), function_(function) { }
 
   Handle<JSFunction> function() const { return function_; }
 
@@ -1285,8 +1289,8 @@ class HCallKeyed: public HBinaryCall {
     return Representation::Tagged();
   }
 
-  HValue* context() const { return first(); }
-  HValue* key() const { return second(); }
+  HValue* context() { return first(); }
+  HValue* key() { return second(); }
 
   DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed")
 };
@@ -1352,10 +1356,10 @@ class HCallGlobal: public HUnaryCall {
 };
 
 
-class HCallKnownGlobal: public HCall {
+class HCallKnownGlobal: public HCall<0> {
  public:
   HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
-      : HCall(argument_count), target_(target) { }
+      : HCall<0>(argument_count), target_(target) { }
 
   virtual void PrintDataTo(StringStream* stream);
 
@@ -1382,19 +1386,19 @@ class HCallNew: public HBinaryCall {
     return Representation::Tagged();
   }
 
-  HValue* context() const { return first(); }
-  HValue* constructor() const { return second(); }
+  HValue* context() { return first(); }
+  HValue* constructor() { return second(); }
 
   DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new")
 };
 
 
-class HCallRuntime: public HCall {
+class HCallRuntime: public HCall<0> {
  public:
   HCallRuntime(Handle<String> name,
                Runtime::Function* c_function,
                int argument_count)
-      : HCall(argument_count), c_function_(c_function), name_(name) { }
+      : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
   virtual void PrintDataTo(StringStream* stream);
 
   Runtime::Function* function() const { return c_function_; }
@@ -1761,7 +1765,7 @@ class HCheckNonSmi: public HUnaryOperation {
 };
 
 
-class HCheckPrototypeMaps: public HInstruction {
+class HCheckPrototypeMaps: public HTemplateInstruction<0> {
  public:
   HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
       : prototype_(prototype), holder_(holder) {
@@ -1923,7 +1927,7 @@ class HPhi: public HValue {
 };
 
 
-class HArgumentsObject: public HInstruction {
+class HArgumentsObject: public HTemplateInstruction<0> {
  public:
   HArgumentsObject() {
     set_representation(Representation::Tagged());
@@ -1938,7 +1942,7 @@ class HArgumentsObject: public HInstruction {
 };
 
 
-class HConstant: public HInstruction {
+class HConstant: public HTemplateInstruction<0> {
  public:
   HConstant(Handle<Object> handle, Representation r);
 
@@ -2001,7 +2005,7 @@ class HConstant: public HInstruction {
 };
 
 
-class HBinaryOperation: public HInstruction {
+class HBinaryOperation: public HTemplateInstruction<2> {
  public:
   HBinaryOperation(HValue* left, HValue* right) {
     ASSERT(left != NULL && right != NULL);
@@ -2026,21 +2030,12 @@ class HBinaryOperation: public HInstruction {
   virtual bool IsCommutative() const { return false; }
 
   virtual void PrintDataTo(StringStream* stream);
-  virtual int OperandCount() { return operands_.length(); }
-  virtual HValue* OperandAt(int index) { return operands_[index]; }
 
   DECLARE_INSTRUCTION(BinaryOperation)
-
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value) {
-    operands_[index] = value;
-  }
-
-  HOperandVector<2> operands_;
 };
 
 
-class HApplyArguments: public HInstruction {
+class HApplyArguments: public HTemplateInstruction<4> {
  public:
   HApplyArguments(HValue* function,
                   HValue* receiver,
@@ -2066,22 +2061,11 @@ class HApplyArguments: public HInstruction {
   HValue* length() { return OperandAt(2); }
   HValue* elements() { return OperandAt(3); }
 
-  virtual int OperandCount() { return operands_.length(); }
-  virtual HValue* OperandAt(int index) { return operands_[index]; }
-
   DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply_arguments")
-
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value) {
-    operands_[index] = value;
-  }
-
- private:
-  HOperandVector<4> operands_;
 };
 
 
-class HArgumentsElements: public HInstruction {
+class HArgumentsElements: public HTemplateInstruction<0> {
  public:
   HArgumentsElements() {
     // The value produced by this instruction is a pointer into the stack
@@ -2108,18 +2092,18 @@ class HArgumentsLength: public HUnaryOperation {
     SetFlag(kUseGVN);
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length")
-
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
 
+  DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length")
+
  protected:
   virtual bool DataEquals(HValue* other) { return true; }
 };
 
 
-class HAccessArgumentsAt: public HInstruction {
+class HAccessArgumentsAt: public HTemplateInstruction<3> {
  public:
   HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
     set_representation(Representation::Tagged());
@@ -2138,24 +2122,13 @@ class HAccessArgumentsAt: public HInstruction {
         : Representation::Integer32();
   }
 
-  HValue* arguments() { return operands_[0]; }
-  HValue* length() { return operands_[1]; }
-  HValue* index() { return operands_[2]; }
-
-  virtual int OperandCount() { return operands_.length(); }
-  virtual HValue* OperandAt(int index) { return operands_[index]; }
+  HValue* arguments() { return OperandAt(0); }
+  HValue* length() { return OperandAt(1); }
+  HValue* index() { return OperandAt(2); }
 
   DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access_arguments_at")
 
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value) {
-    operands_[index] = value;
-  }
-
   virtual bool DataEquals(HValue* other) { return true; }
-
- private:
-  HOperandVector<3> operands_;
 };
 
 
@@ -2373,7 +2346,7 @@ class HIsSmi: public HUnaryPredicate {
 };
 
 
-class HIsConstructCall: public HInstruction {
+class HIsConstructCall: public HTemplateInstruction<0> {
  public:
   HIsConstructCall() {
     set_representation(Representation::Tagged());
@@ -2488,7 +2461,7 @@ class HTypeofIs: public HUnaryPredicate {
 };
 
 
-class HInstanceOf: public HInstruction {
+class HInstanceOf: public HTemplateInstruction<3> {
  public:
   HInstanceOf(HValue* context, HValue* left, HValue* right) {
     SetOperandAt(0, context);
@@ -2498,9 +2471,9 @@ class HInstanceOf: public HInstruction {
     SetAllSideEffects();
   }
 
-  HValue* context() { return operands_[0]; }
-  HValue* left() { return operands_[1]; }
-  HValue* right() { return operands_[2]; }
+  HValue* context() { return OperandAt(0); }
+  HValue* left() { return OperandAt(1); }
+  HValue* right() { return OperandAt(2); }
 
   virtual bool EmitAtUses() const {
     return !HasSideEffects() && (uses()->length() <= 1);
@@ -2512,18 +2485,7 @@ class HInstanceOf: public HInstruction {
 
   virtual void PrintDataTo(StringStream* stream);
 
-  virtual int OperandCount() { return 3; }
-  virtual HValue* OperandAt(int index) { return operands_[index]; }
-
   DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance_of")
-
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value) {
-    operands_[index] = value;
-  }
-
- private:
-  HOperandVector<3> operands_;
 };
 
 
@@ -2760,7 +2722,7 @@ class HSar: public HBitwiseBinaryOperation {
 };
 
 
-class HOsrEntry: public HInstruction {
+class HOsrEntry: public HTemplateInstruction<0> {
  public:
   explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
     SetFlag(kChangesOsrEntries);
@@ -2779,7 +2741,7 @@ class HOsrEntry: public HInstruction {
 };
 
 
-class HParameter: public HInstruction {
+class HParameter: public HTemplateInstruction<0> {
  public:
   explicit HParameter(unsigned index) : index_(index) {
     set_representation(Representation::Tagged());
@@ -2833,7 +2795,7 @@ class HCallStub: public HUnaryCall {
 };
 
 
-class HUnknownOSRValue: public HInstruction {
+class HUnknownOSRValue: public HTemplateInstruction<0> {
  public:
   HUnknownOSRValue() { set_representation(Representation::Tagged()); }
 
@@ -2845,7 +2807,7 @@ class HUnknownOSRValue: public HInstruction {
 };
 
 
-class HLoadGlobal: public HInstruction {
+class HLoadGlobal: public HTemplateInstruction<0> {
  public:
   HLoadGlobal(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
       : cell_(cell), check_hole_value_(check_hole_value) {
@@ -3056,37 +3018,25 @@ class HLoadFunctionPrototype: public HUnaryOperation {
 };
 
 
-class HLoadKeyed: public HBinaryOperation {
+class HLoadKeyedFastElement: public HBinaryOperation {
  public:
-  HLoadKeyed(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
+  HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
     set_representation(Representation::Tagged());
+    SetFlag(kDependsOnArrayElements);
+    SetFlag(kUseGVN);
   }
 
-  virtual void PrintDataTo(StringStream* stream);
-
-  virtual Representation RequiredInputRepresentation(int index) const {
-    return Representation::Tagged();
-  }
   HValue* object() { return OperandAt(0); }
   HValue* key() { return OperandAt(1); }
 
-  DECLARE_INSTRUCTION(LoadKeyed)
-};
-
-
-class HLoadKeyedFastElement: public HLoadKeyed {
- public:
-  HLoadKeyedFastElement(HValue* obj, HValue* key) : HLoadKeyed(obj, key) {
-    SetFlag(kDependsOnArrayElements);
-    SetFlag(kUseGVN);
-  }
-
   virtual Representation RequiredInputRepresentation(int index) const {
     // The key is supposed to be Integer32.
     return (index == 1) ? Representation::Integer32()
         : Representation::Tagged();
   }
 
+  virtual void PrintDataTo(StringStream* stream);
+
   DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement,
                                "load_keyed_fast_element")
 
@@ -3126,65 +3076,39 @@ class HLoadPixelArrayElement: public HBinaryOperation {
 };
 
 
-class HLoadKeyedGeneric: public HLoadKeyed {
+class HLoadKeyedGeneric: public HTemplateInstruction<3> {
  public:
-  HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key)
-      : HLoadKeyed(obj, key), context_(NULL) {
+  HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
+    set_representation(Representation::Tagged());
+    SetOperandAt(0, obj);
+    SetOperandAt(1, key);
     SetOperandAt(2, context);
     SetAllSideEffects();
   }
 
-  HValue* context() const { return context_; }
-  HValue* object() { return operands_[0]; }
-  HValue* key() { return operands_[1]; }
-
-  virtual int OperandCount() { return 3; }
-  virtual HValue* OperandAt(int index) {
-    return (index < 2) ? operands_[index] : context_;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
-
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value);
-
- private:
-  HValue* context_;
-};
-
+  HValue* object() { return OperandAt(0); }
+  HValue* key() { return OperandAt(1); }
+  HValue* context() { return OperandAt(2); }
 
-class HStoreNamed: public HBinaryOperation {
- public:
-  HStoreNamed(HValue* obj, Handle<String> name, HValue* val)
-      : HBinaryOperation(obj, val), name_(name) {
-  }
+  virtual void PrintDataTo(StringStream* stream);
 
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
 
-  virtual void PrintDataTo(StringStream* stream);
-
-  HValue* object() { return OperandAt(0); }
-  Handle<String> name() const { return name_; }
-  HValue* value() { return OperandAt(1); }
-  void set_value(HValue* value) { SetOperandAt(1, value); }
-
-  DECLARE_INSTRUCTION(StoreNamed)
-
- private:
-  Handle<String> name_;
+  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
 };
 
 
-class HStoreNamedField: public HStoreNamed {
+class HStoreNamedField: public HBinaryOperation {
  public:
   HStoreNamedField(HValue* obj,
                    Handle<String> name,
                    HValue* val,
                    bool in_object,
                    int offset)
-      : HStoreNamed(obj, name, val),
+      : HBinaryOperation(obj, val),
+        name_(name),
         is_in_object_(in_object),
         offset_(offset) {
     if (is_in_object_) {
@@ -3201,6 +3125,10 @@ class HStoreNamedField: public HStoreNamed {
   }
   virtual void PrintDataTo(StringStream* stream);
 
+  HValue* object() { return OperandAt(0); }
+  HValue* value() { return OperandAt(1); }
+
+  Handle<String> name() const { return name_; }
   bool is_in_object() const { return is_in_object_; }
   int offset() const { return offset_; }
   Handle<Map> transition() const { return transition_; }
@@ -3211,57 +3139,57 @@ class HStoreNamedField: public HStoreNamed {
   }
 
  private:
+  Handle<String> name_;
   bool is_in_object_;
   int offset_;
   Handle<Map> transition_;
 };
 
 
-class HStoreNamedGeneric: public HStoreNamed {
+class HStoreNamedGeneric: public HTemplateInstruction<3> {
  public:
   HStoreNamedGeneric(HValue* context,
                      HValue* object,
                      Handle<String> name,
                      HValue* value)
-      : HStoreNamed(object, name, value), context_(NULL) {
+      : name_(name) {
+    SetOperandAt(0, object);
+    SetOperandAt(1, value);
     SetOperandAt(2, context);
     SetAllSideEffects();
   }
 
-  HValue* context() const { return context_; }
-  HValue* object() const { return operands_[0]; }
-  HValue* value() const { return operands_[1]; }
+  HValue* object() { return OperandAt(0); }
+  HValue* value() { return OperandAt(1); }
+  HValue* context() { return OperandAt(2); }
+  Handle<String> name() { return name_; }
 
-  virtual int OperandCount() { return 3; }
+  virtual void PrintDataTo(StringStream* stream);
 
-  virtual HValue* OperandAt(int index) {
-    return (index < 2) ? operands_[index] : context_;
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
 
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value);
-
  private:
-  HValue* context_;
+  Handle<String> name_;
 };
 
 
-class HStoreKeyed: public HInstruction {
+class HStoreKeyedFastElement: public HTemplateInstruction<3> {
  public:
-  HStoreKeyed(HValue* obj, HValue* key, HValue* val) {
+  HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
     SetOperandAt(0, obj);
     SetOperandAt(1, key);
     SetOperandAt(2, val);
+    SetFlag(kChangesArrayElements);
   }
 
-  virtual void PrintDataTo(StringStream* stream);
-  virtual int OperandCount() { return operands_.length(); }
-  virtual HValue* OperandAt(int index) { return operands_[index]; }
-
   virtual Representation RequiredInputRepresentation(int index) const {
-    return Representation::Tagged();
+    // The key is supposed to be Integer32.
+    return (index == 1) ? Representation::Integer32()
+        : Representation::Tagged();
   }
 
   HValue* object() { return OperandAt(0); }
@@ -3272,36 +3200,14 @@ class HStoreKeyed: public HInstruction {
     return StoringValueNeedsWriteBarrier(value());
   }
 
-  DECLARE_INSTRUCTION(StoreKeyed)
-
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value) {
-    operands_[index] = value;
-  }
-
-  HOperandVector<3> operands_;
-};
-
-
-class HStoreKeyedFastElement: public HStoreKeyed {
- public:
-  HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val)
-      : HStoreKeyed(obj, key, val) {
-    SetFlag(kChangesArrayElements);
-  }
-
-  virtual Representation RequiredInputRepresentation(int index) const {
-    // The key is supposed to be Integer32.
-    return (index == 1) ? Representation::Integer32()
-        : Representation::Tagged();
-  }
+  virtual void PrintDataTo(StringStream* stream);
 
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
                                "store_keyed_fast_element")
 };
 
 
-class HStorePixelArrayElement: public HInstruction {
+class HStorePixelArrayElement: public HTemplateInstruction<3> {
  public:
   HStorePixelArrayElement(HValue* external_elements, HValue* key, HValue* val) {
     SetFlag(kChangesPixelArrayElements);
@@ -3311,8 +3217,6 @@ class HStorePixelArrayElement: public HInstruction {
   }
 
   virtual void PrintDataTo(StringStream* stream);
-  virtual int OperandCount() { return operands_.length(); }
-  virtual HValue* OperandAt(int index) { return operands_[index]; }
 
   virtual Representation RequiredInputRepresentation(int index) const {
     if (index == 0) {
@@ -3322,51 +3226,40 @@ class HStorePixelArrayElement: public HInstruction {
     }
   }
 
-  HValue* external_pointer() { return operands_[0]; }
-  HValue* key() { return operands_[1]; }
-  HValue* value() { return operands_[2]; }
+  HValue* external_pointer() { return OperandAt(0); }
+  HValue* key() { return OperandAt(1); }
+  HValue* value() { return OperandAt(2); }
 
   DECLARE_CONCRETE_INSTRUCTION(StorePixelArrayElement,
                                "store_pixel_array_element")
-
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value) {
-    operands_[index] = value;
-  }
-
-  HOperandVector<3> operands_;
 };
 
 
-class HStoreKeyedGeneric: public HStoreKeyed {
+class HStoreKeyedGeneric: public HTemplateInstruction<4> {
  public:
   HStoreKeyedGeneric(HValue* context,
                      HValue* object,
                      HValue* key,
-                     HValue* value)
-      : HStoreKeyed(object, key, value), context_(NULL) {
+                     HValue* value) {
+    SetOperandAt(0, object);
+    SetOperandAt(1, key);
+    SetOperandAt(2, value);
     SetOperandAt(3, context);
     SetAllSideEffects();
   }
 
-  HValue* context() { return context_; }
-  HValue* object() { return operands_[0]; }
-  HValue* key() { return operands_[1]; }
-  HValue* value() { return operands_[2]; }
-
-  virtual int OperandCount() { return 4; }
+  HValue* object() { return OperandAt(0); }
+  HValue* key() { return OperandAt(1); }
+  HValue* value() { return OperandAt(2); }
+  HValue* context() { return OperandAt(3); }
 
-  virtual HValue* OperandAt(int index) {
-    return (index < 3) ? operands_[index] : context_;
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
-
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value);
+  virtual void PrintDataTo(StringStream* stream);
 
- private:
-  HValue* context_;
+  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
 };
 
 
@@ -3425,31 +3318,30 @@ class HStringLength: public HUnaryOperation {
 };
 
 
-class HMaterializedLiteral: public HInstruction {
+template <int V>
+class HMaterializedLiteral: public HTemplateInstruction<V> {
  public:
-  HMaterializedLiteral(int index, int depth)
+  HMaterializedLiteral<V>(int index, int depth)
       : literal_index_(index), depth_(depth) {
-    set_representation(Representation::Tagged());
+    this->set_representation(Representation::Tagged());
   }
 
   int literal_index() const { return literal_index_; }
   int depth() const { return depth_; }
 
-  DECLARE_INSTRUCTION(MaterializedLiteral)
-
  private:
   int literal_index_;
   int depth_;
 };
 
 
-class HArrayLiteral: public HMaterializedLiteral {
+class HArrayLiteral: public HMaterializedLiteral<0> {
  public:
   HArrayLiteral(Handle<FixedArray> constant_elements,
                 int length,
                 int literal_index,
                 int depth)
-      : HMaterializedLiteral(literal_index, depth),
+      : HMaterializedLiteral<0>(literal_index, depth),
         length_(length),
         constant_elements_(constant_elements) {}
 
@@ -3470,53 +3362,43 @@ class HArrayLiteral: public HMaterializedLiteral {
 };
 
 
-class HObjectLiteral: public HMaterializedLiteral {
+class HObjectLiteral: public HMaterializedLiteral<1> {
  public:
   HObjectLiteral(HValue* context,
                  Handle<FixedArray> constant_properties,
                  bool fast_elements,
                  int literal_index,
                  int depth)
-      : HMaterializedLiteral(literal_index, depth),
-        context_(NULL),
+      : HMaterializedLiteral<1>(literal_index, depth),
         constant_properties_(constant_properties),
         fast_elements_(fast_elements) {
     SetOperandAt(0, context);
   }
 
-  HValue* context() const { return context_; }
+  HValue* context() { return OperandAt(0); }
   Handle<FixedArray> constant_properties() const {
     return constant_properties_;
   }
   bool fast_elements() const { return fast_elements_; }
 
-  virtual int OperandCount() { return 1; }
-  virtual HValue* OperandAt(int index) { return context_; }
-
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object_literal")
 
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value) {
-    context_ = value;
-  }
-
  private:
-  HValue* context_;
   Handle<FixedArray> constant_properties_;
   bool fast_elements_;
 };
 
 
-class HRegExpLiteral: public HMaterializedLiteral {
+class HRegExpLiteral: public HMaterializedLiteral<0> {
  public:
   HRegExpLiteral(Handle<String> pattern,
                  Handle<String> flags,
                  int literal_index)
-      : HMaterializedLiteral(literal_index, 0),
+      : HMaterializedLiteral<0>(literal_index, 0),
         pattern_(pattern),
         flags_(flags) { }
 
@@ -3535,7 +3417,7 @@ class HRegExpLiteral: public HMaterializedLiteral {
 };
 
 
-class HFunctionLiteral: public HInstruction {
+class HFunctionLiteral: public HTemplateInstruction<0> {
  public:
   HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
       : shared_info_(shared), pretenure_(pretenure) {
index e9e3926..5a1049b 100644 (file)
@@ -2258,7 +2258,8 @@ void HGraphBuilder::PushAndAdd(HInstruction* instr) {
 }
 
 
-void HGraphBuilder::PreProcessCall(HCall* call) {
+template <int V>
+HInstruction* HGraphBuilder::PreProcessCall(HCall<V>* call) {
   int count = call->argument_count();
   ZoneList<HValue*> arguments(count);
   for (int i = 0; i < count; ++i) {
@@ -2268,6 +2269,7 @@ void HGraphBuilder::PreProcessCall(HCall* call) {
   while (!arguments.is_empty()) {
     AddInstruction(new HPushArgument(arguments.RemoveLast()));
   }
+  return call;
 }
 
 
@@ -3951,7 +3953,8 @@ void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
         // Check for bailout, as trying to inline might fail due to bailout
         // during hydrogen processing.
         CHECK_BAILOUT;
-        HCall* call = new HCallConstantFunction(expr->target(), argument_count);
+        HCallConstantFunction* call =
+          new HCallConstantFunction(expr->target(), argument_count);
         call->set_position(expr->position());
         PreProcessCall(call);
         PushAndAdd(call);
@@ -3968,7 +3971,7 @@ void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
   if (maps.length() == 0) {
     HContext* context = new HContext;
     AddInstruction(context);
-    HCall* call = new HCallNamed(context, name, argument_count);
+    HCallNamed* call = new HCallNamed(context, name, argument_count);
     call->set_position(expr->position());
     PreProcessCall(call);
     ast_context()->ReturnInstruction(call, expr->id());
@@ -3981,7 +3984,7 @@ void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
       } else {
         HContext* context = new HContext;
         AddInstruction(context);
-        HCall* call = new HCallNamed(context, name, argument_count);
+        HCallNamed* call = new HCallNamed(context, name, argument_count);
         call->set_position(expr->position());
         PreProcessCall(call);
         PushAndAdd(call);
@@ -4382,7 +4385,7 @@ static bool HasCustomCallGenerator(Handle<JSFunction> function) {
 void HGraphBuilder::VisitCall(Call* expr) {
   Expression* callee = expr->expression();
   int argument_count = expr->arguments()->length() + 1;  // Plus receiver.
-  HCall* call = NULL;
+  HInstruction* call = NULL;
 
   Property* prop = callee->AsProperty();
   if (prop != NULL) {
@@ -4402,9 +4405,8 @@ void HGraphBuilder::VisitCall(Call* expr) {
 
       HContext* context = new HContext;
       AddInstruction(context);
-      call = new HCallKeyed(context, key, argument_count);
+      call = PreProcessCall(new HCallKeyed(context, key, argument_count));
       call->set_position(expr->position());
-      PreProcessCall(call);
       Drop(1);  // Key.
       ast_context()->ReturnInstruction(call, expr->id());
       return;
@@ -4444,7 +4446,7 @@ void HGraphBuilder::VisitCall(Call* expr) {
         // IC when a primitive receiver check is required.
         HContext* context = new HContext;
         AddInstruction(context);
-        call = new HCallNamed(context, name, argument_count);
+        call = PreProcessCall(new HCallNamed(context, name, argument_count));
       } else {
         AddCheckConstantFunction(expr, receiver, receiver_map, true);
 
@@ -4464,7 +4466,8 @@ void HGraphBuilder::VisitCall(Call* expr) {
           // Check for bailout, as the TryInline call in the if condition above
           // might return false due to bailout during hydrogen processing.
           CHECK_BAILOUT;
-          call = new HCallConstantFunction(expr->target(), argument_count);
+          call = PreProcessCall(new HCallConstantFunction(expr->target(),
+                                                          argument_count));
         }
       }
     } else if (types != NULL && types->length() > 1) {
@@ -4475,7 +4478,7 @@ void HGraphBuilder::VisitCall(Call* expr) {
     } else {
       HContext* context = new HContext;
       AddInstruction(context);
-      call = new HCallNamed(context, name, argument_count);
+      call = PreProcessCall(new HCallNamed(context, name, argument_count));
     }
 
   } else {
@@ -4536,7 +4539,8 @@ void HGraphBuilder::VisitCall(Call* expr) {
         // during hydrogen processing.
         CHECK_BAILOUT;
 
-        call = new HCallKnownGlobal(expr->target(), argument_count);
+        call = PreProcessCall(new HCallKnownGlobal(expr->target(),
+                                                   argument_count));
       } else {
         HContext* context = new HContext;
         AddInstruction(context);
@@ -4544,7 +4548,9 @@ void HGraphBuilder::VisitCall(Call* expr) {
         VisitExpressions(expr->arguments());
         CHECK_BAILOUT;
 
-        call = new HCallGlobal(context, var->name(), argument_count);
+        call = PreProcessCall(new HCallGlobal(context,
+                                              var->name(),
+                                              argument_count));
       }
 
     } else {
@@ -4556,12 +4562,11 @@ void HGraphBuilder::VisitCall(Call* expr) {
       VisitExpressions(expr->arguments());
       CHECK_BAILOUT;
 
-      call = new HCallFunction(context, argument_count);
+      call = PreProcessCall(new HCallFunction(context, argument_count));
     }
   }
 
   call->set_position(expr->position());
-  PreProcessCall(call);
   ast_context()->ReturnInstruction(call, expr->id());
 }
 
@@ -4580,7 +4585,7 @@ void HGraphBuilder::VisitCallNew(CallNew* expr) {
   // to the construct call.
   int arg_count = expr->arguments()->length() + 1;  // Plus constructor.
   HValue* constructor = environment()->ExpressionStackAt(arg_count - 1);
-  HCall* call = new HCallNew(context, constructor, arg_count);
+  HCallNew* call = new HCallNew(context, constructor, arg_count);
   call->set_position(expr->position());
   PreProcessCall(call);
   ast_context()->ReturnInstruction(call, expr->id());
@@ -4629,7 +4634,7 @@ void HGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
 
     Handle<String> name = expr->name();
     int argument_count = expr->arguments()->length();
-    HCall* call = new HCallRuntime(name, function, argument_count);
+    HCallRuntime* call = new HCallRuntime(name, function, argument_count);
     call->set_position(RelocInfo::kNoPosition);
     Drop(argument_count);
     ast_context()->ReturnInstruction(call, expr->id());
index e6e3a02..19049c3 100644 (file)
@@ -729,7 +729,7 @@ class HGraphBuilder: public AstVisitor {
 
   // Remove the arguments from the bailout environment and emit instructions
   // to push them as outgoing parameters.
-  void PreProcessCall(HCall* call);
+  template <int V> HInstruction* PreProcessCall(HCall<V>* call);
 
   void AssumeRepresentation(HValue* value, Representation r);
   static Representation ToRepresentation(TypeInfo info);
index f009167..221a7aa 100644 (file)
@@ -404,7 +404,7 @@ void LChunk::MarkEmptyBlocks() {
 }
 
 
-void LStoreNamed::PrintDataTo(StringStream* stream) {
+void LStoreNamedField::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
   stream->Add(".");
   stream->Add(*String::cast(*name())->ToCString());
@@ -413,7 +413,25 @@ void LStoreNamed::PrintDataTo(StringStream* stream) {
 }
 
 
-void LStoreKeyed::PrintDataTo(StringStream* stream) {
+void LStoreNamedGeneric::PrintDataTo(StringStream* stream) {
+  object()->PrintTo(stream);
+  stream->Add(".");
+  stream->Add(*String::cast(*name())->ToCString());
+  stream->Add(" <- ");
+  value()->PrintTo(stream);
+}
+
+
+void LStoreKeyedFastElement::PrintDataTo(StringStream* stream) {
+  object()->PrintTo(stream);
+  stream->Add("[");
+  key()->PrintTo(stream);
+  stream->Add("] <- ");
+  value()->PrintTo(stream);
+}
+
+
+void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
   stream->Add("[");
   key()->PrintTo(stream);
index 2acd0c1..ad0b0ca 100644 (file)
@@ -42,8 +42,6 @@ class LCodeGen;
 #define LITHIUM_ALL_INSTRUCTION_LIST(V)         \
   V(ControlInstruction)                         \
   V(Call)                                       \
-  V(StoreKeyed)                                 \
-  V(StoreNamed)                                 \
   LITHIUM_CONCRETE_INSTRUCTION_LIST(V)
 
 
@@ -1581,34 +1579,23 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
 };
 
 
-class LStoreNamed: public LTemplateInstruction<0, 2, 1> {
+class LStoreNamedField: public LTemplateInstruction<0, 2, 1> {
  public:
-  LStoreNamed(LOperand* obj, LOperand* val) {
+  LStoreNamedField(LOperand* obj, LOperand* val, LOperand* temp) {
     inputs_[0] = obj;
     inputs_[1] = val;
+    temps_[0] = temp;
   }
 
-  DECLARE_INSTRUCTION(StoreNamed)
-  DECLARE_HYDROGEN_ACCESSOR(StoreNamed)
+  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
+  DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
 
   virtual void PrintDataTo(StringStream* stream);
 
   LOperand* object() { return inputs_[0]; }
   LOperand* value() { return inputs_[1]; }
-  Handle<Object> name() const { return hydrogen()->name(); }
-};
-
-
-class LStoreNamedField: public LStoreNamed {
- public:
-  LStoreNamedField(LOperand* obj, LOperand* val, LOperand* temp)
-      : LStoreNamed(obj, val) {
-    temps_[0] = temp;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
-  DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
 
+  Handle<Object> name() const { return hydrogen()->name(); }
   bool is_in_object() { return hydrogen()->is_in_object(); }
   int offset() { return hydrogen()->offset(); }
   bool needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); }
@@ -1627,6 +1614,8 @@ class LStoreNamedGeneric: public LTemplateInstruction<0, 3, 0> {
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
 
+  virtual void PrintDataTo(StringStream* stream);
+
   LOperand* context() { return inputs_[0]; }
   LOperand* object() { return inputs_[1]; }
   LOperand* value() { return inputs_[2]; }
@@ -1634,15 +1623,17 @@ class LStoreNamedGeneric: public LTemplateInstruction<0, 3, 0> {
 };
 
 
-class LStoreKeyed: public LTemplateInstruction<0, 3, 0> {
+class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> {
  public:
-  LStoreKeyed(LOperand* obj, LOperand* key, LOperand* val) {
+  LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val) {
     inputs_[0] = obj;
     inputs_[1] = key;
     inputs_[2] = val;
   }
 
-  DECLARE_INSTRUCTION(StoreKeyed)
+  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
+                               "store-keyed-fast-element")
+  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
 
   virtual void PrintDataTo(StringStream* stream);
 
@@ -1652,17 +1643,6 @@ class LStoreKeyed: public LTemplateInstruction<0, 3, 0> {
 };
 
 
-class LStoreKeyedFastElement: public LStoreKeyed {
- public:
-  LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val)
-      : LStoreKeyed(obj, key, val) {}
-
-  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
-                               "store-keyed-fast-element")
-  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
-};
-
-
 class LStorePixelArrayElement: public LTemplateInstruction<0, 3, 1> {
  public:
   LStorePixelArrayElement(LOperand* external_pointer,
@@ -1699,6 +1679,8 @@ class LStoreKeyedGeneric: public LTemplateInstruction<0, 4, 0> {
 
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
 
+  virtual void PrintDataTo(StringStream* stream);
+
   LOperand* context() { return inputs_[0]; }
   LOperand* object() { return inputs_[1]; }
   LOperand* key() { return inputs_[2]; }
index c8f7b91..bfa3ed4 100644 (file)
@@ -405,7 +405,7 @@ void LChunk::MarkEmptyBlocks() {
 }
 
 
-void LStoreNamed::PrintDataTo(StringStream* stream) {
+void LStoreNamedField::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
   stream->Add(".");
   stream->Add(*String::cast(*name())->ToCString());
@@ -414,7 +414,25 @@ void LStoreNamed::PrintDataTo(StringStream* stream) {
 }
 
 
-void LStoreKeyed::PrintDataTo(StringStream* stream) {
+void LStoreNamedGeneric::PrintDataTo(StringStream* stream) {
+  object()->PrintTo(stream);
+  stream->Add(".");
+  stream->Add(*String::cast(*name())->ToCString());
+  stream->Add(" <- ");
+  value()->PrintTo(stream);
+}
+
+
+void LStoreKeyedFastElement::PrintDataTo(StringStream* stream) {
+  object()->PrintTo(stream);
+  stream->Add("[");
+  key()->PrintTo(stream);
+  stream->Add("] <- ");
+  value()->PrintTo(stream);
+}
+
+
+void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
   stream->Add("[");
   key()->PrintTo(stream);
index 0907240..c37ffb8 100644 (file)
@@ -42,8 +42,6 @@ class LCodeGen;
 #define LITHIUM_ALL_INSTRUCTION_LIST(V)         \
   V(ControlInstruction)                         \
   V(Call)                                       \
-  V(StoreKeyed)                                 \
-  V(StoreNamed)                                 \
   LITHIUM_CONCRETE_INSTRUCTION_LIST(V)
 
 
@@ -1491,34 +1489,23 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
 };
 
 
-class LStoreNamed: public LTemplateInstruction<0, 2, 1> {
+class LStoreNamedField: public LTemplateInstruction<0, 2, 1> {
  public:
-  LStoreNamed(LOperand* object, LOperand* value) {
+  LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) {
     inputs_[0] = object;
     inputs_[1] = value;
+    temps_[0] = temp;
   }
 
-  DECLARE_INSTRUCTION(StoreNamed)
-  DECLARE_HYDROGEN_ACCESSOR(StoreNamed)
+  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
+  DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
 
   virtual void PrintDataTo(StringStream* stream);
 
   LOperand* object() { return inputs_[0]; }
   LOperand* value() { return inputs_[1]; }
-  Handle<Object> name() const { return hydrogen()->name(); }
-};
-
-
-class LStoreNamedField: public LStoreNamed {
- public:
-  LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp)
-      : LStoreNamed(object, value) {
-    temps_[0] = temp;
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
-  DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
 
+  Handle<Object> name() const { return hydrogen()->name(); }
   bool is_in_object() { return hydrogen()->is_in_object(); }
   int offset() { return hydrogen()->offset(); }
   bool needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); }
@@ -1526,25 +1513,35 @@ class LStoreNamedField: public LStoreNamed {
 };
 
 
-class LStoreNamedGeneric: public LStoreNamed {
+class LStoreNamedGeneric: public LTemplateInstruction<0, 2, 0> {
  public:
-  LStoreNamedGeneric(LOperand* object, LOperand* value)
-      : LStoreNamed(object, value) { }
+  LStoreNamedGeneric(LOperand* object, LOperand* value) {
+    inputs_[0] = object;
+    inputs_[1] = value;
+  }
 
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  LOperand* object() { return inputs_[0]; }
+  LOperand* value() { return inputs_[1]; }
+  Handle<Object> name() const { return hydrogen()->name(); }
 };
 
 
-class LStoreKeyed: public LTemplateInstruction<0, 3, 0> {
+class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> {
  public:
-  LStoreKeyed(LOperand* obj, LOperand* key, LOperand* val) {
+  LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val) {
     inputs_[0] = obj;
     inputs_[1] = key;
     inputs_[2] = val;
   }
 
-  DECLARE_INSTRUCTION(StoreKeyed)
+  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
+                               "store-keyed-fast-element")
+  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
 
   virtual void PrintDataTo(StringStream* stream);
 
@@ -1554,17 +1551,6 @@ class LStoreKeyed: public LTemplateInstruction<0, 3, 0> {
 };
 
 
-class LStoreKeyedFastElement: public LStoreKeyed {
- public:
-  LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val)
-      : LStoreKeyed(obj, key, val) {}
-
-  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
-                               "store-keyed-fast-element")
-  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
-};
-
-
 class LStorePixelArrayElement: public LTemplateInstruction<0, 3, 0> {
  public:
   LStorePixelArrayElement(LOperand* external_pointer,
@@ -1585,12 +1571,21 @@ class LStorePixelArrayElement: public LTemplateInstruction<0, 3, 0> {
 };
 
 
-class LStoreKeyedGeneric: public LStoreKeyed {
+class LStoreKeyedGeneric: public LTemplateInstruction<0, 3, 0> {
  public:
-  LStoreKeyedGeneric(LOperand* object, LOperand* key, LOperand* value)
-      : LStoreKeyed(object, key, value) { }
+  LStoreKeyedGeneric(LOperand* object, LOperand* key, LOperand* value) {
+    inputs_[0] = object;
+    inputs_[1] = key;
+    inputs_[2] = value;
+  }
 
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  LOperand* object() { return inputs_[0]; }
+  LOperand* key() { return inputs_[1]; }
+  LOperand* value() { return inputs_[2]; }
 };