Revision: 18630
Author:   [email protected]
Date:     Wed Jan 15 23:37:49 2014 UTC
Log: MIPS: This is a preview of a first step towards unification of the hydrogen call machinery.

Port r18626 (d3368a4c)

Original commit message:
The change replaces CallNamed, CallKeyed, CallConstantFunction and CallKnownGlobal hydrogen instructions with two new instructions with a more lower level semantics:

1. CallJSFunction for direct calls of JSFunction objects (no
   argument adaptation)

2. CallWithDescriptor for calls of a given Code object according to
   the supplied calling convention.

Details:

CallJSFunction should be straightforward, the main difference from the
existing InvokeFunction instruction is the absence of argument adaptor
handling. (As a next step, we will replace InvokeFunction with an
equivalent hydrogen code.)

For CallWithDescriptor, the calling conventions are represented by a
tweaked version of CallStubInterfaceDescriptor. In addition to the
parameter-register mapping, we also define parameter-representation
mapping there. The CallWithDescriptor instruction has variable number of
parameters now - this required some simple tweaks in Lithium, which
assumed fixed number of arguments in some places.

The calling conventions used in the calls are initialized in the
CallDescriptors class (code-stubs.h, <arch>/code-stubs-<arch>.cc), and
they live in a new table in the Isolate class. I should say I am not
quite sure about Representation::Integer32() representation for some of
the params of ArgumentAdaptorCall - it is not clear to me wether the
params could not end up on the stack and thus confuse the GC.

The change also includes an earlier small change to argument adaptor
(https://codereview.chromium.org/98463007) that avoids passing a naked
pointer to the code entry as a parameter. I am sorry for packaging that
with an already biggish change.

Performance implications:

Locally, I see a small regression (.2% or so). It is hard to say where
exactly it comes from, but I do see inefficient call sequences to the
adaptor trampoline. For example:

;;; <@78,#24> constant-t
bf85aa515a     mov edi,0x5a51aa85          ;; debug: position 29
;;; <@72,#53> load-named-field
8b7717         mov esi,[edi+0x17]          ;; debug: position 195
;;; <@80,#51> constant-s
b902000000     mov ecx,0x2                 ;; debug: position 195
;;; <@81,#51> gap
894df0         mov [ebp+0xf0],ecx
;;; <@82,#103> constant-i
bb01000000     mov ebx,0x1
;;; <@84,#102> constant-i
b902000000     mov ecx,0x2
;;; <@85,#102> gap
89d8           mov eax,ebx
89cb           mov ebx,ecx
8b4df0         mov ecx,[ebp+0xf0]
;;; <@86,#58> call-with-descriptor
e8ef57fcff call ArgumentsAdaptorTrampoline (0x2d80e6e0) ;; code: BUILTIN

Note the silly handling of ecx; the hydrogen for this code is:

0 4 s27 Constant 1  range:1_1 <|@
0 3 t30 Constant 0x5bc1aa85 <JS Function xyz (SharedFunctionInfo 0x5bc1a919)> type:object <|@
0 1 t36 LoadNamedField t30.[in-object]@24 <|@
0 1 t38 Constant 0x2300e6a1 <Code> <|@
0 1 i102 Constant 2  range:2_2 <|@
0 1 i103 Constant 1  range:1_1 <|@
0 2 t41 CallWithDescriptor t38 t30 t36 s27 i103 i102 #2 changes[*] <|@

BUG=
[email protected]

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

Modified:
 /branches/bleeding_edge/src/mips/builtins-mips.cc
 /branches/bleeding_edge/src/mips/code-stubs-mips.cc
 /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
 /branches/bleeding_edge/src/mips/lithium-mips.cc
 /branches/bleeding_edge/src/mips/lithium-mips.h
 /branches/bleeding_edge/src/mips/macro-assembler-mips.cc
 /branches/bleeding_edge/src/mips/macro-assembler-mips.h

=======================================
--- /branches/bleeding_edge/src/mips/builtins-mips.cc Tue Jan 14 18:17:24 2014 UTC +++ /branches/bleeding_edge/src/mips/builtins-mips.cc Wed Jan 15 23:37:49 2014 UTC
@@ -629,9 +629,7 @@
       __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
       Handle<Code> code =
           masm->isolate()->builtins()->HandleApiCallConstruct();
-      ParameterCount expected(0);
-      __ InvokeCode(code, expected, expected,
-                    RelocInfo::CODE_TARGET, CALL_FUNCTION);
+      __ Call(code, RelocInfo::CODE_TARGET);
     } else {
       ParameterCount actual(a0);
       __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper());
