Commit 30721257 authored by mark.lam@apple.com's avatar mark.lam@apple.com

Introducing VMEntryScope to update the VM stack limit.

https://bugs.webkit.org/show_bug.cgi?id=124634.

Reviewed by Geoffrey Garen.

Source/JavaScriptCore: 

1. Introduced USE(SEPARATE_C_AND_JS_STACK) (defined in Platform.h).
   Currently, it is hardcoded to use separate C and JS stacks. Once we
   switch to using the C stack for JS frames, we'll need to fix this to
   only be enabled when ENABLE(LLINT_C_LOOP).

2. Stack limits are now tracked in the VM.

   Logically, there are 2 stack limits:
   a. m_stackLimit for the native C stack, and
   b. m_jsStackLimit for the JS stack.

   If USE(SEPARATE_C_AND_JS_STACK), then the 2 limits are the same
   value, and are implemented as 2 fields in a union.

3. The VM native stackLimit is set as follows:
   a. Initially, the VM sets it to the limit of the stack of the thread that
      instantiated the VM. This allows the parser and bytecode generator to
      run before we enter the VM to execute JS code.

   b. Upon entry into the VM to execute JS code (via one of the
      Interpreter::execute...() functions), we instantiate a VMEntryScope
      that sets the VM's stackLimit to the limit of the current thread's
      stack. The VMEntryScope will automatically restore the previous
      entryScope and stack limit upon destruction.

   If USE(SEPARATE_C_AND_JS_STACK), the JSStack's methods will set the VM's
   jsStackLimit whenever it grows or shrinks.

4. The VM now provides a isSafeToRecurse() function that compares the
   current stack pointer against its native stackLimit. This subsumes and
   obsoletes the VMStackBounds class.

5. The VMEntryScope class also subsumes DynamicGlobalObjectScope for
   tracking the JSGlobalObject that we last entered the VM with.

6. Renamed dynamicGlobalObject() to vmEntryGlobalObject() since that is
   the value that the function retrieves.

7. Changed JIT and LLINT code to do stack checks against the jsStackLimit
   in the VM class instead of the JSStack.

* API/JSBase.cpp:
(JSEvaluateScript):
(JSCheckScriptSyntax):
* API/JSContextRef.cpp:
(JSGlobalContextRetain):
(JSGlobalContextRelease):
* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::emitNode):
(JSC::BytecodeGenerator::emitNodeInConditionContext):
* debugger/Debugger.cpp:
(JSC::Debugger::detach):
(JSC::Debugger::recompileAllJSFunctions):
(JSC::Debugger::pauseIfNeeded):
* debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::vmEntryGlobalObject):
* debugger/DebuggerCallFrame.h:
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileFunction):
* dfg/DFGOSREntry.cpp:
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLOSREntry.cpp:
* heap/Heap.cpp:
(JSC::Heap::lastChanceToFinalize):
(JSC::Heap::deleteAllCompiledCode):
* interpreter/CachedCall.h:
(JSC::CachedCall::CachedCall):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::vmEntryGlobalObject):
* interpreter/CallFrame.h:
* interpreter/Interpreter.cpp:
(JSC::unwindCallFrame):
(JSC::Interpreter::unwind):
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):
(JSC::Interpreter::debug):
* interpreter/JSStack.cpp:
(JSC::JSStack::JSStack):
(JSC::JSStack::growSlowCase):
* interpreter/JSStack.h:
* interpreter/JSStackInlines.h:
(JSC::JSStack::shrink):
(JSC::JSStack::grow):
- Moved these inlined functions here from JSStack.h. It reduces some
  #include dependencies of JSSTack.h which had previously resulted
  in some EWS bots' unhappiness with this patch.
