Ignore:
Timestamp:
Sep 14, 2011, 4:00:26 PM (14 years ago)
Author:
[email protected]
Message:

Tiered compilation heuristics do not account for value profile fullness
https://bugs.webkit.org/show_bug.cgi?id=68116

Reviewed by Oliver Hunt.

Tiered compilation avoids invoking the DFG JIT if it finds that value
profiles contain insufficient information. Instead, it produces a
prediction from the current value profile, and then clears the value
profile. This allows the value profile to heat up from scratch for
some number of additional executions. The new profiles will then be
merged with the previous prediction. Once the amount of information
in predictions is enough according to heuristics in CodeBlock.cpp,
DFG optimization is allowed to proceed.

(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::~CodeBlock):
(JSC::CodeBlock::visitAggregate):
(JSC::CodeBlock::visitWeakReferences):
(JSC::CodeBlock::shouldOptimizeNow):
(JSC::CodeBlock::dumpValueProfiles):

  • bytecode/CodeBlock.h:
  • bytecode/PredictedType.cpp:

(JSC::predictionToString):

  • bytecode/PredictedType.h:
  • bytecode/ValueProfile.cpp: Added.

(JSC::ValueProfile::computeStatistics):
(JSC::ValueProfile::computeUpdatedPrediction):

  • bytecode/ValueProfile.h:

(JSC::ValueProfile::ValueProfile):
(JSC::ValueProfile::classInfo):
(JSC::ValueProfile::numberOfSamples):
(JSC::ValueProfile::totalNumberOfSamples):
(JSC::ValueProfile::isLive):
(JSC::ValueProfile::numberOfInt32s):
(JSC::ValueProfile::numberOfDoubles):
(JSC::ValueProfile::numberOfBooleans):
(JSC::ValueProfile::dump):
(JSC::getValueProfileBytecodeOffset):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::stronglyPredict):

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::predictArgumentTypes):

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::exitSpeculativeWithOSR):
(JSC::DFG::JITCompiler::jumpFromSpeculativeToNonSpeculative):

  • jit/JIT.cpp:

(JSC::JIT::emitOptimizationCheck):

  • jit/JITInlineMethods.h:

