Ignore:
Timestamp:
Oct 30, 2008, 5:12:50 PM (17 years ago)
Author:
[email protected]
Message:

2008-10-30 Sam Weinig <[email protected]>

Reviewed by Cameron Zwarich and Geoffrey Garen.

Fix for https://bugs.webkit.org/show_bug.cgi?id=21989
Merge PropertyMap and StructureID

  • Move PropertyMap code into StructureID in preparation for lazily creating the map on gets.
  • Make remove with transition explicit by adding removePropertyTransition.
  • Make the put/remove without transition explicit.
  • Make cache invalidation part of put/remove without transition.

1% speedup on SunSpider; 0.5% speedup on v8 suite.

  • GNUmakefile.am:
  • JavaScriptCore.exp:
  • JavaScriptCore.pri:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • JavaScriptCoreSources.bkl:
  • kjs/AllInOneFile.cpp:
  • kjs/identifier.h:
  • runtime/JSObject.cpp: (JSC::JSObject::removeDirect):
  • runtime/JSObject.h: (JSC::JSObject::putDirect):
  • runtime/PropertyMap.cpp: Removed.
  • runtime/PropertyMap.h: Removed.
  • runtime/PropertyMapHashTable.h: Copied from runtime/PropertyMap.h.
  • runtime/StructureID.cpp: (JSC::StructureID::dumpStatistics): (JSC::StructureID::StructureID): (JSC::StructureID::~StructureID): (JSC::StructureID::getEnumerablePropertyNames): (JSC::StructureID::addPropertyTransition): (JSC::StructureID::removePropertyTransition): (JSC::StructureID::toDictionaryTransition): (JSC::StructureID::changePrototypeTransition): (JSC::StructureID::getterSetterTransition): (JSC::StructureID::addPropertyWithoutTransition): (JSC::StructureID::removePropertyWithoutTransition): (JSC::PropertyMapStatisticsExitLogger::~PropertyMapStatisticsExitLogger): (JSC::StructureID::checkConsistency): (JSC::StructureID::copyPropertyTable): (JSC::StructureID::get): (JSC::StructureID::put): (JSC::StructureID::remove): (JSC::StructureID::insertIntoPropertyMapHashTable): (JSC::StructureID::expandPropertyMapHashTable): (JSC::StructureID::createPropertyMapHashTable): (JSC::StructureID::rehashPropertyMapHashTable): (JSC::comparePropertyMapEntryIndices): (JSC::StructureID::getEnumerablePropertyNamesInternal):
  • runtime/StructureID.h: (JSC::StructureID::propertyStorageSize): (JSC::StructureID::isEmpty): (JSC::StructureID::get):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/StructureID.h

    r37989 r38016  
    1 // -*- mode: c++; c-basic-offset: 4 -*-
    21/*
    32 * Copyright (C) 2008 Apple Inc. All rights reserved.
     
    3029#include "JSType.h"
    3130#include "JSValue.h"
    32 #include "PropertyMap.h"
     31#include "PropertyMapHashTable.h"
    3332#include "StructureIDTransitionTable.h"
    3433#include "TypeInfo.h"
     34#include "identifier.h"
    3535#include "ustring.h"
    3636#include <wtf/HashFunctions.h>
     
    4141
    4242#define DUMP_STRUCTURE_ID_STATISTICS 0
     43
     44#ifndef NDEBUG
     45#define DUMP_PROPERTYMAP_STATS 0
     46#else
     47#define DUMP_PROPERTYMAP_STATS 0
     48#endif
    4349
    4450namespace JSC {
     
    6571        static PassRefPtr<StructureID> changePrototypeTransition(StructureID*, JSValue* prototype);
    6672        static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, unsigned attributes, size_t& offset);
     73        static PassRefPtr<StructureID> removePropertyTransition(StructureID*, const Identifier& propertyName, size_t& offset);
    6774        static PassRefPtr<StructureID> getterSetterTransition(StructureID*);
    6875        static PassRefPtr<StructureID> toDictionaryTransition(StructureID*);
     
    7986        // These should be used with caution. 
    8087        size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes);
     88        size_t removePropertyWithoutTransition(const Identifier& propertyName);
    8189        void setPrototypeWithoutTransition(JSValue* prototype) { m_prototype = prototype; }
    8290
     
    102110        void growPropertyStorageCapacity();
    103111        size_t propertyStorageCapacity() const { return m_propertyStorageCapacity; }
    104         size_t propertyStorageSize() const { return m_propertyMap.storageSize(); }
    105 
    106         size_t get(const Identifier& propertyName) const { return m_propertyMap.get(propertyName); }
    107         size_t get(const Identifier& propertyName, unsigned& attributes) const { return m_propertyMap.get(propertyName, attributes); }
    108         size_t put(const Identifier& propertyName, unsigned attributes) { return m_propertyMap.put(propertyName, attributes); }
    109         size_t remove(const Identifier& propertyName) { return m_propertyMap.remove(propertyName); }
    110 
     112        size_t propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + m_deletedOffsets.size() : 0; }
     113
     114        size_t get(const Identifier& propertyName) const;
     115        size_t get(const Identifier& propertyName, unsigned& attributes) const;
    111116        void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
    112         void clearEnumerationCache();
    113117
    114118        bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
    115119        void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; }
    116120
    117         bool isEmpty() const { return m_propertyMap.isEmpty(); }
     121        bool isEmpty() const { return !m_propertyTable; }
    118122
    119123    private:
    120124        StructureID(JSValue* prototype, const TypeInfo&);
    121125
     126        size_t put(const Identifier& propertyName, unsigned attributes);
     127        size_t remove(const Identifier& propertyName);
     128        void getEnumerablePropertyNamesInternal(PropertyNameArray&) const;
     129
     130        void expandPropertyMapHashTable();
     131        void rehashPropertyMapHashTable();
     132        void rehashPropertyMapHashTable(unsigned newTableSize);
     133        void createPropertyMapHashTable();
     134        void insertIntoPropertyMapHashTable(const PropertyMapEntry&);
     135        void checkConsistency();
     136
     137        PropertyMapHashTable* copyPropertyTable();
     138
     139        void clearEnumerationCache();
     140
     141        static const unsigned emptyEntryIndex = 0;
     142   
    122143        static const size_t s_maxTransitionLength = 64;
    123144
     
    138159        RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData;
    139160
    140         PropertyMap m_propertyMap;
     161        PropertyMapHashTable* m_propertyTable;
     162        Vector<unsigned> m_deletedOffsets;
     163
    141164        size_t m_propertyStorageCapacity;
    142165
     
    149172    };
    150173
     174    inline size_t StructureID::get(const Identifier& propertyName) const
     175    {
     176        ASSERT(!propertyName.isNull());
     177
     178        if (!m_propertyTable)
     179            return WTF::notFound;
     180
     181        UString::Rep* rep = propertyName._ustring.rep();
     182
     183        unsigned i = rep->computedHash();
     184
     185#if DUMP_PROPERTYMAP_STATS
     186        ++numProbes;
     187#endif
     188
     189        unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
     190        if (entryIndex == emptyEntryIndex)
     191            return WTF::notFound;
     192
     193        if (rep == m_propertyTable->entries()[entryIndex - 1].key)
     194            return m_propertyTable->entries()[entryIndex - 1].offset;
     195
     196#if DUMP_PROPERTYMAP_STATS
     197        ++numCollisions;
     198#endif
     199
     200        unsigned k = 1 | WTF::doubleHash(rep->computedHash());
     201
     202        while (1) {
     203            i += k;
     204
     205#if DUMP_PROPERTYMAP_STATS
     206            ++numRehashes;
     207#endif
     208
     209            entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
     210            if (entryIndex == emptyEntryIndex)
     211                return WTF::notFound;
     212
     213            if (rep == m_propertyTable->entries()[entryIndex - 1].key)
     214                return m_propertyTable->entries()[entryIndex - 1].offset;
     215        }
     216    }
     217
    151218    class StructureIDChain : public RefCounted<StructureIDChain> {
    152219    public:
Note: See TracChangeset for help on using the changeset viewer.