Reviewers: danno, Benedikt Meurer, Paul Lind, kisg, palfia,

Description:
MIPS: Lazily save double registers for HCallRuntime instructions within Hydrogen
code stubs.

Port r17044 (94843cc)

Original commit message:
Right now we eagerly save all allocatable double registers upon
entry to every Hydrogen code stub that uses HCallRuntime, and
restore them when we return. Since the HCallRuntime is on the
fallback path for code stubs, this is both a waste of time and
stack space in almost every case.

This patch adds a flag to the HCallRuntime, which controls whether
the instruction saves the double register itself (using the save
doubles flag for the CEntryStub), or whether its up the surrounding
code to handle the clobbering of double registers.

BUG=

Please review this at https://codereview.chromium.org/25567002/

SVN Base: https://github.com/v8/v8.git@gbl

Affected files (+29, -24 lines):
  M src/mips/lithium-codegen-mips.h
  M src/mips/lithium-codegen-mips.cc
  M src/mips/lithium-mips.h
  M src/mips/lithium-mips.cc
  M src/mips/macro-assembler-mips.h
  M src/mips/macro-assembler-mips.cc


Index: src/mips/lithium-codegen-mips.cc
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 97dcd163cf2c7a6b2ffaf0e37e3feacf31db8c29..c8ce78ec57a181e5de664dc9c4cb1493ae9539a2 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -712,13 +712,15 @@ void LCodeGen::CallCodeGeneric(Handle<Code> code,

 void LCodeGen::CallRuntime(const Runtime::Function* function,
                            int num_arguments,
-                           LInstruction* instr) {
+                           LInstruction* instr,
+                           SaveFPRegsMode save_doubles) {
   ASSERT(instr != NULL);
   LPointerMap* pointers = instr->pointer_map();
   ASSERT(pointers != NULL);
   RecordPosition(pointers->position());

-  __ CallRuntime(function, num_arguments);
+  __ CallRuntime(function, num_arguments, save_doubles);
+
   RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
 }

Index: src/mips/lithium-codegen-mips.h
diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h index 84105cae35fe0801b5db1f093e9aaa15e3cf2382..f261f4272a8ddb16382d3e1608c644d3fba0b44e 100644
--- a/src/mips/lithium-codegen-mips.h
+++ b/src/mips/lithium-codegen-mips.h
@@ -245,7 +245,8 @@ class LCodeGen V8_FINAL  BASE_EMBEDDED {

   void CallRuntime(const Runtime::Function* function,
                    int num_arguments,
-                   LInstruction* instr);
+                   LInstruction* instr,
+                   SaveFPRegsMode save_doubles = kDontSaveFPRegs);

   void CallRuntime(Runtime::FunctionId id,
                    int num_arguments,
Index: src/mips/lithium-mips.cc
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index 8a349120eb6458dd51579896282dd99fbebcf9a1..e32a44dde7cf72b63f50ca954e358faa0b854715 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -867,6 +867,10 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
   LInstruction* instr = current->CompileToLithium(this);

   if (instr != NULL) {
+    // Associate the hydrogen instruction first, since we may need it for
+    // the ClobbersRegisters() or ClobbersDoubleRegisters() calls below.
+    instr->set_hydrogen_value(current);
+
 #if DEBUG
     // Make sure that the lithium instruction has either no fixed register
     // constraints in temps or the result OR no uses that are only used at
@@ -903,7 +907,6 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
     if (FLAG_stress_environments && !instr->HasEnvironment()) {
       instr = AssignEnvironment(instr);
     }
-    instr->set_hydrogen_value(current);
     chunk_->AddInstruction(instr, current_block_);
   }
   current_instruction_ = old_current;
Index: src/mips/lithium-mips.h
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index a48422eecf5e4e132afd1e2c4fb3f340286c3573..71360bda299f5e61a6d4aea12e2bf17dfd85ebf3 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -274,7 +274,7 @@ class LInstruction : public ZoneObject {
   // Interface to the register allocator and iterators.
   bool ClobbersTemps() const { return IsCall(); }
   bool ClobbersRegisters() const { return IsCall(); }
-  bool ClobbersDoubleRegisters() const { return IsCall(); }
+  virtual bool ClobbersDoubleRegisters() const { return IsCall(); }

   // Interface to the register allocator and iterators.
   bool IsMarkedAsCall() const { return IsCall(); }
@@ -1963,8 +1963,13 @@ class LCallRuntime V8_FINAL : public LTemplateInstruction<1, 0, 0> {
   DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
   DECLARE_HYDROGEN_ACCESSOR(CallRuntime)

+  virtual bool ClobbersDoubleRegisters() const V8_OVERRIDE {
+    return save_doubles() == kDontSaveFPRegs;
+  }
+
const Runtime::Function* function() const { return hydrogen()->function(); }
   int arity() const { return hydrogen()->argument_count(); }
+ SaveFPRegsMode save_doubles() const { return hydrogen()->save_doubles(); }
 };


Index: src/mips/macro-assembler-mips.cc
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc index cbb538f39d34d8977c978fd08681f5dbce3b31a8..788f2aacd84ecdc9ec803d40f5d1f55bb32392fa 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -4136,7 +4136,8 @@ void MacroAssembler::SubuAndCheckForOverflow(Register dst,


 void MacroAssembler::CallRuntime(const Runtime::Function* f,
-                                 int num_arguments) {
+                                 int num_arguments,
+                                 SaveFPRegsMode save_doubles) {
   // All parameters are on the stack. v0 has the return value after call.

   // If the expected number of arguments of the runtime function is
@@ -4153,25 +4154,11 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f,
   // smarter.
   PrepareCEntryArgs(num_arguments);
   PrepareCEntryFunction(ExternalReference(f, isolate()));
-  CEntryStub stub(1);
-  CallStub(&stub);
-}
-
-
-void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) {
-  const Runtime::Function* function = Runtime::FunctionForId(id);
-  PrepareCEntryArgs(function->nargs);
-  PrepareCEntryFunction(ExternalReference(function, isolate()));
-  CEntryStub stub(1, kSaveFPRegs);
+  CEntryStub stub(1, save_doubles);
   CallStub(&stub);
 }


-void MacroAssembler::CallRuntime(Runtime::FunctionId fid, int num_arguments) {
-  CallRuntime(Runtime::FunctionForId(fid), num_arguments);
-}
-
-
 void MacroAssembler::CallExternalReference(const ExternalReference& ext,
                                            int num_arguments,
                                            BranchDelaySlot bd) {
Index: src/mips/macro-assembler-mips.h
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h index 9cc774873d6d98af8308c5a46eea1c2a95e4c519..2814c943b49b3b2ec54a7a77e062cc086d402cc4 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -1201,11 +1201,18 @@ class MacroAssembler: public Assembler {
   void CallJSExitStub(CodeStub* stub);

   // Call a runtime routine.
-  void CallRuntime(const Runtime::Function* f, int num_arguments);
-  void CallRuntimeSaveDoubles(Runtime::FunctionId id);
+  void CallRuntime(const Runtime::Function* f,
+                   int num_arguments,
+                   SaveFPRegsMode save_doubles = kDontSaveFPRegs);
+  void CallRuntimeSaveDoubles(Runtime::FunctionId id) {
+    const Runtime::Function* function = Runtime::FunctionForId(id);
+    CallRuntime(function, function->nargs, kSaveFPRegs);
+  }

   // Convenience function: Same as above, but takes the fid instead.
-  void CallRuntime(Runtime::FunctionId fid, int num_arguments);
+  void CallRuntime(Runtime::FunctionId id, int num_arguments) {
+    CallRuntime(Runtime::FunctionForId(id), num_arguments);
+  }

   // Convenience function: call an external reference.
   void CallExternalReference(const ExternalReference& ext,


--
--
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