Revision: 21468
Author:   [email protected]
Date:     Fri May 23 14:06:42 2014 UTC
Log:      Allow HPushArgument to handle more than one argument.

[email protected]

Review URL: https://codereview.chromium.org/296113008
http://code.google.com/p/v8/source/detail?r=21468

Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/arm64/lithium-arm64.cc
 /branches/bleeding_edge/src/arm64/lithium-arm64.h
 /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc
 /branches/bleeding_edge/src/arm64/macro-assembler-arm64.cc
 /branches/bleeding_edge/src/arm64/macro-assembler-arm64.h
 /branches/bleeding_edge/src/code-stubs-hydrogen.cc
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.cc
 /branches/bleeding_edge/src/lithium.cc
 /branches/bleeding_edge/src/mips/lithium-mips.cc
 /branches/bleeding_edge/src/x64/lithium-x64.cc

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Fri May 23 13:15:07 2014 UTC +++ /branches/bleeding_edge/src/arm/lithium-arm.cc Fri May 23 14:06:42 2014 UTC
@@ -1005,9 +1005,13 @@
 }


-LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
-  LOperand* argument = Use(instr->argument());
-  return new(zone()) LPushArgument(argument);
+LInstruction* LChunkBuilder::DoPushArguments(HPushArguments* instr) {
+  int argc = instr->OperandCount();
+  for (int i = 0; i < argc; ++i) {
+    LOperand* argument = Use(instr->argument(i));
+    AddInstruction(new(zone()) LPushArgument(argument), instr);
+  }
+  return NULL;
 }


=======================================
--- /branches/bleeding_edge/src/arm64/lithium-arm64.cc Fri May 23 13:15:07 2014 UTC +++ /branches/bleeding_edge/src/arm64/lithium-arm64.cc Fri May 23 14:06:42 2014 UTC
@@ -1995,9 +1995,21 @@
 }


-LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
-  LOperand* argument = UseRegister(instr->argument());
-  return new(zone()) LPushArgument(argument);
+LInstruction* LChunkBuilder::DoPushArguments(HPushArguments* instr) {
+  int argc = instr->OperandCount();
+  AddInstruction(new(zone()) LPreparePushArguments(argc), instr);
+
+  LPushArguments* push_args = new(zone()) LPushArguments(zone());
+
+  for (int i = 0; i < argc; ++i) {
+    if (push_args->ShouldSplitPush()) {
+      AddInstruction(push_args, instr);
+      push_args = new(zone()) LPushArguments(zone());
+    }
+    push_args->AddArgument(UseRegister(instr->argument(i)));
+  }
+
+  return push_args;
 }


=======================================
--- /branches/bleeding_edge/src/arm64/lithium-arm64.h Fri May 23 13:15:07 2014 UTC +++ /branches/bleeding_edge/src/arm64/lithium-arm64.h Fri May 23 14:06:42 2014 UTC
@@ -136,7 +136,8 @@
   V(OsrEntry)                                   \
   V(Parameter)                                  \
   V(Power)                                      \
-  V(PushArgument)                               \
+  V(PreparePushArguments)                       \
+  V(PushArguments)                              \
   V(RegExpLiteral)                              \
   V(Return)                                     \
   V(SeqStringGetChar)                           \
@@ -2249,15 +2250,50 @@
 };


