MIPS: crankshaft support for api method calls
authorpalfia@homejinni.com <palfia@homejinni.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 31 Jan 2014 00:36:19 +0000 (00:36 +0000)
committerpalfia@homejinni.com <palfia@homejinni.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 31 Jan 2014 00:36:19 +0000 (00:36 +0000)
Port r18946 (a152f5ae)

BUG=
R=plind44@gmail.com

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

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

src/mips/code-stubs-mips.cc
src/mips/macro-assembler-mips.cc
src/mips/macro-assembler-mips.h
src/mips/simulator-mips.cc
src/mips/stub-cache-mips.cc

index b900974..47f052f 100644 (file)
@@ -444,6 +444,26 @@ void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
     descriptor->register_params_ = registers;
     descriptor->param_representations_ = representations;
   }
+  {
+    CallInterfaceDescriptor* descriptor =
+        isolate->call_descriptor(Isolate::ApiFunctionCall);
+    static Register registers[] = { a0,  // callee
+                                    t0,  // call_data
+                                    a2,  // holder
+                                    a1,  // api_function_address
+                                    cp,  // context
+    };
+    static Representation representations[] = {
+        Representation::Tagged(),    // callee
+        Representation::Tagged(),    // call_data
+        Representation::Tagged(),    // holder
+        Representation::External(),  // api_function_address
+        Representation::Tagged(),    // context
+    };
+    descriptor->register_param_count_ = 5;
+    descriptor->register_params_ = registers;
+    descriptor->param_representations_ = representations;
+  }
 }
 
 
@@ -5561,8 +5581,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
   //  -- a0                  : callee
   //  -- t0                  : call_data
   //  -- a2                  : holder
-  //  -- a3                  : api_function_address
-  //  -- a1                  : thunk_arg
+  //  -- a1                  : api_function_address
   //  -- cp                  : context
   //  --
   //  -- sp[0]               : last argument
@@ -5574,8 +5593,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
   Register callee = a0;
   Register call_data = t0;
   Register holder = a2;
-  Register api_function_address = a3;
-  Register thunk_arg = a1;
+  Register api_function_address = a1;
   Register context = cp;
 
   int argc = ArgumentBits::decode(bit_field_);
@@ -5621,7 +5639,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
   FrameScope frame_scope(masm, StackFrame::MANUAL);
   __ EnterExitFrame(false, kApiStackSpace);
 
-  ASSERT(!thunk_arg.is(a0) && !api_function_address.is(a0) && !scratch.is(a0));
+  ASSERT(!api_function_address.is(a0) && !scratch.is(a0));
   // a0 = FunctionCallbackInfo&
   // Arguments is after the return address.
   __ Addu(a0, sp, Operand(1 * kPointerSize));
@@ -5651,7 +5669,6 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
 
   __ CallApiFunctionAndReturn(api_function_address,
                               thunk_ref,
-                              thunk_arg,
                               kStackUnwindSpace,
                               return_value_operand,
                               restore_context ?
@@ -5664,12 +5681,10 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
   //  -- sp[0]                  : name
   //  -- sp[4 - kArgsLength*4]  : PropertyCallbackArguments object
   //  -- ...
-  //  -- a3                    : api_function_address
-  //  -- a2                    : thunk_last_arg
+  //  -- a2                     : api_function_address
   // -----------------------------------
 
-  Register api_function_address = a3;
-  Register thunk_last_arg = a2;
+  Register api_function_address = a2;
 
   __ mov(a0, sp);  // a0 = Handle<Name>
   __ Addu(a1, a0, Operand(1 * kPointerSize));  // a1 = PCA
@@ -5693,7 +5708,6 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
       masm->isolate());
   __ CallApiFunctionAndReturn(api_function_address,
                               thunk_ref,
-                              thunk_last_arg,
                               kStackUnwindSpace,
                               MemOperand(fp, 6 * kPointerSize),
                               NULL);
