Title: [103384] trunk/Source/_javascript_Core
Revision
103384
Author
fpi...@apple.com
Date
2011-12-20 18:29:15 -0800 (Tue, 20 Dec 2011)

Log Message

Value Profiles for arguments should be more easily accessible to the interpreter
https://bugs.webkit.org/show_bug.cgi?id=74984
<rdar://problem/10611364>

Reviewed by Gavin Barraclough.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::stronglyVisitStrongReferences):
(JSC::CodeBlock::shouldOptimizeNow):
(JSC::CodeBlock::dumpValueProfiles):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::setArgumentValueProfileSize):
(JSC::CodeBlock::numberOfArgumentValueProfiles):
(JSC::CodeBlock::valueProfileForArgument):
(JSC::CodeBlock::addValueProfile):
(JSC::CodeBlock::valueProfile):
(JSC::CodeBlock::valueProfileForBytecodeOffset):
(JSC::CodeBlock::totalNumberOfValueProfiles):
(JSC::CodeBlock::getFromAllValueProfiles):
* bytecode/ValueProfile.h:
(JSC::ValueProfile::ValueProfile):
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JIT.h:
* jit/JITInlineMethods.h:
(JSC::JIT::emitValueProfilingSite):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (103383 => 103384)


--- trunk/Source/_javascript_Core/ChangeLog	2011-12-21 02:02:19 UTC (rev 103383)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-12-21 02:29:15 UTC (rev 103384)
@@ -1,3 +1,32 @@
+2011-12-20  Filip Pizlo  <fpi...@apple.com>
+
+        Value Profiles for arguments should be more easily accessible to the interpreter
+        https://bugs.webkit.org/show_bug.cgi?id=74984
+        <rdar://problem/10611364>
+
+        Reviewed by Gavin Barraclough.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::stronglyVisitStrongReferences):
+        (JSC::CodeBlock::shouldOptimizeNow):
+        (JSC::CodeBlock::dumpValueProfiles):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::setArgumentValueProfileSize):
+        (JSC::CodeBlock::numberOfArgumentValueProfiles):
+        (JSC::CodeBlock::valueProfileForArgument):
+        (JSC::CodeBlock::addValueProfile):
+        (JSC::CodeBlock::valueProfile):
+        (JSC::CodeBlock::valueProfileForBytecodeOffset):
+        (JSC::CodeBlock::totalNumberOfValueProfiles):
+        (JSC::CodeBlock::getFromAllValueProfiles):
+        * bytecode/ValueProfile.h:
+        (JSC::ValueProfile::ValueProfile):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * jit/JIT.h:
+        * jit/JITInlineMethods.h:
+        (JSC::JIT::emitValueProfilingSite):
+
 2011-12-20  Gavin Barraclough  <barraclo...@apple.com>
 
         JSC shell should accept utf8 input.

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (103383 => 103384)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2011-12-21 02:02:19 UTC (rev 103383)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2011-12-21 02:29:15 UTC (rev 103384)
@@ -1835,6 +1835,8 @@
 #endif
 
 #if ENABLE(VALUE_PROFILER)
+    for (unsigned profileIndex = 0; profileIndex < numberOfArgumentValueProfiles(); ++profileIndex)
+        valueProfileForArgument(profileIndex)->computeUpdatedPrediction();
     for (unsigned profileIndex = 0; profileIndex < numberOfValueProfiles(); ++profileIndex)
         valueProfile(profileIndex)->computeUpdatedPrediction();
 #endif
@@ -2206,11 +2208,10 @@
     if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay)
         return true;
     
-    unsigned numberOfNonArgumentValueProfiles = 0;
     unsigned numberOfLiveNonArgumentValueProfiles = 0;
     unsigned numberOfSamplesInProfiles = 0; // If this divided by ValueProfile::numberOfBuckets equals numberOfValueProfiles() then value profiles are full.
