Changeset 244204 in webkit


Ignore:
Timestamp:
Apr 11, 2019 5:53:12 PM (5 years ago)
Author:
msaboff@apple.com
Message:

Improve the Inline Cache Stats code
https://bugs.webkit.org/show_bug.cgi?id=196836

Reviewed by Saam Barati.

Source/JavaScriptCore:

Needed to handle the case where the Identifier could be null, for example with InstanceOfAddAccessCase
and InstanceOfReplaceWithJump.

Added the ability to log the location of a GetBy and PutBy property as either on self or up the
protocol chain.

  • jit/ICStats.cpp:

(JSC::ICEvent::operator< const):
(JSC::ICEvent::dump const):

  • jit/ICStats.h:

(JSC::ICEvent::ICEvent):
(JSC::ICEvent::hash const):

  • jit/JITOperations.cpp:
  • jit/Repatch.cpp:

(JSC::tryCacheGetByID):
(JSC::tryCachePutByID):
(JSC::tryCacheInByID):

Tools:

Added a new script to consolidate and arrange the output of --useICStats option.

This script merges the output from every group into one large table and sorts it from most common to
least common. It also counts the slow path GetById and PutById variants and then calculates the
percentage of gets or puts for each unique base,property pair compared to all the gets and puts.
Put together, this is useful to see what property accesses are not getting cached.

  • Scripts/ic-stats.py: Added.

(ICStats):
(ICStats.init):
(ICStats.parse):
(ICStats.dumpStats):
(usage):

