Refactoring various pieces of post interceptor caching.
authorantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 15 Feb 2010 12:32:27 +0000 (12:32 +0000)
committerantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 15 Feb 2010 12:32:27 +0000 (12:32 +0000)
Review URL: http://codereview.chromium.org/596096

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

src/arm/macro-assembler-arm.cc
src/arm/macro-assembler-arm.h
src/arm/stub-cache-arm.cc
src/ia32/macro-assembler-ia32.cc
src/ia32/macro-assembler-ia32.h
src/ia32/stub-cache-ia32.cc
src/x64/macro-assembler-x64.cc
src/x64/macro-assembler-x64.h
src/x64/stub-cache-x64.cc

index 31c3b19..b249d69 100644 (file)
@@ -545,6 +545,21 @@ void MacroAssembler::InvokeFunction(Register fun,
 }
 
 
+void MacroAssembler::InvokeFunction(JSFunction* function,
+                                    const ParameterCount& actual,
+                                    InvokeFlag flag) {
+  ASSERT(function->is_compiled());
+
+  // Get the function and setup the context.
+  mov(r1, Operand(Handle<JSFunction>(function)));
+  ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
+
+  // Invoke the cached code.
+  Handle<Code> code(function->code());
+  ParameterCount expected(function->shared()->formal_parameter_count());
+  InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag);
+}
+
 #ifdef ENABLE_DEBUGGER_SUPPORT
 void MacroAssembler::SaveRegistersToMemory(RegList regs) {
   ASSERT((regs & ~kJSCallerSaved) == 0);
@@ -1209,6 +1224,16 @@ void MacroAssembler::CallRuntime(Runtime::FunctionId fid, int num_arguments) {
 }
 
 
+void MacroAssembler::CallExternalReference(const ExternalReference& ext,
+                                           int num_arguments) {
+  mov(r0, Operand(num_arguments));
+  mov(r1, Operand(ext));
+
+  CEntryStub stub(1);
+  CallStub(&stub);
+}
+
+
 void MacroAssembler::TailCallRuntime(const ExternalReference& ext,
                                      int num_arguments,
                                      int result_size) {
index f20eeee..98cea16 100644 (file)
@@ -135,6 +135,10 @@ class MacroAssembler: public Assembler {
                       const ParameterCount& actual,
                       InvokeFlag flag);
 
+  void InvokeFunction(JSFunction* function,
+                      const ParameterCount& actual,
+                      InvokeFlag flag);
+
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
   // ---------------------------------------------------------------------------
@@ -335,6 +339,10 @@ class MacroAssembler: public Assembler {
   // Convenience function: Same as above, but takes the fid instead.
   void CallRuntime(Runtime::FunctionId fid, int num_arguments);
 
+  // Convenience function: call an external reference.
+  void CallExternalReference(const ExternalReference& ext,
+                             int num_arguments);
+
   // Tail call of a runtime routine (jump).
   // Like JumpToRuntime, but also takes care of passing the number
   // of parameters.
index 1ae3ae3..ced0f2b 100644 (file)
@@ -391,23 +391,6 @@ static void GenerateCallFunction(MacroAssembler* masm,
 }
 
 
-static void GenerateCallConstFunction(MacroAssembler* masm,
-                                      JSFunction* function,
-                                      const ParameterCount& arguments) {
-  ASSERT(function->is_compiled());
-
-  // Get the function and setup the context.
-  __ mov(r1, Operand(Handle<JSFunction>(function)));
-  __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
-
-  // Jump to the cached code (tail call).
-  Handle<Code> code(function->code());
-  ParameterCount expected(function->shared()->formal_parameter_count());
-  __ InvokeCode(code, expected, arguments,
-                RelocInfo::CODE_TARGET, JUMP_FUNCTION);
-}
-
-
 static void PushInterceptorArguments(MacroAssembler* masm,
                                      Register receiver,
                                      Register holder,
@@ -458,7 +441,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
                         LookupResult* lookup,
                         String* name,
                         Label* miss_label) {
-    AccessorInfo* callback = 0;
+    AccessorInfo* callback = NULL;
     bool optimize = false;
     // So far the most popular follow ups for interceptor loads are FIELD
     // and CALLBACKS, so inline only them, other cases may be added
@@ -950,7 +933,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
       UNREACHABLE();
   }
 
-  GenerateCallConstFunction(masm(), function, arguments());
+  __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
 
   // Handle call cache miss.
   __ bind(&miss);
@@ -1038,9 +1021,11 @@ Object* CallStubCompiler::CompileCallInterceptor(Object* object,
                     scratch,
                     name,
                     &miss);
-    GenerateCallConstFunction(masm(),
-                              lookup.GetConstantFunction(),
-                              arguments());
+
+    __ InvokeFunction(lookup.GetConstantFunction(),
+                      arguments(),
+                      JUMP_FUNCTION);
+
     __ bind(&invoke);
 
   } else {
@@ -1050,13 +1035,9 @@ Object* CallStubCompiler::CompileCallInterceptor(Object* object,
 
     PushInterceptorArguments(masm(), receiver, holder_reg, name_reg, holder);
 
-    ExternalReference ref = ExternalReference(
-        IC_Utility(IC::kLoadPropertyWithInterceptorForCall));
-    __ mov(r0, Operand(5));
-    __ mov(r1, Operand(ref));
-
-    CEntryStub stub(1);
-    __ CallStub(&stub);
+    __ CallExternalReference(
+        ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall)),
+        5);
 
     __ pop(name_reg);
     __ LeaveInternalFrame();
index 0bb6894..7cd1ee4 100644 (file)
@@ -1145,6 +1145,16 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
 }
 
 
+void MacroAssembler::CallExternalReference(ExternalReference ref,
+                                           int num_arguments) {
+  mov(eax, Immediate(num_arguments));
+  mov(ebx, Immediate(ref));
+
+  CEntryStub stub(1);
+  CallStub(&stub);
+}
+
+
 Object* MacroAssembler::TryCallRuntime(Runtime::Function* f,
                                        int num_arguments) {
   if (f->nargs >= 0 && f->nargs != num_arguments) {
@@ -1365,6 +1375,21 @@ void MacroAssembler::InvokeFunction(Register fun,
 }
 
 
+void MacroAssembler::InvokeFunction(JSFunction* function,
+                                    const ParameterCount& actual,
+                                    InvokeFlag flag) {
+  ASSERT(function->is_compiled());
+  // Get the function and setup the context.
+  mov(edi, Immediate(Handle<JSFunction>(function)));
+  mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
+
+  // Invoke the cached code.
+  Handle<Code> code(function->code());
+  ParameterCount expected(function->shared()->formal_parameter_count());
+  InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag);
+}
+
+
 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
   // Calls are not allowed in some stubs.
   ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
index 02f342e..574e3b8 100644 (file)
@@ -124,6 +124,10 @@ class MacroAssembler: public Assembler {
                       const ParameterCount& actual,
                       InvokeFlag flag);
 
+  void InvokeFunction(JSFunction* function,
+                      const ParameterCount& actual,
+                      InvokeFlag flag);
+
   // Invoke specified builtin JavaScript function. Adds an entry to
   // the unresolved list if the name does not resolve.
   void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag);
@@ -353,6 +357,9 @@ class MacroAssembler: public Assembler {
   // Convenience function: Same as above, but takes the fid instead.
   void CallRuntime(Runtime::FunctionId id, int num_arguments);
 
+  // Convenience function: call an external reference.
+  void CallExternalReference(ExternalReference ref, int num_arguments);
+
   // Convenience function: Same as above, but takes the fid instead.
   Object* TryCallRuntime(Runtime::FunctionId id, int num_arguments);
 
index 69e3bec..a6565ee 100644 (file)
@@ -152,22 +152,6 @@ void StubCache::GenerateProbe(MacroAssembler* masm,
 }
 
 
-static void PushInterceptorArguments(MacroAssembler* masm,
-                                     Register receiver,
-                                     Register holder,
-                                     Register name,
-                                     JSObject* holder_obj) {
-  __ push(receiver);
-  __ push(holder);
-  __ push(name);
-  InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
-  ASSERT(!Heap::InNewSpace(interceptor));
-  __ mov(receiver, Immediate(Handle<Object>(interceptor)));
-  __ push(receiver);
-  __ push(FieldOperand(receiver, InterceptorInfo::kDataOffset));
-}
-
-
 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
                                                        int index,
                                                        Register prototype) {
@@ -287,20 +271,31 @@ void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
 }
 
 
+static void PushInterceptorArguments(MacroAssembler* masm,
+                                     Register receiver,
+                                     Register holder,
+                                     Register name,
+                                     JSObject* holder_obj) {
+  __ push(receiver);
+  __ push(holder);
+  __ push(name);
+  InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
+  ASSERT(!Heap::InNewSpace(interceptor));
+  __ mov(receiver, Immediate(Handle<Object>(interceptor)));
+  __ push(receiver);
+  __ push(FieldOperand(receiver, InterceptorInfo::kDataOffset));
+}
+
+
 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
                                                    Register receiver,
                                                    Register holder,
                                                    Register name,
                                                    JSObject* holder_obj) {
   PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
-
-  ExternalReference ref =
-      ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly));
-  __ mov(eax, Immediate(5));
-  __ mov(ebx, Immediate(ref));
-
-  CEntryStub stub(1);
-  __ CallStub(&stub);
+  __ CallExternalReference(
+        ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly)),
+        5);
 }
 
 
