Revert r18144, r18143.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 29 Nov 2013 10:31:49 +0000 (10:31 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 29 Nov 2013 10:31:49 +0000 (10:31 +0000)
MIPS: Fix register usage.

MIPS: Cleanup in the CallStubCompiler.

The original revisions r18131 and r18139 have been reverted.

TBR=palfia@homejinni.com

Review URL: https://codereview.chromium.org/96743002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18154 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/mips/macro-assembler-mips.cc
src/mips/macro-assembler-mips.h
src/mips/stub-cache-mips.cc

index 703fe754361c59e7d2349847d8521f5d89af9fb4..04aa9c97153352fe1e6b2ed90bef636cd57b414c 100644 (file)
@@ -3728,7 +3728,7 @@ void MacroAssembler::InvokeFunction(Register function,
 }
 
 
-void MacroAssembler::InvokeFunction(Register function,
+void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
                                     const ParameterCount& expected,
                                     const ParameterCount& actual,
                                     InvokeFlag flag,
@@ -3737,10 +3737,8 @@ void MacroAssembler::InvokeFunction(Register function,
   // You can't call a function without a valid frame.
   ASSERT(flag == JUMP_FUNCTION || has_frame());
 
-  // Contract with called JS functions requires that function is passed in a1.
-  ASSERT(function.is(a1));
-
   // Get the function and setup the context.
+  li(a1, function);
   lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
 
   // We call indirectly through the code field in the function to
@@ -3751,17 +3749,6 @@ void MacroAssembler::InvokeFunction(Register function,
 }
 
 
-void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
-                                    const ParameterCount& expected,
-                                    const ParameterCount& actual,
-                                    InvokeFlag flag,
-                                    const CallWrapper& call_wrapper,
-                                    CallKind call_kind) {
-  li(a1, function);
-  InvokeFunction(a1, expected, actual, flag, call_wrapper, call_kind);
-}
-
-
 void MacroAssembler::IsObjectJSObjectType(Register heap_object,
                                           Register map,
                                           Register scratch,
index 4bf3e8913317d254bd5d9f48db892a918579b334..e4187c0fb47ffa93db46d20fd7659ea89461e5ab 100644 (file)
@@ -917,13 +917,6 @@ class MacroAssembler: public Assembler {
                       const CallWrapper& call_wrapper,
                       CallKind call_kind);
 
-  void InvokeFunction(Register function,
-                      const ParameterCount& expected,
-                      const ParameterCount& actual,
-                      InvokeFlag flag,
-                      const CallWrapper& call_wrapper,
-                      CallKind call_kind);
-
   void InvokeFunction(Handle<JSFunction> function,
                       const ParameterCount& expected,
                       const ParameterCount& actual,
index 4190e628c0d6c084b6c8788a48b48994cb1d7748..748a783c513f4b7b8f04728f9640762df4dd4378 100644 (file)
@@ -732,6 +732,35 @@ void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
 }
 
 
+static void GenerateCallFunction(MacroAssembler* masm,
+                                 Handle<Object> object,
+                                 const ParameterCount& arguments,
+                                 Label* miss,
+                                 ExtraICState extra_ic_state) {
+  // ----------- S t a t e -------------
+  //  -- a0: receiver
+  //  -- a1: function to call
+  // -----------------------------------
+  // Check that the function really is a function.
+  __ JumpIfSmi(a1, miss);
+  __ GetObjectType(a1, a3, a3);
+  __ Branch(miss, ne, a3, Operand(JS_FUNCTION_TYPE));
+
+  if (object->IsGlobalObject()) {
+    const int argc = arguments.immediate();
+    const int receiver_offset = argc * kPointerSize;
+    __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
+    __ sw(a3, MemOperand(sp, receiver_offset));
+  }
+
+  // Invoke the function.
+  CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state)
+      ? CALL_AS_FUNCTION
+      : CALL_AS_METHOD;
+  __ InvokeFunction(a1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind);
+}
+
+
 static void PushInterceptorArguments(MacroAssembler* masm,
                                      Register receiver,
                                      Register holder,
@@ -913,7 +942,7 @@ static void GenerateFastApiCall(MacroAssembler* masm,
 
 class CallInterceptorCompiler BASE_EMBEDDED {
  public:
-  CallInterceptorCompiler(CallStubCompiler* stub_compiler,
+  CallInterceptorCompiler(StubCompiler* stub_compiler,
                           const ParameterCount& arguments,
                           Register name,
                           ExtraICState extra_ic_state)
@@ -1025,8 +1054,13 @@ class CallInterceptorCompiler BASE_EMBEDDED {
       GenerateFastApiDirectCall(
           masm, optimization, arguments_.immediate(), false);
     } else {
+      CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+          ? CALL_AS_FUNCTION
+          : CALL_AS_METHOD;
       Handle<JSFunction> function = optimization.constant_function();
-      stub_compiler_->GenerateJumpFunction(object, function);
+      ParameterCount expected(function);
+      __ InvokeFunction(function, expected, arguments_,
+                        JUMP_FUNCTION, NullCallWrapper(), call_kind);
     }
 
     // Deferred code for fast API call case---clean preallocated space.
@@ -1092,7 +1126,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
     __ Branch(interceptor_succeeded, ne, v0, Operand(scratch));
   }
 
-  CallStubCompiler* stub_compiler_;
+  StubCompiler* stub_compiler_;
   const ParameterCount& arguments_;
   Register name_;
   ExtraICState extra_ic_state_;
@@ -1493,15 +1527,6 @@ void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
 }
 
 
-void CallStubCompiler::GenerateFunctionCheck(Register function,
-                                             Register scratch,
-                                             Label* miss) {
-  __ JumpIfSmi(function, miss);
-  __ GetObjectType(function, scratch, scratch);
-  __ Branch(miss, ne, scratch, Operand(JS_FUNCTION_TYPE));
-}
-
-
 void CallStubCompiler::GenerateLoadFunctionFromCell(
     Handle<Cell> cell,
     Handle<JSFunction> function,
@@ -1517,7 +1542,9 @@ void CallStubCompiler::GenerateLoadFunctionFromCell(
     // the nice side effect that multiple closures based on the same
     // function can all use this call IC. Before we load through the
     // function, we have to verify that it still is a function.
-    GenerateFunctionCheck(a1, a3, miss);
+    __ JumpIfSmi(a1, miss);
+    __ GetObjectType(a1, a3, a3);
+    __ Branch(miss, ne, a3, Operand(JS_FUNCTION_TYPE));
 
     // Check the shared function info. Make sure it hasn't changed.
     __ li(a3, Handle<SharedFunctionInfo>(function->shared()));
@@ -1548,7 +1575,8 @@ Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
       object, holder, name, RECEIVER_MAP_CHECK, &miss);
   GenerateFastPropertyLoad(masm(), a1, reg, index.is_inobject(holder),
                            index.translate(holder), Representation::Tagged());
-  GenerateJumpFunction(object, a1, &miss);
+
+  GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_);
 
   HandlerFrontendFooter(&miss);
 
@@ -1960,7 +1988,8 @@ Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
   __ bind(&miss);
   // Restore function name in a2.
   __ li(a2, name);
-  HandlerFrontendFooter(&name_miss);
+  __ bind(&name_miss);
+  GenerateMissBranch();
 
   // Return the generated code.
   return GetCode(type, name);
@@ -2024,7 +2053,8 @@ Handle<Code> CallStubCompiler::CompileStringCharAtCall(
   __ bind(&miss);
   // Restore function name in a2.
   __ li(a2, name);
-  HandlerFrontendFooter(&name_miss);
+  __ bind(&name_miss);
+  GenerateMissBranch();
 
   // Return the generated code.
   return GetCode(type, name);
@@ -2070,10 +2100,12 @@ Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
   StubRuntimeCallHelper call_helper;
   generator.GenerateSlow(masm(), call_helper);
 
+  // Tail call the full function. We do not have to patch the receiver
+  // because the function makes no use of it.
   __ bind(&slow);
-  // We do not have to patch the receiver because the function makes no use of
-  // it.
-  GenerateJumpFunctionIgnoreReceiver(function);
+  ParameterCount expected(function);
+  __ InvokeFunction(function, expected, arguments(),
+                    JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
 
   HandlerFrontendFooter(&miss);
 
@@ -2179,9 +2211,11 @@ Handle<Code> CallStubCompiler::CompileMathFloorCall(
   __ ctc1(a3, FCSR);
 
   __ bind(&slow);
-  // We do not have to patch the receiver because the function makes no use of
-  // it.
-  GenerateJumpFunctionIgnoreReceiver(function);
+  // Tail call the full function. We do not have to patch the receiver
+  // because the function makes no use of it.
+  ParameterCount expected(function);
+  __ InvokeFunction(function, expected, arguments(),
+                    JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
 
   HandlerFrontendFooter(&miss);
 
@@ -2258,10 +2292,12 @@ Handle<Code> CallStubCompiler::CompileMathAbsCall(
   __ sw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
   __ DropAndRet(argc + 1);
 
+  // Tail call the full function. We do not have to patch the receiver
+  // because the function makes no use of it.
   __ bind(&slow);
-  // We do not have to patch the receiver because the function makes no use of
-  // it.
-  GenerateJumpFunctionIgnoreReceiver(function);
+  ParameterCount expected(function);
+  __ InvokeFunction(function, expected, arguments(),
+                    JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
 
   HandlerFrontendFooter(&miss);
 
@@ -2316,7 +2352,8 @@ Handle<Code> CallStubCompiler::CompileFastApiCall(
   __ bind(&miss);
   FreeSpaceForFastApiCall(masm());
 
-  HandlerFrontendFooter(&miss_before_stack_reserved);
+  __ bind(&miss_before_stack_reserved);
+  GenerateMissBranch();
 
   // Return the generated code.
   return GetCode(function);
@@ -2335,7 +2372,7 @@ void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
 
 
 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
-  if (!object.is_null() && object->IsGlobalObject()) {
+  if (object->IsGlobalObject()) {
     const int argc = arguments().immediate();
     const int receiver_offset = argc * kPointerSize;
     __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
@@ -2431,17 +2468,39 @@ Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
 }
 
 
-void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
-                                            Register function,
-                                            Label* miss) {
-  ASSERT(function.is(a1));
-  // Check that the function really is a function.
-  GenerateFunctionCheck(function, a3, miss);
-  if (!function.is(a1)) __ mov(a1, function);
+void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) {
+  CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
+      ? CALL_AS_FUNCTION
+      : CALL_AS_METHOD;
+  ParameterCount expected(function);
+  __ InvokeFunction(function, expected, arguments(),
+                    JUMP_FUNCTION, NullCallWrapper(), call_kind);
+}
+
+
+Handle<Code> CallStubCompiler::CompileCallConstant(
+    Handle<Object> object,
+    Handle<JSObject> holder,
+    Handle<Name> name,
+    CheckType check,
+    Handle<JSFunction> function) {
+  if (HasCustomCallGenerator(function)) {
+    Handle<Code> code = CompileCustomCall(object, holder,
+                                          Handle<Cell>::null(),
+                                          function, Handle<String>::cast(name),
+                                          Code::FAST);
+    // A null handle means bail out to the regular compiler code below.
+    if (!code.is_null()) return code;
+  }
+
+  Label miss;
+  HandlerFrontendHeader(object, holder, name, check, &miss);
   PatchGlobalProxy(object);
-  // Invoke the function.
-  __ InvokeFunction(a1, arguments(), JUMP_FUNCTION,
-                    NullCallWrapper(), call_kind());
+  CompileHandlerBackend(function);
+  HandlerFrontendFooter(&miss);
+
+  // Return the generated code.
+  return GetCode(function);
 }
 
 
@@ -2469,9 +2528,11 @@ Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
   // Restore receiver.
   __ lw(a0, MemOperand(sp, argc * kPointerSize));
 
-  GenerateJumpFunction(object, a1, &miss);
+  GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_);
 
-  HandlerFrontendFooter(&miss);
+  // Handle call cache miss.
+  __ bind(&miss);
+  GenerateMissBranch();
 
   // Return the generated code.
   return GetCode(Code::FAST, name);
@@ -2494,12 +2555,26 @@ Handle<Code> CallStubCompiler::CompileCallGlobal(
 
   Label miss;
   HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
-  // Potentially loads a closure that matches the shared function info of the
-  // function, rather than function.
   GenerateLoadFunctionFromCell(cell, function, &miss);
+  PatchGlobalProxy(object);
+
+  // Set up the context (function already in r1).
+  __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
+
+  // Jump to the cached code (tail call).
   Counters* counters = isolate()->counters();
   __ IncrementCounter(counters->call_global_inline(), 1, a3, t0);
-  GenerateJumpFunction(object, a1, function);
+  ParameterCount expected(function->shared()->formal_parameter_count());
+  CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
+      ? CALL_AS_FUNCTION
+      : CALL_AS_METHOD;
+  // We call indirectly through the code field in the function to
+  // allow recompilation to take effect without changing any of the
+  // call sites.
+  __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
+  __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION,
+                NullCallWrapper(), call_kind);
+
   HandlerFrontendFooter(&miss);
 
   // Return the generated code.