Changeset 181010 in webkit


Ignore:
Timestamp:
Mar 4, 2015 12:00:00 PM (9 years ago)
Author:
akling@apple.com
Message:

Stale entries in WeakGCMaps are keeping tons of WeakBlocks alive unnecessarily.
<https://webkit.org/b/142115>
<rdar://problem/19992268>

Reviewed by Geoffrey Garen.

Prune stale entries from WeakGCMaps as part of every full garbage collection.
This frees up tons of previously-stuck WeakBlocks that were only sitting around
with finalized handles waiting to die.

Note that WeakGCMaps register/unregister themselves with the GC heap in their
ctor/dtor, so creating one now requires passing the VM.

Average time spent in the PruningStaleEntriesFromWeakGCMaps GC phase appears
to be between 0.01ms and 0.3ms, though I've seen a few longer ones at ~1.2ms.
It seems somewhat excessive to do this on every Eden collection, so it's only
doing work in full collections for now.

  • API/JSWeakObjectMapRefInternal.h:

(OpaqueJSWeakObjectMap::create):
(OpaqueJSWeakObjectMap::OpaqueJSWeakObjectMap):

  • API/JSWeakObjectMapRefPrivate.cpp:
  • API/JSWrapperMap.mm:

(-[JSWrapperMap initWithContext:]):
(-[JSWrapperMap jsWrapperForObject:]): Pass VM to WeakGCMap constructor.

  • JavaScriptCore.xcodeproj/project.pbxproj: Add WeakGCMapInlines.h and make

it project-private so WebCore clients can access it.

  • heap/Heap.cpp:

(JSC::Heap::collect):
(JSC::Heap::pruneStaleEntriesFromWeakGCMaps): Added a new GC phase for pruning
stale entries from WeakGCMaps. This is only executed during full collections.

  • heap/Heap.h:
  • heap/HeapInlines.h:

(JSC::Heap::registerWeakGCMap):
(JSC::Heap::unregisterWeakGCMap): Added a mechanism for WeakGCMaps to register
themselves with the Heap and provide a pruning callback.

  • runtime/PrototypeMap.h:

(JSC::PrototypeMap::PrototypeMap):

  • runtime/Structure.cpp:

(JSC::StructureTransitionTable::add): Pass VM to WeakGCMap constructor.

  • runtime/JSCInlines.h: Add "WeakGCMapInlines.h"
  • runtime/JSGlobalObject.cpp: Include "WeakGCMapInlines.h" so this builds.
  • runtime/VM.cpp:

(JSC::VM::VM): Pass VM to WeakGCMap constructor.

  • runtime/WeakGCMap.h:

(JSC::WeakGCMap::set):
(JSC::WeakGCMap::add):
(JSC::WeakGCMap::WeakGCMap): Deleted.
(JSC::WeakGCMap::gcMap): Deleted.
(JSC::WeakGCMap::gcMapIfNeeded): Deleted.

  • runtime/WeakGCMapInlines.h: Added.

(JSC::WeakGCMap::WeakGCMap):
(JSC::WeakGCMap::~WeakGCMap):
(JSC::WeakGCMap::pruneStaleEntries): Moved ctor, dtor and pruning callback
to WeakGCMapInlines.h to fix interdependent header issues. Removed code that
prunes WeakGCMap at certain growth milestones and instead rely on the GC
callback for housekeeping.