index fe07745..d8b6566 100644 (file)
@@ -3874,7 +3874,6 @@ static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
 void MacroAssembler::CallApiFunctionAndReturn(
     Register function_address,
     ExternalReference thunk_ref,
-    Register thunk_last_arg,
     int stack_space,
     MemOperand return_value_operand,
     MemOperand* context_restore_operand) {
@@ -3888,8 +3887,7 @@ void MacroAssembler::CallApiFunctionAndReturn(
       ExternalReference::handle_scope_level_address(isolate()),
       next_address);
 
-  ASSERT(function_address.is(a3));
-  ASSERT(thunk_last_arg.is(a1) || thunk_last_arg.is(a2));
+  ASSERT(function_address.is(a1) || function_address.is(a2));
 
   Label profiler_disabled;
   Label end_profiler_check;
index e4e0277..da22a2b 100644 (file)
@@ -1278,7 +1278,6 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
   // the additional space allocated for the fast call).
   void CallApiFunctionAndReturn(Register function_address,
                                 ExternalReference thunk_ref,
-                                Register thunk_last_arg,
                                 int stack_space,
                                 MemOperand return_value_operand,
                                 MemOperand* context_restore_operand);
index b7e53c9..10417d5 100644 (file)
@@ -972,6 +972,12 @@ class Redirection {
     return reinterpret_cast<Redirection*>(addr_of_redirection);
   }
 
+  static void* ReverseRedirection(int32_t reg) {
+    Redirection* redirection = FromSwiInstruction(
+        reinterpret_cast<Instruction*>(reinterpret_cast<void*>(reg)));
+    return redirection->external_function();
+  }
+
  private:
   void* external_function_;
   uint32_t swi_instruction_;
@@ -1389,12 +1395,12 @@ typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0);
 // This signature supports direct call in to API function native callback
 // (refer to InvocationCallback in v8.h).
 typedef void (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
-typedef void (*SimulatorRuntimeProfilingApiCall)(int32_t arg0, int32_t arg1);
+typedef void (*SimulatorRuntimeProfilingApiCall)(int32_t arg0, void* arg1);
 
 // This signature supports direct call to accessor getter callback.
 typedef void (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, int32_t arg1);
 typedef void (*SimulatorRuntimeProfilingGetterCall)(
-    int32_t arg0, int32_t arg1, int32_t arg2);
+    int32_t arg0, int32_t arg1, void* arg2);
 
 // Software interrupt instructions are used by the simulator to call into the
 // C-based V8 runtime. They are also used for debugging with simulator.
@@ -1555,7 +1561,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
       }
       SimulatorRuntimeProfilingApiCall target =
           reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
