Revision: 11364
Author:   [email protected]
Date:     Wed Apr 18 02:38:45 2012
Log: Simplify invocation sequence at monomorphic function invocation sites.

Provide known target as a hint to HInvokeFunction instruction so that it can statically determine if arguments adaptation is required.

[email protected]
BUG=v8:2079

Review URL: https://chromiumcodereview.appspot.com/10116021
http://code.google.com/p/v8/source/detail?r=11364

Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.h
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.h
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h
 /branches/bleeding_edge/src/ia32/lithium-ia32.h
 /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
 /branches/bleeding_edge/src/mips/lithium-codegen-mips.h
 /branches/bleeding_edge/src/mips/lithium-mips.h
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.h
 /branches/bleeding_edge/src/x64/lithium-x64.h

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h       Wed Apr 11 07:08:11 2012
+++ /branches/bleeding_edge/src/arm/lithium-arm.h       Wed Apr 18 02:38:45 2012
@@ -1473,6 +1473,7 @@
   virtual void PrintDataTo(StringStream* stream);

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


=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Apr 17 04:12:37 2012 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Apr 18 02:38:45 2012
@@ -2962,7 +2962,8 @@
 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
                                  int arity,
                                  LInstruction* instr,
-                                 CallKind call_kind) {
+                                 CallKind call_kind,
+                                 R1State r1_state) {
   bool can_invoke_directly = !function->NeedsArgumentsAdaption() ||
       function->shared()->formal_parameter_count() == arity;

@@ -2970,7 +2971,10 @@
   RecordPosition(pointers->position());

   if (can_invoke_directly) {
-    __ LoadHeapObject(r1, function);
+    if (r1_state == R1_UNINITIALIZED) {
+      __ LoadHeapObject(r1, function);
+    }
+
     // Change context if needed.
     bool change_context =
         (info()->closure()->context() != function->context()) ||
@@ -3009,7 +3013,8 @@
   CallKnownFunction(instr->function(),
                     instr->arity(),
                     instr,
-                    CALL_AS_METHOD);
+                    CALL_AS_METHOD,
+                    R1_UNINITIALIZED);
 }


@@ -3434,12 +3439,21 @@
   ASSERT(ToRegister(instr->function()).is(r1));
   ASSERT(instr->HasPointerMap());
   ASSERT(instr->HasDeoptimizationEnvironment());
-  LPointerMap* pointers = instr->pointer_map();
-  RecordPosition(pointers->position());
-  SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
-  ParameterCount count(instr->arity());
-  __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
-  __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+
+  if (instr->known_function().is_null()) {
+    LPointerMap* pointers = instr->pointer_map();
+    RecordPosition(pointers->position());
+    SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+    ParameterCount count(instr->arity());
+    __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
+    __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  } else {
+    CallKnownFunction(instr->known_function(),
+                      instr->arity(),
+                      instr,
+                      CALL_AS_METHOD,
+                      R1_CONTAINS_TARGET);
+  }
 }


@@ -3494,7 +3508,11 @@

 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
   ASSERT(ToRegister(instr->result()).is(r0));
- CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION);
+  CallKnownFunction(instr->target(),
+                    instr->arity(),
+                    instr,
+                    CALL_AS_FUNCTION,
+                    R1_UNINITIALIZED);
 }


=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Tue Mar 6 08:12:11 2012 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Wed Apr 18 02:38:45 2012
@@ -215,12 +215,18 @@
                                int argc,
                                LInstruction* instr);

+  enum R1State {
+    R1_UNINITIALIZED,
+    R1_CONTAINS_TARGET
+  };
+
   // Generate a direct call to a known function.  Expects the function
   // to be in r1.
   void CallKnownFunction(Handle<JSFunction> function,
                          int arity,
                          LInstruction* instr,
-                         CallKind call_kind);
+                         CallKind call_kind,
+                         R1State r1_state);

   void LoadHeapObject(Register result, Handle<HeapObject> object);

=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Mon Apr 16 04:38:01 2012 +++ /branches/bleeding_edge/src/hydrogen-instructions.h Wed Apr 18 02:38:45 2012
@@ -1643,6 +1643,14 @@
   HInvokeFunction(HValue* context, HValue* function, int argument_count)
       : HBinaryCall(context, function, argument_count) {
   }
+
+  HInvokeFunction(HValue* context,
+                  HValue* function,
+                  Handle<JSFunction> known_function,
+                  int argument_count)
+      : HBinaryCall(context, function, argument_count),
+        known_function_(known_function) {
+  }

   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::Tagged();
@@ -1650,8 +1658,12 @@

   HValue* context() { return first(); }
   HValue* function() { return second(); }
+  Handle<JSFunction> known_function() { return known_function_; }

   DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
+
+ private:
+  Handle<JSFunction> known_function_;
 };