@@ -1178,12 +1176,12 @@

     __ push(a1);  // Re-add proxy object as additional argument.
     __ Addu(a0, a0, Operand(1));
-    __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY);
+    __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY);
     __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
             RelocInfo::CODE_TARGET);

     __ bind(&non_proxy);
-    __ GetBuiltinEntry(a3, Builtins::CALL_NON_FUNCTION);
+    __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION);
     __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
             RelocInfo::CODE_TARGET);
     __ bind(&function);
@@ -1198,11 +1196,11 @@
   __ lw(a2,
FieldMemOperand(a3, SharedFunctionInfo::kFormalParameterCountOffset));
   __ sra(a2, a2, kSmiTagSize);
-  __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
   // Check formal and actual parameter counts.
   __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
           RelocInfo::CODE_TARGET, ne, a2, Operand(a0));

+  __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
   ParameterCount expected(0);
   __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, NullCallWrapper());
 }
@@ -1352,7 +1350,7 @@
     __ push(a1);  // Add function proxy as last argument.
     __ Addu(a0, a0, Operand(1));
     __ li(a2, Operand(0, RelocInfo::NONE32));
-    __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY);
+    __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY);
     __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
             RelocInfo::CODE_TARGET);
     // Tear down the internal frame and remove function, receiver and args.
@@ -1395,12 +1393,12 @@
   //  -- a0: actual arguments count
   //  -- a1: function (passed through to callee)
   //  -- a2: expected arguments count
-  //  -- a3: callee code entry
   // -----------------------------------

   Label invoke, dont_adapt_arguments;

   Label enough, too_few;
+  __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
   __ Branch(&dont_adapt_arguments, eq,
       a2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
// We use Uless as the number of argument should always be greater than 0.
=======================================
--- /branches/bleeding_edge/src/mips/code-stubs-mips.cc Tue Jan 14 18:17:24 2014 UTC +++ /branches/bleeding_edge/src/mips/code-stubs-mips.cc Wed Jan 15 23:37:49 2014 UTC
@@ -360,6 +360,56 @@
   descriptor->deoptimization_handler_ =
       Runtime::FunctionForId(Runtime::kStringAdd)->entry;
 }
+
+
+void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
+  {
+    CallInterfaceDescriptor* descriptor =
+        isolate->call_descriptor(Isolate::ArgumentAdaptorCall);
+    static Register registers[] = { a1,  // JSFunction
+                                    cp,  // context
+                                    a0,  // actual number of arguments
+                                    a2,  // expected number of arguments
+    };
+    static Representation representations[] = {
+        Representation::Tagged(),     // JSFunction
+        Representation::Tagged(),     // context
+        Representation::Integer32(),  // actual number of arguments
+        Representation::Integer32(),  // expected number of arguments
+    };
+    descriptor->register_param_count_ = 4;
+    descriptor->register_params_ = registers;
+    descriptor->param_representations_ = representations;
+  }
+  {
+    CallInterfaceDescriptor* descriptor =
+        isolate->call_descriptor(Isolate::KeyedCall);
+    static Register registers[] = { cp,  // context
+                                    a2,  // key
+    };
+    static Representation representations[] = {
+        Representation::Tagged(),     // context
+        Representation::Tagged(),     // key
+    };
+    descriptor->register_param_count_ = 2;
+    descriptor->register_params_ = registers;
+    descriptor->param_representations_ = representations;
+  }
+  {
+    CallInterfaceDescriptor* descriptor =
+        isolate->call_descriptor(Isolate::NamedCall);
+    static Register registers[] = { cp,  // context
+                                    a2,  // name
+    };
+    static Representation representations[] = {
+        Representation::Tagged(),     // context
+        Representation::Tagged(),     // name
+    };
+    descriptor->register_param_count_ = 2;
+    descriptor->register_params_ = registers;
+    descriptor->param_representations_ = representations;
+  }
+}


 #define __ ACCESS_MASM(masm)
