Remove the uses of the arguments from all calls.
authorkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 11 Feb 2011 13:20:06 +0000 (13:20 +0000)
committerkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 11 Feb 2011 13:20:06 +0000 (13:20 +0000)
Before, Hydrogen call instructions had uses of the PushArgument instructions
for their arguments.  These operands were unneeded, bloated the IR, and
caused calls to be the only Hydrogen instructions with an unpredictable
number of operands.

Now, PushArgument is a pure side-effecting instruction that has no uses.

Review URL: http://codereview.chromium.org/6480030

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

src/hydrogen-instructions.cc
src/hydrogen-instructions.h
src/hydrogen.cc
src/hydrogen.h

index 241a01524dcc0d839426cd233dd0eca50a821dfe..4e43e35603c82f96ef4c62ded362cac8cc4baa4f 100644 (file)
@@ -290,61 +290,6 @@ void HLoadKeyedGeneric::InternalSetOperandAt(int index, HValue* value) {
 }
 
 
-void HCallKeyed::InternalSetOperandAt(int index, HValue* value) {
-  // The key and all the arguments are stored in the base class's arguments_
-  // vector.  The context is in the object itself.  Ugly.
-  if (index <= argument_count()) {
-    arguments_[index] = value;
-  } else {
-    context_ = value;
-  }
-}
-
-
-void HCallNamed::InternalSetOperandAt(int index, HValue* value) {
-  // The arguments are in the base class's arguments_ vector.  The context
-  // is in the object itself.
-  if (index < argument_count()) {
-    arguments_[index] = value;
-  } else {
-    context_ = value;
-  }
-}
-
-
-void HCallFunction::InternalSetOperandAt(int index, HValue* value) {
-  // The arguments are in the base class's arguments_ vector.  The context
-  // is in the object itself.
-  if (index < argument_count()) {
-    arguments_[index] = value;
-  } else {
-    context_ = value;
-  }
-}
-
-
-void HCallGlobal::InternalSetOperandAt(int index, HValue* value) {
-  // The arguments are in the base class's arguments_ vector.  The context
-  // is in the object itself.
-  if (index < argument_count()) {
-    arguments_[index] = value;
-  } else {
-    context_ = value;
-  }
-}
-
-
-void HCallNew::InternalSetOperandAt(int index, HValue* value) {
-  // The arguments are in the base class's arguments_ vector.  The context
-  // is in the object itself.
-  if (index < argument_count()) {
-    arguments_[index] = value;
-  } else {
-    context_ = value;
-  }
-}
-
-
 void HStoreKeyedGeneric::InternalSetOperandAt(int index, HValue* value) {
   if (index < 3) {
     operands_[index] = value;
@@ -609,26 +554,64 @@ void HInstruction::Verify() {
 #endif
 
 
-HCall::HCall(int count) : arguments_(Zone::NewArray<HValue*>(count), count) {
-  for (int i = 0; i < count; ++i) arguments_[i] = NULL;
-  set_representation(Representation::Tagged());
-  SetAllSideEffects();
+void HCall::PrintDataTo(StringStream* stream) const {
+  stream->Add("#%d", argument_count());
 }
 
 
-void HCall::PrintDataTo(StringStream* stream) const {
-  stream->Add("(");
-  for (int i = 0; i < arguments_.length(); ++i) {
-    if (i != 0) stream->Add(", ");
-    arguments_.at(i)->PrintNameTo(stream);
+void HUnaryCall::PrintDataTo(StringStream* stream) const {
+  value()->PrintNameTo(stream);
+  stream->Add(" ");
+  HCall::PrintDataTo(stream);
+}
+
+
+void HBinaryCall::PrintDataTo(StringStream* stream) const {
+  first()->PrintNameTo(stream);
+  stream->Add(" ");
+  second()->PrintNameTo(stream);
+  stream->Add(" ");
+  HCall::PrintDataTo(stream);
+}
+
+
+void HCallConstantFunction::PrintDataTo(StringStream* stream) const {
+  if (IsApplyFunction()) {
+    stream->Add("optimized apply ");
+  } else {
+    stream->Add("%o ", function()->shared()->DebugName());
   }
-  stream->Add(")");
+  HCall::PrintDataTo(stream);
+}
+
+
+void HCallNamed::PrintDataTo(StringStream* stream) const {
+  stream->Add("%o ", *name());
+  HUnaryCall::PrintDataTo(stream);
+}
+
+
+void HCallGlobal::PrintDataTo(StringStream* stream) const {
+  stream->Add("%o ", *name());
+  HUnaryCall::PrintDataTo(stream);
+}
+
+
+void HCallKnownGlobal::PrintDataTo(StringStream* stream) const {
+  stream->Add("o ", target()->shared()->DebugName());
+  HCall::PrintDataTo(stream);
+}
+
+
+void HCallRuntime::PrintDataTo(StringStream* stream) const {
+  stream->Add("%o ", *name());
+  HCall::PrintDataTo(stream);
 }
 
 
 void HClassOfTest::PrintDataTo(StringStream* stream) const {
   stream->Add("class_of_test(");
-  value()->PrintTo(stream);
+  value()->PrintNameTo(stream);
   stream->Add(", \"%o\")", *class_name());
 }
 
@@ -642,22 +625,6 @@ void HAccessArgumentsAt::PrintDataTo(StringStream* stream) const {
 }
 
 
-void HCall::SetArgumentAt(int index, HPushArgument* push_argument) {
-  push_argument->set_argument_index(index);
-  SetOperandAt(index, push_argument);
-}
-
-
-void HCallConstantFunction::PrintDataTo(StringStream* stream) const {
-  if (IsApplyFunction()) {
-    stream->Add("SPECIAL function: apply");
-  } else {
-    stream->Add("%s", *(function()->shared()->DebugName()->ToCString()));
-  }
-  HCall::PrintDataTo(stream);
-}
-
-
 void HControlInstruction::PrintDataTo(StringStream* stream) const {
   if (FirstSuccessor() != NULL) {
     int first_id = FirstSuccessor()->block_id();
@@ -745,14 +712,6 @@ void HTypeofIs::PrintDataTo(StringStream* stream) const {
 }
 
 
-void HPushArgument::PrintDataTo(StringStream* stream) const {
-  HUnaryOperation::PrintDataTo(stream);
-  if (argument_index() != -1) {
-    stream->Add(" [%d]", argument_index_);
-  }
-}
-
-
 void HChange::PrintDataTo(StringStream* stream) const {
   HUnaryOperation::PrintDataTo(stream);
   stream->Add(" %s to %s", from_.Mnemonic(), to_.Mnemonic());
@@ -787,44 +746,10 @@ void HCheckFunction::PrintDataTo(StringStream* stream) const {
 }
 
 
-void HCallKeyed::PrintDataTo(StringStream* stream) const {
-  stream->Add("[");
-  key()->PrintNameTo(stream);
-  stream->Add("](");
-  for (int i = 1; i < arguments_.length(); ++i) {
-    if (i != 1) stream->Add(", ");
-    arguments_.at(i)->PrintNameTo(stream);
-  }
-  stream->Add(")");
-}
-
-
-void HCallNamed::PrintDataTo(StringStream* stream) const {
-  SmartPointer<char> name_string = name()->ToCString();
-  stream->Add("%s ", *name_string);
-  HCall::PrintDataTo(stream);
-}
-
-
-void HCallGlobal::PrintDataTo(StringStream* stream) const {
-  SmartPointer<char> name_string = name()->ToCString();
-  stream->Add("%s ", *name_string);
-  HCall::PrintDataTo(stream);
-}
-
-
-void HCallRuntime::PrintDataTo(StringStream* stream) const {
-  SmartPointer<char> name_string = name()->ToCString();
-  stream->Add("%s ", *name_string);
-  HCall::PrintDataTo(stream);
-}
-
-
 void HCallStub::PrintDataTo(StringStream* stream) const {
-  HUnaryOperation::PrintDataTo(stream);
-  stream->Add(" %s(%d)",
-              CodeStub::MajorName(major_key_, false),
-              argument_count_);
+  stream->Add("%s ",
+              CodeStub::MajorName(major_key_, false));
+  HUnaryCall::PrintDataTo(stream);
 }
 
 
index c65e8303ace88f27da48962b9b9da7973128deab..b9903c8d7e0841fa3cc2c8df1969d906b1bd3b1d 100644 (file)
@@ -48,6 +48,7 @@ class LChunkBuilder;
 
 #define HYDROGEN_ALL_INSTRUCTION_LIST(V)       \
   V(ArithmeticBinaryOperation)                 \
+  V(BinaryCall)                                \
   V(BinaryOperation)                           \
   V(BitwiseBinaryOperation)                    \
   V(Call)                                      \
@@ -58,6 +59,7 @@ class LChunkBuilder;
   V(Phi)                                       \
   V(StoreKeyed)                                \
   V(StoreNamed)                                \
+  V(UnaryCall)                                 \
   V(UnaryControlInstruction)                   \
   V(UnaryOperation)                            \
   HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
@@ -1049,27 +1051,15 @@ class HLeaveInlined: public HInstruction {
 
 class HPushArgument: public HUnaryOperation {
  public:
-  explicit HPushArgument(HValue* value)
-      : HUnaryOperation(value), argument_index_(-1) {
-    set_representation(Representation::Tagged());
-  }
+  explicit HPushArgument(HValue* value) : HUnaryOperation(value) { }
 
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
 
-  virtual void PrintDataTo(StringStream* stream) const;
   HValue* argument() const { return OperandAt(0); }
-  int argument_index() const { return argument_index_; }
-  void set_argument_index(int index) {
-    ASSERT(argument_index_ == -1 || index == argument_index_);
-    argument_index_ = index;
-  }
 
   DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push_argument")
-
- private:
-  int argument_index_;
 };
 
 
@@ -1132,36 +1122,80 @@ class HGlobalReceiver: public HUnaryOperation {
 
 class HCall: public HInstruction {
  public:
-  // Construct a call with uninitialized arguments. The argument count
-  // includes the receiver.
-  explicit HCall(int count);
+  // The argument count includes the receiver.
+  explicit HCall(int argument_count) : argument_count_(argument_count) {
+    set_representation(Representation::Tagged());
+    SetAllSideEffects();
+  }
 
   virtual HType CalculateInferredType() const { return HType::Tagged(); }
 
-  // TODO(3190496): This needs a cleanup. We don't want the arguments
-  // be operands of the call instruction. This results in bad code quality.
-  virtual int argument_count() const { return arguments_.length(); }
-  virtual int OperandCount() const { return argument_count(); }
-  virtual HValue* OperandAt(int index) const { return arguments_[index]; }
-  virtual HPushArgument* PushArgumentAt(int index) const {
-    return HPushArgument::cast(OperandAt(index));
+  virtual int argument_count() const { return argument_count_; }
+
+  virtual void PrintDataTo(StringStream* stream) const;
+
+  DECLARE_INSTRUCTION(Call)
+
+ private:
+  int argument_count_;
+};
+
+
+class HUnaryCall: public HCall {
+ public:
+  HUnaryCall(HValue* value, int argument_count)
+      : HCall(argument_count), value_(NULL) {
+    SetOperandAt(0, value);
+  }
+
+  virtual void PrintDataTo(StringStream* stream) const;
+
+  HValue* value() const { return value_; }
+
+  virtual int OperandCount() const { return 1; }
+  virtual HValue* OperandAt(int index) const {
+    ASSERT(index == 0);
+    return value_;
+  }
+
+  DECLARE_INSTRUCTION(UnaryCall)
+
+ protected:
+  virtual void InternalSetOperandAt(int index, HValue* value) {
+    ASSERT(index == 0);
+    value_ = value;
   }
-  virtual HValue* ArgumentAt(int index) const {
-    return PushArgumentAt(index)->argument();
+
+ private:
+  HValue* value_;
+};
+
+
+class HBinaryCall: public HCall {
+ public:
+  HBinaryCall(HValue* first, HValue* second, int argument_count)
+      : HCall(argument_count) {
+    SetOperandAt(0, first);
+    SetOperandAt(1, second);
   }
-  virtual void SetArgumentAt(int index, HPushArgument* push_argument);
 
   virtual void PrintDataTo(StringStream* stream) const;
 
-  DECLARE_INSTRUCTION(Call)
+  HValue* first() const { return operands_[0]; }
+  HValue* second() const { return operands_[1]; }
+
+  virtual int OperandCount() const { return 2; }
+  virtual HValue* OperandAt(int index) const { return operands_[index]; }
+
+  DECLARE_INSTRUCTION(BinaryCall)
 
  protected:
   virtual void InternalSetOperandAt(int index, HValue* value) {
-    arguments_[index] = value;
+    operands_[index] = value;
   }
 
-  int argument_count_;
-  Vector<HValue*> arguments_;
+ private:
+  HOperandVector<2> operands_;
 };
 
 
@@ -1171,6 +1205,7 @@ class HCallConstantFunction: public HCall {
       : HCall(argument_count), function_(function) { }
 
   Handle<JSFunction> function() const { return function_; }
+
   bool IsApplyFunction() const {
     return function_->code() == Builtins::builtin(Builtins::FunctionApply);
   }
@@ -1184,147 +1219,78 @@ class HCallConstantFunction: public HCall {
 };
 
 
-// TODO(3190496): This class uses hacks to get additional operands that ar
-// not arguments to work with the current setup. This _needs_ a cleanup.
-// (see HCall).
-class HCallKeyed: public HCall {
+class HCallKeyed: public HBinaryCall {
  public:
   HCallKeyed(HValue* context, HValue* key, int argument_count)
-      : HCall(argument_count + 1), context_(NULL) {
-    SetOperandAt(0, key);
-    SetOperandAt(argument_count + 1, context);
+      : HBinaryCall(context, key, argument_count) {
   }
 
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
 
-  virtual void PrintDataTo(StringStream* stream) const;
-
-  HValue* key() const { return OperandAt(0); }
-  HValue* context() const { return context_; }
-
-  virtual int argument_count() const { return arguments_.length() - 1; }
-  virtual int OperandCount() const { return arguments_.length() + 1; }
-
-  virtual HValue* OperandAt(int index) const {
-    // The key and all the arguments are stored in the base class's
-    // arguments_ vector.  The context is in the object itself.  Ugly.
-    return (index <= argument_count()) ? arguments_[index] : context_;
-  }
-
-  virtual HPushArgument* PushArgumentAt(int index) const {
-    return HPushArgument::cast(OperandAt(index + 1));
-  }
-  virtual void SetArgumentAt(int index, HPushArgument* push_argument) {
-    HCall::SetArgumentAt(index + 1, push_argument);
-  }
+  HValue* context() const { return first(); }
+  HValue* key() const { return second(); }
 
   DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed")
-
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value);
-
- private:
-  HValue* context_;
 };
 
 
-class HCallNamed: public HCall {
+class HCallNamed: public HUnaryCall {
  public:
   HCallNamed(HValue* context, Handle<String> name, int argument_count)
-      : HCall(argument_count), context_(NULL), name_(name) {
-    SetOperandAt(argument_count, context);
+      : HUnaryCall(context, argument_count), name_(name) {
   }
 
   virtual void PrintDataTo(StringStream* stream) const;
 
-  HValue* context() const { return context_; }
+  HValue* context() const { return value(); }
   Handle<String> name() const { return name_; }
 
-  virtual int OperandCount() const { return arguments_.length() + 1; }
-
-  virtual HValue* OperandAt(int index) const {
-    // The arguments are in the base class's arguments_ vector.  The context
-    // is in the object itself.
-    return (index < argument_count()) ? arguments_[index] : context_;
-  }
-
   DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call_named")
 
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value);
-
  private:
-  HValue* context_;
   Handle<String> name_;
 };
 
 
-class HCallFunction: public HCall {
+class HCallFunction: public HUnaryCall {
  public:
   HCallFunction(HValue* context, int argument_count)
-      : HCall(argument_count), context_(NULL) {
-    SetOperandAt(argument_count, context);
+      : HUnaryCall(context, argument_count) {
   }
 
-  HValue* context() const { return context_; }
-
-  virtual int OperandCount() const { return arguments_.length() + 1; }
-
-  virtual HValue* OperandAt(int index) const {
-    // The arguments are in the base class's arguments_ vector.  The context
-    // is in the object itself.
-    return (index < argument_count()) ? arguments_[index] : context_;
-  }
+  HValue* context() const { return value(); }
 
   DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call_function")
-
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value);
-
- private:
-  HValue* context_;
 };
 
 
-class HCallGlobal: public HCall {
+class HCallGlobal: public HUnaryCall {
  public:
   HCallGlobal(HValue* context, Handle<String> name, int argument_count)
-      : HCall(argument_count), context_(NULL), name_(name) {
-    SetOperandAt(argument_count, context);
+      : HUnaryCall(context, argument_count), name_(name) {
   }
 
   virtual void PrintDataTo(StringStream* stream) const;
 
-  HValue* context() const { return context_; }
+  HValue* context() const { return value(); }
   Handle<String> name() const { return name_; }
 
-  virtual int OperandCount() const { return arguments_.length() + 1; }
-
-  virtual HValue* OperandAt(int index) const {
-    // The arguments are in the base class's arguments_ vector.  The context
-    // is in the object itself.
-    return (index < argument_count()) ? arguments_[index] : context_;
-  }
-
   DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call_global")
 
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value);
-
  private:
-  HValue* context_;
   Handle<String> name_;
 };
 
 
 class HCallKnownGlobal: public HCall {
  public:
-  HCallKnownGlobal(Handle<JSFunction> target,
-                   int argument_count)
+  HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
       : HCall(argument_count), target_(target) { }
 
+  virtual void PrintDataTo(StringStream* stream) const;
+
   Handle<JSFunction> target() const { return target_; }
 
   DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call_known_global")
@@ -1334,35 +1300,20 @@ class HCallKnownGlobal: public HCall {
 };
 
 
-class HCallNew: public HCall {
+class HCallNew: public HBinaryCall {
  public:
-  HCallNew(HValue* context, int argument_count)
-      : HCall(argument_count), context_(NULL) {
-    SetOperandAt(argument_count, context);
+  HCallNew(HValue* context, HValue* constructor, int argument_count)
+      : HBinaryCall(context, constructor, argument_count) {
   }
 
   virtual Representation RequiredInputRepresentation(int index) const {
     return Representation::Tagged();
   }
 
-  HValue* context() const { return context_; }
-  HValue* constructor() const { return ArgumentAt(0); }
-
-  virtual int OperandCount() const { return arguments_.length() + 1; }
-
-  virtual HValue* OperandAt(int index) const {
-    // The arguments are in the base class's arguments_ vector.  The context
-    // is in the object itself.
-    return (index < argument_count()) ? arguments_[index] : context_;
-  }
+  HValue* context() const { return first(); }
+  HValue* constructor() const { return second(); }
 
   DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new")
-
- protected:
-  virtual void InternalSetOperandAt(int index, HValue* value);
-
- private:
-  HValue* context_;
 };
 
 
@@ -2764,20 +2715,17 @@ class HParameter: public HInstruction {
 };
 
 
-class HCallStub: public HUnaryOperation {
+class HCallStub: public HUnaryCall {
  public:
   HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
-      : HUnaryOperation(context),
+      : HUnaryCall(context, argument_count),
         major_key_(major_key),
-        argument_count_(argument_count),
         transcendental_type_(TranscendentalCache::kNumberOfCaches) {
-    set_representation(Representation::Tagged());
-    SetAllSideEffects();
   }
 
   CodeStub::Major major_key() { return major_key_; }
-  int argument_count() { return argument_count_; }
-  HValue* context() { return OperandAt(0); }
+
+  HValue* context() const { return value(); }
 
   void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
     transcendental_type_ = transcendental_type;
@@ -2785,13 +2733,13 @@ class HCallStub: public HUnaryOperation {
   TranscendentalCache::Type transcendental_type() {
     return transcendental_type_;
   }
+
   virtual void PrintDataTo(StringStream* stream) const;
 
   DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub")
 
  private:
   CodeStub::Major major_key_;
-  int argument_count_;
   TranscendentalCache::Type transcendental_type_;
 };
 
index c341cd3aff8b63cb41c4a056bed3b31a8b7fe458..6b1cf35e66b3ce9d4a604fe10afd6a4018339522 100644 (file)
@@ -2193,10 +2193,8 @@ void HGraphBuilder::VisitForControl(Expression* expr,
 }
 
 
-HValue* HGraphBuilder::VisitArgument(Expression* expr) {
+void HGraphBuilder::VisitArgument(Expression* expr) {
   VisitForValue(expr);
-  if (HasStackOverflow() || !subgraph()->HasExit()) return NULL;
-  return environment()->Top();
 }
 
 
@@ -2315,29 +2313,15 @@ void HGraphBuilder::PushAndAdd(HInstruction* instr) {
 }
 
 
-void HGraphBuilder::PushArgumentsForStubCall(int argument_count) {
-  const int kMaxStubArguments = 4;
-  ASSERT_GE(kMaxStubArguments, argument_count);
-  // Push the arguments on the stack.
-  HValue* arguments[kMaxStubArguments];
-  for (int i = argument_count - 1; i >= 0; i--) {
-    arguments[i] = Pop();
-  }
-  for (int i = 0; i < argument_count; i++) {
-    AddInstruction(new HPushArgument(arguments[i]));
-  }
-}
-
-
-void HGraphBuilder::ProcessCall(HCall* call) {
-  for (int i = call->argument_count() - 1; i >= 0; --i) {
-    HValue* value = Pop();
-    HPushArgument* push = new HPushArgument(value);
-    call->SetArgumentAt(i, push);
+void HGraphBuilder::PreProcessCall(HCall* call) {
+  int count = call->argument_count();
+  ZoneList<HValue*> arguments(count);
+  for (int i = 0; i < count; ++i) {
+    arguments.Add(Pop());
   }
 
-  for (int i = 0; i < call->argument_count(); ++i) {
-    AddInstruction(call->PushArgumentAt(i));
+  while (!arguments.is_empty()) {
+    AddInstruction(new HPushArgument(arguments.RemoveLast()));
   }
 }
 
@@ -3945,7 +3929,7 @@ void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
         CHECK_BAILOUT;
         HCall* call = new HCallConstantFunction(expr->target(), argument_count);
         call->set_position(expr->position());
-        ProcessCall(call);
+        PreProcessCall(call);
         PushAndAdd(call);
       }
       subgraphs.Add(subgraph);
@@ -3961,7 +3945,7 @@ void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
     AddInstruction(context);
     HCall* call = new HCallNamed(context, name, argument_count);
     call->set_position(expr->position());
-    ProcessCall(call);
+    PreProcessCall(call);
     ast_context()->ReturnInstruction(call, expr->id());
   } else {
     // Build subgraph for generic call through IC.
@@ -3975,7 +3959,7 @@ void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
         AddInstruction(context);
         HCall* call = new HCallNamed(context, name, argument_count);
         call->set_position(expr->position());
-        ProcessCall(call);
+        PreProcessCall(call);
         PushAndAdd(call);
       }
       subgraphs.Add(subgraph);
@@ -4397,7 +4381,7 @@ void HGraphBuilder::VisitCall(Call* expr) {
       AddInstruction(context);
       call = new HCallKeyed(context, key, argument_count);
       call->set_position(expr->position());
-      ProcessCall(call);
+      PreProcessCall(call);
       Drop(1);  // Key.
       ast_context()->ReturnInstruction(call, expr->id());
       return;
@@ -4409,7 +4393,7 @@ void HGraphBuilder::VisitCall(Call* expr) {
     if (TryCallApply(expr)) return;
     CHECK_BAILOUT;
 
-    HValue* receiver = VisitArgument(prop->obj());
+    VisitArgument(prop->obj());
     CHECK_BAILOUT;
     VisitArgumentList(expr->arguments());
     CHECK_BAILOUT;
@@ -4419,6 +4403,8 @@ void HGraphBuilder::VisitCall(Call* expr) {
     expr->RecordTypeFeedback(oracle());
     ZoneMapList* types = expr->GetReceiverTypes();
 
+    HValue* receiver =
+        environment()->ExpressionStackAt(expr->arguments()->length());
     if (expr->IsMonomorphic()) {
       Handle<Map> receiver_map =
           (types == NULL) ? Handle<Map>::null() : types->first();
@@ -4554,7 +4540,7 @@ void HGraphBuilder::VisitCall(Call* expr) {
   }
 
   call->set_position(expr->position());
-  ProcessCall(call);
+  PreProcessCall(call);
   ast_context()->ReturnInstruction(call, expr->id());
 }
 
@@ -4567,12 +4553,16 @@ void HGraphBuilder::VisitCallNew(CallNew* expr) {
   VisitArgumentList(expr->arguments());
   CHECK_BAILOUT;
 
-  int argument_count = expr->arguments()->length() + 1;  // Plus constructor.
   HContext* context = new HContext;
   AddInstruction(context);
-  HCall* call = new HCallNew(context, argument_count);
+
+  // The constructor is both an operand to the instruction and an argument
+  // 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);
   call->set_position(expr->position());
-  ProcessCall(call);
+  PreProcessCall(call);
   ast_context()->ReturnInstruction(call, expr->id());
 }
 
@@ -4626,7 +4616,7 @@ void HGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
     ASSERT(function->intrinsic_type == Runtime::RUNTIME);
     HCall* call = new HCallRuntime(name, expr->function(), argument_count);
     call->set_position(RelocInfo::kNoPosition);
-    ProcessCall(call);
+    PreProcessCall(call);
     ast_context()->ReturnInstruction(call, expr->id());
   }
 }
@@ -5313,11 +5303,11 @@ void HGraphBuilder::GenerateStringCharFromCode(int argument_count,
 // Fast support for string.charAt(n) and string[n].
 void HGraphBuilder::GenerateStringCharAt(int argument_count, int ast_id) {
   ASSERT_EQ(2, argument_count);
-  PushArgumentsForStubCall(argument_count);
   HContext* context = new HContext;
   AddInstruction(context);
   HCallStub* result =
       new HCallStub(context, CodeStub::StringCharAt, argument_count);
+  PreProcessCall(result);
   ast_context()->ReturnInstruction(result, ast_id);
 }
 
@@ -5346,11 +5336,11 @@ void HGraphBuilder::GenerateRandomHeapNumber(int argument_count, int ast_id) {
 // Fast support for StringAdd.
 void HGraphBuilder::GenerateStringAdd(int argument_count, int ast_id) {
   ASSERT_EQ(2, argument_count);
-  PushArgumentsForStubCall(argument_count);
   HContext* context = new HContext;
   AddInstruction(context);
   HCallStub* result =
       new HCallStub(context, CodeStub::StringAdd, argument_count);
+  PreProcessCall(result);
   ast_context()->ReturnInstruction(result, ast_id);
 }
 
@@ -5358,11 +5348,11 @@ void HGraphBuilder::GenerateStringAdd(int argument_count, int ast_id) {
 // Fast support for SubString.
 void HGraphBuilder::GenerateSubString(int argument_count, int ast_id) {
   ASSERT_EQ(3, argument_count);
-  PushArgumentsForStubCall(argument_count);
   HContext* context = new HContext;
   AddInstruction(context);
   HCallStub* result =
       new HCallStub(context, CodeStub::SubString, argument_count);
+  PreProcessCall(result);
   ast_context()->ReturnInstruction(result, ast_id);
 }
 
@@ -5370,11 +5360,11 @@ void HGraphBuilder::GenerateSubString(int argument_count, int ast_id) {
 // Fast support for StringCompare.
 void HGraphBuilder::GenerateStringCompare(int argument_count, int ast_id) {
   ASSERT_EQ(2, argument_count);
-  PushArgumentsForStubCall(argument_count);
   HContext* context = new HContext;
   AddInstruction(context);
   HCallStub* result =
       new HCallStub(context, CodeStub::StringCompare, argument_count);
+  PreProcessCall(result);
   ast_context()->ReturnInstruction(result, ast_id);
 }
 
@@ -5382,11 +5372,11 @@ void HGraphBuilder::GenerateStringCompare(int argument_count, int ast_id) {
 // Support for direct calls from JavaScript to native RegExp code.
 void HGraphBuilder::GenerateRegExpExec(int argument_count, int ast_id) {
   ASSERT_EQ(4, argument_count);
-  PushArgumentsForStubCall(argument_count);
   HContext* context = new HContext;
   AddInstruction(context);
   HCallStub* result =
       new HCallStub(context, CodeStub::RegExpExec, argument_count);
+  PreProcessCall(result);
   ast_context()->ReturnInstruction(result, ast_id);
 }
 
@@ -5395,11 +5385,11 @@ void HGraphBuilder::GenerateRegExpExec(int argument_count, int ast_id) {
 void HGraphBuilder::GenerateRegExpConstructResult(int argument_count,
                                                   int ast_id) {
   ASSERT_EQ(3, argument_count);
-  PushArgumentsForStubCall(argument_count);
   HContext* context = new HContext;
   AddInstruction(context);
   HCallStub* result =
       new HCallStub(context, CodeStub::RegExpConstructResult, argument_count);
+  PreProcessCall(result);
   ast_context()->ReturnInstruction(result, ast_id);
 }
 
@@ -5413,11 +5403,11 @@ void HGraphBuilder::GenerateGetFromCache(int argument_count, int ast_id) {
 // Fast support for number to string.
 void HGraphBuilder::GenerateNumberToString(int argument_count, int ast_id) {
   ASSERT_EQ(1, argument_count);
-  PushArgumentsForStubCall(argument_count);
   HContext* context = new HContext;
   AddInstruction(context);
   HCallStub* result =
       new HCallStub(context, CodeStub::NumberToString, argument_count);
+  PreProcessCall(result);
   ast_context()->ReturnInstruction(result, ast_id);
 }
 
@@ -5448,36 +5438,36 @@ void HGraphBuilder::GenerateMathPow(int argument_count, int ast_id) {
 
 void HGraphBuilder::GenerateMathSin(int argument_count, int ast_id) {
   ASSERT_EQ(1, argument_count);
-  PushArgumentsForStubCall(argument_count);
   HContext* context = new HContext;
   AddInstruction(context);
   HCallStub* result =
       new HCallStub(context, CodeStub::TranscendentalCache, argument_count);
   result->set_transcendental_type(TranscendentalCache::SIN);
+  PreProcessCall(result);
   ast_context()->ReturnInstruction(result, ast_id);
 }
 
 
 void HGraphBuilder::GenerateMathCos(int argument_count, int ast_id) {
   ASSERT_EQ(1, argument_count);
-  PushArgumentsForStubCall(argument_count);
   HContext* context = new HContext;
   AddInstruction(context);
   HCallStub* result =
       new HCallStub(context, CodeStub::TranscendentalCache, argument_count);
   result->set_transcendental_type(TranscendentalCache::COS);
+  PreProcessCall(result);
   ast_context()->ReturnInstruction(result, ast_id);
 }
 
 
 void HGraphBuilder::GenerateMathLog(int argument_count, int ast_id) {
   ASSERT_EQ(1, argument_count);
-  PushArgumentsForStubCall(argument_count);
   HContext* context = new HContext;
   AddInstruction(context);
   HCallStub* result =
       new HCallStub(context, CodeStub::TranscendentalCache, argument_count);
   result->set_transcendental_type(TranscendentalCache::LOG);
+  PreProcessCall(result);
   ast_context()->ReturnInstruction(result, ast_id);
 }
 
index 9d0cddf145ad737cee5d4911fef08cccf1bc88bb..7cf80ab3e3d58140c42849f2ba24cc8f7d7a771f 100644 (file)
@@ -706,19 +706,17 @@ class HGraphBuilder: public AstVisitor {
                        HBasicBlock* true_block,
                        HBasicBlock* false_block);
 
-  // Visit an argument and wrap it in a PushArgument instruction.
-  HValue* VisitArgument(Expression* expr);
+  // Visit an argument subexpression.
+  void VisitArgument(Expression* expr);
   void VisitArgumentList(ZoneList<Expression*>* arguments);
 
   void AddPhi(HPhi* phi);
 
   void PushAndAdd(HInstruction* instr);
 
-  void PushArgumentsForStubCall(int argument_count);
-
   // Remove the arguments from the bailout environment and emit instructions
   // to push them as outgoing parameters.
-  void ProcessCall(HCall* call);
+  void PreProcessCall(HCall* call);
 
   void AssumeRepresentation(HValue* value, Representation r);
   static Representation ToRepresentation(TypeInfo info);