Revision: 6749
Author: [email protected]
Date: Fri Feb 11 05:20:06 2011
Log: Remove the uses of the arguments from all calls.

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
http://code.google.com/p/v8/source/detail?r=6749

Modified:
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/hydrogen.h

=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Fri Feb 11 04:56:30 2011 +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Fri Feb 11 05:20:06 2011
@@ -288,61 +288,6 @@
     context_ = 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) {
@@ -609,26 +554,64 @@
 #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);
-  }
-  stream->Add(")");
+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());
+  }
+  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());
 }

@@ -640,22 +623,6 @@
   stream->Add("], length ");
   length()->PrintNameTo(stream);
 }
-
-
-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 {
@@ -743,14 +710,6 @@
   stream->Add(" == ");
   stream->Add(type_literal_->ToAsciiVector());
 }
-
-
-void HPushArgument::PrintDataTo(StringStream* stream) const {
-  HUnaryOperation::PrintDataTo(stream);
-  if (argument_index() != -1) {
-    stream->Add(" [%d]", argument_index_);
-  }
-}


 void HChange::PrintDataTo(StringStream* stream) const {
@@ -785,46 +744,12 @@
   value()->PrintNameTo(stream);
   stream->Add(" %p", *target());
 }
-
-
-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);
 }


=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Fri Feb 11 04:56:30 2011 +++ /branches/bleeding_edge/src/hydrogen-instructions.h Fri Feb 11 05:20:06 2011
@@ -48,6 +48,7 @@

 #define HYDROGEN_ALL_INSTRUCTION_LIST(V)       \
   V(ArithmeticBinaryOperation)                 \
+  V(BinaryCall)                                \
   V(BinaryOperation)                           \
   V(BitwiseBinaryOperation)                    \
   V(Call)                                      \
@@ -58,6 +59,7 @@
   V(Phi)                                       \
   V(StoreKeyed)                                \
   V(StoreNamed)                                \
+  V(UnaryCall)                                 \
   V(UnaryControlInstruction)                   \
   V(UnaryOperation)                            \
   HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
@@ -1049,27 +1051,15 @@

 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 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 HValue* ArgumentAt(int index) const {
-    return PushArgumentAt(index)->argument();
-  }
-  virtual void SetArgumentAt(int index, HPushArgument* push_argument);
+  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;
+  }
+
+ 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 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 @@
       : HCall(argument_count), function_(function) { }

   Handle<JSFunction> function() const { return function_; }
+
   bool IsApplyFunction() const {
     return function_->code() == Builtins::builtin(Builtins::FunctionApply);
   }
@@ -1184,146 +1219,77 @@
 };


-// 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_; }

@@ -1334,35 +1300,20 @@
 };


-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 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 @@
   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_;
 };

=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Fri Feb 11 04:56:30 2011
+++ /branches/bleeding_edge/src/hydrogen.cc     Fri Feb 11 05:20:06 2011
@@ -2193,10 +2193,8 @@
 }


-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::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);
-  }
-
-  for (int i = 0; i < call->argument_count(); ++i) {
-    AddInstruction(call->PushArgumentAt(i));
+void HGraphBuilder::PreProcessCall(HCall* call) {
+  int count = call->argument_count();
+  ZoneList<HValue*> arguments(count);
+  for (int i = 0; i < count; ++i) {
+    arguments.Add(Pop());
+  }
+
+  while (!arguments.is_empty()) {
+    AddInstruction(new HPushArgument(arguments.RemoveLast()));
   }
 }

@@ -3945,7 +3929,7 @@
         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 @@
     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 @@
         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 @@
       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 @@
     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 @@
     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 @@
   }

   call->set_position(expr->position());
-  ProcessCall(call);
+  PreProcessCall(call);
   ast_context()->ReturnInstruction(call, expr->id());
 }

@@ -4567,12 +4553,16 @@
   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 @@
     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 @@
 // 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 @@
 // 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 @@
 // 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 @@
 // 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 @@
 // 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::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 @@
 // 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::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);
 }

=======================================
--- /branches/bleeding_edge/src/hydrogen.h      Thu Feb 10 04:02:36 2011
+++ /branches/bleeding_edge/src/hydrogen.h      Fri Feb 11 05:20:06 2011
@@ -706,19 +706,17 @@
                        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);

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to