-class LPushArgument V8_FINAL : public LTemplateInstruction<0, 1, 0> {
+class LPreparePushArguments V8_FINAL : public LTemplateInstruction<0, 0, 0> {
  public:
-  explicit LPushArgument(LOperand* value) {
-    inputs_[0] = value;
+  explicit LPreparePushArguments(int argc) : argc_(argc) {}
+
+  inline int argc() const { return argc_; }
+
+ DECLARE_CONCRETE_INSTRUCTION(PreparePushArguments, "prepare-push-arguments")
+
+ protected:
+  int argc_;
+};
+
+
+class LPushArguments V8_FINAL : public LTemplateResultInstruction<0> {
+ public:
+  explicit LPushArguments(Zone* zone,
+                          int capacity = kRecommendedMaxPushedArgs)
+      : zone_(zone), inputs_(capacity, zone) {}
+
+  LOperand* argument(int i) { return inputs_[i]; }
+  int ArgumentCount() const { return inputs_.length(); }
+
+  void AddArgument(LOperand* arg) { inputs_.Add(arg, zone_); }
+
+  DECLARE_CONCRETE_INSTRUCTION(PushArguments, "push-arguments")
+
+  // It is better to limit the number of arguments pushed simultaneously to
+  // avoid pressure on the register allocator.
+  static const int kRecommendedMaxPushedArgs = 4;
+  bool ShouldSplitPush() const {
+    return inputs_.length() >= kRecommendedMaxPushedArgs;
   }

-  LOperand* value() { return inputs_[0]; }
+ protected:
+  Zone* zone_;
+  ZoneList<LOperand*> inputs_;

-  DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
+ private:
+  // Iterator support.
+ virtual int InputCount() V8_FINAL V8_OVERRIDE { return inputs_.length(); } + virtual LOperand* InputAt(int i) V8_FINAL V8_OVERRIDE { return inputs_[i]; }
+
+  virtual int TempCount() V8_FINAL V8_OVERRIDE { return 0; }
+  virtual LOperand* TempAt(int i) V8_FINAL V8_OVERRIDE { return NULL; }
 };


=======================================
--- /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc Thu May 22 08:37:50 2014 UTC +++ /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc Fri May 23 14:06:42 2014 UTC
@@ -4677,14 +4677,27 @@
 }


-void LCodeGen::DoPushArgument(LPushArgument* instr) {
-  LOperand* argument = instr->value();
-  if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) {
-    Abort(kDoPushArgumentNotImplementedForDoubleType);
-  } else {
-    __ Push(ToRegister(argument));
-    after_push_argument_ = true;
+void LCodeGen::DoPreparePushArguments(LPreparePushArguments* instr) {
+  __ PushPreamble(instr->argc(), kPointerSize);
+}
+
+
+void LCodeGen::DoPushArguments(LPushArguments* instr) {
+  MacroAssembler::PushPopQueue args(masm());
+
+  for (int i = 0; i < instr->ArgumentCount(); ++i) {
+    LOperand* arg = instr->argument(i);
+    if (arg->IsDoubleRegister() || arg->IsDoubleStackSlot()) {
+      Abort(kDoPushArgumentNotImplementedForDoubleType);
+      return;
+    }
+    args.Queue(ToRegister(arg));
   }
+
+  // The preamble was done by LPreparePushArguments.
+  args.PushQueued(MacroAssembler::PushPopQueue::SKIP_PREAMBLE);
+
+  after_push_argument_ = true;
 }


=======================================
--- /branches/bleeding_edge/src/arm64/macro-assembler-arm64.cc Fri May 16 15:18:24 2014 UTC +++ /branches/bleeding_edge/src/arm64/macro-assembler-arm64.cc Fri May 23 14:06:42 2014 UTC
@@ -805,10 +805,13 @@
 }


-void MacroAssembler::PushPopQueue::PushQueued() {
+void MacroAssembler::PushPopQueue::PushQueued(
+    PreambleDirective preamble_directive) {
   if (queued_.empty()) return;

-  masm_->PushPreamble(size_);
+  if (preamble_directive == WITH_PREAMBLE) {
+    masm_->PushPreamble(size_);
+  }

   int count = queued_.size();
   int index = 0;
=======================================
--- /branches/bleeding_edge/src/arm64/macro-assembler-arm64.h Fri May 23 08:52:05 2014 UTC +++ /branches/bleeding_edge/src/arm64/macro-assembler-arm64.h Fri May 23 14:06:42 2014 UTC
@@ -614,7 +614,11 @@
       queued_.push_back(rt);
     }

-    void PushQueued();
+    enum PreambleDirective {
+      WITH_PREAMBLE,
+      SKIP_PREAMBLE
+    };
+    void PushQueued(PreambleDirective preamble_directive = WITH_PREAMBLE);
     void PopQueued();

    private:
@@ -2012,6 +2016,15 @@
   void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0,
                                         Register scratch1, Label* found);

+  // Perform necessary maintenance operations before a push or after a pop.
+  //
+  // Note that size is specified in bytes.
+  void PushPreamble(Operand total_size);
+  void PopPostamble(Operand total_size);
+
+  void PushPreamble(int count, int size) { PushPreamble(count * size); }
+  void PopPostamble(int count, int size) { PopPostamble(count * size); }
+
  private:
   // Helpers for CopyFields.
   // These each implement CopyFields in a different way.
@@ -2038,15 +2051,6 @@
   void PopHelper(int count, int size,
                  const CPURegister& dst0, const CPURegister& dst1,
                  const CPURegister& dst2, const CPURegister& dst3);
-
-  // Perform necessary maintenance operations before a push or after a pop.
-  //
-  // Note that size is specified in bytes.
-  void PushPreamble(Operand total_size);
-  void PopPostamble(Operand total_size);
-
-  void PushPreamble(int count, int size) { PushPreamble(count * size); }
-  void PopPostamble(int count, int size) { PopPostamble(count * size); }

// Call Printf. On a native build, a simple call will be generated, but if the // simulator is being used then a suitable pseudo-instruction is used. The
=======================================
--- /branches/bleeding_edge/src/code-stubs-hydrogen.cc Tue May 20 11:25:47 2014 UTC +++ /branches/bleeding_edge/src/code-stubs-hydrogen.cc Fri May 23 14:06:42 2014 UTC
@@ -298,7 +298,7 @@

   // Convert the parameter to number using the builtin.
   HValue* function = AddLoadJSBuiltin(Builtins::TO_NUMBER);
-  Add<HPushArgument>(value);
+  Add<HPushArguments>(zone(), value);
   Push(Add<HInvokeFunction>(function, 1));

   if_number.End();
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Thu May 22 08:37:50 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Fri May 23 14:06:42 2014 UTC
@@ -868,7 +868,7 @@
     case HValue::kMathMinMax:
     case HValue::kParameter:
     case HValue::kPhi:
-    case HValue::kPushArgument:
+    case HValue::kPushArguments:
     case HValue::kRegExpLiteral:
     case HValue::kReturn:
     case HValue::kRor:
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Fri May 23 14:02:08 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.h Fri May 23 14:06:42 2014 UTC
@@ -127,7 +127,7 @@
   V(OsrEntry)                                  \
   V(Parameter)                                 \
   V(Power)                                     \
-  V(PushArgument)                              \
+  V(PushArguments)                             \
   V(RegExpLiteral)                             \
   V(Return)                                    \
   V(Ror)                                       \
@@ -2176,23 +2176,66 @@
 };


