Switch CTI runtime calls to the fastcall calling convention
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Oct 2008 04:56:38 +0000 (04:56 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Oct 2008 04:56:38 +0000 (04:56 +0000)
Reviewed by Cameron Zwarich

Basically this means that we get to store the argument for CTI
calls in the ECX register, which saves a register->memory write
and subsequent memory->register read.

This is a 1.7% progression in SunSpider and 2.4% on commandline
v8 tests on Windows

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@37406 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/VM/CTI.cpp
JavaScriptCore/VM/CTI.h
JavaScriptCore/VM/Machine.h
JavaScriptCore/masm/X86Assembler.h
JavaScriptCore/wtf/Platform.h

index 28888bc..defcd96 100644 (file)
@@ -1,3 +1,29 @@
+2008-10-07  Oliver Hunt  <oliver@apple.com>
+
+        Reviewed by Cameron Zwarich.
+
+        Switch CTI runtime calls to the fastcall calling convention
+
+        Basically this means that we get to store the argument for CTI
+        calls in the ECX register, which saves a register->memory write
+        and subsequent memory->register read.
+        
+        This is a 1.7% progression in SunSpider and 2.4% on commandline
+        v8 tests on Windows
+
+        * VM/CTI.cpp:
+        (JSC::):
+        (JSC::CTI::privateCompilePutByIdTransition):
+        (JSC::CTI::privateCompilePatchGetArrayLength):
+        * VM/CTI.h:
+        * VM/Machine.h:
+        * masm/X86Assembler.h:
+        (JSC::X86Assembler::emitRestoreArgumentReference):
+        (JSC::X86Assembler::emitRestoreArgumentReferenceForTrampoline):
+          We need this to correctly reload ecx from inside certain property access
+          trampolines.
+        * wtf/Platform.h:
+
 2008-10-07  Maciej Stachowiak  <mjs@apple.com>
 
         Reviewed by Mark Rowe.
index 2639820..00514be 100644 (file)
@@ -112,7 +112,7 @@ extern "C" {
             push edi;
             sub esp, 0x24;
             mov esi, 512;
-            mov [esp], esp;
+            mov ecx, esp;
             mov edi, [esp + 0x38];
             call [esp + 0x30];
             add esp, 0x24;
@@ -125,7 +125,7 @@ extern "C" {
     __declspec(naked) void ctiVMThrowTrampoline()
     {
         __asm {
-            mov [esp], esp;
+            mov ecx, esp;
             call JSC::Machine::cti_vm_throw;
             add esp, 0x24;
             pop edi;
@@ -2795,7 +2795,7 @@ void CTI::privateCompilePutByIdReplace(StructureID* structureID, size_t cachedOf
 
 extern "C" {
 
-static JSValue* SFX_CALL transitionObject(StructureID* newStructureID, size_t cachedOffset, JSObject* baseObject, JSValue* value)
+static JSValue* transitionObject(StructureID* newStructureID, size_t cachedOffset, JSObject* baseObject, JSValue* value)
 {
     baseObject->transitionTo(newStructureID);
     baseObject->putDirectOffset(cachedOffset, value);
@@ -2871,11 +2871,20 @@ void CTI::privateCompilePutByIdTransition(StructureID* oldStructureID, Structure
         m_jit.addl_i32r(4 * sizeof(void*), X86::esp);
     }
     m_jit.ret();
+    
+    X86Assembler::JmpSrc failureJump;
+    if (failureCases.size()) {
+        for (unsigned i = 0; i < failureCases.size(); ++i)
+            m_jit.link(failureCases[i], m_jit.label());
+        m_jit.emitRestoreArgumentReferenceForTrampoline();
+        failureJump = m_jit.emitUnlinkedJmp();
+    }
+
     void* code = m_jit.copy();
     ASSERT(code);
-    
-    for (unsigned i = 0; i < failureCases.size(); ++i)
-        X86Assembler::link(code, failureCases[i], reinterpret_cast<void*>(Machine::cti_op_put_by_id_fail));
+
+    if (failureCases.size())
+        X86Assembler::link(code, failureJump, reinterpret_cast<void*>(Machine::cti_op_put_by_id_fail));
 
     if (transitionWillNeedStorageRealloc(oldStructureID, newStructureID))
         X86Assembler::link(code, callTarget, reinterpret_cast<void*>(transitionObject));
@@ -2985,11 +2994,15 @@ void CTI::privateCompilePatchGetArrayLength(void* returnAddress)
     m_jit.movl_mr(OBJECT_OFFSET(ArrayStorage, m_length), X86::ecx, X86::ecx);
 
     m_jit.addl_rr(X86::ecx, X86::ecx);
-    X86Assembler::JmpSrc failureCases3 = m_jit.emitUnlinkedJo();
+    X86Assembler::JmpSrc failureClobberedECX = m_jit.emitUnlinkedJo();
     m_jit.addl_i8r(1, X86::ecx);
 
     X86Assembler::JmpSrc success = m_jit.emitUnlinkedJmp();
 
+    m_jit.link(failureClobberedECX, m_jit.label());
+    m_jit.emitRestoreArgumentReference();
+    X86Assembler::JmpSrc failureCases3 = m_jit.emitUnlinkedJmp();
+
     void* code = m_jit.copy();
     ASSERT(code);
 
index b79e5ec..d27a88e 100644 (file)
@@ -107,12 +107,24 @@ namespace JSC {
 
     struct VoidPtrPair { void* first; void* second; };
 
-    typedef JSValue* (*CTIHelper_j)(CTI_ARGS);
-    typedef JSPropertyNameIterator* (*CTIHelper_p)(CTI_ARGS);
-    typedef void (*CTIHelper_v)(CTI_ARGS);
-    typedef void* (*CTIHelper_s)(CTI_ARGS);
-    typedef int (*CTIHelper_b)(CTI_ARGS);
-    typedef VoidPtrPair (*CTIHelper_2)(CTI_ARGS);
+#if COMPILER(MSVC)
+
+#if USE(FAST_CALL_CTI_ARGUMENT)
+#define SFX_CALL __fastcall
+#else
+#define SFX_CALL __cdecl
+#endif
+
+#else
+#define SFX_CALL
+#endif
+
+    typedef JSValue* (SFX_CALL *CTIHelper_j)(CTI_ARGS);
+    typedef JSPropertyNameIterator* (SFX_CALL *CTIHelper_p)(CTI_ARGS);
+    typedef void (SFX_CALL *CTIHelper_v)(CTI_ARGS);
+    typedef void* (SFX_CALL *CTIHelper_s)(CTI_ARGS);
+    typedef int (SFX_CALL *CTIHelper_b)(CTI_ARGS);
+    typedef VoidPtrPair (SFX_CALL *CTIHelper_2)(CTI_ARGS);
 
     struct CallRecord {
         X86Assembler::JmpSrc from;
@@ -250,7 +262,9 @@ namespace JSC {
         // will compress the displacement, and we may not be able to fit a repatched offset.
         static const int repatchGetByIdDefaultOffset = 256;
 
-#if USE(CTI_ARGUMENT)
+#if USE(FAST_CALL_CTI_ARGUMENT)
+        static const int ctiArgumentInitSize = 2;
+#elif USE(CTI_ARGUMENT)
         static const int ctiArgumentInitSize = 4;
 #else
         static const int ctiArgumentInitSize = 0;
index d32776c..9a10b13 100644 (file)
@@ -134,11 +134,6 @@ namespace JSC {
         SamplingTool* m_sampler;
 
 #if ENABLE(CTI)
-#if COMPILER(MSVC)
-#define SFX_CALL __cdecl
-#else
-#define SFX_CALL
-#endif
 
         static void SFX_CALL cti_timeout_check(CTI_ARGS);
 
index 441810d..c5c1fc5 100644 (file)
@@ -1055,11 +1055,25 @@ public:
 
     void emitRestoreArgumentReference()
     {
+#if USE(FAST_CALL_CTI_ARGUMENT)
+        movl_rr(X86::esp, X86::ecx);
+#else
         movl_rm(X86::esp, 0, X86::esp);
+#endif
+    }
+
+    void emitRestoreArgumentReferenceForTrampoline()
+    {
+#if USE(FAST_CALL_CTI_ARGUMENT)
+        movl_rr(X86::esp, X86::ecx);
+        addl_i32r(4, X86::ecx);
+#else
+#endif
     }
 #else
     void emitConvertToFastCall() {};
     void emitRestoreArgumentReference() {};
+    void emitRestoreArgumentReferenceForTrampoline() {};
 #endif
 
 private:
index ce85980..e0ede48 100644 (file)
 #define WTF_USE_CTI_ARGUMENT 1
 #endif
 
+#if COMPILER(MSVC)
+#define WTF_USE_FAST_CALL_CTI_ARGUMENT 1
+#endif
+
 #endif /* WTF_Platform_h */