Title: [97025] trunk/Source/_javascript_Core
Revision
97025
Author
[email protected]
Date
2011-10-09 03:19:23 -0700 (Sun, 09 Oct 2011)

Log Message

Fix value profiling in 32_64 JIT
https://bugs.webkit.org/show_bug.cgi?id=69717

Patch by Yuqiang Xian <[email protected]> on 2011-10-09
Reviewed by Filip Pizlo.

Current value profiling for 32_64 JIT is broken and cannot record
correct predicated types, which results in many speculation failures
in the 32_64 DFG JIT, fallbacks to baseline JIT, and re-optimizations
again and again.
With this fix 32_64 DFG JIT can demonstrate real performance gains.

* bytecode/ValueProfile.cpp:
(JSC::ValueProfile::computeStatistics):
* bytecode/ValueProfile.h:
(JSC::ValueProfile::classInfo):
(JSC::ValueProfile::numberOfSamples):
(JSC::ValueProfile::isLive):
(JSC::ValueProfile::numberOfInt32s):
(JSC::ValueProfile::numberOfDoubles):
(JSC::ValueProfile::numberOfBooleans):
(JSC::ValueProfile::dump):
    Empty value check should be performed on decoded JSValue,
    as for 32_64 empty value is not identical to encoded 0.
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JITInlineMethods.h:
(JSC::JIT::emitValueProfilingSite):
* jit/JITStubCall.h:
(JSC::JITStubCall::callWithValueProfiling):
    Record the right profiling result for 32_64.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (97024 => 97025)


--- trunk/Source/_javascript_Core/ChangeLog	2011-10-09 10:02:58 UTC (rev 97024)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-10-09 10:19:23 UTC (rev 97025)
@@ -1,5 +1,38 @@
 2011-10-09  Yuqiang Xian  <[email protected]>
 
+        Fix value profiling in 32_64 JIT
+        https://bugs.webkit.org/show_bug.cgi?id=69717
+
+        Reviewed by Filip Pizlo.
+
+        Current value profiling for 32_64 JIT is broken and cannot record
+        correct predicated types, which results in many speculation failures
+        in the 32_64 DFG JIT, fallbacks to baseline JIT, and re-optimizations
+        again and again. 
+        With this fix 32_64 DFG JIT can demonstrate real performance gains.
+
+        * bytecode/ValueProfile.cpp:
+        (JSC::ValueProfile::computeStatistics):
+        * bytecode/ValueProfile.h:
+        (JSC::ValueProfile::classInfo):
+        (JSC::ValueProfile::numberOfSamples):
+        (JSC::ValueProfile::isLive):
+        (JSC::ValueProfile::numberOfInt32s):
+        (JSC::ValueProfile::numberOfDoubles):
+        (JSC::ValueProfile::numberOfBooleans):
+        (JSC::ValueProfile::dump):
+            Empty value check should be performed on decoded JSValue,
+            as for 32_64 empty value is not identical to encoded 0.
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * jit/JITInlineMethods.h:
+        (JSC::JIT::emitValueProfilingSite):
+        * jit/JITStubCall.h:
+        (JSC::JITStubCall::callWithValueProfiling):
+            Record the right profiling result for 32_64.
+
+2011-10-09  Yuqiang Xian  <[email protected]>
+
         Remove 32 bit restrictions in DFG JIT
         https://bugs.webkit.org/show_bug.cgi?id=69711
 

Modified: trunk/Source/_javascript_Core/bytecode/ValueProfile.cpp (97024 => 97025)


