Changeset 74454 in webkit
- Timestamp:
- Dec 21, 2010 8:18:58 PM (13 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r74441 r74454 1 2010-12-21 Gavin Barraclough <barraclough@apple.com> 2 3 Reviewed by Geoff Garen. 4 5 <rdar://problem/8765333> CRASH running out of executable memory, loading io9.com 6 https://bugs.webkit.org/show_bug.cgi?id=51443 7 8 The problem here is that each page uses a reasonable amount of memory, (~4Mb), 9 and that when miultiple pages are open we keep all JIT code for all functions 10 in all pages alive. 11 12 Add a check to detect high memory pressure situations in the executable allocator 13 (>50% of available memory allocated), and upon a top level entry into JSC (no code 14 running on the stack) in this situation throw away all JIT code. 15 16 * JavaScriptCore.exp: 17 * debugger/Debugger.cpp: 18 (JSC::Debugger::recompileAllJSFunctions): stop passing exec to recompile. 19 * jit/ExecutableAllocator.h: 20 * jit/ExecutableAllocatorFixedVMPool.cpp: 21 (JSC::ExecutablePool::systemAlloc): Count allocations. 22 (JSC::ExecutablePool::systemRelease): Count deallocations. 23 (JSC::ExecutablePool::underMemoryPressure): Check memory pressure. 24 * jit/ExecutableAllocatorPosix.cpp: 25 (JSC::ExecutablePool::underMemoryPressure): Stub out; only meaningful with FixedVMPool. 26 * jit/ExecutableAllocatorWin.cpp: 27 (JSC::ExecutablePool::underMemoryPressure): Stub out; only meaningful with FixedVMPool. 28 * runtime/Executable.cpp: 29 (JSC::FunctionExecutable::recompile): Remove ExecState argument to recompile. 30 * runtime/Executable.h: 31 * runtime/JSGlobalData.cpp: 32 (JSC::JSGlobalData::recompileAllJSFunctions): throws away all JIT code. 33 * runtime/JSGlobalData.h: 34 * runtime/JSGlobalObject.h: 35 (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope): add check / call to throw away. 36 1 37 2010-12-21 Gavin Barraclough <barraclough@apple.com> 2 38 -
trunk/JavaScriptCore/JavaScriptCore.exp
r74431 r74454 201 201 __ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateE 202 202 __ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE 203 __ZN3JSC24DynamicGlobalObjectScopeC1EPNS_9ExecStateEPNS_14JSGlobalObjectE 203 204 __ZN3JSC24JSObjectWithGlobalObjectC2EPNS_14JSGlobalObjectEN3WTF17NonNullPassRefPtrINS_9StructureEEE 204 205 __ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE -
trunk/JavaScriptCore/debugger/Debugger.cpp
r70703 r74454 86 86 87 87 ExecState* exec = function->scope().globalObject()->JSGlobalObject::globalExec(); 88 executable-> recompile(exec);88 executable->discardCode(); 89 89 if (function->scope().globalObject()->debugger() == this) 90 90 sourceProviders.add(executable->source().provider(), exec); -
trunk/JavaScriptCore/jit/ExecutableAllocator.cpp
r74357 r74454 68 68 } 69 69 70 bool ExecutableAllocator::underMemoryPressure() const 71 { 72 return false; 73 } 74 70 75 size_t ExecutableAllocator::committedByteCount() 71 76 { -
trunk/JavaScriptCore/jit/ExecutableAllocator.h
r74210 r74454 185 185 186 186 bool isValid() const; 187 187 188 static bool underMemoryPressure(); 189 188 190 PassRefPtr<ExecutablePool> poolForSize(size_t n) 189 191 { -
trunk/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
r73570 r74454 432 432 433 433 static FixedVMPoolAllocator* allocator = 0; 434 434 static size_t allocatedCount = 0; 435 435 436 bool ExecutableAllocator::isValid() const 436 437 { … … 441 442 } 442 443 444 bool ExecutableAllocator::underMemoryPressure() 445 { 446 // Technically we should take the spin lock here, but we don't care if we get stale data. 447 // This is only really a heuristic anyway. 448 return allocatedCount > (VM_POOL_SIZE / 2); 449 } 450 443 451 ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t size) 444 452 { 445 453 SpinLockHolder lock_holder(&spinlock); 446 454 ASSERT(allocator); 455 allocatedCount += size; 447 456 return allocator->alloc(size); 448 457 } … … 452 461 SpinLockHolder lock_holder(&spinlock); 453 462 ASSERT(allocator); 463 allocatedCount -= allocation.size(); 454 464 allocator->free(allocation); 455 465 } -
trunk/JavaScriptCore/runtime/Executable.cpp
r72360 r74454 265 265 } 266 266 267 void FunctionExecutable:: recompile(ExecState*)267 void FunctionExecutable::discardCode() 268 268 { 269 269 m_codeBlockForCall.clear(); -
trunk/JavaScriptCore/runtime/Executable.h
r72360 r74454 349 349 SharedSymbolTable* symbolTable() const { return m_symbolTable; } 350 350 351 void recompile(ExecState*);351 void discardCode(); 352 352 void markAggregate(MarkStack&); 353 353 static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception); -
trunk/JavaScriptCore/runtime/JSGlobalData.cpp
r74360 r74454 32 32 #include "ArgList.h" 33 33 #include "Collector.h" 34 #include "CollectorHeapIterator.h" 34 35 #include "CommonIdentifiers.h" 35 36 #include "FunctionConstructor.h" … … 312 313 } 313 314 315 void JSGlobalData::recompileAllJSFunctions() 316 { 317 // If JavaScript is running, it's not safe to recompile, since we'll end 318 // up throwing away code that is live on the stack. 319 ASSERT(!dynamicGlobalObject); 320 321 LiveObjectIterator it = heap.primaryHeapBegin(); 322 LiveObjectIterator heapEnd = heap.primaryHeapEnd(); 323 for ( ; it != heapEnd; ++it) { 324 if ((*it)->inherits(&JSFunction::info)) { 325 JSFunction* function = asFunction(*it); 326 if (!function->executable()->isHostFunction()) 327 function->jsExecutable()->discardCode(); 328 } 329 } 330 } 314 331 315 332 #if ENABLE(REGEXP_TRACING) -
trunk/JavaScriptCore/runtime/JSGlobalData.h
r74441 r74454 249 249 void stopSampling(); 250 250 void dumpSampleData(ExecState* exec); 251 void recompileAllJSFunctions(); 251 252 RegExpCache* regExpCache() { return m_regExpCache; } 252 253 #if ENABLE(REGEXP_TRACING) -
trunk/JavaScriptCore/runtime/JSGlobalObject.cpp
r70496 r74454 456 456 } 457 457 458 DynamicGlobalObjectScope::DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject) 459 : m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject) 460 , m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot) 461 { 462 if (!m_dynamicGlobalObjectSlot) { 463 #if ENABLE(ASSEMBLER) 464 if (ExecutableAllocator::underMemoryPressure()) 465 callFrame->globalData().recompileAllJSFunctions(); 466 #endif 467 468 m_dynamicGlobalObjectSlot = dynamicGlobalObject; 469 470 // Reset the date cache between JS invocations to force the VM 471 // to observe time zone changes. 472 callFrame->globalData().resetDateCache(); 473 } 474 } 475 458 476 } // namespace JSC -
trunk/JavaScriptCore/runtime/JSGlobalObject.h
r72360 r74454 468 468 class DynamicGlobalObjectScope : public Noncopyable { 469 469 public: 470 DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject) 471 : m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject) 472 , m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot) 473 { 474 if (!m_dynamicGlobalObjectSlot) { 475 m_dynamicGlobalObjectSlot = dynamicGlobalObject; 476 477 // Reset the date cache between JS invocations to force the VM 478 // to observe time zone changes. 479 callFrame->globalData().resetDateCache(); 480 } 481 } 470 DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject); 482 471 483 472 ~DynamicGlobalObjectScope()
Note: See TracChangeset
for help on using the changeset viewer.