@@ -3362,7 +3412,7 @@
   __ push(a1);  // Put proxy as additional argument.
   __ li(a0, Operand(argc_ + 1, RelocInfo::NONE32));
   __ li(a2, Operand(0, RelocInfo::NONE32));
-  __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY);
+  __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY);
   {
     Handle<Code> adaptor =
       masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
@@ -3375,7 +3425,7 @@
   __ sw(a1, MemOperand(sp, argc_ * kPointerSize));
   __ li(a0, Operand(argc_));  // Set up the number of arguments.
   __ mov(a2, zero_reg);
-  __ GetBuiltinEntry(a3, Builtins::CALL_NON_FUNCTION);
+  __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION);
   __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
           RelocInfo::CODE_TARGET);
 }
@@ -3411,11 +3461,11 @@
   Label do_call;
   __ bind(&slow);
   __ Branch(&non_function_call, ne, a3, Operand(JS_FUNCTION_PROXY_TYPE));
-  __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
+  __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
   __ jmp(&do_call);

   __ bind(&non_function_call);
-  __ GetBuiltinEntry(a3, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
+  __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
   __ bind(&do_call);
   // Set expected number of arguments to zero (not changing r0).
   __ li(a2, Operand(0, RelocInfo::NONE32));
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Tue Jan 14 19:38:12 2014 UTC +++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Wed Jan 15 23:37:49 2014 UTC
@@ -3547,17 +3547,6 @@
     __ InvokeFunction(function, expected, count, CALL_FUNCTION, generator);
   }
 }
-
-
-void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
-  ASSERT(ToRegister(instr->result()).is(v0));
-  __ mov(a0, v0);
-  CallKnownFunction(instr->hydrogen()->function(),
-                    instr->hydrogen()->formal_parameter_count(),
-                    instr->arity(),
-                    instr,
-                    A1_UNINITIALIZED);
-}


 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
@@ -3889,25 +3878,44 @@
 }


-void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
-  ASSERT(ToRegister(instr->context()).is(cp));
+void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
   ASSERT(ToRegister(instr->result()).is(v0));

-  int arity = instr->arity();
-  Handle<Code> ic =
-      isolate()->stub_cache()->ComputeKeyedCallInitialize(arity);
-  CallCode(ic, RelocInfo::CODE_TARGET, instr);
+  LPointerMap* pointers = instr->pointer_map();
+  SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+
+  if (instr->target()->IsConstantOperand()) {
+    LConstantOperand* target = LConstantOperand::cast(instr->target());
+    Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+    generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
+    __ Call(code, RelocInfo::CODE_TARGET);
+  } else {
+    ASSERT(instr->target()->IsRegister());
+    Register target = ToRegister(instr->target());
+    generator.BeforeCall(__ CallSize(target));
+    __ Addu(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
+    __ Call(target);
+  }
+  generator.AfterCall();
 }


-void LCodeGen::DoCallNamed(LCallNamed* instr) {
-  ASSERT(ToRegister(instr->context()).is(cp));
+void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
+  ASSERT(ToRegister(instr->function()).is(a1));
   ASSERT(ToRegister(instr->result()).is(v0));

-  int arity = instr->arity();
-  Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arity);
-  __ li(a2, Operand(instr->name()));
-  CallCode(ic, RelocInfo::CODE_TARGET, instr);
+  if (instr->hydrogen()->pass_argument_count()) {
+    __ li(a0, Operand(instr->arity()));
+  }
+
+  // Change context.
+  __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
+
+  // Load the code entry address
+  __ lw(at, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
+  __ Call(at);
+
+  RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
 }