--- trunk/Source/_javascript_Core/bytecode/ValueProfile.cpp	2011-10-09 10:02:58 UTC (rev 97024)
+++ trunk/Source/_javascript_Core/bytecode/ValueProfile.cpp	2011-10-09 10:19:23 UTC (rev 97025)
@@ -60,7 +60,8 @@
 void ValueProfile::computeStatistics(Statistics& statistics) const
 {
     for (unsigned i = 0; i < numberOfBuckets; ++i) {
-        if (!m_buckets[i]) {
+        JSValue value = JSValue::decode(m_buckets[i]);
+        if (!value) {
             WeakBucket weakBucket = m_weakBuckets[i];
             if (!!weakBucket) {
                 statistics.samples++;
@@ -72,7 +73,6 @@
         
         statistics.samples++;
         
-        JSValue value = JSValue::decode(m_buckets[i]);
         if (value.isInt32())
             statistics.int32s++;
         else if (value.isDouble())

Modified: trunk/Source/_javascript_Core/bytecode/ValueProfile.h (97024 => 97025)


--- trunk/Source/_javascript_Core/bytecode/ValueProfile.h	2011-10-09 10:02:58 UTC (rev 97024)
+++ trunk/Source/_javascript_Core/bytecode/ValueProfile.h	2011-10-09 10:19:23 UTC (rev 97025)
@@ -55,8 +55,8 @@
     
     const ClassInfo* classInfo(unsigned bucket) const
     {
-        if (!!m_buckets[bucket]) {
-            JSValue value = JSValue::decode(m_buckets[bucket]);
+        JSValue value = JSValue::decode(m_buckets[bucket]);
+        if (!!value) {
             if (!value.isCell())
                 return 0;
             return value.asCell()->structure()->classInfo();
@@ -68,7 +68,7 @@
     {
         unsigned result = 0;
         for (unsigned i = 0; i < numberOfBuckets; ++i) {
-            if (!!m_buckets[i] || !!m_weakBuckets[i])
+            if (!!JSValue::decode(m_buckets[i]) || !!m_weakBuckets[i])
                 result++;
         }
         return result;
@@ -82,7 +82,7 @@
     bool isLive() const
     {
         for (unsigned i = 0; i < numberOfBuckets; ++i) {
-            if (!!m_buckets[i] || !!m_weakBuckets[i])
+            if (!!JSValue::decode(m_buckets[i]) || !!m_weakBuckets[i])
                 return true;
         }
         return false;
@@ -99,7 +99,7 @@
     {
         unsigned result = 0;
         for (unsigned i = 0; i < numberOfBuckets; ++i) {
-            if (!!m_buckets[i] && JSValue::decode(m_buckets[i]).isInt32())
+            if (JSValue::decode(m_buckets[i]).isInt32())
                 result++;
         }
         return result;
@@ -109,7 +109,7 @@
     {
         unsigned result = 0;
         for (unsigned i = 0; i < numberOfBuckets; ++i) {
-            if (!!m_buckets[i] && JSValue::decode(m_buckets[i]).isDouble())
+            if (JSValue::decode(m_buckets[i]).isDouble())
                 result++;
         }
         return result;
@@ -170,7 +170,7 @@
     {
         unsigned result = 0;
         for (unsigned i = 0; i < numberOfBuckets; ++i) {
-            if (!!m_buckets[i] && JSValue::decode(m_buckets[i]).isBoolean())
+            if (JSValue::decode(m_buckets[i]).isBoolean())
                 result++;
         }
         return result;
@@ -238,7 +238,8 @@
                 predictionToString(m_prediction), m_numberOfSamplesInPrediction);
         bool first = true;
         for (unsigned i = 0; i < numberOfBuckets; ++i) {
-            if (!!m_buckets[i] || !!m_weakBuckets[i]) {
+            JSValue value = JSValue::decode(m_buckets[i]);
+            if (!!value || !!m_weakBuckets[i]) {
                 if (first) {
                     fprintf(out, ": ");
                     first = false;
@@ -246,8 +247,8 @@
                     fprintf(out, ", ");
             }
             
-            if (!!m_buckets[i])
-                fprintf(out, "%s", JSValue::decode(m_buckets[i]).description());
+            if (!!value)
+                fprintf(out, "%s", value.description());
             
             if (!!m_weakBuckets[i])
                 fprintf(out, "DeadCell");

Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (97024 => 97025)


--- trunk/Source/_javascript_Core/jit/JIT.cpp	2011-10-09 10:02:58 UTC (rev 97024)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp	2011-10-09 10:19:23 UTC (rev 97025)
@@ -573,7 +573,12 @@
                     && argumentRegister == -RegisterFile::CallFrameHeaderSize - m_codeBlock->m_numParameters)
                     m_codeBlock->addValueProfile(-1);
                 else {
+#if USE(JSVALUE64)
                     loadPtr(Address(callFrameRegister, argumentRegister * sizeof(Register)), regT0);
+#elif USE(JSVALUE32_64)
+                    load32(Address(callFrameRegister, argumentRegister * sizeof(Register) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
+                    load32(Address(callFrameRegister, argumentRegister * sizeof(Register) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
+#endif
                     emitValueProfilingSite(FirstProfilingSite);
                 }
             }

Modified: trunk/Source/_javascript_Core/jit/JITInlineMethods.h (97024 => 97025)


--- trunk/Source/_javascript_Core/jit/JITInlineMethods.h	2011-10-09 10:02:58 UTC (rev 97024)
+++ trunk/Source/_javascript_Core/jit/JITInlineMethods.h	2011-10-09 10:19:23 UTC (rev 97025)
@@ -471,7 +471,13 @@
         add32(Imm32(3), bucketCounterRegister);
     and32(Imm32(ValueProfile::bucketIndexMask), bucketCounterRegister);
     move(ImmPtr(valueProfile->m_buckets), scratch);
+#if USE(JSVALUE64)
     storePtr(value, BaseIndex(scratch, bucketCounterRegister, TimesEight));
+#elif USE(JSVALUE32_64)
+    const RegisterID valueTag = regT1;
+    store32(value, BaseIndex(scratch, bucketCounterRegister, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+    store32(valueTag, BaseIndex(scratch, bucketCounterRegister, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+#endif
 }
 #endif
 

Modified: trunk/Source/_javascript_Core/jit/JITStubCall.h (97024 => 97025)


--- trunk/Source/_javascript_Core/jit/JITStubCall.h	2011-10-09 10:02:58 UTC (rev 97024)
+++ trunk/Source/_javascript_Core/jit/JITStubCall.h	2011-10-09 10:19:23 UTC (rev 97025)
@@ -205,6 +205,9 @@
         {
             ASSERT(m_returnType == Value || m_returnType == Cell);
             JIT::Call call = this->call();
+            ASSERT(JIT::returnValueRegister == JIT::regT0);
+            if (m_returnType == Cell)
+                m_jit->move(JIT::TrustedImm32(JSValue::CellTag), JIT::regT1);
             m_jit->emitValueProfilingSite(kind);
             if (m_returnType == Value)
                 m_jit->emitStore(dst, JIT::regT1, JIT::regT0);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to