Commit 5dca3c2b authored by ggaren@apple.com's avatar ggaren@apple.com

2009-04-21 Geoffrey Garen <ggaren@apple.com>

        Reviewed by Cameron Zwarich and Oliver Hunt.
        
        Re-Fixed <rdar://problem/6406045> REGRESSION: Stack overflow on PowerPC on
        fast/workers/use-machine-stack.html (22531)
        
        SunSpider reports no change.
        
        Use a larger recursion limit on the main thread (because we can, and
        there's some evidence that it may improve compatibility), and a smaller
        recursion limit on secondary threads (because they tend to have smaller
        stacks).

        * interpreter/Interpreter.cpp:
        (JSC::Interpreter::execute):
        (JSC::Interpreter::prepareForRepeatCall):
        * interpreter/Interpreter.h:
        (JSC::): Ditto. I wrote the recursion test slightly funny, so that the
        common case remains a simple compare to constant.

        * runtime/ArrayPrototype.cpp:
        (JSC::arrayProtoFuncToString):
        (JSC::arrayProtoFuncToLocaleString):
        (JSC::arrayProtoFuncJoin): Conservatively, set the array recursion limits
        to the lower, secondary thread limit. We can do something fancier if
        compatibility moves us, but this seems sufficient for now.



git-svn-id: svn://svn.chromium.org/blink/trunk@42734 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 27408f3f
2009-04-21 Geoffrey Garen <ggaren@apple.com>
Reviewed by Cameron Zwarich and Oliver Hunt.
Re-Fixed <rdar://problem/6406045> REGRESSION: Stack overflow on PowerPC on
fast/workers/use-machine-stack.html (22531)
SunSpider reports no change.
Use a larger recursion limit on the main thread (because we can, and
there's some evidence that it may improve compatibility), and a smaller
recursion limit on secondary threads (because they tend to have smaller
stacks).
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
(JSC::Interpreter::prepareForRepeatCall):
* interpreter/Interpreter.h:
(JSC::): Ditto. I wrote the recursion test slightly funny, so that the
common case remains a simple compare to constant.
* runtime/ArrayPrototype.cpp:
(JSC::arrayProtoFuncToString):
(JSC::arrayProtoFuncToLocaleString):
(JSC::arrayProtoFuncJoin): Conservatively, set the array recursion limits
to the lower, secondary thread limit. We can do something fancier if
compatibility moves us, but this seems sufficient for now.
2009-04-21 Geoffrey Garen <ggaren@apple.com> 2009-04-21 Geoffrey Garen <ggaren@apple.com>
Rubber-stamped by Adam Roben. Rubber-stamped by Adam Roben.
...@@ -32,12 +32,14 @@ ...@@ -32,12 +32,14 @@
#include "Arguments.h" #include "Arguments.h"
#include "BatchedTransitionOptimizer.h" #include "BatchedTransitionOptimizer.h"
#include "CallFrame.h"
#include "CallFrameClosure.h" #include "CallFrameClosure.h"
#include "CodeBlock.h" #include "CodeBlock.h"
#include "Collector.h"
#include "Debugger.h"
#include "DebuggerCallFrame.h" #include "DebuggerCallFrame.h"
#include "EvalCodeCache.h" #include "EvalCodeCache.h"
#include "ExceptionHelpers.h" #include "ExceptionHelpers.h"
#include "CallFrame.h"
#include "GlobalEvalFunction.h" #include "GlobalEvalFunction.h"
#include "JSActivation.h" #include "JSActivation.h"
#include "JSArray.h" #include "JSArray.h"
...@@ -48,16 +50,15 @@ ...@@ -48,16 +50,15 @@
#include "JSStaticScopeObject.h" #include "JSStaticScopeObject.h"
#include "JSString.h" #include "JSString.h"
#include "ObjectPrototype.h" #include "ObjectPrototype.h"
#include "Operations.h"
#include "Parser.h" #include "Parser.h"
#include "Profiler.h" #include "Profiler.h"
#include "RegExpObject.h" #include "RegExpObject.h"
#include "RegExpPrototype.h" #include "RegExpPrototype.h"
#include "Register.h" #include "Register.h"
#include "Collector.h"
#include "Debugger.h"
#include "Operations.h"
#include "SamplingTool.h" #include "SamplingTool.h"
#include <stdio.h> #include <stdio.h>
#include <wtf/Threading.h>
#if ENABLE(JIT) #if ENABLE(JIT)
#include "JIT.h" #include "JIT.h"
...@@ -582,9 +583,11 @@ JSValuePtr Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, ...@@ -582,9 +583,11 @@ JSValuePtr Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame,
{ {
ASSERT(!scopeChain->globalData->exception); ASSERT(!scopeChain->globalData->exception);
if (m_reentryDepth >= MaxReentryDepth) { if (m_reentryDepth >= MaxSecondaryThreadReentryDepth) {
*exception = createStackOverflowError(callFrame); if (!isMainThread() || m_reentryDepth >= MaxMainThreadReentryDepth) {
return jsNull(); *exception = createStackOverflowError(callFrame);
return jsNull();
}
} }
CodeBlock* codeBlock = &programNode->bytecode(scopeChain); CodeBlock* codeBlock = &programNode->bytecode(scopeChain);
...@@ -643,9 +646,11 @@ JSValuePtr Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* c ...@@ -643,9 +646,11 @@ JSValuePtr Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* c
{ {
ASSERT(!scopeChain->globalData->exception); ASSERT(!scopeChain->globalData->exception);
if (m_reentryDepth >= MaxReentryDepth) { if (m_reentryDepth >= MaxSecondaryThreadReentryDepth) {
*exception = createStackOverflowError(callFrame); if (!isMainThread() || m_reentryDepth >= MaxMainThreadReentryDepth) {
return jsNull(); *exception = createStackOverflowError(callFrame);
return jsNull();
}
} }
Register* oldEnd = m_registerFile.end(); Register* oldEnd = m_registerFile.end();
...@@ -705,9 +710,11 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionBodyNode* functionBod ...@@ -705,9 +710,11 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionBodyNode* functionBod
{ {
ASSERT(!scopeChain->globalData->exception); ASSERT(!scopeChain->globalData->exception);
if (m_reentryDepth >= MaxReentryDepth) { if (m_reentryDepth >= MaxSecondaryThreadReentryDepth) {
*exception = createStackOverflowError(callFrame); if (!isMainThread() || m_reentryDepth >= MaxMainThreadReentryDepth) {
return CallFrameClosure(); *exception = createStackOverflowError(callFrame);
return CallFrameClosure();
}
} }
Register* oldEnd = m_registerFile.end(); Register* oldEnd = m_registerFile.end();
...@@ -780,9 +787,11 @@ JSValuePtr Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObje ...@@ -780,9 +787,11 @@ JSValuePtr Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObje
{ {
ASSERT(!scopeChain->globalData->exception); ASSERT(!scopeChain->globalData->exception);
if (m_reentryDepth >= MaxReentryDepth) { if (m_reentryDepth >= MaxSecondaryThreadReentryDepth) {
*exception = createStackOverflowError(callFrame); if (!isMainThread() || m_reentryDepth >= MaxMainThreadReentryDepth) {
return jsNull(); *exception = createStackOverflowError(callFrame);
return jsNull();
}
} }
DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain->globalObject()); DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain->globalObject());
......
...@@ -63,7 +63,7 @@ namespace JSC { ...@@ -63,7 +63,7 @@ namespace JSC {
WillExecuteStatement WillExecuteStatement
}; };
enum { MaxReentryDepth = 64 }; enum { MaxMainThreadReentryDepth = 256, MaxSecondaryThreadReentryDepth = 32 };
class Interpreter { class Interpreter {
friend class JIT; friend class JIT;
......
...@@ -148,7 +148,7 @@ JSValuePtr arrayProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisVal ...@@ -148,7 +148,7 @@ JSValuePtr arrayProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisVal
JSObject* thisObj = asArray(thisValue); JSObject* thisObj = asArray(thisValue);
HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements; HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
if (arrayVisitedElements.size() > MaxReentryDepth) if (arrayVisitedElements.size() > MaxSecondaryThreadReentryDepth)
return throwError(exec, RangeError, "Maximum call stack size exceeded."); return throwError(exec, RangeError, "Maximum call stack size exceeded.");
bool alreadyVisited = !arrayVisitedElements.add(thisObj).second; bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
...@@ -192,7 +192,7 @@ JSValuePtr arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr t ...@@ -192,7 +192,7 @@ JSValuePtr arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr t
JSObject* thisObj = asArray(thisValue); JSObject* thisObj = asArray(thisValue);
HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements; HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
if (arrayVisitedElements.size() > MaxReentryDepth) if (arrayVisitedElements.size() > MaxSecondaryThreadReentryDepth)
return throwError(exec, RangeError, "Maximum call stack size exceeded."); return throwError(exec, RangeError, "Maximum call stack size exceeded.");
bool alreadyVisited = !arrayVisitedElements.add(thisObj).second; bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
...@@ -242,7 +242,7 @@ JSValuePtr arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValuePtr thisValue, ...@@ -242,7 +242,7 @@ JSValuePtr arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValuePtr thisValue,
JSObject* thisObj = thisValue.toThisObject(exec); JSObject* thisObj = thisValue.toThisObject(exec);
HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements; HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
if (arrayVisitedElements.size() > MaxReentryDepth) if (arrayVisitedElements.size() > MaxSecondaryThreadReentryDepth)
return throwError(exec, RangeError, "Maximum call stack size exceeded."); return throwError(exec, RangeError, "Maximum call stack size exceeded.");
bool alreadyVisited = !arrayVisitedElements.add(thisObj).second; bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment