Changeset 140259 in webkit


Ignore:
Timestamp:
Jan 19, 2013 1:47:45 PM (11 years ago)
Author:
ggaren@apple.com
Message:

Track inheritance structures in a side table, instead of using a private
name in each prototype
https://bugs.webkit.org/show_bug.cgi?id=107378

Reviewed by Sam Weinig and Phil Pizlo.

This is a step toward object size inference.

Using a side table frees us to use a more complex key (a pair of
prototype and expected inline capacity).

It also avoids ruining inline caches for prototypes. (Adding a new private
name for a new inline capacity would change the prototype's structure,
possibly firing watchpoints, making inline caches go polymorphic, and
generally causing us to have a bad time.)

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Target.pri: Buildage.
  • runtime/ArrayPrototype.cpp:

(JSC::ArrayPrototype::finishCreation): Updated to use new side table API.

  • runtime/JSFunction.cpp:

(JSC::JSFunction::cacheInheritorID): Updated to use new side table API.

(JSC::JSFunction::visitChildren): Fixed a long-standing bug where JSFunction
forgot to visit one of its data members (m_cachedInheritorID). This
wasn't a user-visible problem before because JSFunction would always
visit its .prototype property, which visited its m_cachedInheritorID.
But now, function.prototype only weakly owns function.m_cachedInheritorID.

  • runtime/JSGlobalData.h:

(JSGlobalData): Added the map, taking care to make sure that its
destructor would run after the heap destructor.

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::reset): Updated to use new side table API.

  • runtime/JSObject.cpp:

(JSC::JSObject::notifyPresenceOfIndexedAccessors):
(JSC::JSObject::setPrototype):

  • runtime/JSObject.h:

(JSObject): Updated to use new side table API, and removed lots of code
that used to manage the per-object private name.

  • runtime/JSProxy.cpp:

(JSC::JSProxy::setTarget):

  • runtime/ObjectConstructor.cpp:

(JSC::objectConstructorCreate):

  • runtime/ObjectPrototype.cpp:

(JSC::ObjectPrototype::finishCreation): Updated to use new side table API.

  • runtime/PrototypeMap.cpp: Added.

(JSC):
(JSC::PrototypeMap::addPrototype):
(JSC::PrototypeMap::emptyObjectStructureForPrototype):

  • runtime/PrototypeMap.h: Added.

(PrototypeMap):
(JSC::PrototypeMap::isPrototype):
(JSC::PrototypeMap::clearEmptyObjectStructureForPrototype): New side table.
This is a simple weak map, mapping an object to the structure you should
use when inheriting from that object. (In future, inline capacity will
be a part of the mapping.)

I used two maps to preserve existing behavior that allowed us to speculate
about an object becoming a prototype, even if it wasn't one at the moment.
However, I suspect that behavior can be removed without harm.

  • runtime/WeakGCMap.h:

(JSC::WeakGCMap::contains):
(WeakGCMap): I would rate myself a 6 / 10 in C++.

