Changeset 160967 in webkit
- Timestamp:
- Dec 21, 2013, 11:25:09 AM (11 years ago)
- Location:
- branches/jsCStack/Source/JavaScriptCore
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/jsCStack/Source/JavaScriptCore/ChangeLog
r160963 r160967 1 2013-12-21 Mark Lam <mark.lam@apple.com> 2 3 CStack: Update the VMEntryScope's stack limit when the VM enters/exits ErrorMode. 4 https://bugs.webkit.org/show_bug.cgi?id=126009. 5 6 Not yet reviewed. 7 8 1. Renamed JSStack::updateStackLimit() to setStackLimit() because that 9 is what it actually does. We're going to repurpose the updateStackLimit 10 name for another function. 11 12 2. Fixed a bug in setStackLimit() where setJSStackLimit() was called with 13 the value of newEnd which points past the end of the stack. The fix is 14 to add 1 to point at the last slot at top of the stack. This is what is 15 the users of the jsStackLimit value expects. 16 17 3. Introduce the new JSStack::updateStackLimit() which is responsible for 18 re-setting the current stack limit. updateStackLimit() will handle both 19 cases of the JS stack being on the C stack or a separate stack. 20 21 For the C stack case, JStack::updateStackLimit() will check if a 22 VMEntryScope has been installed in the VM. If so, it will tell the 23 VMEntryScope to do the real work of updating the stack limit. The 24 VMEntryScope will take into account whether the VM's Interpreter is 25 in an error handling mode or not when determining the amount of host 26 zone space to reserve on the stack for computing the stack limit value. 27 28 4. Interpreter::ErrorHandlingMode now calls JSStack::updateStackLimit 29 whenever it enters / exit error handling mode. This allows the stack 30 limit to change with the error mode change. 31 32 5. A lot of places in the code were throwing StackOverflowErrors by 33 creating and throwing the error themselves instead of using the 34 throwStackOverflowError() helper function. As a result, the VM never 35 got the chance to enter error mode. This is a bug and is now fixed by 36 making all these sites use throwStackOverflowError() instead. 37 38 For sites that can't use throwStackOverflowError(), I updated them to 39 instantiate Interpreter::ErrorHandlingMode to set the error mode 40 appropriately. 41 42 6. Made JSStack::enableErrorStackReserve() and disableErrorStackReserve() 43 private. They are no longer called from outside of JSStack. 44 45 * interpreter/Interpreter.cpp: 46 (JSC::Interpreter::ErrorHandlingMode::ErrorHandlingMode): 47 (JSC::Interpreter::ErrorHandlingMode::~ErrorHandlingMode): 48 (JSC::sizeFrameForVarargs): 49 * interpreter/JSStack.cpp: 50 (JSC::JSStack::JSStack): 51 (JSC::JSStack::growSlowCase): 52 (JSC::JSStack::updateStackLimit): 53 * interpreter/JSStack.h: 54 * interpreter/JSStackInlines.h: 55 (JSC::JSStack::shrink): 56 (JSC::JSStack::setStackLimit): 57 * jit/JITOperations.cpp: 58 * llint/LLIntSlowPaths.cpp: 59 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 60 * parser/ParserError.h: 61 (JSC::ParserError::toErrorObject): 62 * runtime/CommonSlowPaths.cpp: 63 (JSC::SLOW_PATH_DECL): 64 * runtime/JSONObject.cpp: 65 (JSC::Walker::walk): 66 * runtime/StringRecursionChecker.cpp: 67 (JSC::StringRecursionChecker::throwStackOverflowError): 68 * runtime/VMEntryScope.cpp: 69 (JSC::VMEntryScope::VMEntryScope): 70 (JSC::VMEntryScope::updateStackLimit): 71 * runtime/VMEntryScope.h: 72 1 73 2013-12-21 Filip Pizlo <fpizlo@apple.com> 2 74 -
branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp
r160960 r160967 95 95 : m_interpreter(*exec->interpreter()) 96 96 { 97 if (!m_interpreter.m_errorHandlingModeReentry)98 m_interpreter.stack().enableErrorStackReserve();99 97 m_interpreter.m_errorHandlingModeReentry++; 98 m_interpreter.stack().updateStackLimit(); 100 99 } 101 100 … … 105 104 ASSERT(m_interpreter.m_errorHandlingModeReentry >= 0); 106 105 if (!m_interpreter.m_errorHandlingModeReentry) 107 m_interpreter.stack(). disableErrorStackReserve();106 m_interpreter.stack().updateStackLimit(); 108 107 } 109 108 … … 162 161 CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset); 163 162 if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->ensureCapacityFor(newCallFrame->registers())) { 164 callFrame->vm().throwException(callFrame, createStackOverflowError(callFrame));163 throwStackOverflowError(callFrame); 165 164 return 0; 166 165 } … … 173 172 CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset); 174 173 if (!stack->ensureCapacityFor(newCallFrame->registers())) { 175 callFrame->vm().throwException(callFrame, createStackOverflowError(callFrame));174 throwStackOverflowError(callFrame); 176 175 return 0; 177 176 } … … 190 189 CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset); 191 190 if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) { 192 callFrame->vm().throwException(callFrame, createStackOverflowError(callFrame));191 throwStackOverflowError(callFrame); 193 192 return 0; 194 193 } … … 202 201 CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset); 203 202 if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) { 204 callFrame->vm().throwException(callFrame, createStackOverflowError(callFrame));203 throwStackOverflowError(callFrame); 205 204 return 0; 206 205 } … … 213 212 CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset); 214 213 if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) { 215 callFrame->vm().throwException(callFrame, createStackOverflowError(callFrame));214 throwStackOverflowError(callFrame); 216 215 return 0; 217 216 } -
branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.cpp
r160824 r160967 32 32 #include "ConservativeRoots.h" 33 33 #include "Interpreter.h" 34 #include "VMEntryScope.h" 34 35 35 36 namespace JSC { … … 51 52 52 53 m_reservation = PageReservation::reserve(roundUpAllocationSize(capacity * sizeof(Register), commitSize), OSAllocator::JSVMStackPages); 53 updateStackLimit(highAddress());54 setStackLimit(highAddress()); 54 55 m_commitEnd = highAddress(); 55 56 … … 74 75 // just update the end pointer and return. 75 76 if (newEnd >= m_commitEnd) { 76 updateStackLimit(newEnd);77 setStackLimit(newEnd); 77 78 return true; 78 79 } … … 90 91 addToCommittedByteCount(delta); 91 92 m_commitEnd = reinterpret_cast_ptr<Register*>(reinterpret_cast<char*>(m_commitEnd) - delta); 92 updateStackLimit(newEnd);93 setStackLimit(newEnd); 93 94 return true; 94 95 } … … 176 177 } 177 178 179 void JSStack::updateStackLimit() 180 { 181 #if ENABLE(LLINT_C_LOOP) 182 if (m_vm.interpreter->isInErrorHandlingMode()) 183 enableErrorStackReserve(); 184 else 185 disableErrorStackReserve(); 186 #endif 187 if (m_vm.entryScope) 188 m_vm.entryScope->updateStackLimit(); 189 } 190 178 191 } // namespace JSC -
branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.h
r160960 r160967 84 84 bool ensureCapacityFor(Register* newTopOfStack); 85 85 86 void updateStackLimit(); 87 86 88 void gatherConservativeRoots(ConservativeRoots&); 87 89 void gatherConservativeRoots(ConservativeRoots&, JITStubRoutineSet&, CodeBlockSet&); … … 105 107 106 108 bool containsAddress(Register* address) { return (lowAddress() <= address && address <= highAddress()); } 107 108 void enableErrorStackReserve();109 void disableErrorStackReserve();110 109 111 110 #if ENABLE(DEBUG_JSSTACK) … … 153 152 void addToCommittedByteCount(long); 154 153 155 void updateStackLimit(Register* newEnd); 154 void setStackLimit(Register* newEnd); 155 156 void enableErrorStackReserve(); 157 void disableErrorStackReserve(); 156 158 157 159 VM& m_vm; -
branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h
r160960 r160967 170 170 if (newEnd >= m_end) 171 171 return; 172 updateStackLimit(newEnd);172 setStackLimit(newEnd); 173 173 if (m_end == baseOfStack() && (m_commitEnd - baseOfStack()) >= maxExcessCapacity) 174 174 releaseExcessCapacity(); … … 183 183 } 184 184 185 inline void JSStack:: updateStackLimit(Register* newEnd)185 inline void JSStack::setStackLimit(Register* newEnd) 186 186 { 187 187 m_end = newEnd; 188 188 #if ENABLE(LLINT_C_LOOP) 189 m_vm.setJSStackLimit(newEnd );189 m_vm.setJSStackLimit(newEnd + 1); 190 190 #endif 191 191 } -
branches/jsCStack/Source/JavaScriptCore/jit/JITOperations.cpp
r160893 r160967 80 80 81 81 NativeCallFrameTracer tracer(vm, callerFrame); 82 Interpreter::ErrorHandlingMode mode(callerFrame); 82 83 vm->throwException(callerFrame, createStackOverflowError(callerFrame)); 83 84 } … … 93 94 int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &stack, CodeForCall); 94 95 if (missingArgCount < 0) 95 vm->throwException(callerFrame, createStackOverflowError(callerFrame));96 throwStackOverflowError(callerFrame); 96 97 97 98 return missingArgCount; … … 108 109 int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &stack, CodeForConstruct); 109 110 if (missingArgCount < 0) 110 vm->throwException(callerFrame, createStackOverflowError(callerFrame));111 throwStackOverflowError(callerFrame); 111 112 112 113 return missingArgCount; … … 704 705 JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind); 705 706 if (error) { 706 vm->throwException(exec, createStackOverflowError(exec));707 throwStackOverflowError(exec); 707 708 return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress()); 708 709 } -
branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r160960 r160967 452 452 { 453 453 exec = exec->callerFrame(); 454 Interpreter::ErrorHandlingMode mode(exec); 454 455 CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec)); 455 456 pc = returnToThrowForThrownException(exec); -
branches/jsCStack/Source/JavaScriptCore/parser/ParserError.h
r149014 r160967 95 95 case EvalError: 96 96 return createSyntaxError(globalObject, m_message); 97 case StackOverflow: 97 case StackOverflow: { 98 Interpreter::ErrorHandlingMode mode(globalObject->globalExec()); 98 99 return createStackOverflowError(globalObject); 100 } 99 101 case OutOfMemory: 100 102 return createOutOfMemoryError(globalObject); -
branches/jsCStack/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
r160936 r160967 191 191 if (slotsToAdd < 0) { 192 192 exec = exec->callerFrame(); 193 Interpreter::ErrorHandlingMode mode(exec); 193 194 CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec)); 194 195 RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec); … … 203 204 if (slotsToAdd < 0) { 204 205 exec = exec->callerFrame(); 206 Interpreter::ErrorHandlingMode mode(exec); 205 207 CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec)); 206 208 RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec); -
branches/jsCStack/Source/JavaScriptCore/runtime/JSONObject.cpp
r157614 r160967 655 655 ASSERT(isJSArray(asObject(inValue)) || asObject(inValue)->inherits(JSArray::info())); 656 656 if (objectStack.size() + arrayStack.size() > maximumFilterRecursion) 657 return m_exec->vm().throwException(m_exec, createStackOverflowError(m_exec));657 return throwStackOverflowError(m_exec); 658 658 659 659 JSArray* array = asArray(inValue); … … 706 706 ASSERT(!isJSArray(asObject(inValue)) && !asObject(inValue)->inherits(JSArray::info())); 707 707 if (objectStack.size() + arrayStack.size() > maximumFilterRecursion) 708 return m_exec->vm().throwException(m_exec, createStackOverflowError(m_exec));708 return throwStackOverflowError(m_exec); 709 709 710 710 JSObject* object = asObject(inValue); -
branches/jsCStack/Source/JavaScriptCore/runtime/StringRecursionChecker.cpp
r154797 r160967 29 29 JSValue StringRecursionChecker::throwStackOverflowError() 30 30 { 31 return m_exec->vm().throwException(m_exec, createStackOverflowError(m_exec));31 return JSC::throwStackOverflowError(m_exec); 32 32 } 33 33 -
branches/jsCStack/Source/JavaScriptCore/runtime/VMEntryScope.cpp
r160694 r160967 54 54 vm.clearExceptionStack(); 55 55 56 void* limit = m_stack.recursionLimit(requiredCapacity()); 57 vm.setStackLimit(limit); 56 updateStackLimit(); 58 57 vm.setLastStackTop(m_stack.origin()); 59 58 } … … 64 63 m_vm.setStackLimit(m_prevStackLimit); 65 64 m_vm.setLastStackTop(m_prevLastStackTop); 65 } 66 67 void VMEntryScope::updateStackLimit() 68 { 69 void* limit = m_stack.recursionLimit(requiredCapacity()); 70 m_vm.setStackLimit(limit); 66 71 } 67 72 -
branches/jsCStack/Source/JavaScriptCore/runtime/VMEntryScope.h
r160694 r160967 41 41 JS_EXPORT_PRIVATE ~VMEntryScope(); 42 42 43 void updateStackLimit(); 43 44 JSGlobalObject* globalObject() const { return m_globalObject; } 44 45
Note:
See TracChangeset
for help on using the changeset viewer.