Avoid indirect function calls for custom getters
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Dec 2013 02:43:26 +0000 (02:43 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Dec 2013 02:43:26 +0000 (02:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=125821

Reviewed by Mark Hahnenberg.

Rather than invoking a helper function to perform an indirect call
through a function pointer, just have the JIT call the function directly.

Unfortunately this only works in JSVALUE64 at the moment as there
is not an obvious way to pass two EncodedJSValues uniformly over
the various effected JITs.

* jit/CCallHelpers.h:
(JSC::CCallHelpers::setupArguments):
* jit/Repatch.cpp:
(JSC::generateProtoChainAccessStub):
(JSC::tryBuildGetByIDList):

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/jit/CCallHelpers.h
Source/JavaScriptCore/jit/Repatch.cpp

index 31351ee580dcce3e1fc0060753e8c84529f04e70..adbcf5516fdd037567bed0c81cf5a247cd2f526c 100644 (file)
@@ -1,3 +1,23 @@
+2013-12-16  Oliver Hunt  <oliver@apple.com>
+
+        Avoid indirect function calls for custom getters
+        https://bugs.webkit.org/show_bug.cgi?id=125821
+
+        Reviewed by Mark Hahnenberg.
+
+        Rather than invoking a helper function to perform an indirect call
+        through a function pointer, just have the JIT call the function directly.
+
+        Unfortunately this only works in JSVALUE64 at the moment as there
+        is not an obvious way to pass two EncodedJSValues uniformly over
+        the various effected JITs.
+
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArguments):
+        * jit/Repatch.cpp:
+        (JSC::generateProtoChainAccessStub):
+        (JSC::tryBuildGetByIDList):
+
 2013-12-16  Joseph Pecoraro  <pecoraro@apple.com>
 
         Fix some whitespace issues in inspector code
index afcccd1ca9a8f262dcc34996cc0c5414368b777d..836573be1df80792fe8300bb50072f96a32a4190 100644 (file)
@@ -956,6 +956,12 @@ public:
         move(arg4, GPRInfo::argumentGPR3);
     }
     
+    ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
+    {
+        setupThreeStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(arg1, arg2, arg3);
+        move(arg4, GPRInfo::argumentGPR3);
+    }
+    
     ALWAYS_INLINE void setupArguments(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3, TrustedImmPtr arg4)
     {
         setupTwoStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR2>(arg1, arg3);
index 962d16f0487c80e8d832945a6a86921571e8d70c..27d113c0581711ebcfab1abbdfc59f05fe5b374e 100644 (file)
@@ -305,11 +305,17 @@ static ProtoChainGenerationResult generateProtoChainAccessStub(ExecState* exec,
             stubJit.setupArguments(callFrameRegister, scratchGPR, resultGPR);
             operationFunction = operationCallGetter;
         } else {
+#if USE(JSVALUE64)
+            // EncodedJSValue (*GetValueFunc)(ExecState*, EncodedJSValue slotBase, EncodedJSValue thisValue, PropertyName);
+            stubJit.setupArguments(callFrameRegister, MacroAssembler::TrustedImmPtr(protoObject), scratchGPR, MacroAssembler::TrustedImmPtr(propertyName.impl()));
+            operationFunction = FunctionPtr(slot.customGetter());
+#else
             stubJit.move(MacroAssembler::TrustedImmPtr(protoObject), scratchGPR);
             stubJit.setupArguments(callFrameRegister, scratchGPR,
                 MacroAssembler::TrustedImmPtr(FunctionPtr(slot.customGetter()).executableAddress()),
                 MacroAssembler::TrustedImmPtr(propertyName.impl()));
             operationFunction = operationCallCustomGetter;
+#endif
         }
 
         // Need to make sure that whenever this call is made in the future, we remember the
@@ -607,11 +613,17 @@ static bool tryBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identi
                 stubJit.setupArguments(callFrameRegister, baseGPR, scratchGPR);
                 operationFunction = operationCallGetter;
             } else {
+#if USE(JSVALUE64)
+                // EncodedJSValue (*GetValueFunc)(ExecState*, EncodedJSValue slotBase, EncodedJSValue thisValue, PropertyName);
+                stubJit.setupArguments(callFrameRegister, baseGPR, baseGPR, MacroAssembler::TrustedImmPtr(ident.impl()));
+                operationFunction = FunctionPtr(slot.customGetter());
+#else
                 stubJit.setupArguments(
                     callFrameRegister, baseGPR,
                     MacroAssembler::TrustedImmPtr(FunctionPtr(slot.customGetter()).executableAddress()),
                     MacroAssembler::TrustedImmPtr(ident.impl()));
                 operationFunction = operationCallCustomGetter;
+#endif
             }
             
             // Need to make sure that whenever this call is made in the future, we remember the