=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Tue Apr 17 04:12:37 2012
+++ /branches/bleeding_edge/src/hydrogen.cc     Wed Apr 18 02:38:45 2012
@@ -6165,9 +6165,11 @@
       if (TryInlineCall(expr, true)) {   // Drop function from environment.
         return;
       } else {
-        call = PreProcessCall(new(zone()) HInvokeFunction(context,
-                                                          function,
-                                                          argument_count));
+        call = PreProcessCall(
+            new(zone()) HInvokeFunction(context,
+                                        function,
+                                        expr->target(),
+                                        argument_count));
         Drop(1);  // The function.
       }

=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Apr 17 04:12:37 2012 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Apr 18 02:38:45 2012
@@ -2738,7 +2738,8 @@
 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
                                  int arity,
                                  LInstruction* instr,
-                                 CallKind call_kind) {
+                                 CallKind call_kind,
+                                 EDIState edi_state) {
   bool can_invoke_directly = !function->NeedsArgumentsAdaption() ||
       function->shared()->formal_parameter_count() == arity;

@@ -2746,7 +2747,9 @@
   RecordPosition(pointers->position());

   if (can_invoke_directly) {
-    __ LoadHeapObject(edi, function);
+    if (edi_state == EDI_UNINITIALIZED) {
+      __ LoadHeapObject(edi, function);
+    }

     // Change context if needed.
     bool change_context =
@@ -2789,7 +2792,8 @@
   CallKnownFunction(instr->function(),
                     instr->arity(),
                     instr,
-                    CALL_AS_METHOD);
+                    CALL_AS_METHOD,
+                    EDI_UNINITIALIZED);
 }


@@ -3236,12 +3240,21 @@
   ASSERT(ToRegister(instr->function()).is(edi));
   ASSERT(instr->HasPointerMap());
   ASSERT(instr->HasDeoptimizationEnvironment());
-  LPointerMap* pointers = instr->pointer_map();
-  RecordPosition(pointers->position());
-  SafepointGenerator generator(
-      this, pointers, Safepoint::kLazyDeopt);
-  ParameterCount count(instr->arity());
-  __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
+
+  if (instr->known_function().is_null()) {
+    LPointerMap* pointers = instr->pointer_map();
+    RecordPosition(pointers->position());
+    SafepointGenerator generator(
+        this, pointers, Safepoint::kLazyDeopt);
+    ParameterCount count(instr->arity());
+ __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
+  } else {
+    CallKnownFunction(instr->known_function(),
+                      instr->arity(),
+                      instr,
+                      CALL_AS_METHOD,
+                      EDI_CONTAINS_TARGET);
+  }
 }


@@ -3296,7 +3309,11 @@

 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
   ASSERT(ToRegister(instr->result()).is(eax));
- CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION);
+  CallKnownFunction(instr->target(),
+                    instr->arity(),
+                    instr,
+                    CALL_AS_FUNCTION,
+                    EDI_UNINITIALIZED);
 }


=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Mon Mar 19 00:45:06 2012 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Wed Apr 18 02:38:45 2012
@@ -206,12 +206,18 @@
                                LInstruction* instr,
                                LOperand* context);

+  enum EDIState {
+    EDI_UNINITIALIZED,
+    EDI_CONTAINS_TARGET
+  };
+
   // Generate a direct call to a known function.  Expects the function
   // to be in edi.
   void CallKnownFunction(Handle<JSFunction> function,
                          int arity,
                          LInstruction* instr,
-                         CallKind call_kind);
+                         CallKind call_kind,
+                         EDIState edi_state);

   void RecordSafepointWithLazyDeopt(LInstruction* instr,
                                     SafepointMode safepoint_mode);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h     Wed Apr 11 07:08:11 2012
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h     Wed Apr 18 02:38:45 2012
@@ -1502,6 +1502,7 @@
   virtual void PrintDataTo(StringStream* stream);

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


=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Tue Apr 17 04:12:37 2012 +++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Wed Apr 18 02:38:45 2012
@@ -2848,7 +2848,8 @@
 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
                                  int arity,
                                  LInstruction* instr,
-                                 CallKind call_kind) {
+                                 CallKind call_kind,
+                                 A1State a1_state) {
   bool can_invoke_directly = !function->NeedsArgumentsAdaption() ||
       function->shared()->formal_parameter_count() == arity;

@@ -2856,7 +2857,10 @@
   RecordPosition(pointers->position());

   if (can_invoke_directly) {
-    __ LoadHeapObject(a1, function);
+    if (a1_state == A1_UNINITIALIZED) {
+      __ LoadHeapObject(a1, function);
+    }
+
     // Change context if needed.
     bool change_context =
         (info()->closure()->context() != function->context()) ||
@@ -2893,7 +2897,11 @@
 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
   ASSERT(ToRegister(instr->result()).is(v0));
   __ mov(a0, v0);
- CallKnownFunction(instr->function(), instr->arity(), instr, CALL_AS_METHOD);
+  CallKnownFunction(instr->function(),
+                    instr->arity(),
+                    instr,
+                    CALL_AS_METHOD,
+                    A1_UNINITIALIZED);
 }


@@ -3330,12 +3338,21 @@
   ASSERT(ToRegister(instr->function()).is(a1));
   ASSERT(instr->HasPointerMap());
   ASSERT(instr->HasDeoptimizationEnvironment());
-  LPointerMap* pointers = instr->pointer_map();
-  RecordPosition(pointers->position());
-  SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
-  ParameterCount count(instr->arity());
-  __ InvokeFunction(a1, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
-  __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+
+  if (instr->known_function().is_null()) {
+    LPointerMap* pointers = instr->pointer_map();
+    RecordPosition(pointers->position());
+    SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+    ParameterCount count(instr->arity());
+    __ InvokeFunction(a1, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
+    __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  } else {
+    CallKnownFunction(instr->known_function(),
+                      instr->arity(),
+                      instr,
+                      CALL_AS_METHOD,
+                      A1_CONTAINS_TARGET);
+  }
 }


@@ -3390,7 +3407,11 @@

 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
   ASSERT(ToRegister(instr->result()).is(v0));
- CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION);
+  CallKnownFunction(instr->target(),
+                    instr->arity(),
+                    instr,
+                    CALL_AS_FUNCTION,
+                    A1_UNINITIALIZED);
 }