-class HPushArgument V8_FINAL : public HUnaryOperation {
+class HPushArguments V8_FINAL : public HInstruction {
  public:
-  DECLARE_INSTRUCTION_FACTORY_P1(HPushArgument, HValue*);
+  DECLARE_INSTRUCTION_FACTORY_P1(HPushArguments, Zone*);
+  DECLARE_INSTRUCTION_FACTORY_P2(HPushArguments, Zone*, HValue*);
+  DECLARE_INSTRUCTION_FACTORY_P3(HPushArguments, Zone*, HValue*, HValue*);
+  DECLARE_INSTRUCTION_FACTORY_P4(HPushArguments, Zone*,
+                                 HValue*, HValue*, HValue*);
+  DECLARE_INSTRUCTION_FACTORY_P5(HPushArguments, Zone*,
+                                 HValue*, HValue*, HValue*, HValue*);

virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
     return Representation::Tagged();
   }

-  virtual int argument_delta() const V8_OVERRIDE { return 1; }
-  HValue* argument() { return OperandAt(0); }
+ virtual int argument_delta() const V8_OVERRIDE { return inputs_.length(); }
+  HValue* argument(int i) { return OperandAt(i); }
+
+ virtual int OperandCount() V8_FINAL V8_OVERRIDE { return inputs_.length(); }
+  virtual HValue* OperandAt(int i) const V8_FINAL V8_OVERRIDE {
+    return inputs_[i];
+  }

-  DECLARE_CONCRETE_INSTRUCTION(PushArgument)
+  void AddArgument(HValue* arg) {
+    inputs_.Add(NULL, zone_);
+    SetOperandAt(inputs_.length() - 1, arg);
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(PushArguments)
+
+ protected:
+ virtual void InternalSetOperandAt(int i, HValue* value) V8_FINAL V8_OVERRIDE {
+    inputs_[i] = value;
+  }

  private:
-  explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
+  HPushArguments(Zone* zone,
+                 HValue* arg1 = NULL, HValue* arg2 = NULL,
+                 HValue* arg3 = NULL, HValue* arg4 = NULL)
+      : HInstruction(HType::Tagged()), zone_(zone), inputs_(4, zone) {
     set_representation(Representation::Tagged());
+    if (arg1) {
+      inputs_.Add(NULL, zone);
+      SetOperandAt(0, arg1);
+    }
+    if (arg2) {
+      inputs_.Add(NULL, zone);
+      SetOperandAt(1, arg2);
+    }
+    if (arg3) {
+      inputs_.Add(NULL, zone);
+      SetOperandAt(2, arg3);
+    }
+    if (arg4) {
+      inputs_.Add(NULL, zone);
+      SetOperandAt(3, arg4);
+    }
   }
+
+  Zone* zone_;
+  ZoneList<HValue*> inputs_;
 };


=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Fri May 23 09:30:47 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc     Fri May 23 14:06:42 2014 UTC
@@ -1726,7 +1726,7 @@
   if_found.Else();
   {
     // Cache miss, fallback to runtime.
-    Add<HPushArgument>(object);
+    Add<HPushArguments>(zone(), object);
     Push(Add<HCallRuntime>(
             isolate()->factory()->empty_string(),
Runtime::FunctionForId(Runtime::kHiddenNumberToStringSkipCache),
@@ -2050,8 +2050,7 @@
     if_sameencodingandsequential.Else();
     {
       // Fallback to the runtime to add the two strings.
-      Add<HPushArgument>(left);
-      Add<HPushArgument>(right);
+      Add<HPushArguments>(zone(), left, right);
       Push(Add<HCallRuntime>(
             isolate()->factory()->empty_string(),
             Runtime::FunctionForId(Runtime::kHiddenStringAdd),
@@ -4188,9 +4187,11 @@
     arguments.Add(Pop(), zone());
   }

+  HPushArguments* push_args = New<HPushArguments>(zone());
   while (!arguments.is_empty()) {
-    Add<HPushArgument>(arguments.RemoveLast());
+    push_args->AddArgument(arguments.RemoveLast());
   }
+  AddInstruction(push_args);
 }


@@ -5184,10 +5185,11 @@
     flags |= expr->has_function()
         ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags;

-    Add<HPushArgument>(Add<HConstant>(closure_literals));
-    Add<HPushArgument>(Add<HConstant>(literal_index));
-    Add<HPushArgument>(Add<HConstant>(constant_properties));
-    Add<HPushArgument>(Add<HConstant>(flags));
+    Add<HPushArguments>(zone(),
+                        Add<HConstant>(closure_literals),
+                        Add<HConstant>(literal_index),
+                        Add<HConstant>(constant_properties),
+                        Add<HConstant>(flags));

     // TODO(mvstanton): Add a flag to turn off creation of any
// AllocationMementos for this call: we are in crankshaft and should have
@@ -5342,10 +5344,11 @@
         : ArrayLiteral::kNoFlags;
     flags |= ArrayLiteral::kDisableMementos;

-    Add<HPushArgument>(Add<HConstant>(literals));
-    Add<HPushArgument>(Add<HConstant>(literal_index));
-    Add<HPushArgument>(Add<HConstant>(constants));
-    Add<HPushArgument>(Add<HConstant>(flags));
+    Add<HPushArguments>(zone(),
+                        Add<HConstant>(literals),
+                        Add<HConstant>(literal_index),
+                        Add<HConstant>(constants),
+                        Add<HConstant>(flags));

     // TODO(mvstanton): Consider a flag to turn off creation of any
// AllocationMementos for this call: we are in crankshaft and should have
@@ -6379,7 +6382,7 @@

   HValue* value = environment()->Pop();
   if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
-  Add<HPushArgument>(value);
+  Add<HPushArguments>(zone(), value);
   Add<HCallRuntime>(isolate()->factory()->empty_string(),
                     Runtime::FunctionForId(Runtime::kHiddenThrow), 1);
   Add<HSimulate>(expr->id());
@@ -6781,7 +6784,7 @@
   HInstruction* insert_after = entry;
   for (int i = 0; i < arguments_values->length(); i++) {
     HValue* argument = arguments_values->at(i);
-    HInstruction* push_argument = New<HPushArgument>(argument);
+    HInstruction* push_argument = New<HPushArguments>(zone(), argument);
     push_argument->InsertAfter(insert_after);
     insert_after = push_argument;
   }
@@ -8076,7 +8079,7 @@
       ASSERT_EQ(NULL, receiver);
       // Receiver is on expression stack.
       receiver = Pop();
-      Add<HPushArgument>(receiver);
+      Add<HPushArguments>(zone(), receiver);
       break;
     case kCallApiSetter:
       {
@@ -8087,8 +8090,7 @@
         // Receiver and value are on expression stack.
         HValue* value = Pop();
         receiver = Pop();
-        Add<HPushArgument>(receiver);
-        Add<HPushArgument>(value);
+        Add<HPushArguments>(zone(), receiver, value);
         break;
      }
   }
@@ -8656,7 +8658,7 @@
     }

     // TODO(mstarzinger): For now we remove the previous HAllocate and all
-    // corresponding instructions and instead add HPushArgument for the
+    // corresponding instructions and instead add HPushArguments for the
// arguments in case inlining failed. What we actually should do is for // inlining to try to build a subgraph without mutating the parent graph.
     HInstruction* instr = current_block()->last();
@@ -9135,9 +9137,8 @@
     HValue* key = Pop();
     HValue* obj = Pop();
     HValue* function = AddLoadJSBuiltin(Builtins::DELETE);
-    Add<HPushArgument>(obj);
-    Add<HPushArgument>(key);
-    Add<HPushArgument>(Add<HConstant>(function_strict_mode()));
+    Add<HPushArguments>(zone(),
+                        obj, key, Add<HConstant>(function_strict_mode()));
     // TODO(olivf) InvokeFunction produces a check for the parameter count,
// even though we are certain to pass the correct number of arguments here.
     HInstruction* instr = New<HInvokeFunction>(function, 3);
@@ -9622,8 +9623,7 @@
     } else if (!left_type->Is(Type::String())) {
       ASSERT(right_type->Is(Type::String()));
       HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT);
-      Add<HPushArgument>(left);
-      Add<HPushArgument>(right);
+      Add<HPushArguments>(zone(), left, right);
       return AddUncasted<HInvokeFunction>(function, 2);
     }

@@ -9634,8 +9634,7 @@
     } else if (!right_type->Is(Type::String())) {
       ASSERT(left_type->Is(Type::String()));
       HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT);