@@ -3925,16 +3933,6 @@
     CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
   }
 }
-
-
-void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
-  ASSERT(ToRegister(instr->result()).is(v0));
-  CallKnownFunction(instr->hydrogen()->target(),
-                    instr->hydrogen()->formal_parameter_count(),
-                    instr->arity(),
-                    instr,
-                    A1_UNINITIALIZED);
-}


 void LCodeGen::DoCallNew(LCallNew* instr) {
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.cc Tue Jan 14 19:38:12 2014 UTC +++ /branches/bleeding_edge/src/mips/lithium-mips.cc Wed Jan 15 23:37:49 2014 UTC
@@ -282,9 +282,20 @@
 }


-void LCallConstantFunction::PrintDataTo(StringStream* stream) {
+void LCallJSFunction::PrintDataTo(StringStream* stream) {
+  stream->Add("= ");
+  function()->PrintTo(stream);
   stream->Add("#%d / ", arity());
 }
+
+
+void LCallWithDescriptor::PrintDataTo(StringStream* stream) {
+  for (int i = 0; i < InputCount(); i++) {
+    InputAt(i)->PrintTo(stream);
+    stream->Add(" ");
+  }
+  stream->Add("#%d / ", arity());
+}


 void LLoadContextSlot::PrintDataTo(StringStream* stream) {
@@ -307,22 +318,6 @@
 }


-void LCallKeyed::PrintDataTo(StringStream* stream) {
-  stream->Add("[a2] #%d / ", arity());
-}
-
-
-void LCallNamed::PrintDataTo(StringStream* stream) {
-  SmartArrayPointer<char> name_string = name()->ToCString();
-  stream->Add("%s #%d / ", name_string.get(), arity());
-}
-
-
-void LCallKnownGlobal::PrintDataTo(StringStream* stream) {
-  stream->Add("#%d / ", arity());
-}
-
-
 void LCallNew::PrintDataTo(StringStream* stream) {
   stream->Add("= ");
   constructor()->PrintTo(stream);
@@ -562,8 +557,7 @@
 }


-template<int I, int T>
-LInstruction* LChunkBuilder::Define(LTemplateInstruction<1, I, T>* instr,
+LInstruction* LChunkBuilder::Define(LTemplateResultInstruction<1>* instr,
                                     LUnallocated* result) {
   result->set_virtual_register(current_instruction_->id());
   instr->set_result(result);
@@ -571,40 +565,35 @@
 }


-template<int I, int T>
 LInstruction* LChunkBuilder::DefineAsRegister(
-    LTemplateInstruction<1, I, T>* instr) {
+    LTemplateResultInstruction<1>* instr) {
   return Define(instr,
new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
 }


-template<int I, int T>
 LInstruction* LChunkBuilder::DefineAsSpilled(
-    LTemplateInstruction<1, I, T>* instr, int index) {
+    LTemplateResultInstruction<1>* instr, int index) {
   return Define(instr,
                 new(zone()) LUnallocated(LUnallocated::FIXED_SLOT, index));
 }


-template<int I, int T>
 LInstruction* LChunkBuilder::DefineSameAsFirst(
-    LTemplateInstruction<1, I, T>* instr) {
+    LTemplateResultInstruction<1>* instr) {
   return Define(instr,
new(zone()) LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT));
 }


-template<int I, int T>
 LInstruction* LChunkBuilder::DefineFixed(
-    LTemplateInstruction<1, I, T>* instr, Register reg) {
+    LTemplateResultInstruction<1>* instr, Register reg) {
   return Define(instr, ToUnallocated(reg));
 }


-template<int I, int T>
 LInstruction* LChunkBuilder::DefineFixedDouble(
-    LTemplateInstruction<1, I, T>* instr, DoubleRegister reg) {
+    LTemplateResultInstruction<1>* instr, DoubleRegister reg) {
   return Define(instr, ToUnallocated(reg));
 }

@@ -1080,9 +1069,32 @@
 }


-LInstruction* LChunkBuilder::DoCallConstantFunction(
-    HCallConstantFunction* instr) {
- return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, v0), instr);
+LInstruction* LChunkBuilder::DoCallJSFunction(
+    HCallJSFunction* instr) {
+  LOperand* function = UseFixed(instr->function(), a1);
+
+  LCallJSFunction* result = new(zone()) LCallJSFunction(function);
+
+  return MarkAsCall(DefineFixed(result, v0), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoCallWithDescriptor(
+    HCallWithDescriptor* instr) {
+  const CallInterfaceDescriptor* descriptor = instr->descriptor();
+
+  LOperand* target = UseRegisterOrConstantAtStart(instr->target());
+  ZoneList<LOperand*> ops(instr->OperandCount(), zone());
+  ops.Add(target, zone());
+  for (int i = 1; i < instr->OperandCount(); i++) {
+    LOperand* op = UseFixed(instr->OperandAt(i),
+        descriptor->GetParameterRegister(i - 1));
+    ops.Add(op, zone());
+  }
+
+  LCallWithDescriptor* result = new(zone()) LCallWithDescriptor(
+      descriptor, ops, zone());
+  return MarkAsCall(DefineFixed(result, v0), instr);
 }


@@ -1171,26 +1183,6 @@
   LMathRound* result = new(zone()) LMathRound(input, temp);
   return AssignEnvironment(DefineAsRegister(result));
 }
-
-
-LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) {
-  ASSERT(instr->key()->representation().IsTagged());
-  LOperand* context = UseFixed(instr->context(), cp);
-  LOperand* key = UseFixed(instr->key(), a2);
-  return MarkAsCall(
-        DefineFixed(new(zone()) LCallKeyed(context, key), v0), instr);
-}
-
-
-LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) {
-  LOperand* context = UseFixed(instr->context(), cp);
- return MarkAsCall(DefineFixed(new(zone()) LCallNamed(context), v0), instr);
-}
-
-
-LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) {
-  return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, v0), instr);
-}


 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.h Tue Jan 14 19:38:12 2014 UTC +++ /branches/bleeding_edge/src/mips/lithium-mips.h Wed Jan 15 23:37:49 2014 UTC
