Changeset 181010 in webkit
- Timestamp:
- Mar 4, 2015 12:00:00 PM (9 years ago)
- Location:
- trunk/Source
- Files:
-
- 1 added
- 15 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/API/JSWeakObjectMapRefInternal.h
r95901 r181010 42 42 struct OpaqueJSWeakObjectMap : public RefCounted<OpaqueJSWeakObjectMap> { 43 43 public: 44 static PassRefPtr<OpaqueJSWeakObjectMap> create(void* data, JSWeakMapDestroyedCallback callback)44 static Ref<OpaqueJSWeakObjectMap> create(JSC::VM& vm, void* data, JSWeakMapDestroyedCallback callback) 45 45 { 46 return adoptRef( new OpaqueJSWeakObjectMap(data, callback));46 return adoptRef(*new OpaqueJSWeakObjectMap(vm, data, callback)); 47 47 } 48 48 … … 55 55 56 56 private: 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) 59 60 , m_callback(callback) 60 61 { -
trunk/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp
r171691 r181010 33 33 #include "JSCInlines.h" 34 34 #include "Weak.h" 35 #include "WeakGCMapInlines.h" 35 36 #include <wtf/HashMap.h> 36 37 #include <wtf/text/StringHash.h> … … 47 48 ExecState* exec = toJS(context); 48 49 JSLockHolder locker(exec); 49 RefPtr<OpaqueJSWeakObjectMap> map = OpaqueJSWeakObjectMap::create( privateData, callback);50 RefPtr<OpaqueJSWeakObjectMap> map = OpaqueJSWeakObjectMap::create(exec->vm(), privateData, callback); 50 51 exec->lexicalGlobalObject()->registerWeakMap(map.get()); 51 52 return map.get(); -
trunk/Source/JavaScriptCore/API/JSWrapperMap.mm
r180467 r181010 38 38 #import "ObjcRuntimeExtras.h" 39 39 #import "WeakGCMap.h" 40 #import "WeakGCMapInlines.h" 40 41 #import <wtf/HashSet.h> 41 42 #import <wtf/TCSpinLock.h> … … 547 548 JSContext *m_context; 548 549 NSMutableDictionary *m_classMap; 549 JSC::WeakGCMap<id, JSC::JSObject> m_cachedJSWrappers;550 std::unique_ptr<JSC::WeakGCMap<id, JSC::JSObject>> m_cachedJSWrappers; 550 551 NSMapTable *m_cachedObjCWrappers; 551 552 } … … 560 561 NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality; 561 562 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 563 566 m_context = context; 564 567 m_classMap = [[NSMutableDictionary alloc] init]; … … 591 594 - (JSValue *)jsWrapperForObject:(id)object 592 595 { 593 JSC::JSObject* jsWrapper = m_cachedJSWrappers .get(object);596 JSC::JSObject* jsWrapper = m_cachedJSWrappers->get(object); 594 597 if (jsWrapper) 595 598 return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context]; … … 607 610 // (2) A long lived object may rack up many JSValues. When the contexts are released these will unprotect the associated JavaScript objects, 608 611 // 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); 610 613 return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context]; 611 614 } -
trunk/Source/JavaScriptCore/ChangeLog
r180993 r181010 1 2015-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 1 69 2015-03-03 Filip Pizlo <fpizlo@apple.com> 2 70 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r180992 r181010 1428 1428 A7FCC26D17A0B6AA00786D1A /* FTLSwitchCase.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FCC26C17A0B6AA00786D1A /* FTLSwitchCase.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1429 1429 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, ); }; }; 1430 1431 ADDB1F6318D77DBE009B58A8 /* OpaqueRootSet.h in Headers */ = {isa = PBXBuildFile; fileRef = ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1431 1432 ADE39FFF16DD144B0003CD4A /* PropertyTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */; }; … … 3145 3146 A8E894330CD0603F00367179 /* JSGlobalObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObject.h; sourceTree = "<group>"; }; 3146 3147 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>"; }; 3147 3149 ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueRootSet.h; sourceTree = "<group>"; }; 3148 3150 B59F89371891AD3300D5CCDC /* UnlinkedInstructionStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedInstructionStream.h; sourceTree = "<group>"; }; … … 4627 4629 FED94F2D171E3E2300BE77A4 /* WatchdogMac.cpp */, 4628 4630 14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */, 4631 AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */, 4629 4632 A7CA3ADD17DA41AE006538AF /* WeakMapConstructor.cpp */, 4630 4633 A7CA3ADE17DA41AE006538AF /* WeakMapConstructor.h */, … … 5522 5525 0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */, 5523 5526 BC18C3ED0E16F5CD00B34460 /* CallData.h in Headers */, 5527 AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */, 5524 5528 1429D8DE0ED2205B00B89619 /* CallFrame.h in Headers */, 5525 5529 A7C1EAEF17987AB600299DB2 /* CallFrameInlines.h in Headers */, -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r180992 r181010 1061 1061 1062 1062 reapWeakHandles(); 1063 pruneStaleEntriesFromWeakGCMaps(); 1063 1064 sweepArrayBuffers(); 1064 1065 snapshotMarkedSpace(); … … 1172 1173 GCPHASE(ReapingWeakHandles); 1173 1174 m_objectSpace.reapWeakSets(); 1175 } 1176 1177 void Heap::pruneStaleEntriesFromWeakGCMaps() 1178 { 1179 GCPHASE(PruningStaleEntriesFromWeakGCMaps); 1180 if (m_operationInProgress != FullCollection) 1181 return; 1182 for (auto& pruneCallback : m_weakGCMaps.values()) 1183 pruneCallback(); 1174 1184 } 1175 1185 -
trunk/Source/JavaScriptCore/heap/Heap.h
r180690 r181010 227 227 228 228 static bool isZombified(JSCell* cell) { return *(void**)cell == zombifiedBits; } 229 230 void registerWeakGCMap(void* weakGCMap, std::function<void()> pruningCallback); 231 void unregisterWeakGCMap(void* weakGCMap); 229 232 230 233 private: … … 299 302 300 303 void reapWeakHandles(); 304 void pruneStaleEntriesFromWeakGCMaps(); 301 305 void sweepArrayBuffers(); 302 306 void snapshotMarkedSpace(); … … 392 396 unsigned m_delayedReleaseRecursionCount; 393 397 #endif 398 399 HashMap<void*, std::function<void()>> m_weakGCMaps; 394 400 }; 395 401 -
trunk/Source/JavaScriptCore/heap/HeapInlines.h
r179728 r181010 290 290 return *m_markListSet; 291 291 } 292 293 inline void Heap::registerWeakGCMap(void* weakGCMap, std::function<void()> pruningCallback) 294 { 295 m_weakGCMaps.add(weakGCMap, WTF::move(pruningCallback)); 296 } 297 298 inline void Heap::unregisterWeakGCMap(void* weakGCMap) 299 { 300 m_weakGCMaps.remove(weakGCMap); 301 } 292 302 293 303 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSCInlines.h
r173410 r181010 52 52 #include "SlotVisitorInlines.h" 53 53 #include "StructureInlines.h" 54 #include "WeakGCMapInlines.h" 54 55 55 56 #endif // JSCInlines_h -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r180637 r181010 121 121 #include "SymbolPrototype.h" 122 122 #include "VariableWatchpointSetInlines.h" 123 #include "WeakGCMapInlines.h" 123 124 #include "WeakMapConstructor.h" 124 125 #include "WeakMapPrototype.h" -
trunk/Source/JavaScriptCore/runtime/PrototypeMap.h
r141588 r181010 34 34 class JSObject; 35 35 class Structure; 36 class VM; 36 37 37 38 // Tracks the canonical structure an object should be allocated with when inheriting from a given prototype. 38 39 class PrototypeMap { 39 40 public: 41 explicit PrototypeMap(VM& vm) 42 : m_prototypes(vm) 43 , m_structures(vm) 44 { 45 } 46 40 47 JS_EXPORT_PRIVATE Structure* emptyObjectStructureForPrototype(JSObject*, unsigned inlineCapacity); 41 48 void clearEmptyObjectStructureForPrototype(JSObject*, unsigned inlineCapacity); -
trunk/Source/JavaScriptCore/runtime/Structure.cpp
r180173 r181010 37 37 #include "StructureChain.h" 38 38 #include "StructureRareDataInlines.h" 39 #include "WeakGCMapInlines.h" 39 40 #include <wtf/CommaPrinter.h> 40 41 #include <wtf/ProcessID.h> … … 91 92 // This handles the second transition being added 92 93 // (or the first transition being despecified!) 93 setMap(new TransitionMap( ));94 setMap(new TransitionMap(vm)); 94 95 add(vm, existingTransition); 95 96 } -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r179609 r181010 84 84 #include "TypeProfilerLog.h" 85 85 #include "UnlinkedCodeBlock.h" 86 #include "WeakGCMapInlines.h" 86 87 #include "WeakMapData.h" 87 88 #include <wtf/ProcessID.h> … … 154 155 , propertyNames(nullptr) 155 156 , emptyList(new MarkedArgumentBuffer) 157 , stringCache(*this) 158 , prototypeMap(*this) 156 159 , keywords(std::make_unique<Keywords>(*this)) 157 160 , interpreter(0) -
trunk/Source/JavaScriptCore/runtime/WeakGCMap.h
r170774 r181010 1 1 /* 2 * Copyright (C) 2009 Apple Inc. All rights reserved.2 * Copyright (C) 2009, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 48 48 typedef typename HashMapType::const_iterator const_iterator; 49 49 50 WeakGCMap() 51 : m_gcThreshold(minGCThreshold) 52 { 53 } 50 explicit WeakGCMap(VM&); 51 ~WeakGCMap(); 54 52 55 53 ValueArg* get(const KeyType& key) const … … 60 58 AddResult set(const KeyType& key, ValueType value) 61 59 { 62 gcMapIfNeeded();63 60 return m_map.set(key, WTF::move(value)); 64 61 } … … 66 63 ALWAYS_INLINE AddResult add(const KeyType& key, ValueType value) 67 64 { 68 gcMapIfNeeded();69 65 AddResult addResult = m_map.fastAdd(key, nullptr); 70 66 if (!addResult.iterator->value) { // New value or found a zombie value. … … 104 100 } 105 101 102 void pruneStaleEntries(); 103 106 104 private: 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 131 105 HashMapType m_map; 132 int m_gcThreshold;106 VM& m_vm; 133 107 }; 134 135 template<typename KeyArg, typename RawMappedArg, typename HashArg, typename KeyTraitsArg>136 const int WeakGCMap<KeyArg, RawMappedArg, HashArg, KeyTraitsArg>::minGCThreshold;137 108 138 109 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/WeakGCMapInlines.h
r181008 r181010 1 1 /* 2 * Copyright (C) 201 0Apple Inc. All rights reserved.2 * Copyright (C) 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 #ifndef JSWeakObjectMapRefInternal_h27 #define JSWeakObjectMapRefInternal_h26 #ifndef WeakGCMapInlines_h 27 #define WeakGCMapInlines_h 28 28 29 #include "HeapInlines.h" 29 30 #include "WeakGCMap.h" 30 #include <wtf/RefCounted.h>31 31 32 32 namespace JSC { 33 33 34 class JSObject; 35 34 template<typename KeyArg, typename ValueArg, typename HashArg, typename KeyTraitsArg> 35 inline WeakGCMap<KeyArg, ValueArg, HashArg, KeyTraitsArg>::WeakGCMap(VM& vm) 36 : m_vm(vm) 37 { 38 vm.heap.registerWeakGCMap(this, [this]() { 39 pruneStaleEntries(); 40 }); 36 41 } 37 42 38 typedef void (*JSWeakMapDestroyedCallback)(struct OpaqueJSWeakObjectMap*, void*); 43 template<typename KeyArg, typename ValueArg, typename HashArg, typename KeyTraitsArg> 44 inline WeakGCMap<KeyArg, ValueArg, HashArg, KeyTraitsArg>::~WeakGCMap() 45 { 46 m_vm.heap.unregisterWeakGCMap(this); 47 } 39 48 40 typedef JSC::WeakGCMap<void*, JSC::JSObject> WeakMapType; 49 template<typename KeyArg, typename ValueArg, typename HashArg, typename KeyTraitsArg> 50 NEVER_INLINE void WeakGCMap<KeyArg, ValueArg, HashArg, KeyTraitsArg>::pruneStaleEntries() 51 { 52 m_map.removeIf([](typename HashMapType::KeyValuePairType& entry) { 53 return !entry.value; 54 }); 55 } 41 56 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 48 58 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 39 39 #include "PageConsoleClient.h" 40 40 #include "PageGroup.h" 41 #include "ScriptController.h" 41 42 #include <heap/StrongInlines.h> 42 43 #include <profiler/Profile.h> 43 44 #include <runtime/JSLock.h> 44 #include "ScriptController.h"45 #include <runtime/WeakGCMapInlines.h> 45 46 46 47 using namespace JSC;
Note: See TracChangeset
for help on using the changeset viewer.