Title: [188889] branches/jsc-tailcall/Source/_javascript_Core
Revision
188889
Author
msab...@apple.com
Date
2015-08-24 15:40:45 -0700 (Mon, 24 Aug 2015)

Log Message

jsc-tailcall: Specialized thunks need to save / restore callee save "tag" registers
https://bugs.webkit.org/show_bug.cgi?id=148345

Reviewed by Basile Clement.

Since these thunks can be called by FTL compiled functions, we can't count on the 
tagTypeNumberRegister and tagMaskRegister.  In fact, the same registers could be used
for other purposes.  Since they are callee saves, save the current values on entry to
these thunks and materialize the tag constant values.  On function exit we restore
the caller's values.

* jit/SpecializedThunkJIT.h:
(JSC::SpecializedThunkJIT::SpecializedThunkJIT):
(JSC::SpecializedThunkJIT::loadDoubleArgument):
(JSC::SpecializedThunkJIT::returnJSValue):
(JSC::SpecializedThunkJIT::returnDouble):
(JSC::SpecializedThunkJIT::returnInt32):
(JSC::SpecializedThunkJIT::returnJSCell):
(JSC::SpecializedThunkJIT::callDoubleToDoublePreservingReturn):
(JSC::SpecializedThunkJIT::emitSaveThenMaterializeTagRegisters):
(JSC::SpecializedThunkJIT::emitRestoreSavedTagRegisters):
(JSC::SpecializedThunkJIT::tagReturnAsInt32):
* jit/ThunkGenerators.cpp:
(JSC::nativeForGenerator):  Since the nativeForGenerator can be called via a tail call
by various specialized thunks, we need to restore the values of the tag constant callee
save registers.  The specialized thunks is the only code that make such tail calls
to nativeForGenerator generated code.

Modified Paths

Diff

Modified: branches/jsc-tailcall/Source/_javascript_Core/ChangeLog (188888 => 188889)


--- branches/jsc-tailcall/Source/_javascript_Core/ChangeLog	2015-08-24 21:56:38 UTC (rev 188888)
+++ branches/jsc-tailcall/Source/_javascript_Core/ChangeLog	2015-08-24 22:40:45 UTC (rev 188889)
@@ -1,3 +1,33 @@
+2015-08-24  Michael Saboff  <msab...@apple.com>
+
+        jsc-tailcall: Specialized thunks need to save / restore callee save "tag" registers
+        https://bugs.webkit.org/show_bug.cgi?id=148345
+
+        Reviewed by Basile Clement.
+
+        Since these thunks can be called by FTL compiled functions, we can't count on the 
+        tagTypeNumberRegister and tagMaskRegister.  In fact, the same registers could be used
+        for other purposes.  Since they are callee saves, save the current values on entry to
+        these thunks and materialize the tag constant values.  On function exit we restore
+        the caller's values.
+
+        * jit/SpecializedThunkJIT.h:
+        (JSC::SpecializedThunkJIT::SpecializedThunkJIT):
+        (JSC::SpecializedThunkJIT::loadDoubleArgument):
+        (JSC::SpecializedThunkJIT::returnJSValue):
+        (JSC::SpecializedThunkJIT::returnDouble):
+        (JSC::SpecializedThunkJIT::returnInt32):
+        (JSC::SpecializedThunkJIT::returnJSCell):
+        (JSC::SpecializedThunkJIT::callDoubleToDoublePreservingReturn):
+        (JSC::SpecializedThunkJIT::emitSaveThenMaterializeTagRegisters):
+        (JSC::SpecializedThunkJIT::emitRestoreSavedTagRegisters):
+        (JSC::SpecializedThunkJIT::tagReturnAsInt32):
+        * jit/ThunkGenerators.cpp:
+        (JSC::nativeForGenerator):  Since the nativeForGenerator can be called via a tail call
+        by various specialized thunks, we need to restore the values of the tag constant callee
+        save registers.  The specialized thunks is the only code that make such tail calls
+        to nativeForGenerator generated code.
+
 2015-08-24  Basile Clement  <basile_clem...@apple.com>
 
         jsc-tailcall: We can't assert that registers are flushed when making a tail call

Modified: branches/jsc-tailcall/Source/_javascript_Core/jit/SpecializedThunkJIT.h (188888 => 188889)