@@ -52,11 +52,9 @@
   V(BitI)                                       \
   V(BoundsCheck)                                \
   V(Branch)                                     \
-  V(CallConstantFunction)                       \
+  V(CallJSFunction)                             \
+  V(CallWithDescriptor)                         \
   V(CallFunction)                               \
-  V(CallKeyed)                                  \
-  V(CallKnownGlobal)                            \
-  V(CallNamed)                                  \
   V(CallNew)                                    \
   V(CallNewArray)                               \
   V(CallRuntime)                                \
@@ -299,10 +297,8 @@


 // R = number of result operands (0 or 1).
-// I = number of input operands.
-// T = number of temporary operands.
-template<int R, int I, int T>
-class LTemplateInstruction : public LInstruction {
+template<int R>
+class LTemplateResultInstruction : public LInstruction {
  public:
   // Allow 0 or 1 output operands.
   STATIC_ASSERT(R == 0 || R == 1);
@@ -314,10 +310,20 @@

  protected:
   EmbeddedContainer<LOperand*, R> results_;
+};
+
+
+// R = number of result operands (0 or 1).
+// I = number of input operands.
+// T = number of temporary operands.
+template<int R, int I, int T>
+class LTemplateInstruction : public LTemplateResultInstruction<R> {
+ protected:
   EmbeddedContainer<LOperand*, I> inputs_;
   EmbeddedContainer<LOperand*, T> temps_;

  private:
+  // Iterator support.
   virtual int InputCount() V8_FINAL V8_OVERRIDE { return I; }
virtual LOperand* InputAt(int i) V8_FINAL V8_OVERRIDE { return inputs_[i]; }

@@ -1813,71 +1819,78 @@
 };


-class LCallConstantFunction V8_FINAL : public LTemplateInstruction<1, 0, 0> {
+class LCallJSFunction V8_FINAL : public LTemplateInstruction<1, 1, 0> {
  public:
- DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function")
-  DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction)
+  explicit LCallJSFunction(LOperand* function) {
+    inputs_[0] = function;
+  }
+
+  LOperand* function() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CallJSFunction, "call-js-function")
+  DECLARE_HYDROGEN_ACCESSOR(CallJSFunction)

   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;

-  Handle<JSFunction> function() { return hydrogen()->function(); }
   int arity() const { return hydrogen()->argument_count() - 1; }
 };