=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.h Tue Mar 6 09:39:12 2012 +++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.h Wed Apr 18 02:38:45 2012
@@ -212,12 +212,18 @@
                                int argc,
                                LInstruction* instr);

+  enum A1State {
+    A1_UNINITIALIZED,
+    A1_CONTAINS_TARGET
+  };
+
   // Generate a direct call to a known function.  Expects the function
   // to be in a1.
   void CallKnownFunction(Handle<JSFunction> function,
                          int arity,
                          LInstruction* instr,
-                         CallKind call_kind);
+                         CallKind call_kind,
+                         A1State a1_state);

   void LoadHeapObject(Register result, Handle<HeapObject> object);

=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.h     Wed Apr 11 06:40:55 2012
+++ /branches/bleeding_edge/src/mips/lithium-mips.h     Wed Apr 18 02:38:45 2012
@@ -1453,6 +1453,7 @@
   virtual void PrintDataTo(StringStream* stream);

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


=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Apr 17 04:12:37 2012 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Apr 18 02:38:45 2012
@@ -2693,7 +2693,8 @@
 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
                                  int arity,
                                  LInstruction* instr,
-                                 CallKind call_kind) {
+                                 CallKind call_kind,
+                                 RDIState rdi_state) {
   bool can_invoke_directly = !function->NeedsArgumentsAdaption() ||
       function->shared()->formal_parameter_count() == arity;

@@ -2701,7 +2702,9 @@
   RecordPosition(pointers->position());

   if (can_invoke_directly) {
-    __ LoadHeapObject(rdi, function);
+    if (rdi_state == RDI_UNINITIALIZED) {
+      __ LoadHeapObject(rdi, function);
+    }

     // Change context if needed.
     bool change_context =
@@ -2746,7 +2749,8 @@
   CallKnownFunction(instr->function(),
                     instr->arity(),
                     instr,
-                    CALL_AS_METHOD);
+                    CALL_AS_METHOD,
+                    RDI_UNINITIALIZED);
 }


@@ -3184,12 +3188,21 @@
   ASSERT(ToRegister(instr->function()).is(rdi));
   ASSERT(instr->HasPointerMap());
   ASSERT(instr->HasDeoptimizationEnvironment());
-  LPointerMap* pointers = instr->pointer_map();
-  RecordPosition(pointers->position());
-  SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
-  ParameterCount count(instr->arity());
-  __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
-  __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
+
+  if (instr->known_function().is_null()) {
+    LPointerMap* pointers = instr->pointer_map();
+    RecordPosition(pointers->position());
+    SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+    ParameterCount count(instr->arity());
+ __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
+    __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
+  } else {
+    CallKnownFunction(instr->known_function(),
+                      instr->arity(),
+                      instr,
+                      CALL_AS_METHOD,
+                      RDI_CONTAINS_TARGET);
+  }
 }


@@ -3243,7 +3256,11 @@

 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
   ASSERT(ToRegister(instr->result()).is(rax));
- CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION);
+  CallKnownFunction(instr->target(),
+                    instr->arity(),
+                    instr,
+                    CALL_AS_FUNCTION,
+                    RDI_UNINITIALIZED);
 }


=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Tue Mar 6 08:12:11 2012 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Wed Apr 18 02:38:45 2012
@@ -196,12 +196,18 @@
                                int argc,
                                LInstruction* instr);

+  enum RDIState {
+    RDI_UNINITIALIZED,
+    RDI_CONTAINS_TARGET
+  };
+
   // Generate a direct call to a known function.  Expects the function
   // to be in rdi.
   void CallKnownFunction(Handle<JSFunction> function,
                          int arity,
                          LInstruction* instr,
-                         CallKind call_kind);
+                         CallKind call_kind,
+                         RDIState rdi_state);


   void RecordSafepointWithLazyDeopt(LInstruction* instr,
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h       Wed Apr 11 07:08:11 2012
+++ /branches/bleeding_edge/src/x64/lithium-x64.h       Wed Apr 18 02:38:45 2012
@@ -1447,6 +1447,7 @@
   virtual void PrintDataTo(StringStream* stream);

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


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

Reply via email to