Diff
Modified: trunk/Source/_javascript_Core/API/JSWeakObjectMapRefInternal.h (181009 => 181010)
--- trunk/Source/_javascript_Core/API/JSWeakObjectMapRefInternal.h 2015-03-04 19:56:39 UTC (rev 181009)
+++ trunk/Source/_javascript_Core/API/JSWeakObjectMapRefInternal.h 2015-03-04 20:00:00 UTC (rev 181010)
@@ -41,9 +41,9 @@
struct OpaqueJSWeakObjectMap : public RefCounted<OpaqueJSWeakObjectMap> {
public:
- static PassRefPtr<OpaqueJSWeakObjectMap> create(void* data, JSWeakMapDestroyedCallback callback)
+ static Ref<OpaqueJSWeakObjectMap> create(JSC::VM& vm, void* data, JSWeakMapDestroyedCallback callback)
{
- return adoptRef(new OpaqueJSWeakObjectMap(data, callback));
+ return adoptRef(*new OpaqueJSWeakObjectMap(vm, data, callback));
}
WeakMapType& map() { return m_map; }
@@ -54,8 +54,9 @@
}
private:
- OpaqueJSWeakObjectMap(void* data, JSWeakMapDestroyedCallback callback)
- : m_data(data)
+ OpaqueJSWeakObjectMap(JSC::VM& vm, void* data, JSWeakMapDestroyedCallback callback)
+ : m_map(vm)
+ , m_data(data)
, m_callback(callback)
{
}
Modified: trunk/Source/_javascript_Core/API/JSWeakObjectMapRefPrivate.cpp (181009 => 181010)
--- trunk/Source/_javascript_Core/API/JSWeakObjectMapRefPrivate.cpp 2015-03-04 19:56:39 UTC (rev 181009)
+++ trunk/Source/_javascript_Core/API/JSWeakObjectMapRefPrivate.cpp 2015-03-04 20:00:00 UTC (rev 181010)
@@ -32,6 +32,7 @@
#include "JSWeakObjectMapRefInternal.h"
#include "JSCInlines.h"
#include "Weak.h"
+#include "WeakGCMapInlines.h"
#include <wtf/HashMap.h>
#include <wtf/text/StringHash.h>
@@ -46,7 +47,7 @@
{
ExecState* exec = toJS(context);
JSLockHolder locker(exec);
- RefPtr<OpaqueJSWeakObjectMap> map = OpaqueJSWeakObjectMap::create(privateData, callback);
+ RefPtr<OpaqueJSWeakObjectMap> map = OpaqueJSWeakObjectMap::create(exec->vm(), privateData, callback);
exec->lexicalGlobalObject()->registerWeakMap(map.get());
return map.get();
}
Modified: trunk/Source/_javascript_Core/API/JSWrapperMap.mm (181009 => 181010)
--- trunk/Source/_javascript_Core/API/JSWrapperMap.mm 2015-03-04 19:56:39 UTC (rev 181009)
+++ trunk/Source/_javascript_Core/API/JSWrapperMap.mm 2015-03-04 20:00:00 UTC (rev 181010)
@@ -37,6 +37,7 @@
#import "ObjCCallbackFunction.h"
#import "ObjcRuntimeExtras.h"
#import "WeakGCMap.h"
+#import "WeakGCMapInlines.h"
#import <wtf/HashSet.h>
#import <wtf/TCSpinLock.h>
#import <wtf/Vector.h>
@@ -546,7 +547,7 @@
@implementation JSWrapperMap {
JSContext *m_context;
NSMutableDictionary *m_classMap;
- JSC::WeakGCMap<id, JSC::JSObject> m_cachedJSWrappers;
+ std::unique_ptr<JSC::WeakGCMap<id, JSC::JSObject>> m_cachedJSWrappers;
NSMapTable *m_cachedObjCWrappers;
}
@@ -559,7 +560,9 @@
NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality;
NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
m_cachedObjCWrappers = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
-
+
+ m_cachedJSWrappers = std::make_unique<JSC::WeakGCMap<id, JSC::JSObject>>(toJS([context JSGlobalContextRef])->vm());
+
m_context = context;
m_classMap = [[NSMutableDictionary alloc] init];
return self;
@@ -590,7 +593,7 @@
- (JSValue *)jsWrapperForObject:(id)object
{
- JSC::JSObject* jsWrapper = m_cachedJSWrappers.get(object);
+ JSC::JSObject* jsWrapper = m_cachedJSWrappers->get(object);
if (jsWrapper)
return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context];
@@ -606,7 +609,7 @@
// (1) For immortal objects JSValues will effectively leak and this results in error output being logged - we should avoid adding associated objects to immortal objects.
// (2) A long lived object may rack up many JSValues. When the contexts are released these will unprotect the associated _javascript_ objects,
// but still, would probably nicer if we made it so that only one associated object was required, broadcasting object dealloc.
- m_cachedJSWrappers.set(object, jsWrapper);
+ m_cachedJSWrappers->set(object, jsWrapper);
return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context];
}
Modified: trunk/Source/_javascript_Core/ChangeLog (181009 => 181010)
--- trunk/Source/_javascript_Core/ChangeLog 2015-03-04 19:56:39 UTC (rev 181009)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-03-04 20:00:00 UTC (rev 181010)
@@ -1,3 +1,71 @@
+2015-03-04 Andreas Kling <[email protected]>
+
+ 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.
+
+ * _javascript_Core.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.
+
2015-03-03 Filip Pizlo <[email protected]>
DFG IR should refer to FunctionExecutables directly and not via the CodeBlock
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (181009 => 181010)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2015-03-04 19:56:39 UTC (rev 181009)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2015-03-04 20:00:00 UTC (rev 181010)
@@ -1427,6 +1427,7 @@
A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7FCC26D17A0B6AA00786D1A /* FTLSwitchCase.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FCC26C17A0B6AA00786D1A /* FTLSwitchCase.h */; settings = {ATTRIBUTES = (Private, ); }; };
A8A4748E151A8306004123FF /* libWTF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A8A4748D151A8306004123FF /* libWTF.a */; };
+ AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
ADDB1F6318D77DBE009B58A8 /* OpaqueRootSet.h in Headers */ = {isa = PBXBuildFile; fileRef = ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
ADE39FFF16DD144B0003CD4A /* PropertyTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */; };
B59F89391891F29F00D5CCDC /* UnlinkedInstructionStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B59F89381891ADB500D5CCDC /* UnlinkedInstructionStream.cpp */; };
@@ -3144,6 +3145,7 @@
A8E894310CD0602400367179 /* JSCallbackObjectFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackObjectFunctions.h; sourceTree = "<group>"; };
A8E894330CD0603F00367179 /* JSGlobalObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObject.h; sourceTree = "<group>"; };
AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PropertyTable.cpp; sourceTree = "<group>"; };
+ AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMapInlines.h; sourceTree = "<group>"; };
ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueRootSet.h; sourceTree = "<group>"; };
B59F89371891AD3300D5CCDC /* UnlinkedInstructionStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedInstructionStream.h; sourceTree = "<group>"; };
B59F89381891ADB500D5CCDC /* UnlinkedInstructionStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkedInstructionStream.cpp; sourceTree = "<group>"; };
@@ -4626,6 +4628,7 @@
FED94F2C171E3E2300BE77A4 /* Watchdog.h */,
FED94F2D171E3E2300BE77A4 /* WatchdogMac.cpp */,
14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */,
+ AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */,
A7CA3ADD17DA41AE006538AF /* WeakMapConstructor.cpp */,
A7CA3ADE17DA41AE006538AF /* WeakMapConstructor.h */,
A7CA3AE917DA5168006538AF /* WeakMapData.cpp */,
@@ -5521,6 +5524,7 @@
0F885E111849A3BE00F1E3FA /* BytecodeUseDef.h in Headers */,
0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */,
BC18C3ED0E16F5CD00B34460 /* CallData.h in Headers */,
+ AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */,
1429D8DE0ED2205B00B89619 /* CallFrame.h in Headers */,
A7C1EAEF17987AB600299DB2 /* CallFrameInlines.h in Headers */,
95E3BC050E1AE68200B2D1C1 /* CallIdentifier.h in Headers */,
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (181009 => 181010)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2015-03-04 19:56:39 UTC (rev 181009)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2015-03-04 20:00:00 UTC (rev 181010)
@@ -1060,6 +1060,7 @@
vm()->typeProfiler()->invalidateTypeSetCache();
reapWeakHandles();
+ pruneStaleEntriesFromWeakGCMaps();
sweepArrayBuffers();
snapshotMarkedSpace();
@@ -1173,6 +1174,15 @@
m_objectSpace.reapWeakSets();
}
+void Heap::pruneStaleEntriesFromWeakGCMaps()
+{
+ GCPHASE(PruningStaleEntriesFromWeakGCMaps);
+ if (m_operationInProgress != FullCollection)
+ return;
+ for (auto& pruneCallback : m_weakGCMaps.values())
+ pruneCallback();
+}
+
void Heap::sweepArrayBuffers()
{
GCPHASE(SweepingArrayBuffers);
Modified: trunk/Source/_javascript_Core/heap/Heap.h (181009 => 181010)
--- trunk/Source/_javascript_Core/heap/Heap.h 2015-03-04 19:56:39 UTC (rev 181009)
+++ trunk/Source/_javascript_Core/heap/Heap.h 2015-03-04 20:00:00 UTC (rev 181010)
@@ -227,6 +227,9 @@
static bool isZombified(JSCell* cell) { return *(void**)cell == zombifiedBits; }
+ void registerWeakGCMap(void* weakGCMap, std::function<void()> pruningCallback);
+ void unregisterWeakGCMap(void* weakGCMap);
+
private:
friend class CodeBlock;
friend class CopiedBlock;
@@ -298,6 +301,7 @@
void resetVisitors();
void reapWeakHandles();
+ void pruneStaleEntriesFromWeakGCMaps();
void sweepArrayBuffers();
void snapshotMarkedSpace();
void deleteSourceProviderCaches();
@@ -391,6 +395,8 @@
Vector<RetainPtr<CFTypeRef>> m_delayedReleaseObjects;
unsigned m_delayedReleaseRecursionCount;
#endif
+
+ HashMap<void*, std::function<void()>> m_weakGCMaps;
};
} // namespace JSC
Modified: trunk/Source/_javascript_Core/heap/HeapInlines.h (181009 => 181010)
--- trunk/Source/_javascript_Core/heap/HeapInlines.h 2015-03-04 19:56:39 UTC (rev 181009)
+++ trunk/Source/_javascript_Core/heap/HeapInlines.h 2015-03-04 20:00:00 UTC (rev 181010)
@@ -289,6 +289,16 @@
m_markListSet = std::make_unique<HashSet<MarkedArgumentBuffer*>>();
return *m_markListSet;
}
+
+inline void Heap::registerWeakGCMap(void* weakGCMap, std::function<void()> pruningCallback)
+{
+ m_weakGCMaps.add(weakGCMap, WTF::move(pruningCallback));
+}
+
+inline void Heap::unregisterWeakGCMap(void* weakGCMap)
+{
+ m_weakGCMaps.remove(weakGCMap);
+}
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/JSCInlines.h (181009 => 181010)
--- trunk/Source/_javascript_Core/runtime/JSCInlines.h 2015-03-04 19:56:39 UTC (rev 181009)
+++ trunk/Source/_javascript_Core/runtime/JSCInlines.h 2015-03-04 20:00:00 UTC (rev 181010)
@@ -51,5 +51,6 @@
#include "Operations.h"
#include "SlotVisitorInlines.h"
#include "StructureInlines.h"
+#include "WeakGCMapInlines.h"
#endif // JSCInlines_h
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (181009 => 181010)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2015-03-04 19:56:39 UTC (rev 181009)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2015-03-04 20:00:00 UTC (rev 181010)
@@ -120,6 +120,7 @@
#include "SymbolConstructor.h"
#include "SymbolPrototype.h"
#include "VariableWatchpointSetInlines.h"
+#include "WeakGCMapInlines.h"
#include "WeakMapConstructor.h"
#include "WeakMapPrototype.h"
Modified: trunk/Source/_javascript_Core/runtime/PrototypeMap.h (181009 => 181010)
--- trunk/Source/_javascript_Core/runtime/PrototypeMap.h 2015-03-04 19:56:39 UTC (rev 181009)
+++ trunk/Source/_javascript_Core/runtime/PrototypeMap.h 2015-03-04 20:00:00 UTC (rev 181010)
@@ -33,10 +33,17 @@
class JSObject;
class Structure;
+class VM;
// Tracks the canonical structure an object should be allocated with when inheriting from a given prototype.
class PrototypeMap {
public:
+ explicit PrototypeMap(VM& vm)
+ : m_prototypes(vm)
+ , m_structures(vm)
+ {
+ }
+
JS_EXPORT_PRIVATE Structure* emptyObjectStructureForPrototype(JSObject*, unsigned inlineCapacity);
void clearEmptyObjectStructureForPrototype(JSObject*, unsigned inlineCapacity);
void addPrototype(JSObject*);
Modified: trunk/Source/_javascript_Core/runtime/Structure.cpp (181009 => 181010)
--- trunk/Source/_javascript_Core/runtime/Structure.cpp 2015-03-04 19:56:39 UTC (rev 181009)
+++ trunk/Source/_javascript_Core/runtime/Structure.cpp 2015-03-04 20:00:00 UTC (rev 181010)
@@ -36,6 +36,7 @@
#include "PropertyNameArray.h"
#include "StructureChain.h"
#include "StructureRareDataInlines.h"
+#include "WeakGCMapInlines.h"
#include <wtf/CommaPrinter.h>
#include <wtf/ProcessID.h>
#include <wtf/RefCountedLeakCounter.h>
@@ -90,7 +91,7 @@
// This handles the second transition being added
// (or the first transition being despecified!)
- setMap(new TransitionMap());
+ setMap(new TransitionMap(vm));
add(vm, existingTransition);
}
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (181009 => 181010)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2015-03-04 19:56:39 UTC (rev 181009)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2015-03-04 20:00:00 UTC (rev 181010)
@@ -83,6 +83,7 @@
#include "TypeProfiler.h"
#include "TypeProfilerLog.h"
#include "UnlinkedCodeBlock.h"
+#include "WeakGCMapInlines.h"
#include "WeakMapData.h"
#include <wtf/ProcessID.h>
#include <wtf/RetainPtr.h>
@@ -153,6 +154,8 @@
, m_atomicStringTable(vmType == Default ? wtfThreadData().atomicStringTable() : new AtomicStringTable)
, propertyNames(nullptr)
, emptyList(new MarkedArgumentBuffer)
+ , stringCache(*this)
+ , prototypeMap(*this)
, keywords(std::make_unique<Keywords>(*this))
, interpreter(0)
, jsArrayClassInfo(JSArray::info())
Modified: trunk/Source/_javascript_Core/runtime/WeakGCMap.h (181009 => 181010)
--- trunk/Source/_javascript_Core/runtime/WeakGCMap.h 2015-03-04 19:56:39 UTC (rev 181009)
+++ trunk/Source/_javascript_Core/runtime/WeakGCMap.h 2015-03-04 20:00:00 UTC (rev 181010)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -47,10 +47,8 @@
typedef typename HashMapType::iterator iterator;
typedef typename HashMapType::const_iterator const_iterator;
- WeakGCMap()
- : m_gcThreshold(minGCThreshold)
- {
- }
+ explicit WeakGCMap(VM&);
+ ~WeakGCMap();
ValueArg* get(const KeyType& key) const
{
@@ -59,13 +57,11 @@
AddResult set(const KeyType& key, ValueType value)
{
- gcMapIfNeeded();
return m_map.set(key, WTF::move(value));
}
ALWAYS_INLINE AddResult add(const KeyType& key, ValueType value)
{
- gcMapIfNeeded();
AddResult addResult = m_map.fastAdd(key, nullptr);
if (!addResult.iterator->value) { // New value or found a zombie value.
addResult.isNewEntry = true;
@@ -103,38 +99,13 @@
return find(key) != m_map.end();
}
-private:
- static const int minGCThreshold = 3;
+ void pruneStaleEntries();
- NEVER_INLINE void gcMap()
- {
- Vector<KeyType, 4> zombies;
-
- for (iterator it = m_map.begin(), end = m_map.end(); it != end; ++it) {
- if (!it->value)
- zombies.append(it->key);
- }
-
- for (size_t i = 0; i < zombies.size(); ++i)
- m_map.remove(zombies[i]);
- }
-
- void gcMapIfNeeded()
- {
- if (m_map.size() < m_gcThreshold)
- return;
-
- gcMap();
- m_gcThreshold = std::max(minGCThreshold, m_map.size() * 2 - 1);
- }
-
+private:
HashMapType m_map;
- int m_gcThreshold;
+ VM& m_vm;
};
-template<typename KeyArg, typename RawMappedArg, typename HashArg, typename KeyTraitsArg>
-const int WeakGCMap<KeyArg, RawMappedArg, HashArg, KeyTraitsArg>::minGCThreshold;
-
} // namespace JSC
#endif // WeakGCMap_h
Copied: trunk/Source/_javascript_Core/runtime/WeakGCMapInlines.h (from rev 181008, trunk/Source/_javascript_Core/API/JSWeakObjectMapRefInternal.h) (0 => 181010)
--- trunk/Source/_javascript_Core/runtime/WeakGCMapInlines.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/WeakGCMapInlines.h 2015-03-04 20:00:00 UTC (rev 181010)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WeakGCMapInlines_h
+#define WeakGCMapInlines_h
+
+#include "HeapInlines.h"
+#include "WeakGCMap.h"
+
+namespace JSC {
+
+template<typename KeyArg, typename ValueArg, typename HashArg, typename KeyTraitsArg>
+inline WeakGCMap<KeyArg, ValueArg, HashArg, KeyTraitsArg>::WeakGCMap(VM& vm)
+ : m_vm(vm)
+{
+ vm.heap.registerWeakGCMap(this, [this]() {
+ pruneStaleEntries();
+ });
+}
+
+template<typename KeyArg, typename ValueArg, typename HashArg, typename KeyTraitsArg>
+inline WeakGCMap<KeyArg, ValueArg, HashArg, KeyTraitsArg>::~WeakGCMap()
+{
+ m_vm.heap.unregisterWeakGCMap(this);
+}
+
+template<typename KeyArg, typename ValueArg, typename HashArg, typename KeyTraitsArg>
+NEVER_INLINE void WeakGCMap<KeyArg, ValueArg, HashArg, KeyTraitsArg>::pruneStaleEntries()
+{
+ m_map.removeIf([](typename HashMapType::KeyValuePairType& entry) {
+ return !entry.value;
+ });
+}
+
+} // namespace JSC
+
+#endif // WeakGCMapInlines_h
Added: trunk/Source/WebCore/ForwardingHeaders/runtime/WeakGCMapInlines.h (0 => 181010)
--- trunk/Source/WebCore/ForwardingHeaders/runtime/WeakGCMapInlines.h (rev 0)
+++ trunk/Source/WebCore/ForwardingHeaders/runtime/WeakGCMapInlines.h 2015-03-04 20:00:00 UTC (rev 181010)
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_WeakGCMapInlines_h
+#define WebCore_FWD_WeakGCMapInlines_h
+#include <_javascript_Core/WeakGCMapInlines.h>
+#endif
Modified: trunk/Source/WebCore/bindings/js/ScriptCachedFrameData.cpp (181009 => 181010)
--- trunk/Source/WebCore/bindings/js/ScriptCachedFrameData.cpp 2015-03-04 19:56:39 UTC (rev 181009)
+++ trunk/Source/WebCore/bindings/js/ScriptCachedFrameData.cpp 2015-03-04 20:00:00 UTC (rev 181010)
@@ -38,10 +38,11 @@
#include "Page.h"
#include "PageConsoleClient.h"
#include "PageGroup.h"
+#include "ScriptController.h"
#include <heap/StrongInlines.h>
#include <profiler/Profile.h>
#include <runtime/JSLock.h>
-#include "ScriptController.h"
+#include <runtime/WeakGCMapInlines.h>
using namespace JSC;