-class LInvokeFunction V8_FINAL : public LTemplateInstruction<1, 2, 0> {
+class LCallWithDescriptor V8_FINAL : public LTemplateResultInstruction<1> {
  public:
-  LInvokeFunction(LOperand* context, LOperand* function) {
-    inputs_[0] = context;
-    inputs_[1] = function;
+  LCallWithDescriptor(const CallInterfaceDescriptor* descriptor,
+                      ZoneList<LOperand*>& operands,
+                      Zone* zone)
+    : descriptor_(descriptor),
+      inputs_(descriptor->environment_length() + 1, zone) {
+    ASSERT(descriptor->environment_length() + 1 == operands.length());
+    inputs_.AddAll(operands, zone);
   }

-  LOperand* context() { return inputs_[0]; }
-  LOperand* function() { return inputs_[1]; }
+  LOperand* target() const { return inputs_[0]; }
+
+  const CallInterfaceDescriptor* descriptor() { return descriptor_; }

-  DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
-  DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
+ private:
+  DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
+  DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor)

   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;

   int arity() const { return hydrogen()->argument_count() - 1; }
-};

+  const CallInterfaceDescriptor* descriptor_;
+  ZoneList<LOperand*> inputs_;

-class LCallKeyed V8_FINAL : public LTemplateInstruction<1, 2, 0> {
- public:
-  LCallKeyed(LOperand* context, LOperand* key) {
-    inputs_[0] = context;
-    inputs_[1] = key;
+  virtual void InternalSetOperandAt(int index,
+                                    LOperand* value) V8_FINAL V8_OVERRIDE {
+    inputs_[index] = value;
   }

-  LOperand* context() { return inputs_[0]; }
-  LOperand* key() { return inputs_[1]; }
+  // Iterator support.
+ virtual int InputCount() V8_FINAL V8_OVERRIDE { return inputs_.length(); } + virtual LOperand* InputAt(int i) V8_FINAL V8_OVERRIDE { return inputs_[i]; }

-  DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
-  DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
-
-  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
-
-  int arity() const { return hydrogen()->argument_count() - 1; }
+  virtual int TempCount() V8_FINAL V8_OVERRIDE { return 0; }
+  virtual LOperand* TempAt(int i) V8_FINAL V8_OVERRIDE { return NULL; }
 };


-
-class LCallNamed V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LInvokeFunction V8_FINAL : public LTemplateInstruction<1, 2, 0> {
  public:
-  explicit LCallNamed(LOperand* context) {
+  LInvokeFunction(LOperand* context, LOperand* function) {
     inputs_[0] = context;
+    inputs_[1] = function;
   }

   LOperand* context() { return inputs_[0]; }
+  LOperand* function() { return inputs_[1]; }

-  DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named")
-  DECLARE_HYDROGEN_ACCESSOR(CallNamed)
+  DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
+  DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)

   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;

-  Handle<String> name() const { return hydrogen()->name(); }
   int arity() const { return hydrogen()->argument_count() - 1; }
 };

@@ -1898,17 +1911,6 @@
   int arity() const { return hydrogen()->argument_count() - 1; }
 };

-
-class LCallKnownGlobal V8_FINAL : public LTemplateInstruction<1, 0, 0> {
- public:
-  DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global")
-  DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal)
-
-  virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
-
-  int arity() const { return hydrogen()->argument_count() - 1;  }
-};
-

 class LCallNew V8_FINAL : public LTemplateInstruction<1, 2, 0> {
  public:
@@ -2762,22 +2764,16 @@

   // Methods for setting up define-use relationships.
   // Return the same instruction that they are passed.
-  template<int I, int T>
-      LInstruction* Define(LTemplateInstruction<1, I, T>* instr,
-                           LUnallocated* result);
-  template<int I, int T>
-      LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr);
-  template<int I, int T>
-      LInstruction* DefineAsSpilled(LTemplateInstruction<1, I, T>* instr,
-                                    int index);
-  template<int I, int T>
- LInstruction* DefineSameAsFirst(LTemplateInstruction<1, I, T>* instr);
-  template<int I, int T>
-      LInstruction* DefineFixed(LTemplateInstruction<1, I, T>* instr,
-                                Register reg);
-  template<int I, int T>
-      LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
-                                      DoubleRegister reg);
+  LInstruction* Define(LTemplateResultInstruction<1>* instr,
+                       LUnallocated* result);
+  LInstruction* DefineAsRegister(LTemplateResultInstruction<1>* instr);
+  LInstruction* DefineAsSpilled(LTemplateResultInstruction<1>* instr,
+                                int index);
+  LInstruction* DefineSameAsFirst(LTemplateResultInstruction<1>* instr);
+  LInstruction* DefineFixed(LTemplateResultInstruction<1>* instr,
+                            Register reg);
+  LInstruction* DefineFixedDouble(LTemplateResultInstruction<1>* instr,
+                                  DoubleRegister reg);
   LInstruction* AssignEnvironment(LInstruction* instr);
   LInstruction* AssignPointerMap(LInstruction* instr);