Location:
trunk/Source
Files:
1 added
15 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/API/JSWeakObjectMapRefInternal.h

    r95901 r181010  
    4242struct OpaqueJSWeakObjectMap : public RefCounted<OpaqueJSWeakObjectMap> {
    4343public:
    44     static PassRefPtr<OpaqueJSWeakObjectMap> create(void* data, JSWeakMapDestroyedCallback callback)
     44    static Ref<OpaqueJSWeakObjectMap> create(JSC::VM& vm, void* data, JSWeakMapDestroyedCallback callback)
    4545    {
    46         return adoptRef(new OpaqueJSWeakObjectMap(data, callback));
     46        return adoptRef(*new OpaqueJSWeakObjectMap(vm, data, callback));
    4747    }
    4848
     
    5555
    5656private:
    57     OpaqueJSWeakObjectMap(void* data, JSWeakMapDestroyedCallback callback)
    58         : m_data(data)
     57    OpaqueJSWeakObjectMap(JSC::VM& vm, void* data, JSWeakMapDestroyedCallback callback)
     58        : m_map(vm)
     59        , m_data(data)
    5960        , m_callback(callback)
    6061    {
  • trunk/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp

    r171691 r181010  
    3333#include "JSCInlines.h"
    3434#include "Weak.h"
     35#include "WeakGCMapInlines.h"
    3536#include <wtf/HashMap.h>
    3637#include <wtf/text/StringHash.h>
     
    4748    ExecState* exec = toJS(context);
    4849    JSLockHolder locker(exec);
    49     RefPtr<OpaqueJSWeakObjectMap> map = OpaqueJSWeakObjectMap::create(privateData, callback);
     50    RefPtr<OpaqueJSWeakObjectMap> map = OpaqueJSWeakObjectMap::create(exec->vm(), privateData, callback);
    5051    exec->lexicalGlobalObject()->registerWeakMap(map.get());
    5152    return map.get();
  • trunk/Source/JavaScriptCore/API/JSWrapperMap.mm

    r180467 r181010  
    3838#import "ObjcRuntimeExtras.h"
    3939#import "WeakGCMap.h"
     40#import "WeakGCMapInlines.h"
    4041#import <wtf/HashSet.h>
    4142#import <wtf/TCSpinLock.h>
     
    547548    JSContext *m_context;
    548549    NSMutableDictionary *m_classMap;
    549     JSC::WeakGCMap<id, JSC::JSObject> m_cachedJSWrappers;
     550    std::unique_ptr<JSC::WeakGCMap<id, JSC::JSObject>> m_cachedJSWrappers;
    550551    NSMapTable *m_cachedObjCWrappers;
    551552}
     
    560561    NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
    561562    m_cachedObjCWrappers = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
    562    
     563
     564    m_cachedJSWrappers = std::make_unique<JSC::WeakGCMap<id, JSC::JSObject>>(toJS([context JSGlobalContextRef])->vm());
     565
    563566    m_context = context;
    564567    m_classMap = [[NSMutableDictionary alloc] init];
     
    591594- (JSValue *)jsWrapperForObject:(id)object
    592595{
    593     JSC::JSObject* jsWrapper = m_cachedJSWrappers.get(object);
     596    JSC::JSObject* jsWrapper = m_cachedJSWrappers->get(object);
    594597    if (jsWrapper)
    595598        return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context];
     
    607610    // (2) A long lived object may rack up many JSValues. When the contexts are released these will unprotect the associated JavaScript objects,
    608611    //     but still, would probably nicer if we made it so that only one associated object was required, broadcasting object dealloc.
    609     m_cachedJSWrappers.set(object, jsWrapper);
     612    m_cachedJSWrappers->set(object, jsWrapper);
    610613    return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context];
    611614}
  • trunk/Source/JavaScriptCore/ChangeLog

    r180993 r181010  
     12015-03-04  Andreas Kling  <akling@apple.com>
     2
     3        Stale entries in WeakGCMaps are keeping tons of WeakBlocks alive unnecessarily.
     4        <https://webkit.org/b/142115>
     5        <rdar://problem/19992268>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        Prune stale entries from WeakGCMaps as part of every full garbage collection.
     10        This frees up tons of previously-stuck WeakBlocks that were only sitting around
     11        with finalized handles waiting to die.
     12
     13        Note that WeakGCMaps register/unregister themselves with the GC heap in their
     14        ctor/dtor, so creating one now requires passing the VM.
     15
     16        Average time spent in the PruningStaleEntriesFromWeakGCMaps GC phase appears
     17        to be between 0.01ms and 0.3ms, though I've seen a few longer ones at ~1.2ms.
     18        It seems somewhat excessive to do this on every Eden collection, so it's only
     19        doing work in full collections for now.
     20
     21        * API/JSWeakObjectMapRefInternal.h:
     22        (OpaqueJSWeakObjectMap::create):
     23        (OpaqueJSWeakObjectMap::OpaqueJSWeakObjectMap):
     24        * API/JSWeakObjectMapRefPrivate.cpp:
     25        * API/JSWrapperMap.mm:
     26        (-[JSWrapperMap initWithContext:]):
     27        (-[JSWrapperMap jsWrapperForObject:]): Pass VM to WeakGCMap constructor.
     28
     29        * JavaScriptCore.xcodeproj/project.pbxproj: Add WeakGCMapInlines.h and make
     30        it project-private so WebCore clients can access it.
     31
     32        * heap/Heap.cpp:
     33        (JSC::Heap::collect):
     34        (JSC::Heap::pruneStaleEntriesFromWeakGCMaps): Added a new GC phase for pruning
     35        stale entries from WeakGCMaps. This is only executed during full collections.
     36
     37        * heap/Heap.h:
     38        * heap/HeapInlines.h:
     39        (JSC::Heap::registerWeakGCMap):
     40        (JSC::Heap::unregisterWeakGCMap): Added a mechanism for WeakGCMaps to register
     41        themselves with the Heap and provide a pruning callback.
     42
     43        * runtime/PrototypeMap.h:
     44        (JSC::PrototypeMap::PrototypeMap):
     45        * runtime/Structure.cpp:
     46        (JSC::StructureTransitionTable::add): Pass VM to WeakGCMap constructor.
     47
     48        * runtime/JSCInlines.h: Add "WeakGCMapInlines.h"
     49
     50        * runtime/JSGlobalObject.cpp: Include "WeakGCMapInlines.h" so this builds.
     51
     52        * runtime/VM.cpp:
     53        (JSC::VM::VM): Pass VM to WeakGCMap constructor.
     54
     55        * runtime/WeakGCMap.h:
     56        (JSC::WeakGCMap::set):
     57        (JSC::WeakGCMap::add):
     58        (JSC::WeakGCMap::WeakGCMap): Deleted.
     59        (JSC::WeakGCMap::gcMap): Deleted.
     60        (JSC::WeakGCMap::gcMapIfNeeded): Deleted.
     61        * runtime/WeakGCMapInlines.h: Added.
     62        (JSC::WeakGCMap::WeakGCMap):
     63        (JSC::WeakGCMap::~WeakGCMap):
     64        (JSC::WeakGCMap::pruneStaleEntries): Moved ctor, dtor and pruning callback
     65        to WeakGCMapInlines.h to fix interdependent header issues. Removed code that
     66        prunes WeakGCMap at certain growth milestones and instead rely on the GC
     67        callback for housekeeping.
     68
    1692015-03-03  Filip Pizlo  <fpizlo@apple.com>
    270
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r180992 r181010  
    14281428                A7FCC26D17A0B6AA00786D1A /* FTLSwitchCase.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FCC26C17A0B6AA00786D1A /* FTLSwitchCase.h */; settings = {ATTRIBUTES = (Private, ); }; };
    14291429                A8A4748E151A8306004123FF /* libWTF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A8A4748D151A8306004123FF /* libWTF.a */; };
     1430                AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
    14301431                ADDB1F6318D77DBE009B58A8 /* OpaqueRootSet.h in Headers */ = {isa = PBXBuildFile; fileRef = ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
    14311432                ADE39FFF16DD144B0003CD4A /* PropertyTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */; };
     
    31453146                A8E894330CD0603F00367179 /* JSGlobalObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObject.h; sourceTree = "<group>"; };
    31463147                AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PropertyTable.cpp; sourceTree = "<group>"; };
     3148                AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMapInlines.h; sourceTree = "<group>"; };
    31473149                ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueRootSet.h; sourceTree = "<group>"; };
    31483150                B59F89371891AD3300D5CCDC /* UnlinkedInstructionStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedInstructionStream.h; sourceTree = "<group>"; };
     
    46274629                                FED94F2D171E3E2300BE77A4 /* WatchdogMac.cpp */,
    46284630                                14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */,
     4631                                AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */,
    46294632                                A7CA3ADD17DA41AE006538AF /* WeakMapConstructor.cpp */,
    46304633                                A7CA3ADE17DA41AE006538AF /* WeakMapConstructor.h */,
     
    55225525                                0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */,
    55235526                                BC18C3ED0E16F5CD00B34460 /* CallData.h in Headers */,
     5527                                AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */,
    55245528                                1429D8DE0ED2205B00B89619 /* CallFrame.h in Headers */,
    55255529                                A7C1EAEF17987AB600299DB2 /* CallFrameInlines.h in Headers */,
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r180992 r181010  
    10611061
    10621062    reapWeakHandles();
     1063    pruneStaleEntriesFromWeakGCMaps();
    10631064    sweepArrayBuffers();
    10641065    snapshotMarkedSpace();
     
    11721173    GCPHASE(ReapingWeakHandles);
    11731174    m_objectSpace.reapWeakSets();
     1175}
     1176
     1177void Heap::pruneStaleEntriesFromWeakGCMaps()
     1178{
     1179    GCPHASE(PruningStaleEntriesFromWeakGCMaps);
     1180    if (m_operationInProgress != FullCollection)
     1181        return;
     1182    for (auto& pruneCallback : m_weakGCMaps.values())
     1183        pruneCallback();
    11741184}
    11751185
  • trunk/Source/JavaScriptCore/heap/Heap.h

    r180690 r181010  
    227227
    228228    static bool isZombified(JSCell* cell) { return *(void**)cell == zombifiedBits; }
     229
     230    void registerWeakGCMap(void* weakGCMap, std::function<void()> pruningCallback);
     231    void unregisterWeakGCMap(void* weakGCMap);
    229232
    230233private:
     
    299302
    300303    void reapWeakHandles();
     304    void pruneStaleEntriesFromWeakGCMaps();
    301305    void sweepArrayBuffers();
    302306    void snapshotMarkedSpace();
     
    392396    unsigned m_delayedReleaseRecursionCount;
    393397#endif
     398
     399    HashMap<void*, std::function<void()>> m_weakGCMaps;
    394400};
    395401
  • trunk/Source/JavaScriptCore/heap/HeapInlines.h

    r179728 r181010  
    290290    return *m_markListSet;
    291291}
     292
     293inline void Heap::registerWeakGCMap(void* weakGCMap, std::function<void()> pruningCallback)
     294{
     295    m_weakGCMaps.add(weakGCMap, WTF::move(pruningCallback));
     296}
     297
     298inline void Heap::unregisterWeakGCMap(void* weakGCMap)
     299{
     300    m_weakGCMaps.remove(weakGCMap);
     301}
    292302   
    293303} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSCInlines.h

    r173410 r181010  
    5252#include "SlotVisitorInlines.h"
    5353#include "StructureInlines.h"
     54#include "WeakGCMapInlines.h"
    5455
    5556#endif // JSCInlines_h
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r180637 r181010  
    121121#include "SymbolPrototype.h"
    122122#include "VariableWatchpointSetInlines.h"
     123#include "WeakGCMapInlines.h"
    123124#include "WeakMapConstructor.h"
    124125#include "WeakMapPrototype.h"
  • trunk/Source/JavaScriptCore/runtime/PrototypeMap.h

    r141588 r181010  
    3434class JSObject;
    3535class Structure;
     36class VM;
    3637
    3738// Tracks the canonical structure an object should be allocated with when inheriting from a given prototype.
    3839class PrototypeMap {
    3940public:
     41    explicit PrototypeMap(VM& vm)
     42        : m_prototypes(vm)
     43        , m_structures(vm)
     44    {
     45    }
     46
    4047    JS_EXPORT_PRIVATE Structure* emptyObjectStructureForPrototype(JSObject*, unsigned inlineCapacity);
    4148    void clearEmptyObjectStructureForPrototype(JSObject*, unsigned inlineCapacity);
  • trunk/Source/JavaScriptCore/runtime/Structure.cpp

    r180173 r181010  
    3737#include "StructureChain.h"
    3838#include "StructureRareDataInlines.h"
     39#include "WeakGCMapInlines.h"
    3940#include <wtf/CommaPrinter.h>
    4041#include <wtf/ProcessID.h>
     
    9192        // This handles the second transition being added
    9293        // (or the first transition being despecified!)
    93         setMap(new TransitionMap());
     94        setMap(new TransitionMap(vm));
    9495        add(vm, existingTransition);
    9596    }
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r179609 r181010  
    8484#include "TypeProfilerLog.h"
    8585#include "UnlinkedCodeBlock.h"
     86#include "WeakGCMapInlines.h"
    8687#include "WeakMapData.h"
    8788#include <wtf/ProcessID.h>
     
    154155    , propertyNames(nullptr)
    155156    , emptyList(new MarkedArgumentBuffer)
     157    , stringCache(*this)
     158    , prototypeMap(*this)
    156159    , keywords(std::make_unique<Keywords>(*this))
    157160    , interpreter(0)
  • trunk/Source/JavaScriptCore/runtime/WeakGCMap.h

    r170774 r181010  
    11/*
    2  * Copyright (C) 2009 Apple Inc. All rights reserved.
     2 * Copyright (C) 2009, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4848    typedef typename HashMapType::const_iterator const_iterator;
    4949
    50     WeakGCMap()
    51         : m_gcThreshold(minGCThreshold)
    52     {
    53     }
     50    explicit WeakGCMap(VM&);
     51    ~WeakGCMap();
    5452
    5553    ValueArg* get(const KeyType& key) const
     
    6058    AddResult set(const KeyType& key, ValueType value)
    6159    {
    62         gcMapIfNeeded();
    6360        return m_map.set(key, WTF::move(value));
    6461    }
     
    6663    ALWAYS_INLINE AddResult add(const KeyType& key, ValueType value)
    6764    {
    68         gcMapIfNeeded();
    6965        AddResult addResult = m_map.fastAdd(key, nullptr);
    7066        if (!addResult.iterator->value) { // New value or found a zombie value.
     
    104100    }
    105101
     102    void pruneStaleEntries();
     103
    106104private:
    107     static const int minGCThreshold = 3;
    108 
    109     NEVER_INLINE void gcMap()
    110     {
    111         Vector<KeyType, 4> zombies;
    112 
    113         for (iterator it = m_map.begin(), end = m_map.end(); it != end; ++it) {
    114             if (!it->value)
    115                 zombies.append(it->key);
    116         }
    117 
    118         for (size_t i = 0; i < zombies.size(); ++i)
    119             m_map.remove(zombies[i]);
    120     }
    121 
    122     void gcMapIfNeeded()
    123     {
    124         if (m_map.size() < m_gcThreshold)
    125             return;
    126 
    127         gcMap();
    128         m_gcThreshold = std::max(minGCThreshold, m_map.size() * 2 - 1);
    129     }
    130 
    131105    HashMapType m_map;
    132     int m_gcThreshold;
     106    VM& m_vm;
    133107};
    134 
    135 template<typename KeyArg, typename RawMappedArg, typename HashArg, typename KeyTraitsArg>
    136 const int WeakGCMap<KeyArg, RawMappedArg, HashArg, KeyTraitsArg>::minGCThreshold;
    137108
    138109} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/WeakGCMapInlines.h

    r181008 r181010  
    11/*
    2  * Copyright (C) 2010 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #ifndef JSWeakObjectMapRefInternal_h
    27 #define JSWeakObjectMapRefInternal_h
     26#ifndef WeakGCMapInlines_h
     27#define WeakGCMapInlines_h
    2828
     29#include "HeapInlines.h"
    2930#include "WeakGCMap.h"
    30 #include <wtf/RefCounted.h>
    3131
    3232namespace JSC {
    3333
    34 class JSObject;
    35 
     34template<typename KeyArg, typename ValueArg, typename HashArg, typename KeyTraitsArg>
     35inline WeakGCMap<KeyArg, ValueArg, HashArg, KeyTraitsArg>::WeakGCMap(VM& vm)
     36    : m_vm(vm)
     37{
     38    vm.heap.registerWeakGCMap(this, [this]() {
     39        pruneStaleEntries();
     40    });
    3641}
    3742
    38 typedef void (*JSWeakMapDestroyedCallback)(struct OpaqueJSWeakObjectMap*, void*);
     43template<typename KeyArg, typename ValueArg, typename HashArg, typename KeyTraitsArg>
     44inline WeakGCMap<KeyArg, ValueArg, HashArg, KeyTraitsArg>::~WeakGCMap()
     45{
     46    m_vm.heap.unregisterWeakGCMap(this);
     47}
    3948
    40 typedef JSC::WeakGCMap<void*, JSC::JSObject> WeakMapType;
     49template<typename KeyArg, typename ValueArg, typename HashArg, typename KeyTraitsArg>
     50NEVER_INLINE void WeakGCMap<KeyArg, ValueArg, HashArg, KeyTraitsArg>::pruneStaleEntries()
     51{
     52    m_map.removeIf([](typename HashMapType::KeyValuePairType& entry) {
     53        return !entry.value;
     54    });
     55}
    4156
    42 struct OpaqueJSWeakObjectMap : public RefCounted<OpaqueJSWeakObjectMap> {
    43 public:
    44     static PassRefPtr<OpaqueJSWeakObjectMap> create(void* data, JSWeakMapDestroyedCallback callback)
    45     {
    46         return adoptRef(new OpaqueJSWeakObjectMap(data, callback));
    47     }
     57} // namespace JSC
    4858
    49     WeakMapType& map() { return m_map; }
    50    
    51     ~OpaqueJSWeakObjectMap()
    52     {
    53         m_callback(this, m_data);
    54     }
    55 
    56 private:
    57     OpaqueJSWeakObjectMap(void* data, JSWeakMapDestroyedCallback callback)
    58         : m_data(data)
    59         , m_callback(callback)
    60     {
    61     }
    62     WeakMapType m_map;
    63     void* m_data;
    64     JSWeakMapDestroyedCallback m_callback;
    65 };
    66 
    67 
    68 #endif // JSWeakObjectMapInternal_h
     59#endif // WeakGCMapInlines_h
  • trunk/Source/WebCore/bindings/js/ScriptCachedFrameData.cpp

    r180653 r181010  
    3939#include "PageConsoleClient.h"
    4040#include "PageGroup.h"
     41#include "ScriptController.h"
    4142#include <heap/StrongInlines.h>
    4243#include <profiler/Profile.h>
    4344#include <runtime/JSLock.h>
    44 #include "ScriptController.h"
     45#include <runtime/WeakGCMapInlines.h>
    4546
    4647using namespace JSC;
Note: See TracChangeset for help on using the changeset viewer.