(JSC::JIT::emitValueProfilingSite):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecode/ValueProfile.h

    r95115 r95134  
    3131
    3232#include "JSArray.h"
     33#include "PredictedType.h"
    3334#include "Structure.h"
    3435#include "WriteBarrier.h"
     
    4546   
    4647    ValueProfile(int bytecodeOffset)
    47         : bytecodeOffset(bytecodeOffset)
     48        : m_bytecodeOffset(bytecodeOffset)
     49        , m_prediction(PredictNone)
     50        , m_numberOfSamplesInPrediction(0)
    4851    {
    4952        for (unsigned i = 0; i < numberOfBuckets; ++i)
    50             buckets[i] = JSValue::encode(JSValue());
     53            m_buckets[i] = JSValue::encode(JSValue());
    5154    }
    5255   
    5356    const ClassInfo* classInfo(unsigned bucket) const
    5457    {
    55         if (!!buckets[bucket]) {
    56             JSValue value = JSValue::decode(buckets[bucket]);
     58        if (!!m_buckets[bucket]) {
     59            JSValue value = JSValue::decode(m_buckets[bucket]);
    5760            if (!value.isCell())
    5861                return 0;
    5962            return value.asCell()->structure()->classInfo();
    6063        }
    61         return weakBuckets[bucket].getClassInfo();
     64        return m_weakBuckets[bucket].getClassInfo();
    6265    }
    6366   
     
    6669        unsigned result = 0;
    6770        for (unsigned i = 0; i < numberOfBuckets; ++i) {
    68             if (!!buckets[i] || !!weakBuckets[i])
    69                 result++;
    70         }
    71         return result;
     71            if (!!m_buckets[i] || !!m_weakBuckets[i])
     72                result++;
     73        }
     74        return result;
     75    }
     76   
     77    unsigned totalNumberOfSamples() const
     78    {
     79        return numberOfSamples() + m_numberOfSamplesInPrediction;
     80    }
     81   
     82    bool isLive() const
     83    {
     84        for (unsigned i = 0; i < numberOfBuckets; ++i) {
     85            if (!!m_buckets[i] || !!m_weakBuckets[i])
     86                return true;
     87        }
     88        return false;
    7289    }
    7390   
     
    83100        unsigned result = 0;
    84101        for (unsigned i = 0; i < numberOfBuckets; ++i) {
    85             if (!!buckets[i] && JSValue::decode(buckets[i]).isInt32())
     102            if (!!m_buckets[i] && JSValue::decode(m_buckets[i]).isInt32())
    86103                result++;
    87104        }
     
    93110        unsigned result = 0;
    94111        for (unsigned i = 0; i < numberOfBuckets; ++i) {
    95             if (!!buckets[i] && JSValue::decode(buckets[i]).isDouble())
     112            if (!!m_buckets[i] && JSValue::decode(m_buckets[i]).isDouble())
    96113                result++;
    97114        }
     
    154171        unsigned result = 0;
    155172        for (unsigned i = 0; i < numberOfBuckets; ++i) {
    156             if (!!buckets[i] && JSValue::decode(buckets[i]).isBoolean())
     173            if (!!m_buckets[i] && JSValue::decode(m_buckets[i]).isBoolean())
    157174                result++;
    158175        }
     
    209226    {
    210227        fprintf(out,
    211                 "samples = %u, int32 = %u (%u), double = %u (%u), cell = %u (%u), object = %u (%u), final object = %u (%u), array = %u (%u), string = %u (%u), boolean = %u (%u)",
     228                "samples = %u, int32 = %u (%u), double = %u (%u), cell = %u (%u), object = %u (%u), final object = %u (%u), array = %u (%u), string = %u (%u), boolean = %u (%u), prediction = %s, samples in prediction = %u",
    212229                numberOfSamples(),
    213230                probabilityOfInt32(), numberOfInt32s(),
     
    218235                probabilityOfArray(), numberOfArrays(),
    219236                probabilityOfString(), numberOfStrings(),
    220                 probabilityOfBoolean(), numberOfBooleans());
     237                probabilityOfBoolean(), numberOfBooleans(),
     238                predictionToString(m_prediction), m_numberOfSamplesInPrediction);
    221239        bool first = true;
    222240        for (unsigned i = 0; i < numberOfBuckets; ++i) {
    223             if (!!buckets[i] || !!weakBuckets[i]) {
     241            if (!!m_buckets[i] || !!m_weakBuckets[i]) {
    224242                if (first) {
    225243                    fprintf(out, ": ");
     
    229247            }
    230248           
    231             if (!!buckets[i])
    232                 fprintf(out, "%s", JSValue::decode(buckets[i]).description());
     249            if (!!m_buckets[i])
     250                fprintf(out, "%s", JSValue::decode(m_buckets[i]).description());
    233251           
    234             if (!!weakBuckets[i])
     252            if (!!m_weakBuckets[i])
    235253                fprintf(out, "DeadCell");
    236254        }
     
    258276    // incrementing the number of samples, which the caller is responsible for
    259277    // doing.
    260     static void computeStatistics(const ClassInfo* classInfo, Statistics& statistics)
    261     {
    262         statistics.cells++;
    263        
    264         if (classInfo == &JSFinalObject::s_info) {
    265             statistics.finalObjects++;
    266             statistics.objects++;
    267             return;
    268         }
    269        
    270         if (classInfo == &JSArray::s_info) {
    271             statistics.arrays++;
    272             statistics.objects++;
    273             return;
    274         }
    275        
    276         if (classInfo == &JSString::s_info) {
    277             statistics.strings++;
    278             return;
    279         }
    280        
    281         if (classInfo->isSubClassOf(&JSObject::s_info))
    282             statistics.objects++;
    283     }
     278    static void computeStatistics(const ClassInfo*, Statistics&);
    284279
    285280    // Optimized method for getting all counts at once.
    286     void computeStatistics(Statistics& statistics) const
    287     {
    288         for (unsigned i = 0; i < numberOfBuckets; ++i) {
    289             if (!buckets[i]) {
    290                 WeakBucket weakBucket = weakBuckets[i];
    291                 if (!!weakBucket) {
    292                     statistics.samples++;
    293                     computeStatistics(weakBucket.getClassInfo(), statistics);
    294                 }
    295                
    296                 continue;
    297             }
    298            
    299             statistics.samples++;
    300            
    301             JSValue value = JSValue::decode(buckets[i]);
    302             if (value.isInt32())
    303                 statistics.int32s++;
    304             else if (value.isDouble())
    305                 statistics.doubles++;
    306             else if (value.isCell())
    307                 computeStatistics(value.asCell()->structure()->classInfo(), statistics);
    308             else if (value.isBoolean())
    309                 statistics.booleans++;
    310         }
    311     }
    312    
    313     int bytecodeOffset; // -1 for prologue
    314     EncodedJSValue buckets[numberOfBuckets];
     281    void computeStatistics(Statistics&) const;
     282   
     283    // Updates the prediction and returns the new one.
     284    PredictedType computeUpdatedPrediction();
     285   
     286    int m_bytecodeOffset; // -1 for prologue
     287   
     288    PredictedType m_prediction;
     289    unsigned m_numberOfSamplesInPrediction;
     290   
     291    EncodedJSValue m_buckets[numberOfBuckets];
    315292   
    316293    class WeakBucket {
     
    376353    };
    377354   
    378     WeakBucket weakBuckets[numberOfBuckets]; // this is not covered by a write barrier because it is only set from GC
     355    WeakBucket m_weakBuckets[numberOfBuckets]; // this is not covered by a write barrier because it is only set from GC
    379356};
    380357
    381358inline int getValueProfileBytecodeOffset(ValueProfile* valueProfile)
    382359{
    383     return valueProfile->bytecodeOffset;
     360    return valueProfile->m_bytecodeOffset;
    384361}
    385362#endif
Note: See TracChangeset for help on using the changeset viewer.