@@ -364,7 +359,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
                         LookupResult* lookup,
                         String* name,
                         Label* miss_label) {
-    AccessorInfo* callback = 0;
+    AccessorInfo* callback = NULL;
     bool optimize = false;
     // So far the most popular follow ups for interceptor loads are FIELD
     // and CALLBACKS, so inline only them, other cases may be added
@@ -683,7 +678,6 @@ class CallInterceptorCompiler BASE_EMBEDDED {
                           Register name)
       : stub_compiler_(stub_compiler),
         arguments_(arguments),
-        argc_(arguments.immediate()),
         name_(name) {}
 
   void Compile(MacroAssembler* masm,
@@ -740,6 +734,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
                         const CallOptimization& optimization,
                         Label* miss_label) {
     ASSERT(optimization.is_constant_call());
+    ASSERT(!lookup->holder()->IsGlobalObject());
 
     int depth1 = kInvalidProtoDepth;
     int depth2 = kInvalidProtoDepth;
@@ -780,27 +775,11 @@ class CallInterceptorCompiler BASE_EMBEDDED {
                                     scratch1, scratch2, name,
                                     depth2, miss);
 
-    if (lookup->holder()->IsGlobalObject()) {
-      ASSERT(!can_do_fast_api_call);
-      __ mov(edx, Operand(esp, (argc_ + 1) * kPointerSize));
-      __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
-      __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edx);
-    }
-
     if (can_do_fast_api_call) {
-      GenerateFastApiCall(masm, optimization, argc_);
+      GenerateFastApiCall(masm, optimization, arguments_.immediate());
     } else {
-      // Get the function and setup the context.
-      JSFunction* function = optimization.constant_function();
-      __ mov(edi, Immediate(Handle<JSFunction>(function)));
-      __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
-
-      // Jump to the cached code (tail call).
-      ASSERT(function->is_compiled());
-      Handle<Code> code(function->code());
-      ParameterCount expected(function->shared()->formal_parameter_count());
-      __ InvokeCode(code, expected, arguments_,
-                    RelocInfo::CODE_TARGET, JUMP_FUNCTION);
+      __ InvokeFunction(optimization.constant_function(), arguments_,
+                        JUMP_FUNCTION);
     }
 
     if (can_do_fast_api_call) {
@@ -838,13 +817,10 @@ class CallInterceptorCompiler BASE_EMBEDDED {
                              name_,
                              holder_obj);
 
-    ExternalReference ref = ExternalReference(
-        IC_Utility(IC::kLoadPropertyWithInterceptorForCall));
-    __ mov(eax, Immediate(5));
-    __ mov(ebx, Immediate(ref));
-
-    CEntryStub stub(1);
-    __ CallStub(&stub);
+    __ CallExternalReference(
+          ExternalReference(
+              IC_Utility(IC::kLoadPropertyWithInterceptorForCall)),
+          5);
 
     // Restore the name_ register.
     __ pop(name_);
@@ -876,7 +852,6 @@ class CallInterceptorCompiler BASE_EMBEDDED {
 
   StubCompiler* stub_compiler_;
   const ParameterCount& arguments_;
-  const int argc_;
   Register name_;
 };
 
@@ -1378,16 +1353,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
   if (depth != kInvalidProtoDepth) {
     GenerateFastApiCall(masm(), optimization, argc);
   } else {
-    // Get the function and setup the context.
-    __ mov(edi, Immediate(Handle<JSFunction>(function)));
-    __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
-
-    // Jump to the cached code (tail call).
-    ASSERT(function->is_compiled());
-    Handle<Code> code(function->code());
-    ParameterCount expected(function->shared()->formal_parameter_count());
-    __ InvokeCode(code, expected, arguments(),
-                  RelocInfo::CODE_TARGET, JUMP_FUNCTION);
+    __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
   }
 
   // Handle call cache miss.
index f6e44bc..a504fa0 100644 (file)
@@ -386,6 +386,16 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
 }
 
 
+void MacroAssembler::CallExternalReference(const ExternalReference& ext,
+                                           int num_arguments) {
+  movq(rax, Immediate(num_arguments));
+  movq(rbx, ext);
+
+  CEntryStub stub(1);
+  CallStub(&stub);
+}
+
+
 void MacroAssembler::TailCallRuntime(ExternalReference const& ext,
                                      int num_arguments,
                                      int result_size) {
@@ -1892,6 +1902,21 @@ void MacroAssembler::InvokeFunction(Register function,
 }
 
 
+void MacroAssembler::InvokeFunction(JSFunction* function,
+                                    const ParameterCount& actual,
+                                    InvokeFlag flag) {
+  ASSERT(function->is_compiled());
+  // Get the function and setup the context.
+  Move(rdi, Handle<JSFunction>(function));
+  movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
+
+  // Invoke the cached code.
+  Handle<Code> code(function->code());
+  ParameterCount expected(function->shared()->formal_parameter_count());
+  InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag);
+}
+
+
 void MacroAssembler::EnterFrame(StackFrame::Type type) {
   push(rbp);
   movq(rbp, rsp);
index c119028..937ec12 100644 (file)
@@ -149,6 +149,10 @@ class MacroAssembler: public Assembler {
                       const ParameterCount& actual,
                       InvokeFlag flag);
 
+  void InvokeFunction(JSFunction* function,
+                      const ParameterCount& actual,
+                      InvokeFlag flag);
+
   // Invoke specified builtin JavaScript function. Adds an entry to
   // the unresolved list if the name does not resolve.
   void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag);
@@ -644,6 +648,10 @@ class MacroAssembler: public Assembler {
   // Convenience function: Same as above, but takes the fid instead.
   void CallRuntime(Runtime::FunctionId id, int num_arguments);
 
+  // Convenience function: call an external reference.
+  void CallExternalReference(const ExternalReference& ext,
+                             int num_arguments);
+
   // Tail call of a runtime routine (jump).
   // Like JumpToRuntime, but also takes care of passing the number
   // of arguments.
index 8dab38e..770a22f 100644 (file)
@@ -435,7 +435,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
                         LookupResult* lookup,
                         String* name,
                         Label* miss_label) {
-    AccessorInfo* callback = 0;
+    AccessorInfo* callback = NULL;
     bool optimize = false;
     // So far the most popular follow ups for interceptor loads are FIELD
     // and CALLBACKS, so inline only them, other cases may be added
@@ -559,7 +559,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
 class CallInterceptorCompiler BASE_EMBEDDED {
  public:
   CallInterceptorCompiler(const ParameterCount& arguments, Register name)
-      : arguments_(arguments), argc_(arguments.immediate()), name_(name) {}
+      : arguments_(arguments), name_(name) {}
 
   void CompileCacheable(MacroAssembler* masm,
                         StubCompiler* stub_compiler,
@@ -589,6 +589,8 @@ class CallInterceptorCompiler BASE_EMBEDDED {
       return;
     }
 
+    ASSERT(!lookup->holder()->IsGlobalObject());
+
     __ EnterInternalFrame();
     __ push(holder);  // Save the holder.
     __ push(name_);  // Save the name.
@@ -612,22 +614,8 @@ class CallInterceptorCompiler BASE_EMBEDDED {
                                    scratch2,
                                    name,
                                    miss_label);
-    if (lookup->holder()->IsGlobalObject()) {
-      __ movq(rdx, Operand(rsp, (argc_ + 1) * kPointerSize));
-      __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
-      __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdx);
-    }
 
-    ASSERT(function->is_compiled());
-    // Get the function and setup the context.
-    __ Move(rdi, Handle<JSFunction>(function));
-    __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
-
-    // Jump to the cached code (tail call).
-    Handle<Code> code(function->code());
-    ParameterCount expected(function->shared()->formal_parameter_count());
-    __ InvokeCode(code, expected, arguments_,
-                  RelocInfo::CODE_TARGET, JUMP_FUNCTION);
+    __ InvokeFunction(function, arguments_, JUMP_FUNCTION);
 
     __ bind(&invoke);
   }
@@ -648,13 +636,9 @@ class CallInterceptorCompiler BASE_EMBEDDED {
                              name_,
                              holder_obj);
 
-    ExternalReference ref = ExternalReference(
-        IC_Utility(IC::kLoadPropertyWithInterceptorForCall));
-    __ movq(rax, Immediate(5));
-    __ movq(rbx, ref);
-
-    CEntryStub stub(1);
-    __ CallStub(&stub);
+    __ CallExternalReference(
+        ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall)),
+        5);
 
     __ pop(name_);
     __ LeaveInternalFrame();
@@ -662,7 +646,6 @@ class CallInterceptorCompiler BASE_EMBEDDED {
 
  private:
   const ParameterCount& arguments_;
-  int argc_;
   Register name_;
 };
 
@@ -792,16 +775,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
       UNREACHABLE();
   }
 
-  // Get the function and setup the context.
-  __ Move(rdi, Handle<JSFunction>(function));
-  __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
-
-  // Jump to the cached code (tail call).
-  ASSERT(function->is_compiled());
-  Handle<Code> code(function->code());
-  ParameterCount expected(function->shared()->formal_parameter_count());
-  __ InvokeCode(code, expected, arguments(),
-                RelocInfo::CODE_TARGET, JUMP_FUNCTION);
+  __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
 
   // Handle call cache miss.
   __ bind(&miss);