Diff
Modified: trunk/LayoutTests/ChangeLog (151868 => 151869)
--- trunk/LayoutTests/ChangeLog 2013-06-21 23:39:41 UTC (rev 151868)
+++ trunk/LayoutTests/ChangeLog 2013-06-21 23:58:52 UTC (rev 151869)
@@ -1,3 +1,12 @@
+2013-06-21 Mark Lam <[email protected]>
+
+ Reverting failure expectation for fast/xmlhttprequest/xmlhttprequest-recursive-sync-event.html.
+ https://bugs.webkit.org/show_bug.cgi?id=117862.
+
+ Reviewed by Geoffrey Garen.
+
+ * platform/mac/TestExpectations:
+
2013-06-21 Brent Fulgham <[email protected]>
AX: Title for ListItemRole should consist of concatenated child text elements.
Modified: trunk/LayoutTests/platform/mac/TestExpectations (151868 => 151869)
--- trunk/LayoutTests/platform/mac/TestExpectations 2013-06-21 23:39:41 UTC (rev 151868)
+++ trunk/LayoutTests/platform/mac/TestExpectations 2013-06-21 23:58:52 UTC (rev 151869)
@@ -1336,5 +1336,3 @@
webkit.org/b/116582 [ Debug ] inspector/styles/import-pseudoclass-crash.html [ Pass Crash ]
webkit.org/b/116592 inspector/geolocation-error.html [ Pass Failure ]
-
-webkit.org/b/117862 fast/xmlhttprequest/xmlhttprequest-recursive-sync-event.html [ Failure ]
Modified: trunk/Source/_javascript_Core/ChangeLog (151868 => 151869)
--- trunk/Source/_javascript_Core/ChangeLog 2013-06-21 23:39:41 UTC (rev 151868)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-06-21 23:58:52 UTC (rev 151869)
@@ -1,3 +1,38 @@
+2013-06-21 Mark Lam <[email protected]>
+
+ Introducing the VMStackBounds class.
+ https://bugs.webkit.org/show_bug.cgi?id=117862.
+
+ Reviewed by Geoffrey Garen.
+
+ - Removed Interpreter::StackPolicy.
+ - The new VMStackBounds will take over choosing the appropriate stack
+ size requirements, and invoking the underlying WTF::StackBounds to
+ to the real bounds check.
+ - VMStackBounds will now be used universally throughout JSC instead of
+ WTF::StackBounds.
+
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ * bytecompiler/BytecodeGenerator.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct):
+ (JSC::Interpreter::prepareForRepeatCall):
+ * interpreter/Interpreter.h:
+ (JSC::Interpreter::isInErrorHandlingMode):
+ * parser/Parser.cpp:
+ (JSC::::Parser):
+ * parser/Parser.h:
+ * runtime/StringRecursionChecker.h:
+ (JSC::StringRecursionChecker::performCheck):
+ * runtime/VMStackBounds.h: Added.
+ (JSC::VMStackBounds::VMStackBounds):
+ (JSC::VMStackBounds::isSafeToRecurse):
+ (JSC::VMStackBounds::requiredCapacity):
+
2013-06-20 Mark Lam <[email protected]>
Change stack capacity requirement to be more reasonable.
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (151868 => 151869)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2013-06-21 23:39:41 UTC (rev 151868)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2013-06-21 23:58:52 UTC (rev 151869)
@@ -871,6 +871,7 @@
FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE4A331F15BD2E07006F54F3 /* VMInspector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */; };
FE4A332015BD2E07006F54F3 /* VMInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4A331E15BD2E07006F54F3 /* VMInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ FE6617281774E03500495B00 /* VMStackBounds.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6617271774E03500495B00 /* VMStackBounds.h */; settings = {ATTRIBUTES = (Private, ); }; };
FED287B215EC9A5700DA8161 /* LLIntOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = FED287B115EC9A5700DA8161 /* LLIntOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
FED94F2E171E3E2300BE77A4 /* Watchdog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */; };
FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1817,6 +1818,7 @@
FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntCLoop.h; path = llint/LLIntCLoop.h; sourceTree = "<group>"; };
FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMInspector.cpp; sourceTree = "<group>"; };
FE4A331E15BD2E07006F54F3 /* VMInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMInspector.h; sourceTree = "<group>"; };
+ FE6617271774E03500495B00 /* VMStackBounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMStackBounds.h; sourceTree = "<group>"; };
FED287B115EC9A5700DA8161 /* LLIntOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntOpcode.h; path = llint/LLIntOpcode.h; sourceTree = "<group>"; };
FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Watchdog.cpp; sourceTree = "<group>"; };
FED94F2C171E3E2300BE77A4 /* Watchdog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Watchdog.h; sourceTree = "<group>"; };
@@ -2618,6 +2620,7 @@
5D53726E0E1C54880021E549 /* Tracing.h */,
0FEB3ECB16237F4700AB67AD /* TypedArrayDescriptor.h */,
866739D113BFDE710023D87C /* Uint16WithFraction.h */,
+ FE6617271774E03500495B00 /* VMStackBounds.h */,
FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */,
FED94F2C171E3E2300BE77A4 /* Watchdog.h */,
FED94F2D171E3E2300BE77A4 /* WatchdogMac.cpp */,
@@ -2994,6 +2997,7 @@
BC18C3E70E16F5CD00B34460 /* ArrayPrototype.h in Headers */,
C2DF44301707AC0100A5CA96 /* SuperRegion.h in Headers */,
C20B25991706536200C21F4E /* Region.h in Headers */,
+ FE6617281774E03500495B00 /* VMStackBounds.h in Headers */,
C283190016FE4B7D00157BFD /* HandleBlock.h in Headers */,
BC18C41D0E16F5CD00B34460 /* JSClassRef.h in Headers */,
86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */,
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (151868 => 151869)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2013-06-21 23:39:41 UTC (rev 151868)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2013-06-21 23:58:52 UTC (rev 151869)
@@ -179,7 +179,7 @@
#ifndef NDEBUG
, m_lastOpcodePosition(0)
#endif
- , m_stack(wtfThreadData().stack())
+ , m_stack(vm, wtfThreadData().stack())
, m_usesExceptions(false)
, m_expressionTooDeep(false)
{
@@ -228,7 +228,7 @@
#ifndef NDEBUG
, m_lastOpcodePosition(0)
#endif
- , m_stack(wtfThreadData().stack())
+ , m_stack(vm, wtfThreadData().stack())
, m_usesExceptions(false)
, m_expressionTooDeep(false)
{
@@ -425,7 +425,7 @@
#ifndef NDEBUG
, m_lastOpcodePosition(0)
#endif
- , m_stack(wtfThreadData().stack())
+ , m_stack(vm, wtfThreadData().stack())
, m_usesExceptions(false)
, m_expressionTooDeep(false)
{
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (151868 => 151869)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2013-06-21 23:39:41 UTC (rev 151868)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2013-06-21 23:58:52 UTC (rev 151869)
@@ -44,6 +44,7 @@
#include "Nodes.h"
#include "StaticPropertyAnalyzer.h"
#include "UnlinkedCodeBlock.h"
+#include "VMStackBounds.h"
#include <wtf/PassRefPtr.h>
#include <wtf/SegmentedVector.h>
#include <wtf/Vector.h>
@@ -825,7 +826,7 @@
size_t m_lastOpcodePosition;
#endif
- StackBounds m_stack;
+ VMStackBounds m_stack;
bool m_usesExceptions;
bool m_expressionTooDeep;
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (151868 => 151869)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2013-06-21 23:39:41 UTC (rev 151868)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2013-06-21 23:58:52 UTC (rev 151869)
@@ -64,6 +64,7 @@
#include "SamplingTool.h"
#include "StrictEvalActivation.h"
#include "StrongInlines.h"
+#include "VMStackBounds.h"
#include <limits.h>
#include <stdio.h>
#include <wtf/StackStats.h>
@@ -98,45 +99,6 @@
m_interpreter.stack().disableErrorStackReserve();
}
-
-// The Interpreter::StackPolicy class is used to compute a stack capacity
-// requirement to ensure that we have enough room on the native stack for:
-// 1. the max cumulative stack used by the interpreter and all code
-// paths sub of it up till leaf functions.
-// 2. the max cumulative stack used by the interpreter before it reaches
-// the next checkpoint (execute...() function) in the interpreter.
-//
-// The interpreter can be run on different threads and hence, different
-// native stacks (with different sizes) before exiting out of the first
-// frame. Hence, the required capacity needs to be re-computed on every
-// entry into the interpreter.
-//
-// Currently the requiredStack is computed based on a policy. See comments
-// in StackPolicy::StackPolicy() for details.
-
-Interpreter::StackPolicy::StackPolicy(Interpreter& interpreter, const StackBounds& stack)
- : m_interpreter(interpreter)
-{
- const size_t size = stack.size();
-
- // We have two separate stack limits, one for regular JS execution, and one
- // for when we're handling errors. We need the error stack to be smaller
- // otherwise there would obviously not be any stack left to execute JS in when
- // there's a stack overflow.
- //
- // These sizes were derived from the stack usage of a number of sites when
- // layout occurs when we've already consumed most of the C stack.
- const size_t requiredStack = 32 * KB;
- const size_t errorModeRequiredStack = 16 * KB;
-
- size_t requiredCapacity = m_interpreter.m_errorHandlingModeReentry ? errorModeRequiredStack : requiredStack;
-
- RELEASE_ASSERT(size >= requiredCapacity);
-
- m_requiredCapacity = requiredCapacity;
-}
-
-
static CallFrame* getCallerInfo(VM*, CallFrame*, unsigned& bytecodeOffset, CodeBlock*& callerOut);
// Returns the depth of the scope chain within a given call frame.
@@ -829,9 +791,8 @@
return jsNull();
StackStats::CheckPoint stackCheckPoint;
- const StackBounds& nativeStack = wtfThreadData().stack();
- StackPolicy policy(*this, nativeStack);
- if (!nativeStack.isSafeToRecurse(policy.requiredCapacity()))
+ const VMStackBounds vmStackBounds(vm, wtfThreadData().stack());
+ if (!vmStackBounds.isSafeToRecurse())
return checkedReturn(throwStackOverflowError(callFrame));
// First check if the "program" is actually just a JSON object. If so,
@@ -995,9 +956,8 @@
return jsNull();
StackStats::CheckPoint stackCheckPoint;
- const StackBounds& nativeStack = wtfThreadData().stack();
- StackPolicy policy(*this, nativeStack);
- if (!nativeStack.isSafeToRecurse(policy.requiredCapacity()))
+ const VMStackBounds vmStackBounds(vm, wtfThreadData().stack());
+ if (!vmStackBounds.isSafeToRecurse())
return checkedReturn(throwStackOverflowError(callFrame));
bool isJSCall = (callType == CallTypeJS);
@@ -1073,9 +1033,8 @@
return checkedReturn(throwStackOverflowError(callFrame));
StackStats::CheckPoint stackCheckPoint;
- const StackBounds& nativeStack = wtfThreadData().stack();
- StackPolicy policy(*this, nativeStack);
- if (!nativeStack.isSafeToRecurse(policy.requiredCapacity()))
+ const VMStackBounds vmStackBounds(vm, wtfThreadData().stack());
+ if (!vmStackBounds.isSafeToRecurse())
return checkedReturn(throwStackOverflowError(callFrame));
bool isJSConstruct = (constructType == ConstructTypeJS);
@@ -1154,9 +1113,8 @@
return CallFrameClosure();
StackStats::CheckPoint stackCheckPoint;
- const StackBounds& nativeStack = wtfThreadData().stack();
- StackPolicy policy(*this, nativeStack);
- if (!nativeStack.isSafeToRecurse(policy.requiredCapacity())) {
+ const VMStackBounds vmStackBounds(vm, wtfThreadData().stack());
+ if (!vmStackBounds.isSafeToRecurse()) {
throwStackOverflowError(callFrame);
return CallFrameClosure();
}
@@ -1257,9 +1215,8 @@
DynamicGlobalObjectScope globalObjectScope(vm, scope->globalObject());
StackStats::CheckPoint stackCheckPoint;
- const StackBounds& nativeStack = wtfThreadData().stack();
- StackPolicy policy(*this, nativeStack);
- if (!nativeStack.isSafeToRecurse(policy.requiredCapacity()))
+ const VMStackBounds vmStackBounds(vm, wtfThreadData().stack());
+ if (!vmStackBounds.isSafeToRecurse())
return checkedReturn(throwStackOverflowError(callFrame));
// Compile the callee:
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.h (151868 => 151869)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.h 2013-06-21 23:39:41 UTC (rev 151868)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.h 2013-06-21 23:58:52 UTC (rev 151869)
@@ -216,6 +216,8 @@
SamplingTool* sampler() { return m_sampler.get(); }
+ bool isInErrorHandlingMode() { return m_errorHandlingModeReentry; }
+
NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset);
NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine, int column);
static const String getTraceLine(CallFrame*, StackFrameCodeType, const String&, int);
@@ -229,16 +231,6 @@
JS_EXPORT_PRIVATE void dumpCallFrame(CallFrame*);
private:
- class StackPolicy {
- public:
- StackPolicy(Interpreter&, const StackBounds&);
- inline size_t requiredCapacity() { return m_requiredCapacity; }
-
- private:
- Interpreter& m_interpreter;
- size_t m_requiredCapacity;
- };
-
enum ExecutionFlag { Normal, InitializeAndReturn };
CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*);
Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (151868 => 151869)
--- trunk/Source/_javascript_Core/parser/Parser.cpp 2013-06-21 23:39:41 UTC (rev 151868)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp 2013-06-21 23:58:52 UTC (rev 151869)
@@ -66,7 +66,7 @@
Parser<LexerType>::Parser(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode)
: m_vm(vm)
, m_source(&source)
- , m_stack(wtfThreadData().stack())
+ , m_stack(*vm, wtfThreadData().stack())
, m_hasStackOverflow(false)
, m_allowsIn(true)
, m_lastLine(0)
Modified: trunk/Source/_javascript_Core/parser/Parser.h (151868 => 151869)
--- trunk/Source/_javascript_Core/parser/Parser.h 2013-06-21 23:39:41 UTC (rev 151868)
+++ trunk/Source/_javascript_Core/parser/Parser.h 2013-06-21 23:58:52 UTC (rev 151869)
@@ -35,6 +35,7 @@
#include "SourceProvider.h"
#include "SourceProviderCache.h"
#include "SourceProviderCacheItem.h"
+#include "VMStackBounds.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
@@ -938,7 +939,7 @@
ParserArena* m_arena;
OwnPtr<LexerType> m_lexer;
- StackBounds m_stack;
+ VMStackBounds m_stack;
bool m_hasStackOverflow;
String m_errorMessage;
JSToken m_token;
Modified: trunk/Source/_javascript_Core/runtime/StringRecursionChecker.h (151868 => 151869)
--- trunk/Source/_javascript_Core/runtime/StringRecursionChecker.h 2013-06-21 23:39:41 UTC (rev 151868)
+++ trunk/Source/_javascript_Core/runtime/StringRecursionChecker.h 2013-06-21 23:58:52 UTC (rev 151869)
@@ -21,6 +21,7 @@
#define StringRecursionChecker_h
#include "Interpreter.h"
+#include "VMStackBounds.h"
#include <wtf/StackStats.h>
#include <wtf/WTFThreadData.h>
@@ -49,10 +50,11 @@
inline JSValue StringRecursionChecker::performCheck()
{
- const StackBounds& nativeStack = wtfThreadData().stack();
+ VM& vm = m_exec->vm();
+ const VMStackBounds nativeStack(vm, wtfThreadData().stack());
if (!nativeStack.isSafeToRecurse())
return throwStackOverflowError();
- bool alreadyVisited = !m_exec->vm().stringRecursionCheckVisitedObjects.add(m_thisObject).isNewEntry;
+ bool alreadyVisited = !vm.stringRecursionCheckVisitedObjects.add(m_thisObject).isNewEntry;
if (alreadyVisited)
return emptyString(); // Return empty string to avoid infinite recursion.
return JSValue(); // Indicate success.
Added: trunk/Source/_javascript_Core/runtime/VMStackBounds.h (0 => 151869)
--- trunk/Source/_javascript_Core/runtime/VMStackBounds.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/VMStackBounds.h 2013-06-21 23:58:52 UTC (rev 151869)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VMStackBounds_h
+#define VMStackBounds_h
+
+#include "VM.h"
+#include <wtf/StackBounds.h>
+
+namespace JSC {
+
+class VMStackBounds {
+public:
+ VMStackBounds(VM& vm, const StackBounds& bounds)
+ : m_vm(vm)
+ , m_bounds(bounds)
+ {
+ }
+
+ bool isSafeToRecurse() const { return m_bounds.isSafeToRecurse(requiredCapacity()); }
+
+private:
+ inline size_t requiredCapacity() const
+ {
+ Interpreter* interpreter = m_vm.interpreter;
+
+ // We have two separate stack limits, one for regular JS execution, and one
+ // for when we're handling errors. We need the error stack to be smaller
+ // otherwise there would obviously not be any stack left to execute JS in when
+ // there's a stack overflow.
+ //
+ // These sizes were derived from the stack usage of a number of sites when
+ // layout occurs when we've already consumed most of the C stack.
+ const size_t requiredStack = 128 * KB;
+ const size_t errorModeRequiredStack = 64 * KB;
+
+ size_t requiredCapacity = interpreter->isInErrorHandlingMode() ? errorModeRequiredStack : requiredStack;
+ RELEASE_ASSERT(m_bounds.size() >= requiredCapacity);
+ return requiredCapacity;
+ }
+
+ VM& m_vm;
+ const StackBounds& m_bounds;
+};
+
+} // namespace JSC
+
+#endif // VMStackBounds_h
+