=======================================
--- /branches/bleeding_edge/src/mips/macro-assembler-mips.cc Tue Jan 14 18:17:24 2014 UTC +++ /branches/bleeding_edge/src/mips/macro-assembler-mips.cc Wed Jan 15 23:37:49 2014 UTC
@@ -3591,7 +3591,6 @@
   //  a0: actual arguments count
   //  a1: function (passed through to callee)
   //  a2: expected arguments count
-  //  a3: callee code entry

// The code below is made a lot easier because the calling code already sets // up actual and expected registers according to the contract if values are
@@ -3676,33 +3675,6 @@
     bind(&done);
   }
 }
-
-
-void MacroAssembler::InvokeCode(Handle<Code> code,
-                                const ParameterCount& expected,
-                                const ParameterCount& actual,
-                                RelocInfo::Mode rmode,
-                                InvokeFlag flag) {
-  // You can't call a function without a valid frame.
-  ASSERT(flag == JUMP_FUNCTION || has_frame());
-
-  Label done;
-
-  bool definitely_mismatches = false;
-  InvokePrologue(expected, actual, code, no_reg,
-                 &done, &definitely_mismatches, flag,
-                 NullCallWrapper());
-  if (!definitely_mismatches) {
-    if (flag == CALL_FUNCTION) {
-      Call(code, rmode);
-    } else {
-      Jump(code, rmode);
-    }
-    // Continue here if InvokePrologue does handle the invocation due to
-    // mismatched parameter counts.
-    bind(&done);
-  }
-}


 void MacroAssembler::InvokeFunction(Register function,
=======================================
--- /branches/bleeding_edge/src/mips/macro-assembler-mips.h Tue Jan 14 18:17:24 2014 UTC +++ /branches/bleeding_edge/src/mips/macro-assembler-mips.h Wed Jan 15 23:37:49 2014 UTC
@@ -901,12 +901,6 @@
                   InvokeFlag flag,
                   const CallWrapper& call_wrapper);

-  void InvokeCode(Handle<Code> code,
-                  const ParameterCount& expected,
-                  const ParameterCount& actual,
-                  RelocInfo::Mode rmode,
-                  InvokeFlag flag);
-
   // Invoke the JavaScript function in the given register. Changes the
   // current context to the context in the function before invoking.
   void InvokeFunction(Register function,

--
--
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/groups/opt_out.

Reply via email to