(JSC::JSStack::updateStackLimit):
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JITCall.cpp:
(JSC::JIT::compileLoadVarargs):
* jit/JITCall32_64.cpp:
(JSC::JIT::compileLoadVarargs):
* jit/JITOperations.cpp:
* llint/LLIntSlowPaths.cpp:
* llint/LowLevelInterpreter.asm:
* parser/Parser.cpp:
(JSC::::Parser):
* parser/Parser.h:
(JSC::Parser::canRecurse):
* runtime/CommonSlowPaths.h:
* runtime/Completion.cpp:
(JSC::evaluate):
* runtime/FunctionConstructor.cpp:
(JSC::constructFunctionSkippingEvalEnabledCheck):
* runtime/JSGlobalObject.cpp:
* runtime/JSGlobalObject.h:
* runtime/StringRecursionChecker.h:
(JSC::StringRecursionChecker::performCheck):
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::releaseExecutableMemory):
(JSC::VM::throwException):
* runtime/VM.h:
(JSC::VM::addressOfJSStackLimit):
(JSC::VM::jsStackLimit):
(JSC::VM::setJSStackLimit):
(JSC::VM::stackLimit):
(JSC::VM::setStackLimit):
(JSC::VM::isSafeToRecurse):
* runtime/VMEntryScope.cpp: Added.
(JSC::VMEntryScope::VMEntryScope):
(JSC::VMEntryScope::~VMEntryScope):
(JSC::VMEntryScope::requiredCapacity):
* runtime/VMEntryScope.h: Added.
(JSC::VMEntryScope::globalObject):
* runtime/VMStackBounds.h: Removed.

Source/WebCore: 

No new tests.

Renamed dynamicGlobalObject() to vmEntryGlobalObject().
Replaced uses of DynamicGlobalObjectScope with VMEntryScope.

* ForwardingHeaders/runtime/VMEntryScope.h: Added.
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* bindings/js/JSCryptoAlgorithmBuilder.cpp:
(WebCore::JSCryptoAlgorithmBuilder::add):
* bindings/js/JSCustomXPathNSResolver.cpp:
(WebCore::JSCustomXPathNSResolver::create):
* bindings/js/JSDOMBinding.cpp:
(WebCore::firstDOMWindow):
* bindings/js/JSErrorHandler.cpp:
(WebCore::JSErrorHandler::handleEvent):
* bindings/js/JSEventListener.cpp:
(WebCore::JSEventListener::handleEvent):
* bindings/js/JavaScriptCallFrame.h:
(WebCore::JavaScriptCallFrame::vmEntryGlobalObject):
* bindings/js/PageScriptDebugServer.cpp:
(WebCore::PageScriptDebugServer::recompileAllJSFunctions):
* bindings/js/ScriptDebugServer.cpp:
(WebCore::ScriptDebugServer::evaluateBreakpointAction):
(WebCore::ScriptDebugServer::handlePause):
* bindings/js/WorkerScriptDebugServer.cpp:
(WebCore::WorkerScriptDebugServer::recompileAllJSFunctions):
* bindings/objc/WebScriptObject.mm:
(WebCore::addExceptionToConsole):
* bridge/c/c_utility.cpp:
(JSC::Bindings::convertValueToNPVariant):
* bridge/objc/objc_instance.mm:
(ObjcInstance::moveGlobalExceptionToExecState):
* bridge/objc/objc_runtime.mm:
(JSC::Bindings::convertValueToObjcObject):
* bridge/objc/objc_utility.mm:
(JSC::Bindings::convertValueToObjcValue):

Source/WebKit/mac: 

* WebView/WebScriptDebugger.mm:
(WebScriptDebugger::sourceParsed):

Source/WTF: 