-    for (unsigned i = 0; i < numberOfValueProfiles(); ++i) {
-        ValueProfile* profile = ""
+    for (unsigned i = 0; i < totalNumberOfValueProfiles(); ++i) {
+        ValueProfile* profile = ""
         unsigned numSamples = profile->totalNumberOfSamples();
         if (numSamples > ValueProfile::numberOfBuckets)
             numSamples = ValueProfile::numberOfBuckets; // We don't want profiles that are extremely hot to be given more weight.
@@ -2219,18 +2220,17 @@
             profile->computeUpdatedPrediction();
             continue;
         }
-        numberOfNonArgumentValueProfiles++;
         if (profile->numberOfSamples() || profile->m_prediction != PredictNone)
             numberOfLiveNonArgumentValueProfiles++;
         profile->computeUpdatedPrediction();
     }
 
 #if ENABLE(JIT_VERBOSE_OSR)
-    printf("Profile hotness: %lf, %lf\n", (double)numberOfLiveNonArgumentValueProfiles / numberOfNonArgumentValueProfiles, (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles());
+    printf("Profile hotness: %lf, %lf\n", (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles(), (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles());
 #endif
 
-    if ((!numberOfNonArgumentValueProfiles || (double)numberOfLiveNonArgumentValueProfiles / numberOfNonArgumentValueProfiles >= Options::desiredProfileLivenessRate)
-        && (!numberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles() >= Options::desiredProfileFullnessRate)
+    if ((!numberOfValueProfiles() || (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles() >= Options::desiredProfileLivenessRate)
+        && (!totalNumberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / totalNumberOfValueProfiles() >= Options::desiredProfileFullnessRate)
         && static_cast<unsigned>(m_optimizationDelayCounter) + 1 >= Options::minimumOptimizationDelay)
         return true;
     
@@ -2267,8 +2267,8 @@
 void CodeBlock::dumpValueProfiles()
 {
     fprintf(stderr, "ValueProfile for %p:\n", this);
-    for (unsigned i = 0; i < numberOfValueProfiles(); ++i) {
-        ValueProfile* profile = ""
+    for (unsigned i = 0; i < totalNumberOfValueProfiles(); ++i) {
+        ValueProfile* profile = ""
         if (profile->m_bytecodeOffset < 0) {
             ASSERT(profile->m_bytecodeOffset == -1);
             fprintf(stderr, "   arg = %u: ", i);

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (103383 => 103384)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2011-12-21 02:02:19 UTC (rev 103383)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2011-12-21 02:29:15 UTC (rev 103384)
@@ -657,28 +657,52 @@
 #endif
         
 #if ENABLE(VALUE_PROFILER)
+        void setArgumentValueProfileSize(unsigned size)
+        {
+            m_argumentValueProfiles.resize(size);
+        }
+        unsigned numberOfArgumentValueProfiles()
+        {
+            return m_argumentValueProfiles.size();
+        }
+        ValueProfile* valueProfileForArgument(unsigned argumentIndex)
+        {
+            ValueProfile* result = &m_argumentValueProfiles[argumentIndex];
+            ASSERT(result->m_bytecodeOffset == -1);
+            return result;
+        }
+        
         ValueProfile* addValueProfile(int bytecodeOffset)
         {
+            ASSERT(bytecodeOffset != -1);
             m_valueProfiles.append(ValueProfile(bytecodeOffset));
             return &m_valueProfiles.last();
         }
         unsigned numberOfValueProfiles() { return m_valueProfiles.size(); }
-        ValueProfile* valueProfile(int index) { return &m_valueProfiles[index]; }
-        ValueProfile* valueProfileForBytecodeOffset(int bytecodeOffset)
+        ValueProfile* valueProfile(int index)
         {
-            return WTF::genericBinarySearch<ValueProfile, int, getValueProfileBytecodeOffset>(m_valueProfiles, m_valueProfiles.size(), bytecodeOffset);
+            ValueProfile* result = &m_valueProfiles[index];
+            ASSERT(result->m_bytecodeOffset != -1);
+            return result;
         }
-        ValueProfile* valueProfileForArgument(int argument)
+        ValueProfile* valueProfileForBytecodeOffset(int bytecodeOffset)
         {
-            size_t index = argument;
-            if (index >= m_valueProfiles.size())
-                return 0;
-            ValueProfile* result = valueProfile(index);
-            if (result->m_bytecodeOffset != -1)
-                return 0;
+            ValueProfile* result = WTF::genericBinarySearch<ValueProfile, int, getValueProfileBytecodeOffset>(m_valueProfiles, m_valueProfiles.size(), bytecodeOffset);
+            ASSERT(result->m_bytecodeOffset != -1);
             return result;
         }
         
+        unsigned totalNumberOfValueProfiles()
+        {
+            return numberOfArgumentValueProfiles() + numberOfValueProfiles();
+        }
+        ValueProfile* getFromAllValueProfiles(unsigned index)
+        {
+            if (index < numberOfArgumentValueProfiles())
+                return valueProfileForArgument(index);
+            return valueProfile(index - numberOfArgumentValueProfiles());
+        }
+        
         RareCaseProfile* addRareCaseProfile(int bytecodeOffset)
         {
             m_rareCaseProfiles.append(RareCaseProfile(bytecodeOffset));
@@ -1251,6 +1275,7 @@
         DFG::ExitProfile m_exitProfile;
 #endif
 #if ENABLE(VALUE_PROFILER)
+        Vector<ValueProfile> m_argumentValueProfiles;
         SegmentedVector<ValueProfile, 8> m_valueProfiles;
         SegmentedVector<RareCaseProfile, 8> m_rareCaseProfiles;
         SegmentedVector<RareCaseProfile, 8> m_specialFastCaseProfiles;

Modified: trunk/Source/_javascript_Core/bytecode/ValueProfile.h (103383 => 103384)


--- trunk/Source/_javascript_Core/bytecode/ValueProfile.h	2011-12-21 02:02:19 UTC (rev 103383)
+++ trunk/Source/_javascript_Core/bytecode/ValueProfile.h	2011-12-21 02:29:15 UTC (rev 103384)
@@ -44,6 +44,15 @@
     static const unsigned bucketIndexMask = numberOfBuckets - 1;
     static const unsigned totalNumberOfBuckets = numberOfBuckets + numberOfSpecFailBuckets;
     
+    ValueProfile()
+        : m_bytecodeOffset(-1)
+        , m_prediction(PredictNone)
+        , m_numberOfSamplesInPrediction(0)
+    {
+        for (unsigned i = 0; i < totalNumberOfBuckets; ++i)
+            m_buckets[i] = JSValue::encode(JSValue());
+    }
+    
     ValueProfile(int bytecodeOffset)
         : m_bytecodeOffset(bytecodeOffset)
         , m_prediction(PredictNone)

Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (103383 => 103384)


--- trunk/Source/_javascript_Core/jit/JIT.cpp	2011-12-21 02:02:19 UTC (rev 103383)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp	2011-12-21 02:29:15 UTC (rev 103384)
@@ -557,21 +557,20 @@
 #if ENABLE(VALUE_PROFILER)
         ASSERT(m_bytecodeOffset == (unsigned)-1);
         if (shouldEmitProfiling()) {
+            m_codeBlock->setArgumentValueProfileSize(m_codeBlock->m_numParameters);
             for (int argument = 0; argument < m_codeBlock->m_numParameters; ++argument) {
                 // If this is a constructor, then we want to put in a dummy profiling site (to
                 // keep things consistent) but we don't actually want to record the dummy value.
                 if (m_codeBlock->m_isConstructor && !argument)
-                    m_codeBlock->addValueProfile(-1);
-                else {
-                    int offset = CallFrame::argumentOffsetIncludingThis(argument) * static_cast<int>(sizeof(Register));
+                    continue;
+                int offset = CallFrame::argumentOffsetIncludingThis(argument) * static_cast<int>(sizeof(Register));
 #if USE(JSVALUE64)
-                    loadPtr(Address(callFrameRegister, offset), regT0);
+                loadPtr(Address(callFrameRegister, offset), regT0);
 #elif USE(JSVALUE32_64)
-                    load32(Address(callFrameRegister, offset + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
-                    load32(Address(callFrameRegister, offset + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
+                load32(Address(callFrameRegister, offset + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
+                load32(Address(callFrameRegister, offset + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
 #endif
-                    emitValueProfilingSite(FirstProfilingSite);
-                }
+                emitValueProfilingSite(m_codeBlock->valueProfileForArgument(argument));
             }
         }
 #endif

Modified: trunk/Source/_javascript_Core/jit/JIT.h (103383 => 103384)


--- trunk/Source/_javascript_Core/jit/JIT.h	2011-12-21 02:02:19 UTC (rev 103383)
+++ trunk/Source/_javascript_Core/jit/JIT.h	2011-12-21 02:29:15 UTC (rev 103384)
@@ -337,6 +337,7 @@
 #if ENABLE(VALUE_PROFILER)
         // This assumes that the value to profile is in regT0 and that regT3 is available for
         // scratch.
+        void emitValueProfilingSite(ValueProfile*);
         void emitValueProfilingSite(ValueProfilingSiteKind);
 #else
         void emitValueProfilingSite(ValueProfilingSiteKind) { }

Modified: trunk/Source/_javascript_Core/jit/JITInlineMethods.h (103383 => 103384)


--- trunk/Source/_javascript_Core/jit/JITInlineMethods.h	2011-12-21 02:02:19 UTC (rev 103383)
+++ trunk/Source/_javascript_Core/jit/JITInlineMethods.h	2011-12-21 02:29:15 UTC (rev 103384)
@@ -448,27 +448,17 @@
 }
 
 #if ENABLE(VALUE_PROFILER)
-inline void JIT::emitValueProfilingSite(ValueProfilingSiteKind siteKind)
+inline void JIT::emitValueProfilingSite(ValueProfile* valueProfile)
 {
-    if (!shouldEmitProfiling())
-        return;
-    
+    ASSERT(shouldEmitProfiling());
+    ASSERT(valueProfile);
+
     const RegisterID value = regT0;
 #if USE(JSVALUE32_64)
     const RegisterID valueTag = regT1;
 #endif
     const RegisterID scratch = regT3;
     
-    ValueProfile* valueProfile;
-    if (siteKind == FirstProfilingSite)
-        valueProfile = m_codeBlock->addValueProfile(m_bytecodeOffset);
-    else {
-        ASSERT(siteKind == SubsequentProfilingSite);
-        valueProfile = m_codeBlock->valueProfileForBytecodeOffset(m_bytecodeOffset);
-    }
-    
-    ASSERT(valueProfile);
-    
     if (ValueProfile::numberOfBuckets == 1) {
         // We're in a simple configuration: only one bucket, so we can just do a direct
         // store.
@@ -495,6 +485,22 @@
     store32(valueTag, BaseIndex(scratch, bucketCounterRegister, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
 #endif
 }
+
+inline void JIT::emitValueProfilingSite(ValueProfilingSiteKind siteKind)
+{
+    if (!shouldEmitProfiling())
+        return;
+    
+    ValueProfile* valueProfile;
+    if (siteKind == FirstProfilingSite)
+        valueProfile = m_codeBlock->addValueProfile(m_bytecodeOffset);
+    else {
+        ASSERT(siteKind == SubsequentProfilingSite);
+        valueProfile = m_codeBlock->valueProfileForBytecodeOffset(m_bytecodeOffset);
+    }
+    
+    emitValueProfilingSite(valueProfile);
+}
 #endif
 
 #if USE(JSVALUE32_64)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to