-      target(arg0, arg1);
+      target(arg0, Redirection::ReverseRedirection(arg1));
     } else if (
         redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
       if (::v8::internal::FLAG_trace_sim) {
@@ -1573,7 +1579,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
       }
       SimulatorRuntimeProfilingGetterCall target =
           reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
-      target(arg0, arg1, arg2);
+      target(arg0, arg1, Redirection::ReverseRedirection(arg2));
     } else {
       SimulatorRuntimeCall target =
                   reinterpret_cast<SimulatorRuntimeCall>(external);
index da19d89..e6d3f7d 100644 (file)
@@ -776,8 +776,7 @@ static void GenerateFastApiCallBody(MacroAssembler* masm,
   Register callee = a0;
   Register call_data = t0;
   Register holder = a2;
-  Register api_function_address = a3;
-  Register thunk_arg = a1;
+  Register api_function_address = a1;
 
   // Put holder in place.
   __ mov(holder, holder_in);
@@ -810,7 +809,6 @@ static void GenerateFastApiCallBody(MacroAssembler* masm,
                         type,
                         masm->isolate());
   __ li(api_function_address, Operand(ref));
-  __ li(thunk_arg, Operand(reinterpret_cast<int32_t>(function_address)));
 
   // Jump to stub.
   CallApiFunctionStub stub(restore_context, call_data_undefined, argc);
@@ -818,47 +816,6 @@ static void GenerateFastApiCallBody(MacroAssembler* masm,
 }
 
 
-// Generates call to API function.
-static void GenerateFastApiCall(MacroAssembler* masm,
-                                const CallOptimization& optimization,
-                                int argc,
-                                Handle<Map> map_to_holder,
-                                CallOptimization::HolderLookup holder_lookup) {
-  Counters* counters = masm->isolate()->counters();
-  __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a1);
-
-  // Move holder to a register.
-  Register holder_reg = a2;
-  switch (holder_lookup) {
-    case CallOptimization::kHolderIsReceiver:
-      {
-        ASSERT(map_to_holder.is_null());
-        __ lw(holder_reg, MemOperand(sp, argc * kPointerSize));
-      }
-      break;
-    case CallOptimization::kHolderIsPrototypeOfMap:
-      {
-        Handle<JSObject> holder(JSObject::cast(map_to_holder->prototype()));
-        if (!masm->isolate()->heap()->InNewSpace(*holder)) {
-          __ li(holder_reg, holder);
-        } else {
-          __ li(holder_reg, map_to_holder);
-          __ lw(holder_reg,
-                FieldMemOperand(holder_reg, Map::kPrototypeOffset));
-        }
-      }
-     break;
-    case CallOptimization::kHolderNotFound:
-      UNREACHABLE();
-  }
-  GenerateFastApiCallBody(masm,
-                          optimization,
-                          argc,
-                          holder_reg,
-                          false);
-}
-
-
 // Generate call to api function.
 static void GenerateFastApiCall(MacroAssembler* masm,
                                 const CallOptimization& optimization,
@@ -964,36 +921,9 @@ class CallInterceptorCompiler BASE_EMBEDDED {
           name, miss_label);
     }
 
-    Handle<Map> lookup_map;
-    CallOptimization::HolderLookup holder_lookup =
-        CallOptimization::kHolderNotFound;
-    if (optimization.is_simple_api_call() &&
-        !lookup->holder()->IsGlobalObject()) {
-      lookup_map = optimization.LookupHolderOfExpectedType(
-          object, object, interceptor_holder, &holder_lookup);
-      if (holder_lookup == CallOptimization::kHolderNotFound) {
-        lookup_map =
-            optimization.LookupHolderOfExpectedType(
-                object,
-                interceptor_holder,
-                Handle<JSObject>(lookup->holder()),
-                &holder_lookup);
-      }
-    }
-
-    // Invoke function.
-    if (holder_lookup != CallOptimization::kHolderNotFound) {
-      int argc = arguments_.immediate();
-      GenerateFastApiCall(masm,
-                          optimization,
-                          argc,
-                          lookup_map,
-                          holder_lookup);
-    } else {
-      Handle<JSFunction> function = optimization.constant_function();
-      __ Move(a0, receiver);
-      stub_compiler_->GenerateJumpFunction(object, function);
-    }
+    Handle<JSFunction> function = optimization.constant_function();
+    __ Move(a0, receiver);
+    stub_compiler_->GenerateJumpFunction(object, function);
 
     // Invoke a regular function.
     __ bind(&regular_invoke);
@@ -1314,15 +1244,13 @@ void LoadStubCompiler::GenerateLoadCallback(
 
   __ mov(a2, scratch2());  // Saved in case scratch2 == a1.
   // Abi for CallApiGetter.
-  Register getter_address_reg = a3;
-  Register thunk_last_arg = a2;
+  Register getter_address_reg = a2;
 
   Address getter_address = v8::ToCData<Address>(callback->getter());
   ApiFunction fun(getter_address);
   ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
   ExternalReference ref = ExternalReference(&fun, type, isolate());
   __ li(getter_address_reg, Operand(ref));
-  __ li(thunk_last_arg, Operand(reinterpret_cast<int32_t>(getter_address)));
 
   CallApiGetterStub stub;
   __ TailCallStub(&stub);
@@ -1485,58 +1413,6 @@ Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
 }
 
 
-Handle<Code> CallStubCompiler::CompileFastApiCall(
-    const CallOptimization& optimization,
-    Handle<Object> object,
-    Handle<JSObject> holder,
-    Handle<Cell> cell,
-    Handle<JSFunction> function,
-    Handle<String> name) {
-
-  Counters* counters = isolate()->counters();
-
-  ASSERT(optimization.is_simple_api_call());
-  // Bail out if object is a global object as we don't want to
-  // repatch it to global receiver.
-  if (object->IsGlobalObject()) return Handle<Code>::null();
-  if (!cell.is_null()) return Handle<Code>::null();
-  if (!object->IsJSObject()) return Handle<Code>::null();
-  Handle<JSObject> receiver = Handle<JSObject>::cast(object);
-  CallOptimization::HolderLookup holder_lookup =
-      CallOptimization::kHolderNotFound;
-  Handle<Map> lookup_map = optimization.LookupHolderOfExpectedType(
-      receiver, receiver, holder, &holder_lookup);
-  if (holder_lookup == CallOptimization::kHolderNotFound) {
-    return Handle<Code>::null();
-  }
-
-  Label miss;
-  GenerateNameCheck(name, &miss);
-
-  // Get the receiver from the stack.
-  const int argc = arguments().immediate();
-  __ lw(a1, MemOperand(sp, argc * kPointerSize));
-
-  // Check that the receiver isn't a smi.
-  __ JumpIfSmi(a1, &miss);
-
-  __ IncrementCounter(counters->call_const(), 1, a0, a3);
-
-  // Check that the maps haven't changed and find a Holder as a side effect.
-  CheckPrototypes(
-      IC::CurrentTypeOf(object, isolate()),
-      a1, holder, a0, a3, t0, name, &miss);
-
-  GenerateFastApiCall(
-      masm(), optimization, argc, lookup_map, holder_lookup);
-
-  HandlerFrontendFooter(&miss);
-
-  // Return the generated code.
-  return GetCode(function);
-}
-
-
 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
   Label success;
   // Check that the object is a boolean.
@@ -1697,14 +1573,6 @@ Handle<Code> CallStubCompiler::CompileCallGlobal(
     Handle<PropertyCell> cell,
     Handle<JSFunction> function,
     Handle<Name> name) {
-  if (HasCustomCallGenerator(function)) {
-    Handle<Code> code = CompileCustomCall(
-        object, holder, cell, function, Handle<String>::cast(name),
-        Code::NORMAL);
-    // A null handle means bail out to the regular compiler code below.
-    if (!code.is_null()) return code;
-  }
-
   Label miss;
   HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
   // Potentially loads a closure that matches the shared function info of the