-      Add<HPushArgument>(left);
-      Add<HPushArgument>(right);
+      Add<HPushArguments>(zone(), left, right);
       return AddUncasted<HInvokeFunction>(function, 2);
     }

@@ -9697,8 +9696,7 @@
// operation in optimized code, which is more expensive, than a stub call.
   if (graph()->info()->IsStub() && is_non_primitive) {
     HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op));
-    Add<HPushArgument>(left);
-    Add<HPushArgument>(right);
+    Add<HPushArguments>(zone(), left, right);
     instr = AddUncasted<HInvokeFunction>(function, 2);
   } else {
     switch (op) {
@@ -10062,8 +10060,7 @@
     UNREACHABLE();
   } else if (op == Token::IN) {
     HValue* function = AddLoadJSBuiltin(Builtins::IN);
-    Add<HPushArgument>(left);
-    Add<HPushArgument>(right);
+    Add<HPushArguments>(zone(), left, right);
     // TODO(olivf) InvokeFunction produces a check for the parameter count,
// even though we are certain to pass the correct number of arguments here.
     HInstruction* result = New<HInvokeFunction>(function, 2);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Fri May 23 13:15:07 2014 UTC +++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Fri May 23 14:06:42 2014 UTC
@@ -1060,9 +1060,13 @@
 }


-LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
-  LOperand* argument = UseAny(instr->argument());
-  return new(zone()) LPushArgument(argument);
+LInstruction* LChunkBuilder::DoPushArguments(HPushArguments* instr) {
+  int argc = instr->OperandCount();
+  for (int i = 0; i < argc; ++i) {
+    LOperand* argument = UseAny(instr->argument(i));
+    AddInstruction(new(zone()) LPushArgument(argument), instr);
+  }
+  return NULL;
 }


=======================================
--- /branches/bleeding_edge/src/lithium.cc      Thu May 22 09:36:20 2014 UTC
+++ /branches/bleeding_edge/src/lithium.cc      Fri May 23 14:06:42 2014 UTC
@@ -509,7 +509,7 @@

     LOperand* op;
     HValue* value = hydrogen_env->values()->at(i);
-    CHECK(!value->IsPushArgument());  // Do not deopt outgoing arguments
+    CHECK(!value->IsPushArguments());  // Do not deopt outgoing arguments
     if (value->IsArgumentsObject() || value->IsCapturedObject()) {
       op = LEnvironment::materialization_marker();
     } else {
@@ -590,7 +590,7 @@
       // Insert a hole for nested objects
       op = LEnvironment::materialization_marker();
     } else {
-      ASSERT(!arg_value->IsPushArgument());
+      ASSERT(!arg_value->IsPushArguments());
       // For ordinary values, tell the register allocator we need the value
       // to be alive here
       op = UseAny(arg_value);
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.cc Fri May 23 13:15:07 2014 UTC +++ /branches/bleeding_edge/src/mips/lithium-mips.cc Fri May 23 14:06:42 2014 UTC
@@ -1008,9 +1008,13 @@
 }


-LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
-  LOperand* argument = Use(instr->argument());
-  return new(zone()) LPushArgument(argument);
+LInstruction* LChunkBuilder::DoPushArguments(HPushArguments* instr) {
+  int argc = instr->OperandCount();
+  for (int i = 0; i < argc; ++i) {
+    LOperand* argument = Use(instr->argument(i));
+    AddInstruction(new(zone()) LPushArgument(argument), instr);
+  }
+  return NULL;
 }


=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Fri May 23 13:15:07 2014 UTC +++ /branches/bleeding_edge/src/x64/lithium-x64.cc Fri May 23 14:06:42 2014 UTC
@@ -1023,9 +1023,13 @@
 }


-LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
-  LOperand* argument = UseOrConstant(instr->argument());
-  return new(zone()) LPushArgument(argument);
+LInstruction* LChunkBuilder::DoPushArguments(HPushArguments* instr) {
+  int argc = instr->OperandCount();
+  for (int i = 0; i < argc; ++i) {
+    LOperand* argument = UseOrConstant(instr->argument(i));
+    AddInstruction(new(zone()) LPushArgument(argument), instr);
+  }
+  return NULL;
 }


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to