[SCM] WebKit Debian packaging branch, debian/experimental, updated. debian/1.3.8-1-142-g786665c
barraclough at apple.com
barraclough at apple.com
Mon Dec 27 16:29:04 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit bd837624dd3e57455e4b2cbf0ba30c2a89ed9ded
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Wed Dec 22 04:18:58 2010 +0000
Reviewed by Geoff Garen.
<rdar://problem/8765333> CRASH running out of executable memory, loading io9.com
https://bugs.webkit.org/show_bug.cgi?id=51443
The problem here is that each page uses a reasonable amount of memory, (~4Mb),
and that when miultiple pages are open we keep all JIT code for all functions
in all pages alive.
Add a check to detect high memory pressure situations in the executable allocator
(>50% of available memory allocated), and upon a top level entry into JSC (no code
running on the stack) in this situation throw away all JIT code.
* JavaScriptCore.exp:
* debugger/Debugger.cpp:
(JSC::Debugger::recompileAllJSFunctions): stop passing exec to recompile.
* jit/ExecutableAllocator.h:
* jit/ExecutableAllocatorFixedVMPool.cpp:
(JSC::ExecutablePool::systemAlloc): Count allocations.
(JSC::ExecutablePool::systemRelease): Count deallocations.
(JSC::ExecutablePool::underMemoryPressure): Check memory pressure.
* jit/ExecutableAllocatorPosix.cpp:
(JSC::ExecutablePool::underMemoryPressure): Stub out; only meaningful with FixedVMPool.
* jit/ExecutableAllocatorWin.cpp:
(JSC::ExecutablePool::underMemoryPressure): Stub out; only meaningful with FixedVMPool.
* runtime/Executable.cpp:
(JSC::FunctionExecutable::recompile): Remove ExecState argument to recompile.
* runtime/Executable.h:
* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::recompileAllJSFunctions): throws away all JIT code.
* runtime/JSGlobalData.h:
* runtime/JSGlobalObject.h:
(JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope): add check / call to throw away.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@74454 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 0bf8863..eb25e7d 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,5 +1,41 @@
2010-12-21 Gavin Barraclough <barraclough at apple.com>
+ Reviewed by Geoff Garen.
+
+ <rdar://problem/8765333> CRASH running out of executable memory, loading io9.com
+ https://bugs.webkit.org/show_bug.cgi?id=51443
+
+ The problem here is that each page uses a reasonable amount of memory, (~4Mb),
+ and that when miultiple pages are open we keep all JIT code for all functions
+ in all pages alive.
+
+ Add a check to detect high memory pressure situations in the executable allocator
+ (>50% of available memory allocated), and upon a top level entry into JSC (no code
+ running on the stack) in this situation throw away all JIT code.
+
+ * JavaScriptCore.exp:
+ * debugger/Debugger.cpp:
+ (JSC::Debugger::recompileAllJSFunctions): stop passing exec to recompile.
+ * jit/ExecutableAllocator.h:
+ * jit/ExecutableAllocatorFixedVMPool.cpp:
+ (JSC::ExecutablePool::systemAlloc): Count allocations.
+ (JSC::ExecutablePool::systemRelease): Count deallocations.
+ (JSC::ExecutablePool::underMemoryPressure): Check memory pressure.
+ * jit/ExecutableAllocatorPosix.cpp:
+ (JSC::ExecutablePool::underMemoryPressure): Stub out; only meaningful with FixedVMPool.
+ * jit/ExecutableAllocatorWin.cpp:
+ (JSC::ExecutablePool::underMemoryPressure): Stub out; only meaningful with FixedVMPool.
+ * runtime/Executable.cpp:
+ (JSC::FunctionExecutable::recompile): Remove ExecState argument to recompile.
+ * runtime/Executable.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::recompileAllJSFunctions): throws away all JIT code.
+ * runtime/JSGlobalData.h:
+ * runtime/JSGlobalObject.h:
+ (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope): add check / call to throw away.
+
+2010-12-21 Gavin Barraclough <barraclough at apple.com>
+
Reviewed by Geoff Garen.
<rdar://problem/8241425> JIT executable memory excessive usage due to regex caching
diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp
index a8ee65b..2e999ef 100644
--- a/JavaScriptCore/JavaScriptCore.exp
+++ b/JavaScriptCore/JavaScriptCore.exp
@@ -200,6 +200,7 @@ __ZN3JSC22globalMemoryStatisticsEv
__ZN3JSC23AbstractSamplingCounter4dumpEv
__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateE
__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC24DynamicGlobalObjectScopeC1EPNS_9ExecStateEPNS_14JSGlobalObjectE
__ZN3JSC24JSObjectWithGlobalObjectC2EPNS_14JSGlobalObjectEN3WTF17NonNullPassRefPtrINS_9StructureEEE
__ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE
__ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE
diff --git a/JavaScriptCore/debugger/Debugger.cpp b/JavaScriptCore/debugger/Debugger.cpp
index 472a03a..6b24c5a 100644
--- a/JavaScriptCore/debugger/Debugger.cpp
+++ b/JavaScriptCore/debugger/Debugger.cpp
@@ -85,7 +85,7 @@ void Debugger::recompileAllJSFunctions(JSGlobalData* globalData)
continue;
ExecState* exec = function->scope().globalObject()->JSGlobalObject::globalExec();
- executable->recompile(exec);
+ executable->discardCode();
if (function->scope().globalObject()->debugger() == this)
sourceProviders.add(executable->source().provider(), exec);
}
diff --git a/JavaScriptCore/jit/ExecutableAllocator.cpp b/JavaScriptCore/jit/ExecutableAllocator.cpp
index 4ebc8b3..8d4036a 100644
--- a/JavaScriptCore/jit/ExecutableAllocator.cpp
+++ b/JavaScriptCore/jit/ExecutableAllocator.cpp
@@ -67,6 +67,11 @@ bool ExecutableAllocator::isValid() const
return true;
}
+bool ExecutableAllocator::underMemoryPressure() const
+{
+ return false;
+}
+
size_t ExecutableAllocator::committedByteCount()
{
return 0;
diff --git a/JavaScriptCore/jit/ExecutableAllocator.h b/JavaScriptCore/jit/ExecutableAllocator.h
index b6debe4..4580a67 100644
--- a/JavaScriptCore/jit/ExecutableAllocator.h
+++ b/JavaScriptCore/jit/ExecutableAllocator.h
@@ -184,7 +184,9 @@ public:
}
bool isValid() const;
-
+
+ static bool underMemoryPressure();
+
PassRefPtr<ExecutablePool> poolForSize(size_t n)
{
// Try to fit in the existing small allocator
diff --git a/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp b/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
index b79df77..e280b2d 100644
--- a/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
+++ b/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
@@ -431,7 +431,8 @@ void ExecutableAllocator::intializePageSize()
}
static FixedVMPoolAllocator* allocator = 0;
-
+static size_t allocatedCount = 0;
+
bool ExecutableAllocator::isValid() const
{
SpinLockHolder lock_holder(&spinlock);
@@ -440,10 +441,18 @@ bool ExecutableAllocator::isValid() const
return allocator->isValid();
}
+bool ExecutableAllocator::underMemoryPressure()
+{
+ // Technically we should take the spin lock here, but we don't care if we get stale data.
+ // This is only really a heuristic anyway.
+ return allocatedCount > (VM_POOL_SIZE / 2);
+}
+
ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t size)
{
SpinLockHolder lock_holder(&spinlock);
ASSERT(allocator);
+ allocatedCount += size;
return allocator->alloc(size);
}
@@ -451,6 +460,7 @@ void ExecutablePool::systemRelease(ExecutablePool::Allocation& allocation)
{
SpinLockHolder lock_holder(&spinlock);
ASSERT(allocator);
+ allocatedCount -= allocation.size();
allocator->free(allocation);
}
diff --git a/JavaScriptCore/runtime/Executable.cpp b/JavaScriptCore/runtime/Executable.cpp
index f229f96..c7262be 100644
--- a/JavaScriptCore/runtime/Executable.cpp
+++ b/JavaScriptCore/runtime/Executable.cpp
@@ -264,7 +264,7 @@ void FunctionExecutable::markAggregate(MarkStack& markStack)
m_codeBlockForConstruct->markAggregate(markStack);
}
-void FunctionExecutable::recompile(ExecState*)
+void FunctionExecutable::discardCode()
{
m_codeBlockForCall.clear();
m_codeBlockForConstruct.clear();
diff --git a/JavaScriptCore/runtime/Executable.h b/JavaScriptCore/runtime/Executable.h
index 14ed927..544e487 100644
--- a/JavaScriptCore/runtime/Executable.h
+++ b/JavaScriptCore/runtime/Executable.h
@@ -348,7 +348,7 @@ namespace JSC {
UString paramString() const;
SharedSymbolTable* symbolTable() const { return m_symbolTable; }
- void recompile(ExecState*);
+ void discardCode();
void markAggregate(MarkStack&);
static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp
index 6f1de3b..aca995a 100644
--- a/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -31,6 +31,7 @@
#include "ArgList.h"
#include "Collector.h"
+#include "CollectorHeapIterator.h"
#include "CommonIdentifiers.h"
#include "FunctionConstructor.h"
#include "GetterSetter.h"
@@ -311,6 +312,22 @@ void JSGlobalData::dumpSampleData(ExecState* exec)
interpreter->dumpSampleData(exec);
}
+void JSGlobalData::recompileAllJSFunctions()
+{
+ // If JavaScript is running, it's not safe to recompile, since we'll end
+ // up throwing away code that is live on the stack.
+ ASSERT(!dynamicGlobalObject);
+
+ LiveObjectIterator it = heap.primaryHeapBegin();
+ LiveObjectIterator heapEnd = heap.primaryHeapEnd();
+ for ( ; it != heapEnd; ++it) {
+ if ((*it)->inherits(&JSFunction::info)) {
+ JSFunction* function = asFunction(*it);
+ if (!function->executable()->isHostFunction())
+ function->jsExecutable()->discardCode();
+ }
+ }
+}
#if ENABLE(REGEXP_TRACING)
void JSGlobalData::addRegExpToTrace(PassRefPtr<RegExp> regExp)
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index 1dad920..699f975 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -248,6 +248,7 @@ namespace JSC {
void startSampling();
void stopSampling();
void dumpSampleData(ExecState* exec);
+ void recompileAllJSFunctions();
RegExpCache* regExpCache() { return m_regExpCache; }
#if ENABLE(REGEXP_TRACING)
void addRegExpToTrace(PassRefPtr<RegExp> regExp);
diff --git a/JavaScriptCore/runtime/JSGlobalObject.cpp b/JavaScriptCore/runtime/JSGlobalObject.cpp
index a8fb7bf..408aea7 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -455,4 +455,22 @@ void JSGlobalObject::destroyJSGlobalObjectData(void* jsGlobalObjectData)
delete static_cast<JSGlobalObjectData*>(jsGlobalObjectData);
}
+DynamicGlobalObjectScope::DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject)
+ : m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject)
+ , m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot)
+{
+ if (!m_dynamicGlobalObjectSlot) {
+#if ENABLE(ASSEMBLER)
+ if (ExecutableAllocator::underMemoryPressure())
+ callFrame->globalData().recompileAllJSFunctions();
+#endif
+
+ m_dynamicGlobalObjectSlot = dynamicGlobalObject;
+
+ // Reset the date cache between JS invocations to force the VM
+ // to observe time zone changes.
+ callFrame->globalData().resetDateCache();
+ }
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h
index 714999f..a22b0aa 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/JavaScriptCore/runtime/JSGlobalObject.h
@@ -467,18 +467,7 @@ namespace JSC {
class DynamicGlobalObjectScope : public Noncopyable {
public:
- DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject)
- : m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject)
- , m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot)
- {
- if (!m_dynamicGlobalObjectSlot) {
- m_dynamicGlobalObjectSlot = dynamicGlobalObject;
-
- // Reset the date cache between JS invocations to force the VM
- // to observe time zone changes.
- callFrame->globalData().resetDateCache();
- }
- }
+ DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject);
~DynamicGlobalObjectScope()
{
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list