Ignore:
Timestamp:
Sep 15, 2009, 4:17:19 PM (16 years ago)
Author:
[email protected]
Message:

Allow anonymous storage inside JSObject
https://bugs.webkit.org/show_bug.cgi?id=29168

Reviewed by Geoff Garen

Add the concept of anonymous slots to Structures so that it is
possible to store references to values that need marking in the
standard JSObject storage buffer. This allows us to reduce the
malloc overhead of some objects (by allowing them to store JS
values in the inline storage of the object) and reduce the
dependence of custom mark functions (if all an objects children
are in the standard object property storage there's no need to
mark them manually).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/Structure.cpp

    r48336 r48403  
    153153Structure::~Structure()
    154154{
    155     if (m_previous)
    156         m_previous->table.remove(make_pair(m_nameInPrevious.get(), m_attributesInPrevious), m_specificValueInPrevious);
     155    if (m_previous) {
     156        if (m_nameInPrevious)
     157            m_previous->table.remove(make_pair(m_nameInPrevious.get(), m_attributesInPrevious), m_specificValueInPrevious);
     158        else
     159            m_previous->table.removeAnonymousSlotTransition(m_anonymousSlotsInPrevious);
     160
     161    }
    157162
    158163    if (m_cachedPropertyNameArrayData)
     
    268273    for (ptrdiff_t i = structures.size() - 2; i >= 0; --i) {
    269274        structure = structures[i];
     275        if (!structure->m_nameInPrevious) {
     276            m_propertyTable->anonymousSlotCount += structure->m_anonymousSlotsInPrevious;
     277            continue;
     278        }
    270279        structure->m_nameInPrevious->ref();
    271280        PropertyMapEntry entry(structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious, ++m_propertyTable->lastIndexUsed);
     
    490499}
    491500
     501PassRefPtr<Structure> Structure::addAnonymousSlotsTransition(Structure* structure, unsigned count)
     502{
     503    if (Structure* transition = structure->table.getAnonymousSlotTransition(count)) {
     504        ASSERT(transition->storedPrototype() == structure->storedPrototype());
     505        return transition;
     506    }
     507    ASSERT(count);
     508    ASSERT(count < ((1<<6) - 2));
     509    RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo());
     510   
     511    transition->m_cachedPrototypeChain = structure->m_cachedPrototypeChain;
     512    transition->m_previous = structure;
     513    transition->m_nameInPrevious = 0;
     514    transition->m_attributesInPrevious = 0;
     515    transition->m_anonymousSlotsInPrevious = count;
     516    transition->m_specificValueInPrevious = 0;
     517    transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
     518    transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
     519
     520    if (structure->m_propertyTable) {
     521        if (structure->m_isPinnedPropertyTable)
     522            transition->m_propertyTable = structure->copyPropertyTable();
     523        else {
     524            transition->m_propertyTable = structure->m_propertyTable;
     525            structure->m_propertyTable = 0;
     526        }
     527    } else {
     528        if (structure->m_previous)
     529            transition->materializePropertyMap();
     530        else
     531            transition->createPropertyMapHashTable();
     532    }
     533
     534    transition->addAnonymousSlots(count);
     535    if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
     536        transition->growPropertyStorageCapacity();
     537
     538    structure->table.addAnonymousSlotTransition(count, transition.get());
     539    return transition.release();   
     540}
     541
    492542PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure)
    493543{
     
    614664        newTable->deletedOffsets = new Vector<unsigned>(*m_propertyTable->deletedOffsets);
    615665
     666    newTable->anonymousSlotCount = m_propertyTable->anonymousSlotCount;
    616667    return newTable;
    617668}
     
    793844        m_propertyTable->deletedOffsets->removeLast();
    794845    } else
    795         newOffset = m_propertyTable->keyCount;
     846        newOffset = m_propertyTable->keyCount + m_propertyTable->anonymousSlotCount;
    796847    m_propertyTable->entries()[entryIndex - 1].offset = newOffset;
    797848
     
    803854    checkConsistency();
    804855    return newOffset;
     856}
     857
     858void Structure::addAnonymousSlots(unsigned count)
     859{
     860    m_propertyTable->anonymousSlotCount += count;
    805861}
    806862
     
    9631019    m_propertyTable->size = newTableSize;
    9641020    m_propertyTable->sizeMask = newTableSize - 1;
     1021    m_propertyTable->anonymousSlotCount = oldTable->anonymousSlotCount;
    9651022
    9661023    unsigned lastIndexUsed = 0;
Note: See TracChangeset for help on using the changeset viewer.