--- branches/jsc-tailcall/Source/_javascript_Core/jit/SpecializedThunkJIT.h	2015-08-24 21:56:38 UTC (rev 188888)
+++ branches/jsc-tailcall/Source/_javascript_Core/jit/SpecializedThunkJIT.h	2015-08-24 22:40:45 UTC (rev 188889)
@@ -44,6 +44,7 @@
             : JSInterfaceJIT(vm)
         {
             emitFunctionPrologue();
+            emitSaveThenMaterializeTagRegisters();
             // Check that we have the expected number of arguments
             m_failures.append(branch32(NotEqual, payloadFor(JSStack::ArgumentCount), TrustedImm32(expectedArgCount + 1)));
         }
@@ -52,6 +53,7 @@
             : JSInterfaceJIT(vm)
         {
             emitFunctionPrologue();
+            emitSaveThenMaterializeTagRegisters();
         }
         
         void loadDoubleArgument(int argument, FPRegisterID dst, RegisterID scratch)
@@ -105,6 +107,8 @@
         {
             if (src != regT0)
                 move(src, regT0);
+            
+            emitRestoreSavedTagRegisters();
             emitFunctionEpilogue();
             ret();
         }
@@ -113,6 +117,7 @@
         {
             ASSERT_UNUSED(payload, payload == regT0);
             ASSERT_UNUSED(tag, tag == regT1);
+            emitRestoreSavedTagRegisters();
             emitFunctionEpilogue();
             ret();
         }
@@ -137,6 +142,7 @@
             lowNonZero.link(this);
             highNonZero.link(this);
 #endif
+            emitRestoreSavedTagRegisters();
             emitFunctionEpilogue();
             ret();
         }
@@ -146,6 +152,7 @@
             if (src != regT0)
                 move(src, regT0);
             tagReturnAsInt32();
+            emitRestoreSavedTagRegisters();
             emitFunctionEpilogue();
             ret();
         }
@@ -155,6 +162,7 @@
             if (src != regT0)
                 move(src, regT0);
             tagReturnAsJSCell();
+            emitRestoreSavedTagRegisters();
             emitFunctionEpilogue();
             ret();
         }
@@ -185,7 +193,31 @@
         }
 
     private:
+        void emitSaveThenMaterializeTagRegisters()
+        {
+#if USE(JSVALUE64)
+#if CPU(ARM64)
+            pushPair(tagTypeNumberRegister, tagMaskRegister);
+#else
+            push(tagTypeNumberRegister);
+            push(tagMaskRegister);
+#endif
+            emitMaterializeTagCheckRegisters();
+#endif
+        }
 
+        void emitRestoreSavedTagRegisters()
+        {
+#if USE(JSVALUE64)
+#if CPU(ARM64)
+            popPair(tagTypeNumberRegister, tagMaskRegister);
+#else
+            pop(tagMaskRegister);
+            pop(tagTypeNumberRegister);
+#endif
+#endif
+        }
+        
         void tagReturnAsInt32()
         {
 #if USE(JSVALUE64)

Modified: branches/jsc-tailcall/Source/_javascript_Core/jit/ThunkGenerators.cpp (188888 => 188889)


--- branches/jsc-tailcall/Source/_javascript_Core/jit/ThunkGenerators.cpp	2015-08-24 21:56:38 UTC (rev 188888)
+++ branches/jsc-tailcall/Source/_javascript_Core/jit/ThunkGenerators.cpp	2015-08-24 22:40:45 UTC (rev 188889)
@@ -223,6 +223,18 @@
 
     if (entryType == EnterViaCall)
         jit.emitFunctionPrologue();
+#if USE(JSVALUE64)
+    else if (entryType == EnterViaJump) {
+        // We're coming from a specialized thunk that has saved the prior tag registers' contents.
+        // Restore them now.
+#if CPU(ARM64)
+        jit.popPair(JSInterfaceJIT::tagTypeNumberRegister, JSInterfaceJIT::tagMaskRegister);
+#else
+        jit.pop(JSInterfaceJIT::tagMaskRegister);
+        jit.pop(JSInterfaceJIT::tagTypeNumberRegister);
+#endif
+    }
+#endif
 
     jit.emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock);
     jit.storePtr(JSInterfaceJIT::callFrameRegister, &vm->topCallFrame);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to