Location:
trunk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r244195 r244204  
     12019-04-11  Michael Saboff  <msaboff@apple.com>
     2
     3        Improve the Inline Cache Stats code
     4        https://bugs.webkit.org/show_bug.cgi?id=196836
     5
     6        Reviewed by Saam Barati.
     7
     8        Needed to handle the case where the Identifier could be null, for example with InstanceOfAddAccessCase
     9        and InstanceOfReplaceWithJump.
     10
     11        Added the ability to log the location of a GetBy and PutBy property as either on self or up the
     12        protocol chain.
     13
     14        * jit/ICStats.cpp:
     15        (JSC::ICEvent::operator< const):
     16        (JSC::ICEvent::dump const):
     17        * jit/ICStats.h:
     18        (JSC::ICEvent::ICEvent):
     19        (JSC::ICEvent::hash const):
     20        * jit/JITOperations.cpp:
     21        * jit/Repatch.cpp:
     22        (JSC::tryCacheGetByID):
     23        (JSC::tryCachePutByID):
     24        (JSC::tryCacheInByID):
     25
    1262019-04-11  Devin Rousso  <drousso@apple.com>
    227
  • trunk/Source/JavaScriptCore/jit/ICStats.cpp

    r215265 r244204  
    4141    if (m_propertyName != other.m_propertyName)
    4242        return codePointCompare(m_propertyName.string(), other.m_propertyName.string()) < 0;
    43    
    44     return m_kind < other.m_kind;
     43
     44    if (m_kind != other.m_kind)
     45        return m_kind < other.m_kind;
     46
     47    return m_propertyLocation < other.m_propertyLocation;
    4548}
    4649
     
    4851{
    4952    out.print(m_kind, "(", m_classInfo ? m_classInfo->className : "<null>", ", ", m_propertyName, ")");
     53    if (m_propertyLocation != Unknown)
     54        out.print(m_propertyLocation == BaseObject ? " self" : " proto lookup");
    5055}
    5156
  • trunk/Source/JavaScriptCore/jit/ICStats.h

    r232047 r244204  
    7979#undef ICEVENT_KIND_DECLARATION
    8080    };
    81    
     81
     82    enum PropertyLocation {
     83        Unknown,
     84        BaseObject,
     85        ProtoLookup
     86    };
     87
    8288    ICEvent()
    8389    {
     
    8894        , m_classInfo(classInfo)
    8995        , m_propertyName(propertyName)
    90     {
    91     }
    92 
     96        , m_propertyLocation(Unknown)
     97    {
     98    }
     99
     100    ICEvent(Kind kind, const ClassInfo* classInfo, const Identifier propertyName, bool isBaseProperty)
     101        : m_kind(kind)
     102        , m_classInfo(classInfo)
     103        , m_propertyName(propertyName)
     104        , m_propertyLocation(isBaseProperty ? BaseObject : ProtoLookup)
     105    {
     106    }
     107   
    93108    ICEvent(WTF::HashTableDeletedValueType)
    94109        : m_kind(OperationGetById)
     
    124139    unsigned hash() const
    125140    {
    126         return m_kind + WTF::PtrHash<const ClassInfo*>::hash(m_classInfo) + StringHash::hash(m_propertyName.string());
     141        if (m_propertyName.isNull())
     142            return m_kind + m_propertyLocation + WTF::PtrHash<const ClassInfo*>::hash(m_classInfo);
     143        return m_kind + m_propertyLocation + WTF::PtrHash<const ClassInfo*>::hash(m_classInfo) + StringHash::hash(m_propertyName.string());
    127144    }
    128145   
     
    141158    const ClassInfo* m_classInfo { nullptr };
    142159    Identifier m_propertyName;
     160    PropertyLocation m_propertyLocation;
    143161};
    144162
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r244069 r244204  
    253253    PropertySlot slot(baseValue, PropertySlot::InternalMethodType::Get);
    254254    Identifier ident = Identifier::fromUid(vm, uid);
    255    
    256     LOG_IC((ICEvent::OperationGetById, baseValue.classInfoOrNull(*vm), ident));
    257     return JSValue::encode(baseValue.get(exec, ident, slot));
     255    JSValue result = baseValue.get(exec, ident, slot);
     256
     257    LOG_IC((ICEvent::OperationGetById, baseValue.classInfoOrNull(*vm), ident, baseValue == slot.slotBase()));
     258
     259    return JSValue::encode(result);
    258260}
    259261
     
    268270    PropertySlot slot(baseValue, PropertySlot::InternalMethodType::Get);
    269271    Identifier ident = Identifier::fromUid(vm, uid);
    270     LOG_IC((ICEvent::OperationGetByIdGeneric, baseValue.classInfoOrNull(*vm), ident));
    271     return JSValue::encode(baseValue.get(exec, ident, slot));
     272    JSValue result = baseValue.get(exec, ident, slot);
     273   
     274    LOG_IC((ICEvent::OperationGetByIdGeneric, baseValue.classInfoOrNull(*vm), ident, baseValue == slot.slotBase()));
     275   
     276    return JSValue::encode(result);
    272277}
    273278
     
    281286
    282287    JSValue baseValue = JSValue::decode(base);
    283     LOG_IC((ICEvent::OperationGetByIdOptimize, baseValue.classInfoOrNull(*vm), ident));
    284288
    285289    return JSValue::encode(baseValue.getPropertySlot(exec, ident, [&] (bool found, PropertySlot& slot) -> JSValue {
     290       
     291        LOG_IC((ICEvent::OperationGetByIdOptimize, baseValue.classInfoOrNull(*vm), ident, baseValue == slot.slotBase()));
     292       
    286293        if (stubInfo->considerCaching(exec->codeBlock(), baseValue.structureOrNull()))
    287294            repatchGetByID(exec, baseValue, ident, slot, *stubInfo, GetByIDKind::Normal);
     
    332339    JSValue baseValue = JSValue::decode(base);
    333340    JSValue thisValue = JSValue::decode(thisEncoded);
    334     LOG_IC((ICEvent::OperationGetByIdWithThisOptimize, baseValue.classInfoOrNull(*vm), ident));
    335341
    336342    PropertySlot slot(thisValue, PropertySlot::InternalMethodType::Get);
    337343    return JSValue::encode(baseValue.getPropertySlot(exec, ident, slot, [&] (bool found, PropertySlot& slot) -> JSValue {
     344        LOG_IC((ICEvent::OperationGetByIdWithThisOptimize, baseValue.classInfoOrNull(*vm), ident, baseValue == slot.slotBase()));
     345       
    338346        if (stubInfo->considerCaching(exec->codeBlock(), baseValue.structureOrNull()))
    339347            repatchGetByID(exec, baseValue, ident, slot, *stubInfo, GetByIDKind::WithThis);
     
    440448    JSValue baseValue = JSValue::decode(encodedBase);
    441449    Identifier ident = Identifier::fromUid(vm, uid);
    442     LOG_IC((ICEvent::OperationPutByIdStrict, baseValue.classInfoOrNull(*vm), ident));
    443 
    444450    PutPropertySlot slot(baseValue, true, exec->codeBlock()->putByIdContext());
    445451    baseValue.putInline(exec, ident, JSValue::decode(encodedValue), slot);
     452   
     453    LOG_IC((ICEvent::OperationPutByIdStrict, baseValue.classInfoOrNull(*vm), ident, slot.base() == baseValue));
    446454}
    447455
     
    457465    JSValue baseValue = JSValue::decode(encodedBase);
    458466    Identifier ident = Identifier::fromUid(vm, uid);
    459     LOG_IC((ICEvent::OperationPutByIdNonStrict, baseValue.classInfoOrNull(*vm), ident));
    460467    PutPropertySlot slot(baseValue, false, exec->codeBlock()->putByIdContext());
    461468    baseValue.putInline(exec, ident, JSValue::decode(encodedValue), slot);
     469
     470    LOG_IC((ICEvent::OperationPutByIdNonStrict, baseValue.classInfoOrNull(*vm), ident, slot.base() == baseValue));
    462471}
    463472
     
    473482    JSValue baseValue = JSValue::decode(encodedBase);
    474483    Identifier ident = Identifier::fromUid(&vm, uid);
    475     LOG_IC((ICEvent::OperationPutByIdDirectStrict, baseValue.classInfoOrNull(vm), ident));
    476484    PutPropertySlot slot(baseValue, true, exec->codeBlock()->putByIdContext());
    477485    CommonSlowPaths::putDirectWithReify(vm, exec, asObject(baseValue), ident, JSValue::decode(encodedValue), slot);
     486
     487    LOG_IC((ICEvent::OperationPutByIdDirectStrict, baseValue.classInfoOrNull(vm), ident, slot.base() == baseValue));
    478488}
    479489
     
    489499    JSValue baseValue = JSValue::decode(encodedBase);
    490500    Identifier ident = Identifier::fromUid(&vm, uid);
    491     LOG_IC((ICEvent::OperationPutByIdDirectNonStrict, baseValue.classInfoOrNull(vm), ident));
    492501    PutPropertySlot slot(baseValue, false, exec->codeBlock()->putByIdContext());
    493502    CommonSlowPaths::putDirectWithReify(vm, exec, asObject(baseValue), ident, JSValue::decode(encodedValue), slot);
     503
     504    LOG_IC((ICEvent::OperationPutByIdDirectNonStrict, baseValue.classInfoOrNull(vm), ident, slot.base() == baseValue));
    494505}
    495506
     
    507518    JSValue value = JSValue::decode(encodedValue);
    508519    JSValue baseValue = JSValue::decode(encodedBase);
    509     LOG_IC((ICEvent::OperationPutByIdStrictOptimize, baseValue.classInfoOrNull(*vm), ident));
    510520    CodeBlock* codeBlock = exec->codeBlock();
    511521    PutPropertySlot slot(baseValue, true, codeBlock->putByIdContext());
     
    513523    Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr;
    514524    baseValue.putInline(exec, ident, value, slot);
     525
     526    LOG_IC((ICEvent::OperationPutByIdStrictOptimize, baseValue.classInfoOrNull(*vm), ident, slot.base() == baseValue));
     527
    515528    RETURN_IF_EXCEPTION(scope, void());
    516529
     
    535548    JSValue value = JSValue::decode(encodedValue);
    536549    JSValue baseValue = JSValue::decode(encodedBase);
    537     LOG_IC((ICEvent::OperationPutByIdNonStrictOptimize, baseValue.classInfoOrNull(*vm), ident));
    538550    CodeBlock* codeBlock = exec->codeBlock();
    539551    PutPropertySlot slot(baseValue, false, codeBlock->putByIdContext());
     
    541553    Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr;   
    542554    baseValue.putInline(exec, ident, value, slot);
     555
     556    LOG_IC((ICEvent::OperationPutByIdNonStrictOptimize, baseValue.classInfoOrNull(*vm), ident, slot.base() == baseValue));
     557
    543558    RETURN_IF_EXCEPTION(scope, void());
    544559
     
    563578    JSValue value = JSValue::decode(encodedValue);
    564579    JSObject* baseObject = asObject(JSValue::decode(encodedBase));
    565     LOG_IC((ICEvent::OperationPutByIdDirectStrictOptimize, baseObject->classInfo(vm), ident));
    566580    CodeBlock* codeBlock = exec->codeBlock();
    567581    PutPropertySlot slot(baseObject, true, codeBlock->putByIdContext());
    568582    Structure* structure = nullptr;
    569583    CommonSlowPaths::putDirectWithReify(vm, exec, baseObject, ident, value, slot, &structure);
     584
     585    LOG_IC((ICEvent::OperationPutByIdDirectStrictOptimize, baseObject->classInfo(vm), ident, slot.base() == baseObject));
     586
    570587    RETURN_IF_EXCEPTION(scope, void());
    571588   
     
    590607    JSValue value = JSValue::decode(encodedValue);
    591608    JSObject* baseObject = asObject(JSValue::decode(encodedBase));
    592     LOG_IC((ICEvent::OperationPutByIdDirectNonStrictOptimize, baseObject->classInfo(vm), ident));
    593609    CodeBlock* codeBlock = exec->codeBlock();
    594610    PutPropertySlot slot(baseObject, false, codeBlock->putByIdContext());
    595611    Structure* structure = nullptr;
    596612    CommonSlowPaths::putDirectWithReify(vm, exec, baseObject, ident, value, slot, &structure);
     613
     614    LOG_IC((ICEvent::OperationPutByIdDirectNonStrictOptimize, baseObject->classInfo(vm), ident, slot.base() == baseObject));
     615
    597616    RETURN_IF_EXCEPTION(scope, void());
    598617   
  • trunk/Source/JavaScriptCore/jit/Repatch.cpp

    r243966 r244204  
    268268                bool generatedCodeInline = InlineAccess::generateSelfPropertyAccess(stubInfo, structure, slot.cachedOffset());
    269269                if (generatedCodeInline) {
    270                     LOG_IC((ICEvent::GetByIdSelfPatch, structure->classInfo(), propertyName));
     270                    LOG_IC((ICEvent::GetByIdSelfPatch, structure->classInfo(), propertyName, slot.slotBase() == baseValue));
    271271                    structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
    272272                    ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation(), appropriateOptimizingGetByIdFunction(kind));
     
    377377        }
    378378
    379         LOG_IC((ICEvent::GetByIdAddAccessCase, baseValue.classInfoOrNull(vm), propertyName));
     379        LOG_IC((ICEvent::GetByIdAddAccessCase, baseValue.classInfoOrNull(vm), propertyName, slot.slotBase() == baseValue));
    380380
    381381        result = stubInfo.addAccessCase(locker, codeBlock, propertyName, WTFMove(newCase));
    382382
    383383        if (result.generatedSomeCode()) {
    384             LOG_IC((ICEvent::GetByIdReplaceWithJump, baseValue.classInfoOrNull(vm), propertyName));
     384            LOG_IC((ICEvent::GetByIdReplaceWithJump, baseValue.classInfoOrNull(vm), propertyName, slot.slotBase() == baseValue));
    385385           
    386386            RELEASE_ASSERT(result.code());
     
    476476                    bool generatedCodeInline = InlineAccess::generateSelfPropertyReplace(stubInfo, structure, slot.cachedOffset());
    477477                    if (generatedCodeInline) {
    478                         LOG_IC((ICEvent::PutByIdSelfPatch, structure->classInfo(), ident));
     478                        LOG_IC((ICEvent::PutByIdSelfPatch, structure->classInfo(), ident, slot.base() == baseValue));
    479479                        ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation(), appropriateOptimizingPutByIdFunction(slot, putKind));
    480480                        stubInfo.initPutByIdReplace(codeBlock, structure, slot.cachedOffset());
     
    589589        }
    590590
    591         LOG_IC((ICEvent::PutByIdAddAccessCase, structure->classInfo(), ident));
     591        LOG_IC((ICEvent::PutByIdAddAccessCase, structure->classInfo(), ident, slot.base() == baseValue));
    592592       
    593593        result = stubInfo.addAccessCase(locker, codeBlock, ident, WTFMove(newCase));
    594594
    595595        if (result.generatedSomeCode()) {
    596             LOG_IC((ICEvent::PutByIdReplaceWithJump, structure->classInfo(), ident));
     596            LOG_IC((ICEvent::PutByIdReplaceWithJump, structure->classInfo(), ident, slot.base() == baseValue));
    597597           
    598598            RELEASE_ASSERT(result.code());
     
    655655                bool generatedCodeInline = InlineAccess::generateSelfInAccess(stubInfo, structure);
    656656                if (generatedCodeInline) {
    657                     LOG_IC((ICEvent::InByIdSelfPatch, structure->classInfo(), ident));
     657                    LOG_IC((ICEvent::InByIdSelfPatch, structure->classInfo(), ident, slot.slotBase() == base));
    658658                    structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
    659659                    ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation(), operationInByIdOptimize);
     
    693693            return GiveUpOnCache;
    694694
    695         LOG_IC((ICEvent::InAddAccessCase, structure->classInfo(), ident));
     695        LOG_IC((ICEvent::InAddAccessCase, structure->classInfo(), ident, slot.slotBase() == base));
    696696
    697697        std::unique_ptr<AccessCase> newCase = AccessCase::create(
     
    701701
    702702        if (result.generatedSomeCode()) {
    703             LOG_IC((ICEvent::InReplaceWithJump, structure->classInfo(), ident));
     703            LOG_IC((ICEvent::InReplaceWithJump, structure->classInfo(), ident, slot.slotBase() == base));
    704704           
    705705            RELEASE_ASSERT(result.code());
  • trunk/Tools/ChangeLog

    r244184 r244204  
     12019-04-11  Michael Saboff  <msaboff@apple.com>
     2
     3        Improve the Inline Cache Stats code
     4        https://bugs.webkit.org/show_bug.cgi?id=196836
     5
     6        Reviewed by Saam Barati.
     7
     8        Added a new script to consolidate and arrange the output of --useICStats option.
     9
     10        This script merges the output from every group into one large table and sorts it from most common to
     11        least common.  It also counts the slow path GetById and PutById variants and then calculates the
     12        percentage of gets or puts for each unique base,property pair compared to all the gets and puts.
     13        Put together, this is useful to see what property accesses are not getting cached.
     14
     15        * Scripts/ic-stats.py: Added.
     16        (ICStats):
     17        (ICStats.__init__):
     18        (ICStats.parse):
     19        (ICStats.dumpStats):
     20        (usage):
     21
    1222019-04-10  Alex Christensen  <achristensen@webkit.org>
    223
Note: See TracChangeset for help on using the changeset viewer.