* wtf/Platform.h:
* wtf/StackBounds.h:
(WTF::StackBounds::StackBounds):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@159605 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent b86fc58f
/*
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2006, 2007, 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
......@@ -54,7 +54,7 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
JSObject* jsThisObject = toJS(thisObject);
// evaluate sets "this" to the global object if it is NULL
JSGlobalObject* globalObject = exec->dynamicGlobalObject();
JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
SourceCode source = makeSource(script->string(), sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
JSValue evaluationException;
......@@ -85,7 +85,7 @@ bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourc
SourceCode source = makeSource(script->string(), sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
JSValue syntaxException;
bool isValidSyntax = checkSyntax(exec->dynamicGlobalObject()->globalExec(), source, &syntaxException);
bool isValidSyntax = checkSyntax(exec->vmEntryGlobalObject()->globalExec(), source, &syntaxException);
if (!isValidSyntax) {
if (exception)
......
/*
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2006, 2007, 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
......@@ -155,7 +155,7 @@ JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx)
APIEntryShim entryShim(exec);
VM& vm = exec->vm();
gcProtect(exec->dynamicGlobalObject());
gcProtect(exec->vmEntryGlobalObject());
vm.ref();
return ctx;
}
......@@ -170,7 +170,7 @@ void JSGlobalContextRelease(JSGlobalContextRef ctx)
VM& vm = exec->vm();
savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(vm.identifierTable);
bool protectCountIsZero = Heap::heap(exec->dynamicGlobalObject())->unprotect(exec->dynamicGlobalObject());
bool protectCountIsZero = Heap::heap(exec->vmEntryGlobalObject())->unprotect(exec->vmEntryGlobalObject());
if (protectCountIsZero)
vm.heap.reportAbandonedObjectGraph();
vm.deref();
......
......@@ -422,6 +422,7 @@ set(JavaScriptCore_SOURCES
runtime/TypedArrayController.cpp
runtime/TypedArrayType.cpp
runtime/VM.cpp
runtime/VMEntryScope.cpp
runtime/Watchdog.cpp
runtime/WatchdogNone.cpp
runtime/WeakMapConstructor.cpp
......
2013-11-20 Mark Lam <mark.lam@apple.com>
Introducing VMEntryScope to update the VM stack limit.
https://bugs.webkit.org/show_bug.cgi?id=124634.
Reviewed by Geoffrey Garen.
1. Introduced USE(SEPARATE_C_AND_JS_STACK) (defined in Platform.h).
Currently, it is hardcoded to use separate C and JS stacks. Once we
switch to using the C stack for JS frames, we'll need to fix this to
only be enabled when ENABLE(LLINT_C_LOOP).
2. Stack limits are now tracked in the VM.
Logically, there are 2 stack limits:
a. m_stackLimit for the native C stack, and
b. m_jsStackLimit for the JS stack.
If USE(SEPARATE_C_AND_JS_STACK), then the 2 limits are the same
value, and are implemented as 2 fields in a union.
3. The VM native stackLimit is set as follows:
a. Initially, the VM sets it to the limit of the stack of the thread that
instantiated the VM. This allows the parser and bytecode generator to
run before we enter the VM to execute JS code.
b. Upon entry into the VM to execute JS code (via one of the
Interpreter::execute...() functions), we instantiate a VMEntryScope
that sets the VM's stackLimit to the limit of the current thread's
stack. The VMEntryScope will automatically restore the previous
entryScope and stack limit upon destruction.
If USE(SEPARATE_C_AND_JS_STACK), the JSStack's methods will set the VM's
jsStackLimit whenever it grows or shrinks.
4. The VM now provides a isSafeToRecurse() function that compares the
current stack pointer against its native stackLimit. This subsumes and
obsoletes the VMStackBounds class.
5. The VMEntryScope class also subsumes DynamicGlobalObjectScope for
tracking the JSGlobalObject that we last entered the VM with.
6. Renamed dynamicGlobalObject() to vmEntryGlobalObject() since that is
the value that the function retrieves.
7. Changed JIT and LLINT code to do stack checks against the jsStackLimit
in the VM class instead of the JSStack.
* API/JSBase.cpp:
(JSEvaluateScript):
(JSCheckScriptSyntax):
* API/JSContextRef.cpp:
(JSGlobalContextRetain):
(JSGlobalContextRelease):
* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::emitNode):
(JSC::BytecodeGenerator::emitNodeInConditionContext):
* debugger/Debugger.cpp:
(JSC::Debugger::detach):
(JSC::Debugger::recompileAllJSFunctions):
(JSC::Debugger::pauseIfNeeded):
* debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::vmEntryGlobalObject):
* debugger/DebuggerCallFrame.h:
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileFunction):
* dfg/DFGOSREntry.cpp:
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLOSREntry.cpp:
* heap/Heap.cpp:
(JSC::Heap::lastChanceToFinalize):
(JSC::Heap::deleteAllCompiledCode):
* interpreter/CachedCall.h:
(JSC::CachedCall::CachedCall):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::vmEntryGlobalObject):
* interpreter/CallFrame.h:
* interpreter/Interpreter.cpp:
(JSC::unwindCallFrame):
(JSC::Interpreter::unwind):
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):
(JSC::Interpreter::debug):
* interpreter/JSStack.cpp:
(JSC::JSStack::JSStack):
(JSC::JSStack::growSlowCase):
* interpreter/JSStack.h:
* interpreter/JSStackInlines.h:
(JSC::JSStack::shrink):
(JSC::JSStack::grow):
- Moved these inlined functions here from JSStack.h. It reduces some
#include dependencies of JSSTack.h which had previously resulted
in some EWS bots' unhappiness with this patch.
(JSC::JSStack::updateStackLimit):
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JITCall.cpp:
(JSC::JIT::compileLoadVarargs):
* jit/JITCall32_64.cpp:
(JSC::JIT::compileLoadVarargs):
* jit/JITOperations.cpp:
* llint/LLIntSlowPaths.cpp:
* llint/LowLevelInterpreter.asm:
* parser/Parser.cpp:
(JSC::::Parser):
* parser/Parser.h:
(JSC::Parser::canRecurse):
* runtime/CommonSlowPaths.h:
* runtime/Completion.cpp:
(JSC::evaluate):
* runtime/FunctionConstructor.cpp:
(JSC::constructFunctionSkippingEvalEnabledCheck):
* runtime/JSGlobalObject.cpp:
* runtime/JSGlobalObject.h:
* runtime/StringRecursionChecker.h:
(JSC::StringRecursionChecker::performCheck):
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::releaseExecutableMemory):
(JSC::VM::throwException):
* runtime/VM.h:
(JSC::VM::addressOfJSStackLimit):
(JSC::VM::jsStackLimit):
(JSC::VM::setJSStackLimit):
(JSC::VM::stackLimit):
(JSC::VM::setStackLimit):
(JSC::VM::isSafeToRecurse):
* runtime/VMEntryScope.cpp: Added.
(JSC::VMEntryScope::VMEntryScope):
(JSC::VMEntryScope::~VMEntryScope):
(JSC::VMEntryScope::requiredCapacity):
* runtime/VMEntryScope.h: Added.
(JSC::VMEntryScope::globalObject):
* runtime/VMStackBounds.h: Removed.
2013-11-20 Michael Saboff <msaboff@apple.com>
[Win] JavaScript JIT crash (with DFG enabled).
......
......@@ -913,6 +913,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/runtime/JSExportMacros.h \
Source/JavaScriptCore/runtime/VM.cpp \
Source/JavaScriptCore/runtime/VM.h \
Source/JavaScriptCore/runtime/VMEntryScope.cpp \
Source/JavaScriptCore/runtime/VMEntryScope.h \
Source/JavaScriptCore/runtime/JSFunctionInlines.h \
Source/JavaScriptCore/runtime/JSGenericTypedArrayView.h \
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructor.h \
......@@ -1127,7 +1129,6 @@ javascriptcore_sources += \
Source/JavaScriptCore/runtime/Uint32Array.h \
Source/JavaScriptCore/runtime/Uint8Array.h \
Source/JavaScriptCore/runtime/Uint8ClampedArray.h \
Source/JavaScriptCore/runtime/VMStackBounds.h \
Source/JavaScriptCore/runtime/Watchdog.cpp \
Source/JavaScriptCore/runtime/Watchdog.h \
Source/JavaScriptCore/runtime/WatchdogNone.cpp \
......
......@@ -662,6 +662,7 @@
<ClCompile Include="..\runtime\TypedArrayController.cpp" />
<ClCompile Include="..\runtime\TypedArrayType.cpp" />
<ClCompile Include="..\runtime\VM.cpp" />
<ClCompile Include="..\runtime\VMEntryScope.cpp" />
<ClCompile Include="..\runtime\Watchdog.cpp" />
<ClCompile Include="..\runtime\WatchdogNone.cpp" />
<ClCompile Include="..\runtime\WeakMapConstructor.cpp" />
......@@ -1289,6 +1290,7 @@
<ClInclude Include="..\runtime\Uint32Array.h" />
<ClInclude Include="..\runtime\Uint8Array.h" />
<ClInclude Include="..\runtime\VM.h" />
<ClInclude Include="..\runtime\VMEntryScope.h" />
<ClInclude Include="..\runtime\Watchdog.h" />
<ClInclude Include="..\runtime\WeakGCMap.h" />
<ClInclude Include="..\runtime\WeakMapConstructor.h" />
......
......@@ -801,6 +801,9 @@
<ClCompile Include="..\runtime\VM.cpp">
<Filter>runtime</Filter>
</ClCompile>
<ClCompile Include="..\runtime\VMEntryScope.cpp">
<Filter>runtime</Filter>
</ClCompile>
<ClCompile Include="..\parser\SourceCode.cpp">
<Filter>parser</Filter>
</ClCompile>
......@@ -2418,6 +2421,9 @@
<ClInclude Include="..\runtime\VM.h">
<Filter>runtime</Filter>
</ClInclude>
<ClInclude Include="..\runtime\VMEntryScope.h">
<Filter>runtime</Filter>
</ClInclude>
<ClInclude Include="..\assembler\MacroAssemblerX86Common.cpp">
<Filter>assembler</Filter>
</ClInclude>
......
......@@ -1238,7 +1238,8 @@
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, ); }; };
FE5932A7183C5A2600A1ECCC /* VMEntryScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */; };
FE5932A8183C5A2600A1ECCC /* VMEntryScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
FEA08620182B7A0400F6D851 /* Breakpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA0861E182B7A0400F6D851 /* Breakpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
FEA08621182B7A0400F6D851 /* DebuggerPrimitives.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */; settings = {ATTRIBUTES = (Private, ); }; };
FED287B215EC9A5700DA8161 /* LLIntOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = FED287B115EC9A5700DA8161 /* LLIntOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
......@@ -2566,7 +2567,8 @@
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>"; };
FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMEntryScope.cpp; sourceTree = "<group>"; };
FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMEntryScope.h; sourceTree = "<group>"; };
FEA0861E182B7A0400F6D851 /* Breakpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Breakpoint.h; sourceTree = "<group>"; };
FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerPrimitives.h; sourceTree = "<group>"; };
FED287B115EC9A5700DA8161 /* LLIntOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntOpcode.h; path = llint/LLIntOpcode.h; sourceTree = "<group>"; };
......@@ -3316,6 +3318,8 @@
7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
isa = PBXGroup;
children = (
FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */,
FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */,
BCF605110E203EF800B9A64D /* ArgList.cpp */,
BCF605120E203EF800B9A64D /* ArgList.h */,
BC257DE50E1F51C50016B6C9 /* Arguments.cpp */,
......@@ -3662,7 +3666,6 @@
A7A8AF3117ADB5F3005AB174 /* Uint8ClampedArray.h */,
E18E3A570DF9278C00D90B34 /* VM.cpp */,
E18E3A560DF9278C00D90B34 /* VM.h */,
FE6617271774E03500495B00 /* VMStackBounds.h */,
FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */,
FED94F2C171E3E2300BE77A4 /* Watchdog.h */,
FED94F2D171E3E2300BE77A4 /* WatchdogMac.cpp */,
......@@ -4177,6 +4180,7 @@
86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */,
65C0285D1717966800351E35 /* ARMv7DOpcode.h in Headers */,
FE5932A8183C5A2600A1ECCC /* VMEntryScope.h in Headers */,
0F24E54F17EE274900ABB217 /* TempRegisterSet.h in Headers */,
A7BFF3C0179868940002F462 /* DFGFiltrationResult.h in Headers */,
C2FCAE1117A9C24E0034C735 /* BytecodeBasicBlock.h in Headers */,
......@@ -4828,7 +4832,6 @@
0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */,
BC18C4200E16F5CD00B34460 /* VM.h in Headers */,
FE4A332015BD2E07006F54F3 /* VMInspector.h in Headers */,
FE6617281774E03500495B00 /* VMStackBounds.h in Headers */,
FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */,
0F919D2615853CE3004A4E7D /* Watchpoint.h in Headers */,
142E313C134FF0A600AFADB5 /* Weak.h in Headers */,
......@@ -5566,6 +5569,7 @@
14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */,
147F39D7107EC37600427A48 /* JSVariableObject.cpp in Sources */,
86E3C61C167BABEE006D760A /* JSVirtualMachine.mm in Sources */,
FE5932A7183C5A2600A1ECCC /* VMEntryScope.cpp in Sources */,
A7CA3AE717DA41AE006538AF /* JSWeakMap.cpp in Sources */,
A7482B9411671147003B0712 /* JSWeakObjectMapRefPrivate.cpp in Sources */,
1442566115EDE98D0066A49B /* JSWithScope.cpp in Sources */,
......
......@@ -159,7 +159,6 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedP
#ifndef NDEBUG
, m_lastOpcodePosition(0)
#endif
, m_stack(vm, wtfThreadData().stack())
, m_usesExceptions(false)
, m_expressionTooDeep(false)
{
......@@ -207,7 +206,6 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionBodyNode* functionBody, Unl
#ifndef NDEBUG
, m_lastOpcodePosition(0)
#endif
, m_stack(vm, wtfThreadData().stack())
, m_usesExceptions(false)
, m_expressionTooDeep(false)
{
......@@ -421,7 +419,6 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCod
#ifndef NDEBUG
, m_lastOpcodePosition(0)
#endif
, m_stack(vm, wtfThreadData().stack())
, m_usesExceptions(false)
, m_expressionTooDeep(false)
{
......
......@@ -44,7 +44,6 @@
#include "Nodes.h"
#include "StaticPropertyAnalyzer.h"
#include "UnlinkedCodeBlock.h"
#include "VMStackBounds.h"
#include <functional>
......@@ -233,7 +232,7 @@ namespace JSC {
{
// Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
if (!m_stack.isSafeToRecurse()) {
if (!m_vm->isSafeToRecurse()) {
emitThrowExpressionTooDeepException();
return;
}
......@@ -249,7 +248,7 @@ namespace JSC {
{
// Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
if (!m_stack.isSafeToRecurse())
if (!m_vm->isSafeToRecurse())
return emitThrowExpressionTooDeepException();
return n->emitBytecode(*this, dst);
}
......@@ -261,7 +260,7 @@ namespace JSC {
void emitNodeInConditionContext(ExpressionNode* n, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
{
if (!m_stack.isSafeToRecurse()) {
if (!m_vm->isSafeToRecurse()) {
emitThrowExpressionTooDeepException();
return;
}
......@@ -639,8 +638,6 @@ namespace JSC {
size_t m_lastOpcodePosition;
#endif
VMStackBounds m_stack;
bool m_usesExceptions;
bool m_expressionTooDeep;
};
......
......@@ -32,6 +32,7 @@
#include "Operations.h"
#include "Parser.h"
#include "Protect.h"
#include "VMEntryScope.h"
namespace {
......@@ -172,7 +173,7 @@ void Debugger::detach(JSGlobalObject* globalObject)
// If we're detaching from the currently executing global object, manually tear down our
// stack, since we won't get further debugger callbacks to do so. Also, resume execution,
// since there's no point in staying paused once a window closes.
if (m_currentCallFrame && m_currentCallFrame->dynamicGlobalObject() == globalObject) {
if (m_currentCallFrame && m_currentCallFrame->vmEntryGlobalObject() == globalObject) {
m_currentCallFrame = 0;
m_pauseOnCallFrame = 0;
continueProgram();
......@@ -193,8 +194,8 @@ void Debugger::recompileAllJSFunctions(VM* vm)
{
// 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(!vm->dynamicGlobalObject);
if (vm->dynamicGlobalObject)
ASSERT(!vm->entryScope);
if (vm->entryScope)
return;
vm->prepareToDiscardCode();
......@@ -438,8 +439,8 @@ void Debugger::pauseIfNeeded(CallFrame* callFrame)
if (m_isPaused)
return;
JSGlobalObject* dynamicGlobalObject = callFrame->dynamicGlobalObject();
if (!needPauseHandling(dynamicGlobalObject))
JSGlobalObject* vmEntryGlobalObject = callFrame->vmEntryGlobalObject();
if (!needPauseHandling(vmEntryGlobalObject))
return;
Breakpoint breakpoint;
......@@ -470,7 +471,7 @@ void Debugger::pauseIfNeeded(CallFrame* callFrame)
return;
}
handlePause(m_reasonForPause, dynamicGlobalObject);
handlePause(m_reasonForPause, vmEntryGlobalObject);
if (!m_pauseOnNextStatement && !m_pauseOnCallFrame) {
setShouldPause(false);
......
......@@ -35,6 +35,7 @@
#include "Operations.h"
#include "Parser.h"
#include "StackVisitor.h"
#include "VMEntryScope.h"
namespace JSC {
......@@ -77,12 +78,12 @@ PassRefPtr<DebuggerCallFrame> DebuggerCallFrame::callerFrame()
return m_caller;
}
JSC::JSGlobalObject* DebuggerCallFrame::dynamicGlobalObject() const
JSC::JSGlobalObject* DebuggerCallFrame::vmEntryGlobalObject() const
{
ASSERT(isValid());
if (!isValid())
return 0;
return m_callFrame->dynamicGlobalObject();
return m_callFrame->vmEntryGlobalObject();
}
SourceID DebuggerCallFrame::sourceID() const
......
......@@ -58,7 +58,7 @@ public:
int column() const { return m_position.m_column.zeroBasedInt(); }
JS_EXPORT_PRIVATE const TextPosition& position() const { return m_position; }
JS_EXPORT_PRIVATE JSGlobalObject* dynamicGlobalObject() const;
JS_EXPORT_PRIVATE JSGlobalObject* vmEntryGlobalObject() const;
JS_EXPORT_PRIVATE JSScope* scope() const;
JS_EXPORT_PRIVATE String functionName() const;
JS_EXPORT_PRIVATE Type type() const;
......
......@@ -331,9 +331,8 @@ void JITCompiler::compileFunction()
// so enter after this.
Label fromArityCheck(this);
// Plant a check that sufficient space is available in the JSStack.
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=56291
addPtr(TrustedImm32(virtualRegisterForLocal(m_codeBlock->m_numCalleeRegisters).offset() * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::regT1);
Jump stackCheck = branchPtr(Above, AbsoluteAddress(m_vm->interpreter->stack().addressOfEnd()), GPRInfo::regT1);
Jump stackCheck = branchPtr(Above, AbsoluteAddress(m_vm->addressOfJSStackLimit()), GPRInfo::regT1);
// Return here after stack check.
Label fromStackCheck = label();
......
......@@ -33,6 +33,7 @@
#include "DFGJITCode.h"
#include "DFGNode.h"
#include "JIT.h"
#include "JSStackInlines.h"
#include "Operations.h"
namespace JSC { namespace DFG {
......
......@@ -84,7 +84,7 @@ void link(State& state)
GPRInfo::callFrameRegister, GPRInfo::regT1);
CCallHelpers::Jump stackCheck = jit.branchPtr(
CCallHelpers::Above,
CCallHelpers::AbsoluteAddress(state.graph.m_vm.interpreter->stack().addressOfEnd()),
CCallHelpers::AbsoluteAddress(state.graph.m_vm.addressOfJSStackLimit()),
GPRInfo::regT1);
CCallHelpers::Label fromStackCheck = jit.label();
......
......@@ -30,6 +30,7 @@
#include "CodeBlock.h"
#include "DFGJITCode.h"
#include "FTLForOSREntryJITCode.h"
#include "JSStackInlines.h"
#if ENABLE(FTL_JIT)
......
......@@ -291,7 +291,7 @@ bool Heap::isPagedOut(double deadline)
// Run all pending finalizers now because we won't get another chance.
void Heap::lastChanceToFinalize()
{
RELEASE_ASSERT(!m_vm->dynamicGlobalObject);
RELEASE_ASSERT(!m_vm->entryScope);
RELEASE_ASSERT(m_operationInProgress == NoOperation);
m_objectSpace.lastChanceToFinalize();
......@@ -689,7 +689,7 @@ void Heap::deleteAllCompiledCode()
{
// If JavaScript is running, it's not safe to delete code, since we'll end
// up deleting code that is live on the stack.
if (m_vm->dynamicGlobalObject)
if (m_vm->entryScope)
return;
for (ExecutableBase* current = m_compiledCode.head(); current; current = current->next()) {
......
......@@ -27,9 +27,11 @@
#define CachedCall_h
#include "CallFrameClosure.h"
#include "ExceptionHelpers.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "Interpreter.h"
#include "VMEntryScope.h"
namespace JSC {
class CachedCall {
......@@ -38,10 +40,13 @@ namespace JSC {
CachedCall(CallFrame* callFrame, JSFunction* function, int argumentCount)
: m_valid(false)
, m_interpreter(callFrame->interpreter())
, m_globalObjectScope(callFrame->vm(), function->scope()->globalObject())
, m_entryScope(callFrame->vm(), function->scope()->globalObject())
{
ASSERT(!function->isHostFunction());
m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, function, argumentCount + 1, function->scope());
if (callFrame->vm().isSafeToRecurse())
m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, function, argumentCount + 1, function->scope());
else
throwStackOverflowError(callFrame);
m_valid = !callFrame->hadException();
}
......@@ -69,7 +74,7 @@ namespace JSC {
private:
bool m_valid;
Interpreter* m_interpreter;
DynamicGlobalObjectScope m_globalObjectScope;
VMEntryScope m_entryScope;
CallFrameClosure m_closure;
};
}
......
......@@ -30,6 +30,7 @@
#include "CodeBlock.h"
#include "Interpreter.h"
#include "Operations.h"
#include "VMEntryScope.h"
namespace JSC {
......@@ -122,4 +123,15 @@ Register* CallFrame::frameExtentInternal()
return registers() + virtualRegisterForLocal(codeBlock->m_numCalleeRegisters).offset();
}
JSGlobalObject* CallFrame::vmEntryGlobalObject()
{
if (this == lexicalGlobalObject()->globalExec())
return lexicalGlobalObject();
// For any ExecState that's not a globalExec, the
// dynamic global object must be set since code is running
ASSERT(vm().entryScope);
return vm().entryScope->globalObject();
}
} // namespace JSC
......@@ -51,7 +51,7 @@ namespace JSC {
}
// Global object in which execution began.
JSGlobalObject* dynamicGlobalObject();
JS_EXPORT_PRIVATE JSGlobalObject* vmEntryGlobalObject();
// Global object in which the currently executing code was defined.
// Differs from dynamicGlobalObject() during function calls across web browser frames.
......
......@@ -66,7 +66,7 @@
#include "StackVisitor.h"
#include "StrictEvalActivation.h"
#include "StrongInlines.h"
#include "VMStackBounds.h"
#include "VMEntryScope.h"
#include "VirtualRegister.h"
#include <limits.h>
......@@ -395,7 +395,7 @@ static bool unwindCallFrame(StackVisitor& visitor)
CodeBlock* oldCodeBlock = codeBlock;
JSScope* scope = callFrame->scope();
if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
if (Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger()) {
if (callFrame->callee())
debugger->returnEvent(callFrame);
else
......@@ -650,7 +650,7 @@ NEVER_INLINE HandlerInfo* Interpreter::unwind(CallFrame*& callFrame, JSValue& ex
ASSERT(callFrame->vm().exceptionStack().size());
ASSERT(!exceptionValue.isObject() || asObject(exceptionValue)->hasProperty(callFrame, callFrame->vm().propertyNames->stack));
Debugger* debugger = callFrame->dynamicGlobalObject()->debugger();
Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger();
if (debugger && debugger->needsExceptionCallbacks()) {
// We need to clear the exception and the exception stack here in order to see if a new exception happens.
// Afterwards, the values are put back to continue processing this error.
......@@ -739,15 +739,14 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, J
if (vm.isCollectorBusy())
return jsNull();
StackStats::CheckPoint stackCheckPoint;
const VMStackBounds vmStackBounds(vm, wtfThreadData().stack());
if (!vmStackBounds.isSafeToRecurse())
VMEntryScope entryScope(vm, scope->globalObject());
if (!vm.isSafeToRecurse())
return checkedReturn(throwStackOverflowError(callFrame));
// First check if the "program" is actually just a JSON object. If so,
// we'll handle the JSON object here. Else, we'll handle real JS code
// below at failedJSONP.
DynamicGlobalObjectScope globalObjectScope(vm, scope->globalObject());
Vector<JSONPData> JSONPData;
bool parseResult;
const String programSource = program->source().toString();
......@@ -900,11 +899,6 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
if (vm.isCollectorBusy())
return jsNull();
StackStats::CheckPoint stackCheckPoint;
const VMStackBounds vmStackBounds(vm, wtfThreadData().stack());
if (!vmStackBounds.isSafeToRecurse())
return checkedReturn(throwStackOverflowError(callFrame));
bool isJSCall = (callType == CallTypeJS);
JSScope* scope;
CodeBlock* newCodeBlock;
......@@ -916,7 +910,10 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
ASSERT(callType == CallTypeHost);
scope = callFrame->scope();
}
DynamicGlobalObjectScope globalObjectScope(vm, scope->globalObject());
VMEntryScope entryScope(vm, scope->globalObject());
if (!vm.isSafeToRecurse())
return checkedReturn(throwStackOverflowError(callFrame));
if (isJSCall) {
// Compile the callee:
......@@ -978,11 +975,6 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
if (vm.isCollectorBusy())
return checkedReturn(throwStackOverflowError(callFrame));
StackStats::CheckPoint stackCheckPoint;
const VMStackBounds vmStackBounds(vm, wtfThreadData().stack());
if (!vmStackBounds.isSafeToRecurse())