Changeset 160947 in webkit
- Timestamp:
- Dec 20, 2013 4:56:24 PM (10 years ago)
- Location:
- branches/jsCStack/Source/JavaScriptCore
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/jsCStack/Source/JavaScriptCore/ChangeLog
r160936 r160947 1 2013-12-20 Mark Lam <mark.lam@apple.com> 2 3 CStack: callToJavaScript should do stack check for incoming args. 4 https://bugs.webkit.org/show_bug.cgi?id=126088. 5 6 Not yet reviewed. 7 8 1. Change callToJavaScript()'s prototype to: 9 EncodedJSValue callToJavaScript(void*, VM*, ProtoCallFrame*); 10 11 We now pass VM* instead of &vm.topCallFrame for the second argument. 12 This gives us greater utility out of that arg. 13 We also now save the VM* in the VMEntrySentinelFrame instead of 14 &vm.topCallFrame. 15 16 2. Change callToJavaScript() to do a stack check to ensure that we have 17 adequate stack space to copy all the args from the protoCallFrame. 18 If not, it'll throw a StackOverflowError. 19 20 3. Removed JSStack::entryCheck() and calls to it. 21 22 callToJavaScript now takes care of the stack check that ensures 23 adequate stack space for incoming args. 24 callToJavaScript does assume that we have adequate stack space for 25 the VMEntrySentinelFrame, but that is ensured by our stack host zone. 26 27 Changes to callToJavaScript are done in the doCallToJavaScript macro. 28 Hence, all the changes apply to callToNativeFunction as well. 29 30 * interpreter/Interpreter.cpp: 31 (JSC::Interpreter::execute): 32 (JSC::Interpreter::executeCall): 33 (JSC::Interpreter::executeConstruct): 34 (JSC::Interpreter::prepareForRepeatCall): 35 * interpreter/JSStack.h: 36 * interpreter/JSStackInlines.h: 37 * jit/JITCode.cpp: 38 (JSC::JITCode::execute): 39 * jit/JITStubs.h: 40 * jit/JITStubsMSVC64.asm: Added a FIXME. 41 * jit/JITStubsX86.h: Added a FIXME. 42 * llint/LLIntSlowPaths.cpp: 43 (JSC::LLInt::llint_throw_stack_overflow_error): 44 * llint/LLIntSlowPaths.h: 45 * llint/LLIntThunks.h: 46 * llint/LowLevelInterpreter64.asm: 47 1 48 2013-12-20 Filip Pizlo <fpizlo@apple.com> 2 49 -
branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp
r160831 r160947 893 893 ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'. 894 894 895 if (UNLIKELY(!m_stack.entryCheck(codeBlock, 1)))896 return checkedReturn(throwStackOverflowError(callFrame));897 898 895 ProtoCallFrame protoCallFrame; 899 896 protoCallFrame.init(codeBlock, scope, 0, thisObj, 1); … … 956 953 return throwTerminatedExecutionException(callFrame); 957 954 958 if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount)))959 return checkedReturn(throwStackOverflowError(callFrame));960 961 955 ProtoCallFrame protoCallFrame; 962 956 protoCallFrame.init(newCodeBlock, scope, function, thisValue, argsCount, args.data()); … … 974 968 result = callData.js.functionExecutable->generatedJITCodeForCall()->execute(&vm, &protoCallFrame); 975 969 else 976 result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(callData.native.function), &vm .topCallFrame, &protoCallFrame));970 result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(callData.native.function), &vm, &protoCallFrame)); 977 971 } 978 972 … … 1024 1018 return throwTerminatedExecutionException(callFrame); 1025 1019 1026 if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount)))1027 return checkedReturn(throwStackOverflowError(callFrame));1028 1029 1020 ProtoCallFrame protoCallFrame; 1030 1021 protoCallFrame.init(newCodeBlock, scope, constructor, jsUndefined(), argsCount, args.data()); … … 1042 1033 result = constructData.js.functionExecutable->generatedJITCodeForConstruct()->execute(&vm, &protoCallFrame); 1043 1034 else { 1044 result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(constructData.native.function), &vm .topCallFrame, &protoCallFrame));1035 result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(constructData.native.function), &vm, &protoCallFrame)); 1045 1036 1046 1037 if (!callFrame->hadException()) … … 1076 1067 1077 1068 size_t argsCount = argumentCountIncludingThis; 1078 1079 if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount))) {1080 throwStackOverflowError(callFrame);1081 return CallFrameClosure();1082 }1083 1069 1084 1070 protoCallFrame->init(newCodeBlock, scope, function, jsUndefined(), argsCount, args); … … 1182 1168 1183 1169 ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'. 1184 1185 if (UNLIKELY(!m_stack.entryCheck(codeBlock, 1)))1186 return checkedReturn(throwStackOverflowError(callFrame));1187 1170 1188 1171 ProtoCallFrame protoCallFrame; -
branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.h
r160835 r160947 102 102 Register* topOfStack(); 103 103 104 bool entryCheck(class CodeBlock*, int);105 106 104 CallFrame* pushFrame(class CodeBlock*, JSScope*, int argsCount, JSObject* callee); 107 105 -
branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h
r160835 r160947 52 52 } 53 53 54 inline bool JSStack::entryCheck(class CodeBlock* codeBlock, int argsCount)55 {56 Register* oldEnd = topOfStack();57 58 // Ensure that we have enough space for the parameters:59 size_t paddedArgsCount = argsCount;60 if (codeBlock) {61 size_t numParameters = codeBlock->numParameters();62 if (paddedArgsCount < numParameters)63 paddedArgsCount = numParameters;64 }65 66 Register* newCallFrameSlot = oldEnd - paddedArgsCount - (2 * JSStack::CallFrameHeaderSize) + 1;67 68 #if ENABLE(DEBUG_JSSTACK)69 newCallFrameSlot -= JSStack::FenceSize;70 #endif71 72 Register* topOfStack = newCallFrameSlot;73 if (!!codeBlock)74 topOfStack += codeBlock->stackPointerOffset();75 76 // Ensure that we have the needed stack capacity to push the new frame:77 if (!grow(topOfStack))78 return false;79 80 return true;81 }82 83 54 inline CallFrame* JSStack::pushFrame(class CodeBlock* codeBlock, JSScope* scope, int argsCount, JSObject* callee) 84 55 { -
branches/jsCStack/Source/JavaScriptCore/jit/JITCode.cpp
r160936 r160947 45 45 JSValue JITCode::execute(VM* vm, ProtoCallFrame* protoCallFrame) 46 46 { 47 JSValue result = JSValue::decode(callToJavaScript(executableAddress(), &vm->topCallFrame, protoCallFrame));47 JSValue result = JSValue::decode(callToJavaScript(executableAddress(), vm, protoCallFrame)); 48 48 return vm->exception() ? jsNull() : result; 49 49 } -
branches/jsCStack/Source/JavaScriptCore/jit/JITStubs.h
r160660 r160947 38 38 39 39 #if OS(WINDOWS) 40 class ExecState;41 class Register;42 40 struct ProtoCallFrame; 41 class VM; 43 42 44 43 extern "C" { 45 EncodedJSValue callToJavaScript(void*, ExecState**, ProtoCallFrame*); 44 EncodedJSValue callToJavaScript(void*, VM*, ProtoCallFrame*); 45 EncodedJSValue callToNativeFunction(void*, VM*, ProtoCallFrame*); 46 46 void handleUncaughtException(); 47 EncodedJSValue callToNativeFunction(void*, ExecState**, ProtoCallFrame*);48 47 } 49 48 #endif -
branches/jsCStack/Source/JavaScriptCore/jit/JITStubsMSVC64.asm
r160497 r160947 36 36 ;; It is believed to be an accurate adaptation of the assembly created by the llint stub of the 37 37 ;; same name with changes for agrument register differences. 38 39 ;; FIXME: This code is stale and need to be updated for the following: 40 ;; 1. The prototype is now: 41 ;; EncodedJSValue callToJavaScript(void* code, VM*, ProtoCallFrame*) 42 ;; The code below was implemented for a prototype of: 43 ;; EncodedJSValue callToJavaScript(void* code, ExecState**, ProtoCallFrame*, Register*) 44 ;; 45 ;; 2. Need to add code for a stack check to ensure that we have enough stack space 46 ;; for incoming args. 47 38 48 int 3 39 49 mov r10, qword ptr[rsp] -
branches/jsCStack/Source/JavaScriptCore/jit/JITStubsX86.h
r160497 r160947 207 207 // FIXME: Since Windows doesn't use the LLInt, we have inline stubs here. 208 208 // Until the LLInt is changed to support Windows, these stub needs to be updated. 209 210 // FIXME: This code is stale and need to be updated for the following: 211 // 1. The prototype is now: 212 // EncodedJSValue callToJavaScript(void* code, VM*, ProtoCallFrame*) 213 // I've left the old prototype in place to give context for what the implementation 214 // below is doing. 215 // 216 // 2. Need to add code for a stack check to ensure that we have enough stack space 217 // for incoming args. 218 209 219 __declspec(naked) EncodedJSValue callToJavaScript(void* code, ExecState**, ProtoCallFrame*, Register*) 210 220 { -
branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r160936 r160947 52 52 #include "ObjectConstructor.h" 53 53 #include "Operations.h" 54 #include "ProtoCallFrame.h" 54 55 #include "StructureRareDataInlines.h" 55 56 #include <wtf/StringPrintStream.h> … … 1393 1394 } 1394 1395 1396 void llint_throw_stack_overflow_error(VM* vm, ProtoCallFrame* protoFrame) 1397 { 1398 ExecState* exec = vm->topCallFrame; 1399 if (!exec) 1400 exec = protoFrame->scope()->globalObject()->globalExec(); 1401 throwStackOverflowError(exec); 1402 } 1403 1395 1404 } } // namespace JSC::LLInt 1396 1405 -
branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.h
r160831 r160947 37 37 class ExecState; 38 38 struct Instruction; 39 struct ProtoCallFrame; 39 40 40 41 namespace LLInt { … … 123 124 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_from_scope); 124 125 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_to_scope); 126 extern "C" void llint_throw_stack_overflow_error(VM*, ProtoCallFrame*); 125 127 126 128 } } // namespace JSC::LLInt -
branches/jsCStack/Source/JavaScriptCore/llint/LLIntThunks.h
r160660 r160947 35 35 namespace JSC { 36 36 37 class ExecState;38 class Register;39 37 class VM; 40 38 struct ProtoCallFrame; 41 39 42 40 extern "C" { 43 EncodedJSValue callToJavaScript(void*, ExecState**, ProtoCallFrame*);44 EncodedJSValue callToNativeFunction(void*, ExecState**, ProtoCallFrame*);41 EncodedJSValue callToJavaScript(void*, VM*, ProtoCallFrame*); 42 EncodedJSValue callToNativeFunction(void*, VM*, ProtoCallFrame*); 45 43 #if ENABLE(JIT) 46 44 void handleUncaughtException(); -
branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r160936 r160947 152 152 if X86_64 153 153 const entry = t4 154 const vm TopCallFrame= t5154 const vm = t5 155 155 const protoCallFrame = t1 156 const topOfStack = t2157 156 158 157 const previousCFR = t0 … … 163 162 elsif ARM64 164 163 const entry = a0 165 const vm TopCallFrame= a1164 const vm = a1 166 165 const protoCallFrame = a2 167 const topOfStack = a3168 166 169 167 const previousCFR = t5 … … 182 180 checkStackPointerAlignment(temp2, 0xbad0dc01) 183 181 184 # Allocate and initialize the sentinel frame. 182 # The stack host zone ensures that we have adequate space for the 183 # VMEntrySentinelFrame. Proceed with allocating and initializing the 184 # sentinel frame. 185 185 move sp, cfr 186 186 subp CallFrameHeaderSlots*8, cfr 187 187 storep 0, ArgumentCount[cfr] 188 storep vm TopCallFrame, Callee[cfr]189 loadp [vmTopCallFrame], temp2188 storep vm, Callee[cfr] 189 loadp VM::topCallFrame[vm], temp2 190 190 storep temp2, ScopeChain[cfr] 191 191 storep 1, CodeBlock[cfr] … … 196 196 addp CallFrameHeaderSlots, temp2, temp2 197 197 lshiftp 3, temp2 198 subp cfr, temp2, sp 199 198 subp cfr, temp2, temp1 199 200 # Ensure that we have enough additional stack capacity for the incoming args, 201 # and the frame for the JS code we're executing. We need to do this check 202 # before we start copying the args from the protoCallFrame below. 203 bpaeq temp1, VM::m_jsStackLimit[vm], .stackHeightOK 204 205 move cfr, sp 206 207 if C_LOOP 208 # FIXME: Need to call stack check here to see if we can grow the stack. 209 # Will need to preserve registers so that we can recover if we do not end 210 # up throwing a StackOverflowError. 211 end 212 213 cCall2(_llint_throw_stack_overflow_error, vm, protoCallFrame) 214 callToJavaScriptEpilogue() 215 ret 216 217 .stackHeightOK: 218 move temp1, sp 200 219 move 5, temp1 201 220 … … 229 248 230 249 .copyArgsDone: 231 storep sp, [vmTopCallFrame]250 storep sp, VM::topCallFrame[vm] 232 251 233 252 move 0xffff000000000000, csr1 … … 244 263 245 264 .calleeFramePopped: 246 loadp Callee[cfr], temp2 # VM .topCallFrame247 loadp ScopeChain[cfr], temp3 248 storep temp3, [temp2]265 loadp Callee[cfr], temp2 # VM 266 loadp ScopeChain[cfr], temp3 # previous topCallFrame 267 storep temp3, VM::topCallFrame[temp2] 249 268 250 269 checkStackPointerAlignment(temp3, 0xbad0dc04) … … 286 305 loadp CallerFrame[cfr], cfr 287 306 288 loadp Callee[cfr], t3 # VM .topCallFrame289 loadp ScopeChain[cfr], t6 290 storep t6, [t3]307 loadp Callee[cfr], t3 # VM 308 loadp ScopeChain[cfr], t6 # previous topCallFrame 309 storep t6, VM::topCallFrame[t3] 291 310 292 311 callToJavaScriptEpilogue()
Note: See TracChangeset
for help on using the changeset viewer.