Changeset 234646 in webkit
- Timestamp:
- Aug 7, 2018 3:01:18 AM (6 years ago)
- Location:
- trunk/Source/WTF
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WTF/ChangeLog
r234619 r234646 1 2018-08-07 Antti Koivisto <antti@apple.com> 2 3 Web process never leaves memory pressured state if caused by process size limit 4 https://bugs.webkit.org/show_bug.cgi?id=188299 5 <rdar://problem/42157442> 6 7 Reviewed by Darin Adler. 8 9 For vm memory pressure warnings we get notified when exiting the state and we can clear 10 the isUnderMemoryPressure bit. However as a compatibility behavior we were also notified using 11 the same event when approaching the process size limit. In this case there is no "all clear" 12 event so we'd stay in pressured state forever, leading to unnecessarily degraded user experience. 13 14 * WTF.xcodeproj/project.pbxproj: 15 * wtf/cocoa/MemoryPressureHandlerCocoa.mm: 16 (WTF::MemoryPressureHandler::install): 17 18 Install a handler for process size limit events. This disables the compatibility behavior, 19 vm pressure events will be received for vm pressure only. 20 21 Process size limit events are treated as one-shot. We do cleanups based on criticality but 22 don't enter the pressured state. 23 24 (WTF::MemoryPressureHandler::uninstall): 25 (WTF::MemoryPressureHandler::holdOff): 26 * wtf/spi/darwin/DispatchSPI.h: Added. 27 1 28 2018-08-06 Alex Christensen <achristensen@webkit.org> 2 29 -
trunk/Source/WTF/WTF.xcodeproj/project.pbxproj
r233409 r234646 633 633 E3A32BC31FC830E2007D7E76 /* JSValueMalloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSValueMalloc.h; sourceTree = "<group>"; }; 634 634 E3E158251EADA53C004A079D /* SystemFree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SystemFree.h; sourceTree = "<group>"; }; 635 E431CC4A21187ADB000C8A07 /* DispatchSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DispatchSPI.h; sourceTree = "<group>"; }; 635 636 E4A0AD371A96245500536DF6 /* WorkQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkQueue.cpp; sourceTree = "<group>"; }; 636 637 E4A0AD381A96245500536DF6 /* WorkQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkQueue.h; sourceTree = "<group>"; }; … … 1288 1289 children = ( 1289 1290 DE5A09FB1BA36992003D4424 /* CommonCryptoSPI.h */, 1291 E431CC4A21187ADB000C8A07 /* DispatchSPI.h */, 1290 1292 93DDE9311CDC052D00FD3491 /* dyldSPI.h */, 1291 1293 A5098AFF1C169E0700087797 /* SandboxSPI.h */, -
trunk/Source/WTF/wtf/cocoa/MemoryPressureHandlerCocoa.mm
r233128 r234646 31 31 #import <malloc/malloc.h> 32 32 #import <notify.h> 33 #import <wtf/spi/darwin/DispatchSPI.h> 33 34 34 35 #define ENABLE_FMW_FOOTPRINT_COMPARISON 0 … … 47 48 } 48 49 49 static dispatch_source_t _cache_event_source = 0;50 static dispatch_source_t _timer_event_source = 0;51 static int _notifyTokens[3];50 static dispatch_source_t memoryPressureEventSource = nullptr; 51 static dispatch_source_t timerEventSource = nullptr; 52 static int notifyTokens[3]; 52 53 53 54 // Disable memory event reception for a minimum of s_minimumHoldOffTime … … 64 65 void MemoryPressureHandler::install() 65 66 { 66 if (m_installed || _timer_event_source)67 if (m_installed || timerEventSource) 67 68 return; 68 69 69 70 dispatch_async(dispatch_get_main_queue(), ^{ 70 71 #if PLATFORM(IOS) 71 _cache_event_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, DISPATCH_MEMORYPRESSURE_NORMAL | DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL, dispatch_get_main_queue());72 #el ifPLATFORM(MAC)73 _cache_event_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, DISPATCH_MEMORYPRESSURE_CRITICAL, dispatch_get_main_queue());74 #endif 75 76 dispatch_set_context(_cache_event_source, this); 77 dispatch_source_set_event_handler( _cache_event_source, ^{78 bool critical = true;72 auto memoryStatusFlags = DISPATCH_MEMORYPRESSURE_NORMAL | DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL | DISPATCH_MEMORYPRESSURE_PROC_LIMIT_WARN | DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL; 73 #else // PLATFORM(MAC) 74 auto memoryStatusFlags = DISPATCH_MEMORYPRESSURE_CRITICAL; 75 #endif 76 memoryPressureEventSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, memoryStatusFlags, dispatch_get_main_queue()); 77 78 dispatch_source_set_event_handler(memoryPressureEventSource, ^{ 79 auto status = dispatch_source_get_data(memoryPressureEventSource); 79 80 #if PLATFORM(IOS) 80 unsigned long status = dispatch_source_get_data(_cache_event_source); 81 critical = status == DISPATCH_MEMORYPRESSURE_CRITICAL; 82 auto& memoryPressureHandler = MemoryPressureHandler::singleton(); 83 bool wasCritical = memoryPressureHandler.isUnderMemoryPressure(); 84 memoryPressureHandler.setUnderMemoryPressure(critical); 85 if (status == DISPATCH_MEMORYPRESSURE_NORMAL) { 86 if (ReliefLogger::loggingEnabled()) 87 NSLog(@"System is no longer under (%s) memory pressure.", wasCritical ? "critical" : "non-critical"); 88 return; 81 switch (status) { 82 // VM pressure events. 83 case DISPATCH_MEMORYPRESSURE_NORMAL: 84 setUnderMemoryPressure(false); 85 break; 86 case DISPATCH_MEMORYPRESSURE_WARN: 87 setUnderMemoryPressure(false); 88 respondToMemoryPressure(Critical::No); 89 break; 90 case DISPATCH_MEMORYPRESSURE_CRITICAL: 91 setUnderMemoryPressure(true); 92 respondToMemoryPressure(Critical::Yes); 93 break; 94 // Process memory limit events. 95 case DISPATCH_MEMORYPRESSURE_PROC_LIMIT_WARN: 96 respondToMemoryPressure(Critical::No); 97 break; 98 case DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL: 99 respondToMemoryPressure(Critical::Yes); 100 break; 89 101 } 90 91 if (ReliefLogger::loggingEnabled()) 92 NSLog(@"Got memory pressure notification (%s)", critical ? "critical" : "non-critical"); 93 #endif 94 MemoryPressureHandler::singleton().respondToMemoryPressure(critical ? Critical::Yes : Critical::No); 102 #else // PLATFORM(MAC) 103 respondToMemoryPressure(Critical::Yes); 104 #endif 105 WTFLogAlways("Received memory pressure event %lu vm pressure %d", status, isUnderMemoryPressure()); 95 106 }); 96 dispatch_resume( _cache_event_source);107 dispatch_resume(memoryPressureEventSource); 97 108 }); 98 109 99 110 // Allow simulation of memory pressure with "notifyutil -p org.WebKit.lowMemory" 100 notify_register_dispatch("org.WebKit.lowMemory", & _notifyTokens[0], dispatch_get_main_queue(), ^(int) {111 notify_register_dispatch("org.WebKit.lowMemory", ¬ifyTokens[0], dispatch_get_main_queue(), ^(int) { 101 112 #if ENABLE(FMW_FOOTPRINT_COMPARISON) 102 113 auto footprintBefore = pagesPerVMTag(); … … 117 128 }); 118 129 119 notify_register_dispatch("org.WebKit.lowMemory.begin", & _notifyTokens[1], dispatch_get_main_queue(), ^(int) {130 notify_register_dispatch("org.WebKit.lowMemory.begin", ¬ifyTokens[1], dispatch_get_main_queue(), ^(int) { 120 131 beginSimulatedMemoryPressure(); 121 132 }); 122 notify_register_dispatch("org.WebKit.lowMemory.end", & _notifyTokens[2], dispatch_get_main_queue(), ^(int) {133 notify_register_dispatch("org.WebKit.lowMemory.end", ¬ifyTokens[2], dispatch_get_main_queue(), ^(int) { 123 134 endSimulatedMemoryPressure(); 124 135 }); … … 133 144 134 145 dispatch_async(dispatch_get_main_queue(), ^{ 135 if ( _cache_event_source) {136 dispatch_source_cancel( _cache_event_source);137 _cache_event_source = 0;146 if (memoryPressureEventSource) { 147 dispatch_source_cancel(memoryPressureEventSource); 148 memoryPressureEventSource = nullptr; 138 149 } 139 150 140 if ( _timer_event_source) {141 dispatch_source_cancel( _timer_event_source);142 _timer_event_source = 0;151 if (timerEventSource) { 152 dispatch_source_cancel(timerEventSource); 153 timerEventSource = nullptr; 143 154 } 144 155 }); … … 146 157 m_installed = false; 147 158 148 for (auto& token : _notifyTokens)159 for (auto& token : notifyTokens) 149 160 notify_cancel(token); 150 161 } … … 153 164 { 154 165 dispatch_async(dispatch_get_main_queue(), ^{ 155 _timer_event_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());156 if ( _timer_event_source) {157 dispatch_set_context( _timer_event_source, this);166 timerEventSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); 167 if (timerEventSource) { 168 dispatch_set_context(timerEventSource, this); 158 169 // FIXME: The final argument `s_minimumHoldOffTime.seconds()` seems wrong. 159 170 // https://bugs.webkit.org/show_bug.cgi?id=183277 160 dispatch_source_set_timer( _timer_event_source, dispatch_time(DISPATCH_TIME_NOW, seconds.seconds() * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, s_minimumHoldOffTime.seconds());161 dispatch_source_set_event_handler( _timer_event_source, ^{162 if ( _timer_event_source) {163 dispatch_source_cancel( _timer_event_source);164 _timer_event_source = 0;171 dispatch_source_set_timer(timerEventSource, dispatch_time(DISPATCH_TIME_NOW, seconds.seconds() * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, s_minimumHoldOffTime.seconds()); 172 dispatch_source_set_event_handler(timerEventSource, ^{ 173 if (timerEventSource) { 174 dispatch_source_cancel(timerEventSource); 175 timerEventSource = nullptr; 165 176 } 166 177 MemoryPressureHandler::singleton().install(); 167 178 }); 168 dispatch_resume( _timer_event_source);179 dispatch_resume(timerEventSource); 169 180 } 170 181 });
Note: See TracChangeset
for help on using the changeset viewer.