Location:
trunk/Source/JavaScriptCore
Files:
2 added
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r138472 r140259  
    270270    runtime/PropertyNameArray.cpp
    271271    runtime/PropertySlot.cpp
     272    runtime/PrototypeMap.cpp
    272273    runtime/RegExp.cpp
    273274    runtime/RegExpCache.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r140232 r140259  
     12013-01-19  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Track inheritance structures in a side table, instead of using a private
     4        name in each prototype
     5        https://bugs.webkit.org/show_bug.cgi?id=107378
     6
     7        Reviewed by Sam Weinig and Phil Pizlo.
     8
     9        This is a step toward object size inference.
     10
     11        Using a side table frees us to use a more complex key (a pair of
     12        prototype and expected inline capacity).
     13
     14        It also avoids ruining inline caches for prototypes. (Adding a new private
     15        name for a new inline capacity would change the prototype's structure,
     16        possibly firing watchpoints, making inline caches go polymorphic, and
     17        generally causing us to have a bad time.)
     18
     19        * CMakeLists.txt:
     20        * GNUmakefile.list.am:
     21        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
     22        * JavaScriptCore.xcodeproj/project.pbxproj:
     23        * Target.pri: Buildage.
     24
     25        * runtime/ArrayPrototype.cpp:
     26        (JSC::ArrayPrototype::finishCreation): Updated to use new side table API.
     27
     28        * runtime/JSFunction.cpp:
     29        (JSC::JSFunction::cacheInheritorID): Updated to use new side table API.
     30
     31        (JSC::JSFunction::visitChildren): Fixed a long-standing bug where JSFunction
     32        forgot to visit one of its data members (m_cachedInheritorID). This
     33        wasn't a user-visible problem before because JSFunction would always
     34        visit its .prototype property, which visited its m_cachedInheritorID.
     35        But now, function.prototype only weakly owns function.m_cachedInheritorID.
     36
     37        * runtime/JSGlobalData.h:
     38        (JSGlobalData): Added the map, taking care to make sure that its
     39        destructor would run after the heap destructor.
     40
     41        * runtime/JSGlobalObject.cpp:
     42        (JSC::JSGlobalObject::reset): Updated to use new side table API.
     43
     44        * runtime/JSObject.cpp:
     45        (JSC::JSObject::notifyPresenceOfIndexedAccessors):
     46        (JSC::JSObject::setPrototype):
     47        * runtime/JSObject.h:
     48        (JSObject): Updated to use new side table API, and removed lots of code
     49        that used to manage the per-object private name.
     50
     51        * runtime/JSProxy.cpp:
     52        (JSC::JSProxy::setTarget):
     53        * runtime/ObjectConstructor.cpp:
     54        (JSC::objectConstructorCreate):
     55        * runtime/ObjectPrototype.cpp:
     56        (JSC::ObjectPrototype::finishCreation): Updated to use new side table API.
     57
     58        * runtime/PrototypeMap.cpp: Added.
     59        (JSC):
     60        (JSC::PrototypeMap::addPrototype):
     61        (JSC::PrototypeMap::emptyObjectStructureForPrototype):
     62        * runtime/PrototypeMap.h: Added.
     63        (PrototypeMap):
     64        (JSC::PrototypeMap::isPrototype):
     65        (JSC::PrototypeMap::clearEmptyObjectStructureForPrototype): New side table.
     66        This is a simple weak map, mapping an object to the structure you should
     67        use when inheriting from that object. (In future, inline capacity will
     68        be a part of the mapping.)
     69
     70        I used two maps to preserve existing behavior that allowed us to speculate
     71        about an object becoming a prototype, even if it wasn't one at the moment.
     72        However, I suspect that behavior can be removed without harm.
     73
     74        * runtime/WeakGCMap.h:
     75        (JSC::WeakGCMap::contains):
     76        (WeakGCMap): I would rate myself a 6 / 10 in C++.
     77
    1782013-01-18  Dan Bernstein  <mitz@apple.com>
    279
  • trunk/Source/JavaScriptCore/GNUmakefile.list.am

    r139765 r140259  
    696696        Source/JavaScriptCore/runtime/PropertySlot.cpp \
    697697        Source/JavaScriptCore/runtime/PropertySlot.h \
     698        Source/JavaScriptCore/runtime/PrototypeMap.cpp \
     699        Source/JavaScriptCore/runtime/PrototypeMap.h \
    698700        Source/JavaScriptCore/runtime/PropertyStorage.h \
    699701        Source/JavaScriptCore/runtime/Protect.h \
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj

    r139682 r140259  
    11751175                        </File>
    11761176                        <File
     1177                                RelativePath="..\..\runtime\PrototypeMap.cpp"
     1178                                >
     1179                        </File>
     1180                        <File
     1181                                RelativePath="..\..\runtime\PrototypeMap.h"
     1182                                >
     1183                        </File>
     1184                        <File
    11771185                                RelativePath="..\..\runtime\PropertyStorage.h"
    11781186                                >
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r140232 r140259  
    399399                146B16D812EB5B59001BEC1B /* ConservativeRoots.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 146B14DB12EB5B12001BEC1B /* ConservativeRoots.cpp */; };
    400400                146FE51211A710430087AE66 /* JITCall32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 146FE51111A710430087AE66 /* JITCall32_64.cpp */; };
     401                1474C33B16AA2D950062F01D /* PrototypeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D844A316AA2C7000A65AF0 /* PrototypeMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
     402                1474C33C16AA2D9B0062F01D /* PrototypeMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14D844A216AA2C7000A65AF0 /* PrototypeMap.cpp */; };
    401403                1478297B1379E8A800A7C2A3 /* HandleTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 146FA5A81378F6B0003627A3 /* HandleTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
    402404                147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B83AA0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h */; };
     
    12781280                14D2F3D9139F4BE200491031 /* MarkedSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedSpace.h; sourceTree = "<group>"; };
    12791281                14D792640DAA03FB001A9F05 /* JSStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStack.h; sourceTree = "<group>"; };
     1282                14D844A216AA2C7000A65AF0 /* PrototypeMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrototypeMap.cpp; sourceTree = "<group>"; };
     1283                14D844A316AA2C7000A65AF0 /* PrototypeMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrototypeMap.h; sourceTree = "<group>"; };
    12801284                14D857740A4696C80032146C /* testapi.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = testapi.js; path = API/tests/testapi.js; sourceTree = "<group>"; };
    12811285                14DA818E0D99FD2000B0A4FB /* JSActivation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSActivation.h; sourceTree = "<group>"; };
     
    23222326                                F692A85D0255597D01FF60F7 /* FunctionPrototype.h */,
    23232327                                C2D58C3315912FEE0021A844 /* GCActivityCallback.cpp */,
    2324                                 C2D58C3315912FEE0021A844 /* GCActivityCallback.cpp */,
    23252328                                DDF7ABD211F60ED200108E36 /* GCActivityCallback.h */,
    23262329                                BC02E9B80E184545000F9297 /* GetterSetter.cpp */,
     
    24402443                                0FB7F39015ED8E3800F167B2 /* PropertyStorage.h */,
    24412444                                65C02FBB0637462A003E7EE6 /* Protect.h */,
     2445                                14D844A216AA2C7000A65AF0 /* PrototypeMap.cpp */,
     2446                                14D844A316AA2C7000A65AF0 /* PrototypeMap.h */,
    24422447                                0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */,
    24432448                                147B84620E6DE6B1004775A4 /* PutPropertySlot.h */,
     
    24912496                                1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */,
    24922497                                A7DCB77912E3D90500911940 /* WriteBarrier.h */,
     2498                                C2D58C3315912FEE0021A844 /* GCActivityCallback.cpp */,
    24932499                        );
    24942500                        path = runtime;
     
    32713277                                86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
    32723278                                0F9749711687ADE400A4FF6A /* JSCellInlines.h in Headers */,
     3279                                1474C33B16AA2D950062F01D /* PrototypeMap.h in Headers */,
    32733280                        );
    32743281                        runOnlyForDeploymentPostprocessing = 0;
     
    38983905                                86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
    38993906                                86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
     3907                                1474C33C16AA2D9B0062F01D /* PrototypeMap.cpp in Sources */,
    39003908                        );
    39013909                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/JavaScriptCore/Target.pri

    r138465 r140259  
    288288    runtime/PropertyNameArray.cpp \
    289289    runtime/PropertySlot.cpp \
     290    runtime/PrototypeMap.cpp \
    290291    runtime/RegExpConstructor.cpp \
    291292    runtime/RegExpCachedResult.cpp \
  • trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp

    r134081 r140259  
    133133    Base::finishCreation(globalData);
    134134    ASSERT(inherits(&s_info));
    135     notifyUsedAsPrototype(globalData);
     135    globalData.prototypeMap.addPrototype(this);
    136136}
    137137
  • trunk/Source/JavaScriptCore/runtime/JSFunction.cpp

    r139541 r140259  
    109109Structure* JSFunction::cacheInheritorID(ExecState* exec)
    110110{
    111     JSValue prototype = get(exec, exec->globalData().propertyNames->prototype);
     111    JSGlobalData& globalData = exec->globalData();
     112    JSValue prototype = get(exec, globalData.propertyNames->prototype);
    112113    if (prototype.isObject())
    113         m_cachedInheritorID.set(exec->globalData(), this, asObject(prototype)->inheritorID(exec->globalData()));
     114        m_cachedInheritorID.set(globalData, this, globalData.prototypeMap.emptyObjectStructureForPrototype(asObject(prototype)));
    114115    else
    115         m_cachedInheritorID.set(exec->globalData(), this, globalObject()->emptyObjectStructure());
     116        m_cachedInheritorID.set(globalData, this, globalData.prototypeMap.emptyObjectStructureForPrototype(globalObject()->objectPrototype()));
    116117    return m_cachedInheritorID.get();
    117118}
     
    163164    visitor.append(&thisObject->m_scope);
    164165    visitor.append(&thisObject->m_executable);
     166    visitor.append(&thisObject->m_cachedInheritorID);
    165167}
    166168
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.h

    r139541 r140259  
    4343#include "ProfilerDatabase.h"
    4444#include "PrivateName.h"
     45#include "PrototypeMap.h"
    4546#include "SmallStrings.h"
    4647#include "Strong.h"
     
    287288#endif
    288289
    289         PrivateName m_inheritorIDKey;
     290        PrototypeMap prototypeMap;
    290291
    291292        OwnPtr<ParserArena> parserArena;
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r139541 r140259  
    224224    m_withScopeStructure.set(exec->globalData(), this, JSWithScope::createStructure(exec->globalData(), this, jsNull()));
    225225
    226     m_emptyObjectStructure.set(exec->globalData(), this, m_objectPrototype->inheritorID(exec->globalData()));
    227     m_nullPrototypeObjectStructure.set(exec->globalData(), this, createEmptyObjectStructure(exec->globalData(), this, jsNull()));
     226    m_emptyObjectStructure.set(exec->globalData(), this, globalData().prototypeMap.emptyObjectStructureForPrototype(m_objectPrototype.get()));
     227    m_nullPrototypeObjectStructure.set(exec->globalData(), this, JSFinalObject::createStructure(globalData(), this, jsNull()));
    228228
    229229    m_callbackFunctionStructure.set(exec->globalData(), this, JSCallbackFunction::createStructure(exec->globalData(), this, m_functionPrototype.get()));
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r139491 r140259  
    597597    setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AddIndexedAccessors));
    598598   
    599     if (!mayBeUsedAsPrototype(globalData))
     599    if (!globalData.prototypeMap.isPrototype(this))
    600600        return;
    601601   
     
    11501150    ASSERT(prototype);
    11511151    if (prototype.isObject())
    1152         asObject(prototype)->notifyUsedAsPrototype(globalData);
     1152        globalData.prototypeMap.addPrototype(asObject(prototype));
    11531153   
    11541154    Structure* newStructure = Structure::changePrototypeTransition(globalData, structure(), prototype);
     
    11581158        return;
    11591159   
    1160     if (mayBeUsedAsPrototype(globalData)) {
     1160    if (globalData.prototypeMap.isPrototype(this)) {
    11611161        newStructure->globalObject()->haveABadTime(globalData);
    11621162        return;
     
    11861186    setPrototype(globalData, prototype);
    11871187    return true;
    1188 }
    1189 
    1190 void JSObject::resetInheritorID(JSGlobalData& globalData)
    1191 {
    1192     PropertyOffset offset = structure()->get(globalData, globalData.m_inheritorIDKey);
    1193     if (!isValidOffset(offset))
    1194         return;
    1195    
    1196     putDirect(globalData, offset, jsUndefined());
    1197 }
    1198 
    1199 Structure* JSObject::inheritorID(JSGlobalData& globalData)
    1200 {
    1201     if (JSValue value = getDirect(globalData, globalData.m_inheritorIDKey)) {
    1202         if (value.isCell()) {
    1203             Structure* inheritorID = jsCast<Structure*>(value);
    1204             ASSERT(inheritorID->isEmpty());
    1205             return inheritorID;
    1206         }
    1207         ASSERT(value.isUndefined());
    1208     }
    1209     return createInheritorID(globalData);
    12101188}
    12111189
     
    16621640    } else
    16631641        slot.setUndefined();
    1664 }
    1665 
    1666 void JSObject::notifyUsedAsPrototype(JSGlobalData& globalData)
    1667 {
    1668     PropertyOffset offset = structure()->get(globalData, globalData.m_inheritorIDKey);
    1669     if (isValidOffset(offset))
    1670         return;
    1671    
    1672     PutPropertySlot slot;
    1673     putDirectInternal<PutModeDefineOwnProperty>(globalData, globalData.m_inheritorIDKey, jsUndefined(), DontEnum, slot, 0);
    1674    
    1675     // Note that this method makes the somewhat odd decision to not check if this
    1676     // object currently has indexed accessors. We could do that check here, and if
    1677     // indexed accessors were found, we could tell the global object to have a bad
    1678     // time. But we avoid this, to allow the following to be always fast:
    1679     //
    1680     // 1) Create an object.
    1681     // 2) Give it a setter or read-only property that happens to have a numeric name.
    1682     // 3) Allocate objects that use this object as a prototype.
    1683     //
    1684     // This avoids anyone having a bad time. Even if the instance objects end up
    1685     // having indexed storage, the creation of indexed storage leads to a prototype
    1686     // chain walk that detects the presence of indexed setters and then does the
    1687     // right thing. As a result, having a bad time only happens if you add an
    1688     // indexed setter (or getter, or read-only field) to an object that is already
    1689     // used as a prototype.
    1690 }
    1691 
    1692 Structure* JSObject::createInheritorID(JSGlobalData& globalData)
    1693 {
    1694     Structure* inheritorID = createEmptyObjectStructure(globalData, globalObject(), this);
    1695     ASSERT(inheritorID->isEmpty());
    1696 
    1697     PutPropertySlot slot;
    1698     putDirectInternal<PutModeDefineOwnProperty>(globalData, globalData.m_inheritorIDKey, inheritorID, DontEnum, slot, 0);
    1699     return inheritorID;
    17001642}
    17011643
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r139541 r140259  
    125125    bool setPrototypeWithCycleCheck(JSGlobalData&, JSValue prototype);
    126126       
    127     Structure* inheritorID(JSGlobalData&);
    128     void notifyUsedAsPrototype(JSGlobalData&);
    129        
    130     bool mayBeUsedAsPrototype(JSGlobalData& globalData)
    131     {
    132         return isValidOffset(structure()->get(globalData, globalData.m_inheritorIDKey));
    133     }
    134        
    135127    bool mayInterceptIndexedAccesses()
    136128    {
     
    719711    JSObject(JSGlobalData&, Structure*, Butterfly* = 0);
    720712       
    721     void resetInheritorID(JSGlobalData&);
    722        
    723713    void visitButterfly(SlotVisitor&, Butterfly*, size_t storageSize);
    724714    void copyButterfly(CopyVisitor&, Butterfly*, size_t storageSize);
     
    935925
    936926    const HashEntry* findPropertyHashEntry(ExecState*, PropertyName) const;
    937     Structure* createInheritorID(JSGlobalData&);
    938927       
    939928    void putIndexedDescriptor(ExecState*, SparseArrayEntry*, PropertyDescriptor&, PropertyDescriptor& old);
     
    11241113    ASSERT(result == ConstructTypeNone || value.isValidCallee());
    11251114    return result;
    1126 }
    1127 
    1128 inline Structure* createEmptyObjectStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
    1129 {
    1130     return JSFinalObject::createStructure(globalData, globalObject, prototype);
    11311115}
    11321116
  • trunk/Source/JavaScriptCore/runtime/JSProxy.cpp

    r139541 r140259  
    5353    m_target.set(globalData, this, globalObject);
    5454    setPrototype(globalData, globalObject->prototype());
    55     resetInheritorID(globalData);
     55    globalData.prototypeMap.clearEmptyObjectStructureForPrototype(this);
    5656}
    5757
  • trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp

    r139541 r140259  
    351351        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object prototype may only be an Object or null.")));
    352352    JSValue proto = exec->argument(0);
    353     JSObject* newObject = proto.isObject() ? constructEmptyObject(exec, asObject(proto)->inheritorID(exec->globalData())) : constructEmptyObject(exec, exec->lexicalGlobalObject()->nullPrototypeObjectStructure());
     353    JSObject* newObject = proto.isObject()
     354        ? constructEmptyObject(exec, exec->globalData().prototypeMap.emptyObjectStructureForPrototype(asObject(proto)))
     355        : constructEmptyObject(exec, exec->lexicalGlobalObject()->nullPrototypeObjectStructure());
    354356    if (exec->argument(1).isUndefined())
    355357        return JSValue::encode(newObject);
  • trunk/Source/JavaScriptCore/runtime/ObjectPrototype.cpp

    r139541 r140259  
    7474    Base::finishCreation(globalData);
    7575    ASSERT(inherits(&s_info));
    76     notifyUsedAsPrototype(globalData);
     76    globalData.prototypeMap.addPrototype(this);
    7777}
    7878
  • trunk/Source/JavaScriptCore/runtime/WeakGCMap.h

    r140211 r140259  
    8989    }
    9090
    91     template<typename T, typename HashTranslator> bool contains(const T& key) const
     91    bool contains(const KeyType& key) const
    9292    {
    9393        return find(key) != end();
     
    9595
    9696private:
    97     static const int minGCThreshold;
     97    static const int minGCThreshold = 3;
    9898
    9999    void gcMap()
     
    122122
    123123template<typename KeyArg, typename RawMappedArg, typename HashArg, typename KeyTraitsArg>
    124 const int WeakGCMap<KeyArg, RawMappedArg, HashArg, KeyTraitsArg>::minGCThreshold = 3;
     124const int WeakGCMap<KeyArg, RawMappedArg, HashArg, KeyTraitsArg>::minGCThreshold;
    125125
    126126} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.