Changeset 179887 in webkit
- Timestamp:
- Feb 10, 2015, 3:16:36 PM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 1 added
- 18 edited
-
ChangeLog (modified) (1 diff)
-
interpreter/Interpreter.cpp (modified) (4 diffs)
-
interpreter/Interpreter.h (modified) (3 diffs)
-
jit/CCallHelpers.h (modified) (4 diffs)
-
jit/JIT.h (modified) (3 diffs)
-
jit/JITCall.cpp (modified) (1 diff)
-
jit/JITCall32_64.cpp (modified) (1 diff)
-
jit/JITInlines.h (modified) (4 diffs)
-
jit/JITOperations.cpp (modified) (2 diffs)
-
jit/JITOperations.h (modified) (3 diffs)
-
jit/SetupVarargsFrame.cpp (modified) (2 diffs)
-
jit/SetupVarargsFrame.h (modified) (1 diff)
-
llint/LLIntSlowPaths.cpp (modified) (3 diffs)
-
runtime/Arguments.cpp (modified) (1 diff)
-
runtime/Arguments.h (modified) (1 diff)
-
runtime/JSArray.cpp (modified) (3 diffs)
-
runtime/JSArray.h (modified) (1 diff)
-
runtime/VM.h (modified) (1 diff)
-
tests/stress/call-varargs-length-effects.js (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r179882 r179887 1 2015-02-10 Filip Pizlo <fpizlo@apple.com> 2 3 op_call_varargs should only load the length once 4 https://bugs.webkit.org/show_bug.cgi?id=141440 5 rdar://problem/19761683 6 7 Reviewed by Michael Saboff. 8 9 Refactors the pair of calls that set up the varargs frame so that the first call returns the 10 length, and the second call uses the length returned by the first one. It turns out that this 11 gave me an opportunity to shorten a lot of the code. 12 13 * interpreter/Interpreter.cpp: 14 (JSC::sizeFrameForVarargs): 15 (JSC::loadVarargs): 16 (JSC::setupVarargsFrame): 17 (JSC::setupVarargsFrameAndSetThis): 18 * interpreter/Interpreter.h: 19 (JSC::calleeFrameForVarargs): 20 * jit/CCallHelpers.h: 21 (JSC::CCallHelpers::setupArgumentsWithExecState): 22 * jit/JIT.h: 23 * jit/JITCall.cpp: 24 (JSC::JIT::compileSetupVarargsFrame): 25 * jit/JITCall32_64.cpp: 26 (JSC::JIT::compileSetupVarargsFrame): 27 * jit/JITInlines.h: 28 (JSC::JIT::callOperation): 29 * jit/JITOperations.cpp: 30 * jit/JITOperations.h: 31 * jit/SetupVarargsFrame.cpp: 32 (JSC::emitSetVarargsFrame): 33 (JSC::emitSetupVarargsFrameFastCase): 34 * jit/SetupVarargsFrame.h: 35 * llint/LLIntSlowPaths.cpp: 36 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 37 * runtime/Arguments.cpp: 38 (JSC::Arguments::copyToArguments): 39 * runtime/Arguments.h: 40 * runtime/JSArray.cpp: 41 (JSC::JSArray::copyToArguments): 42 * runtime/JSArray.h: 43 * runtime/VM.h: 44 * tests/stress/call-varargs-length-effects.js: Added. 45 (foo): 46 (bar): 47 1 48 2015-02-10 Michael Saboff <msaboff@apple.com> 2 49 -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r179862 r179887 1 1 /* 2 * Copyright (C) 2008, 2009, 2010, 2012, 2013, 2014 Apple Inc. All rights reserved.2 * Copyright (C) 2008, 2009, 2010, 2012, 2013, 2014, 2015 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca> 4 4 * … … 135 135 } 136 136 137 CallFrame* sizeFrameForVarargs(CallFrame* callFrame, JSStack* stack, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset) 138 { 139 if (!arguments) { // f.apply(x, arguments), with arguments unmodified. 140 unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis(); 141 if (argumentCountIncludingThis > firstVarArgOffset) 142 argumentCountIncludingThis -= firstVarArgOffset; 143 else 144 argumentCountIncludingThis = 1; 145 unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize); 146 CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset); 147 if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->ensureCapacityFor(newCallFrame->registers())) { 148 throwStackOverflowError(callFrame); 149 return 0; 150 } 151 return newCallFrame; 152 } 153 154 if (arguments.isUndefinedOrNull()) { 155 unsigned argumentCountIncludingThis = 1; 156 unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize); 157 CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset); 158 if (!stack->ensureCapacityFor(newCallFrame->registers())) { 159 throwStackOverflowError(callFrame); 160 return 0; 161 } 162 return newCallFrame; 163 } 164 165 if (!arguments.isObject()) { 137 unsigned sizeFrameForVarargs(CallFrame* callFrame, JSStack* stack, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset) 138 { 139 unsigned length; 140 if (!arguments) 141 length = callFrame->argumentCount(); 142 else if (arguments.isUndefinedOrNull()) 143 length = 0; 144 else if (!arguments.isObject()) { 166 145 callFrame->vm().throwException(callFrame, createInvalidParameterError(callFrame, "Function.prototype.apply", arguments)); 167 146 return 0; 168 } 169 170 if (asObject(arguments)->classInfo() == Arguments::info()) { 171 Arguments* argsObject = asArguments(arguments); 172 unsigned argCount = argsObject->length(callFrame); 173 if (argCount >= firstVarArgOffset) 174 argCount -= firstVarArgOffset; 175 else 176 argCount = 0; 177 unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argCount + 1 + JSStack::CallFrameHeaderSize); 178 CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset); 179 if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) { 180 throwStackOverflowError(callFrame); 181 return 0; 182 } 183 return newCallFrame; 184 } 185 186 if (isJSArray(arguments)) { 187 JSArray* array = asArray(arguments); 188 unsigned argCount = array->length(); 189 if (argCount >= firstVarArgOffset) 190 argCount -= firstVarArgOffset; 191 else 192 argCount = 0; 193 unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argCount + 1 + JSStack::CallFrameHeaderSize); 194 CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset); 195 if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) { 196 throwStackOverflowError(callFrame); 197 return 0; 198 } 199 return newCallFrame; 200 } 201 202 JSObject* argObject = asObject(arguments); 203 unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame); 204 if (argCount >= firstVarArgOffset) 205 argCount -= firstVarArgOffset; 147 } else if (asObject(arguments)->classInfo() == Arguments::info()) 148 length = asArguments(arguments)->length(callFrame); 149 else if (isJSArray(arguments)) 150 length = asArray(arguments)->length(); 206 151 else 207 argCount = 0; 208 unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argCount + 1 + JSStack::CallFrameHeaderSize); 209 CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset); 210 if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) { 152 length = asObject(arguments)->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame); 153 154 if (length >= firstVarArgOffset) 155 length -= firstVarArgOffset; 156 else 157 length = 0; 158 159 CallFrame* calleeFrame = calleeFrameForVarargs(callFrame, numUsedStackSlots, length + 1); 160 if (length > Arguments::MaxArguments || !stack->ensureCapacityFor(calleeFrame->registers())) { 211 161 throwStackOverflowError(callFrame); 212 162 return 0; 213 163 } 214 return newCallFrame; 215 } 216 217 void loadVarargs(CallFrame* callFrame, VirtualRegister firstElementDest, VirtualRegister countDest, JSValue arguments, uint32_t firstVarArgOffset) 164 165 return length; 166 } 167 168 void loadVarargs(CallFrame* callFrame, VirtualRegister firstElementDest, JSValue arguments, uint32_t offset, uint32_t length) 218 169 { 219 170 if (!arguments) { // f.apply(x, arguments), with arguments unmodified. 220 unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis(); 221 if (argumentCountIncludingThis > firstVarArgOffset) 222 argumentCountIncludingThis -= firstVarArgOffset; 223 else 224 argumentCountIncludingThis = 1; 225 callFrame->r(countDest).payload() = argumentCountIncludingThis; 226 for (size_t i = firstVarArgOffset; i < callFrame->argumentCount(); ++i) 227 callFrame->r(firstElementDest + i - firstVarArgOffset) = callFrame->argumentAfterCapture(i); 171 for (size_t i = 0; i < length; ++i) 172 callFrame->r(firstElementDest + i) = callFrame->argumentAfterCapture(i + offset); 228 173 return; 229 174 } 230 175 231 if (arguments.isUndefinedOrNull()) { 232 callFrame->r(countDest).payload() = 1; 176 if (arguments.isUndefinedOrNull()) 233 177 return; 234 }235 178 236 179 if (asObject(arguments)->classInfo() == Arguments::info()) { 237 Arguments* argsObject = asArguments(arguments); 238 unsigned argCount = argsObject->length(callFrame); 239 if (argCount >= firstVarArgOffset) { 240 argCount -= firstVarArgOffset; 241 callFrame->r(countDest).payload() = argCount + 1; 242 argsObject->copyToArguments(callFrame, firstElementDest, argCount, firstVarArgOffset); 243 } else 244 callFrame->r(countDest).payload() = 1; 180 asArguments(arguments)->copyToArguments(callFrame, firstElementDest, offset, length); 245 181 return; 246 182 } 247 183 248 184 if (isJSArray(arguments)) { 249 JSArray* array = asArray(arguments); 250 unsigned argCount = array->length(); 251 if (argCount >= firstVarArgOffset) { 252 argCount -= firstVarArgOffset; 253 callFrame->r(countDest).payload() = argCount + 1; 254 array->copyToArguments(callFrame, firstElementDest, argCount, firstVarArgOffset); 255 } else 256 callFrame->r(countDest).payload() = 1; 185 asArray(arguments)->copyToArguments(callFrame, firstElementDest, offset, length); 257 186 return; 258 187 } 259 188 260 JSObject* argObject = asObject(arguments); 261 unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame); 262 if (argCount >= firstVarArgOffset) { 263 argCount -= firstVarArgOffset; 264 callFrame->r(countDest).payload() = argCount + 1; 265 } else 266 callFrame->r(countDest).payload() = 1; 267 268 for (size_t i = 0; i < argCount; ++i) { 269 callFrame->r(firstElementDest + i) = asObject(arguments)->get(callFrame, i + firstVarArgOffset); 189 for (unsigned i = 0; i < length; ++i) { 190 callFrame->r(firstElementDest + i) = asObject(arguments)->get(callFrame, i + offset); 270 191 if (UNLIKELY(callFrame->vm().exception())) 271 192 return; … … 273 194 } 274 195 275 void setupVarargsFrame(CallFrame* callFrame, CallFrame* newCallFrame, JSValue arguments, uint32_t firstVarArgOffset)196 void setupVarargsFrame(CallFrame* callFrame, CallFrame* newCallFrame, JSValue arguments, uint32_t offset, uint32_t length) 276 197 { 277 198 VirtualRegister calleeFrameOffset(newCallFrame - callFrame); … … 280 201 callFrame, 281 202 calleeFrameOffset + CallFrame::argumentOffset(0), 282 calleeFrameOffset + JSStack::ArgumentCount, 283 arguments, firstVarArgOffset); 284 } 285 286 void setupVarargsFrameAndSetThis(CallFrame* callFrame, CallFrame* newCallFrame, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset) 287 { 288 setupVarargsFrame(callFrame, newCallFrame, arguments, firstVarArgOffset); 203 arguments, offset, length); 204 205 newCallFrame->setArgumentCountIncludingThis(length + 1); 206 } 207 208 void setupVarargsFrameAndSetThis(CallFrame* callFrame, CallFrame* newCallFrame, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length) 209 { 210 setupVarargsFrame(callFrame, newCallFrame, arguments, firstVarArgOffset, length); 289 211 newCallFrame->setThisValue(thisValue); 290 212 } -
trunk/Source/JavaScriptCore/interpreter/Interpreter.h
r179862 r179887 1 1 /* 2 * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2008, 2013, 2015 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2012 Research In Motion Limited. All rights reserved. 4 4 * … … 40 40 #include "Opcode.h" 41 41 #include "SourceProvider.h" 42 #include "StackAlignment.h" 42 43 43 44 #include <wtf/HashMap.h> … … 299 300 300 301 JSValue eval(CallFrame*); 301 CallFrame* sizeFrameForVarargs(CallFrame* exec, JSStack*, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset); 302 void loadVarargs(CallFrame* execCaller, VirtualRegister firstElementDest, VirtualRegister countDest, JSValue source, uint32_t offset); 303 void setupVarargsFrame(CallFrame* execCaller, CallFrame* execCallee, JSValue arguments, uint32_t firstVarArgOffset); 304 void setupVarargsFrameAndSetThis(CallFrame* execCaller, CallFrame* execCallee, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset); 302 303 inline CallFrame* calleeFrameForVarargs(CallFrame* callFrame, unsigned numUsedStackSlots, unsigned argumentCountIncludingThis) 304 { 305 unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf( 306 stackAlignmentRegisters(), 307 numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize); 308 return CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset); 309 } 310 311 unsigned sizeFrameForVarargs(CallFrame* exec, JSStack*, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset); 312 void loadVarargs(CallFrame* execCaller, VirtualRegister firstElementDest, JSValue source, uint32_t offset, uint32_t length); 313 void setupVarargsFrame(CallFrame* execCaller, CallFrame* execCallee, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length); 314 void setupVarargsFrameAndSetThis(CallFrame* execCaller, CallFrame* execCallee, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length); 305 315 306 316 } // namespace JSC -
trunk/Source/JavaScriptCore/jit/CCallHelpers.h
r175766 r179887 434 434 addCallArgument(arg3); 435 435 addCallArgument(arg4); 436 } 437 438 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, GPRReg arg5) 439 { 440 resetCallArguments(); 441 addCallArgument(GPRInfo::callFrameRegister); 442 addCallArgument(arg1); 443 addCallArgument(arg2); 444 addCallArgument(arg3); 445 addCallArgument(arg4); 446 addCallArgument(arg5); 436 447 } 437 448 … … 1382 1393 } 1383 1394 1395 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, GPRReg arg5) 1396 { 1397 poke(arg4, POKE_ARGUMENT_OFFSET); 1398 setupArgumentsWithExecState(arg1, arg2, arg3); 1399 } 1400 1384 1401 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4) 1385 1402 { … … 1524 1541 1525 1542 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImmPtr arg4) 1543 { 1544 poke(arg4, POKE_ARGUMENT_OFFSET); 1545 setupArgumentsWithExecState(arg1, arg2, arg3); 1546 } 1547 1548 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4) 1526 1549 { 1527 1550 poke(arg4, POKE_ARGUMENT_OFFSET); … … 1767 1790 setupThreeStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg1, arg2, arg3); 1768 1791 move(arg4, GPRInfo::argumentGPR4); 1792 move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 1793 } 1794 1795 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4) 1796 { 1797 setupThreeStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, GPRInfo::argumentGPR4>(arg1, arg2, arg4); 1798 move(arg3, GPRInfo::argumentGPR3); 1769 1799 move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 1770 1800 } -
trunk/Source/JavaScriptCore/jit/JIT.h
r179862 r179887 680 680 MacroAssembler::Call callOperation(C_JITOperation_ESt, Structure*); 681 681 MacroAssembler::Call callOperation(C_JITOperation_EZ, int32_t); 682 MacroAssembler::Call callOperation( F_JITOperation_EJZZ, GPRReg, int32_t, int32_t);682 MacroAssembler::Call callOperation(Z_JITOperation_EJZZ, GPRReg, int32_t, int32_t); 683 683 MacroAssembler::Call callOperation(J_JITOperation_E, int); 684 684 MacroAssembler::Call callOperation(J_JITOperation_EAapJ, int, ArrayAllocationProfile*, GPRReg); … … 731 731 MacroAssembler::Call callOperation(V_JITOperation_EJIdJJ, RegisterID, const Identifier*, RegisterID, RegisterID); 732 732 #if USE(JSVALUE64) 733 MacroAssembler::Call callOperation(F_JITOperation_EFJZ , RegisterID, RegisterID, int32_t);733 MacroAssembler::Call callOperation(F_JITOperation_EFJZZ, RegisterID, RegisterID, int32_t, RegisterID); 734 734 MacroAssembler::Call callOperation(V_JITOperation_ESsiJJI, StructureStubInfo*, RegisterID, RegisterID, StringImpl*); 735 735 #else … … 746 746 MacroAssembler::Call callOperationWithCallFrameRollbackOnException(Z_JITOperation_E); 747 747 #if USE(JSVALUE32_64) 748 MacroAssembler::Call callOperation(F_JITOperation_EFJZ , RegisterID, RegisterID, RegisterID, int32_t);749 MacroAssembler::Call callOperation( F_JITOperation_EJZZ, GPRReg, GPRReg, int32_t, int32_t);748 MacroAssembler::Call callOperation(F_JITOperation_EFJZZ, RegisterID, RegisterID, RegisterID, int32_t, RegisterID); 749 MacroAssembler::Call callOperation(Z_JITOperation_EJZZ, GPRReg, GPRReg, int32_t, int32_t); 750 750 MacroAssembler::Call callOperation(J_JITOperation_EAapJ, int, ArrayAllocationProfile*, GPRReg, GPRReg); 751 751 MacroAssembler::Call callOperation(J_JITOperation_EJ, int, GPRReg, GPRReg); -
trunk/Source/JavaScriptCore/jit/JITCall.cpp
r179862 r179887 81 81 emitGetVirtualRegister(arguments, regT1); 82 82 callOperation(operationSizeFrameForVarargs, regT1, -firstFreeRegister, firstVarArgOffset); 83 move(returnValueGPR, stackPointerRegister); 84 emitGetVirtualRegister(arguments, regT1); 85 callOperation(operationSetupVarargsFrame, returnValueGPR, regT1, firstVarArgOffset); 83 move(TrustedImm32(-firstFreeRegister), regT1); 84 emitSetVarargsFrame(*this, returnValueGPR, false, regT1, regT1); 85 addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 5 * sizeof(void*)))), regT1, stackPointerRegister); 86 emitGetVirtualRegister(arguments, regT2); 87 callOperation(operationSetupVarargsFrame, regT1, regT2, firstVarArgOffset, regT0); 86 88 move(returnValueGPR, regT1); 87 89 -
trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp
r179862 r179887 141 141 emitLoad(arguments, regT1, regT0); 142 142 callOperation(operationSizeFrameForVarargs, regT1, regT0, -firstFreeRegister, firstVarArgOffset); 143 // This is spectacularly dirty. We want to pass four arguments to operationSetupVarargsFrame. On x86-32 we 144 // will pass them on the stack. We want four stack slots, or 16 bytes. Extending the stack by 8 bytes 145 // over where we planned on pointing the FP gives us enough room. The reason is that the FP gives an 146 // extra CallerFrameAndPC bytes beyond where SP should point prior to the call. So if we just did 147 // move(returnValueGPR, stackPointerRegister), we'd have enough room for passing two args, or 8 148 // bytes - except that we'd have a misaligned stack. So if we subtract *another* CallerFrameAndPC 149 // bytes, we are up to 16 bytes of spare room *and* we have an aligned stack. Gross, but correct! 150 addPtr(TrustedImm32(-sizeof(CallerFrameAndPC)), returnValueGPR, stackPointerRegister); 151 emitLoad(arguments, regT2, regT1); 152 callOperation(operationSetupVarargsFrame, returnValueGPR, regT2, regT1, firstVarArgOffset); 143 move(TrustedImm32(-firstFreeRegister), regT1); 144 emitSetVarargsFrame(*this, returnValueGPR, false, regT1, regT1); 145 addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 6 * sizeof(void*)))), regT1, stackPointerRegister); 146 emitLoad(arguments, regT2, regT4); 147 callOperation(operationSetupVarargsFrame, regT1, regT2, regT4, firstVarArgOffset, regT0); 153 148 move(returnValueGPR, regT1); 154 149 -
trunk/Source/JavaScriptCore/jit/JITInlines.h
r179862 r179887 370 370 371 371 #if USE(JSVALUE64) 372 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation( F_JITOperation_EJZZ operation, GPRReg arg1, int32_t arg2, int32_t arg3)372 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(Z_JITOperation_EJZZ operation, GPRReg arg1, int32_t arg2, int32_t arg3) 373 373 { 374 374 setupArgumentsWithExecState(arg1, TrustedImm32(arg2), TrustedImm32(arg3)); … … 376 376 } 377 377 378 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJZ operation, GPRReg arg1, GPRReg arg2, int32_t arg3)379 { 380 setupArgumentsWithExecState(arg1, arg2, TrustedImm32(arg3) );378 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJZZ operation, GPRReg arg1, GPRReg arg2, int32_t arg3, GPRReg arg4) 379 { 380 setupArgumentsWithExecState(arg1, arg2, TrustedImm32(arg3), arg4); 381 381 return appendCallWithExceptionCheck(operation); 382 382 } … … 517 517 } 518 518 519 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation( F_JITOperation_EJZZ operation, GPRReg arg1Tag, GPRReg arg1Payload, int32_t arg2, int32_t arg3)519 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(Z_JITOperation_EJZZ operation, GPRReg arg1Tag, GPRReg arg1Payload, int32_t arg2, int32_t arg3) 520 520 { 521 521 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImm32(arg2), TrustedImm32(arg3)); … … 523 523 } 524 524 525 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJZ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, int32_t arg3)526 { 527 setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, TrustedImm32(arg3) );525 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJZZ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, int32_t arg3, GPRReg arg4) 526 { 527 setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, TrustedImm32(arg3), arg4); 528 528 return appendCallWithExceptionCheck(operation); 529 529 } -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r179862 r179887 1605 1605 } 1606 1606 1607 CallFrame*JIT_OPERATION operationSizeFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset)1607 int32_t JIT_OPERATION operationSizeFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset) 1608 1608 { 1609 1609 VM& vm = exec->vm(); … … 1611 1611 JSStack* stack = &exec->interpreter()->stack(); 1612 1612 JSValue arguments = JSValue::decode(encodedArguments); 1613 CallFrame* newCallFrame = sizeFrameForVarargs(exec, stack, arguments, numUsedStackSlots, firstVarArgOffset); 1614 return newCallFrame; 1615 } 1616 1617 CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState* exec, CallFrame* newCallFrame, EncodedJSValue encodedArguments, int32_t firstVarArgOffset) 1613 return sizeFrameForVarargs(exec, stack, arguments, numUsedStackSlots, firstVarArgOffset); 1614 } 1615 1616 CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState* exec, CallFrame* newCallFrame, EncodedJSValue encodedArguments, int32_t firstVarArgOffset, int32_t length) 1618 1617 { 1619 1618 VM& vm = exec->vm(); 1620 1619 NativeCallFrameTracer tracer(&vm, exec); 1621 1620 JSValue arguments = JSValue::decode(encodedArguments); 1622 setupVarargsFrame(exec, newCallFrame, arguments, firstVarArgOffset );1621 setupVarargsFrame(exec, newCallFrame, arguments, firstVarArgOffset, length); 1623 1622 return newCallFrame; 1624 1623 } -
trunk/Source/JavaScriptCore/jit/JITOperations.h
r179862 r179887 88 88 */ 89 89 90 typedef CallFrame* JIT_OPERATION (*F_JITOperation_EFJZ)(ExecState*, CallFrame*, EncodedJSValue, int32_t); 91 typedef CallFrame* JIT_OPERATION (*F_JITOperation_EJZZ)(ExecState*, EncodedJSValue, int32_t, int32_t); 90 typedef CallFrame* JIT_OPERATION (*F_JITOperation_EFJZZ)(ExecState*, CallFrame*, EncodedJSValue, int32_t, int32_t); 92 91 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_E)(ExecState*); 93 92 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EA)(ExecState*, JSArray*); … … 152 151 typedef int32_t JIT_OPERATION (*Z_JITOperation_E)(ExecState*); 153 152 typedef int32_t JIT_OPERATION (*Z_JITOperation_EC)(ExecState*, JSCell*); 153 typedef int32_t JIT_OPERATION (*Z_JITOperation_EJZZ)(ExecState*, EncodedJSValue, int32_t, int32_t); 154 154 typedef size_t JIT_OPERATION (*S_JITOperation_ECC)(ExecState*, JSCell*, JSCell*); 155 155 typedef size_t JIT_OPERATION (*S_JITOperation_EJ)(ExecState*, EncodedJSValue); … … 310 310 JSCell* JIT_OPERATION operationGetPNames(ExecState*, JSObject*) WTF_INTERNAL; 311 311 EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState*, EncodedJSValue, EncodedJSValue proto) WTF_INTERNAL; 312 CallFrame*JIT_OPERATION operationSizeFrameForVarargs(ExecState*, EncodedJSValue arguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset) WTF_INTERNAL;313 CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState*, CallFrame*, EncodedJSValue arguments, int32_t firstVarArgOffset ) WTF_INTERNAL;312 int32_t JIT_OPERATION operationSizeFrameForVarargs(ExecState*, EncodedJSValue arguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset) WTF_INTERNAL; 313 CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState*, CallFrame*, EncodedJSValue arguments, int32_t firstVarArgOffset, int32_t length) WTF_INTERNAL; 314 314 EncodedJSValue JIT_OPERATION operationToObject(ExecState*, EncodedJSValue) WTF_INTERNAL; 315 315 -
trunk/Source/JavaScriptCore/jit/SetupVarargsFrame.cpp
r179862 r179887 35 35 namespace JSC { 36 36 37 void emitSetVarargsFrame(CCallHelpers& jit, GPRReg lengthGPR, bool lengthIncludesThis, GPRReg numUsedSlotsGPR, GPRReg resultGPR) 38 { 39 jit.move(numUsedSlotsGPR, resultGPR); 40 jit.addPtr(lengthGPR, resultGPR); 41 jit.addPtr(CCallHelpers::TrustedImm32(JSStack::CallFrameHeaderSize + (lengthIncludesThis? 0 : 1)), resultGPR); 42 43 // resultGPR now has the required frame size in Register units 44 // Round resultGPR to next multiple of stackAlignmentRegisters() 45 jit.addPtr(CCallHelpers::TrustedImm32(stackAlignmentRegisters() - 1), resultGPR); 46 jit.andPtr(CCallHelpers::TrustedImm32(~(stackAlignmentRegisters() - 1)), resultGPR); 47 48 // Now resultGPR has the right stack frame offset in Register units. 49 jit.negPtr(resultGPR); 50 jit.lshiftPtr(CCallHelpers::Imm32(3), resultGPR); 51 jit.addPtr(GPRInfo::callFrameRegister, resultGPR); 52 } 53 37 54 void emitSetupVarargsFrameFastCase(CCallHelpers& jit, GPRReg numUsedSlotsGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, GPRReg scratchGPR3, int inlineStackOffset, unsigned firstVarArgOffset, CCallHelpers::JumpList& slowCase) 38 55 { … … 49 66 } 50 67 slowCase.append(jit.branch32(CCallHelpers::Above, scratchGPR1, CCallHelpers::TrustedImm32(Arguments::MaxArguments + 1))); 51 // scratchGPR1: argumentCountIncludingThis 52 jit.move(numUsedSlotsGPR, scratchGPR2); 53 jit.addPtr(scratchGPR1, scratchGPR2); 54 jit.addPtr(CCallHelpers::TrustedImm32(JSStack::CallFrameHeaderSize), scratchGPR2); 55 // scratchGPR2 now has the required frame size in Register units 56 // Round scratchGPR2 to next multiple of stackAlignmentRegisters() 57 jit.addPtr(CCallHelpers::TrustedImm32(stackAlignmentRegisters() - 1), scratchGPR2); 58 jit.andPtr(CCallHelpers::TrustedImm32(~(stackAlignmentRegisters() - 1)), scratchGPR2); 59 60 jit.negPtr(scratchGPR2); 61 jit.lshiftPtr(CCallHelpers::Imm32(3), scratchGPR2); 62 jit.addPtr(GPRInfo::callFrameRegister, scratchGPR2); 63 // scratchGPR2: newCallFrame 68 69 emitSetVarargsFrame(jit, scratchGPR1, true, numUsedSlotsGPR, scratchGPR2); 64 70 65 71 slowCase.append(jit.branchPtr(CCallHelpers::Above, CCallHelpers::AbsoluteAddress(jit.vm()->addressOfStackLimit()), scratchGPR2)); -
trunk/Source/JavaScriptCore/jit/SetupVarargsFrame.h
r179862 r179887 34 34 namespace JSC { 35 35 36 void emitSetVarargsFrame(CCallHelpers&, GPRReg lengthGPR, bool lengthIncludesThis, GPRReg numUsedSlotsGPR, GPRReg resultGPR); 37 36 38 // Assumes that SP refers to the last in-use stack location, and after this returns SP will point to 37 39 // the newly created frame plus the native header. scratchGPR2 may be the same as numUsedSlotsGPR. 38 void emitSetupVarargsFrameFastCase(CCallHelpers& jit, GPRReg numUsedSlotsGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, GPRReg scratchGPR3, int inlineStackOffset, unsigned firstVarArgOffset, CCallHelpers::JumpList& slowCase);40 void emitSetupVarargsFrameFastCase(CCallHelpers&, GPRReg numUsedSlotsGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, GPRReg scratchGPR3, int inlineStackOffset, unsigned firstVarArgOffset, CCallHelpers::JumpList& slowCase); 39 41 40 42 } // namespace JSC -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r179862 r179887 1165 1165 // - Set up a call frame while respecting the variable arguments. 1166 1166 1167 ExecState* execCallee = sizeFrameForVarargs(exec, &vm.interpreter->stack(), 1168 LLINT_OP_C(4).jsValue(), -pc[5].u.operand, pc[6].u.operand); 1167 unsigned numUsedStackSlots = -pc[5].u.operand; 1168 unsigned length = sizeFrameForVarargs(exec, &vm.interpreter->stack(), 1169 LLINT_OP_C(4).jsValue(), numUsedStackSlots, pc[6].u.operand); 1169 1170 LLINT_CALL_CHECK_EXCEPTION(exec, exec); 1170 1171 1172 ExecState* execCallee = calleeFrameForVarargs(exec, numUsedStackSlots, length + 1); 1173 vm.varargsLength = length; 1171 1174 vm.newCallFrameReturnValue = execCallee; 1172 1175 … … 1185 1188 ExecState* execCallee = vm.newCallFrameReturnValue; 1186 1189 1187 setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand );1190 setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand, vm.varargsLength); 1188 1191 LLINT_CALL_CHECK_EXCEPTION(exec, exec); 1189 1192 … … 1206 1209 ExecState* execCallee = vm.newCallFrameReturnValue; 1207 1210 1208 setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand );1211 setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand, vm.varargsLength); 1209 1212 LLINT_CALL_CHECK_EXCEPTION(exec, exec); 1210 1213 -
trunk/Source/JavaScriptCore/runtime/Arguments.cpp
r179862 r179887 88 88 static EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState*); 89 89 90 void Arguments::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, uint32_t copyLength, int32_t firstVarArgOffset) 91 { 92 uint32_t length = copyLength + firstVarArgOffset; 93 94 if (UNLIKELY(m_overrodeLength)) { 95 length = min(get(exec, exec->propertyNames().length).toUInt32(exec), length); 96 for (unsigned i = firstVarArgOffset; i < length; i++) 97 exec->r(firstElementDest + i - firstVarArgOffset) = get(exec, i); 98 return; 99 } 100 ASSERT(length == this->length(exec)); 101 for (size_t i = firstVarArgOffset; i < length; ++i) { 102 if (JSValue value = tryGetArgument(i)) 103 exec->r(firstElementDest + i - firstVarArgOffset) = value; 90 void Arguments::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length) 91 { 92 for (unsigned i = 0; i < length; ++i) { 93 if (JSValue value = tryGetArgument(i + offset)) 94 exec->r(firstElementDest + i) = value; 104 95 else { 105 exec->r(firstElementDest + i - firstVarArgOffset) = get(exec, i);96 exec->r(firstElementDest + i) = get(exec, i + offset); 106 97 if (UNLIKELY(exec->vm().exception())) 107 98 return; -
trunk/Source/JavaScriptCore/runtime/Arguments.h
r179862 r179887 85 85 } 86 86 87 void copyToArguments(ExecState*, VirtualRegister firstElementDest, u int32_t copyLength, int32_t firstArgumentOffset);87 void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length); 88 88 void tearOff(CallFrame*); 89 89 void tearOff(CallFrame*, InlineCallFrame*); -
trunk/Source/JavaScriptCore/runtime/JSArray.cpp
r179862 r179887 1571 1571 } 1572 1572 1573 void JSArray::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, u int32_t copyLength, int32_t firstVarArgOffset)1574 { 1575 unsigned i = firstVarArgOffset;1573 void JSArray::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length) 1574 { 1575 unsigned i = offset; 1576 1576 WriteBarrier<Unknown>* vector; 1577 1577 unsigned vectorEnd; 1578 unsigned length = copyLength + firstVarArgOffset;1578 length += offset; // We like to think of the length as being our length, rather than the output length. 1579 1579 ASSERT(length == this->length()); 1580 1580 switch (indexingType()) { … … 1603 1603 if (v != v) 1604 1604 break; 1605 exec->r(firstElementDest + i - firstVarArgOffset) = JSValue(JSValue::EncodeAsDouble, v);1605 exec->r(firstElementDest + i - offset) = JSValue(JSValue::EncodeAsDouble, v); 1606 1606 } 1607 1607 break; … … 1628 1628 if (!v) 1629 1629 break; 1630 exec->r(firstElementDest + i - firstVarArgOffset) = v.get();1630 exec->r(firstElementDest + i - offset) = v.get(); 1631 1631 } 1632 1632 1633 1633 for (; i < length; ++i) { 1634 exec->r(firstElementDest + i - firstVarArgOffset) = get(exec, i);1634 exec->r(firstElementDest + i - offset) = get(exec, i); 1635 1635 if (UNLIKELY(exec->vm().exception())) 1636 1636 return; -
trunk/Source/JavaScriptCore/runtime/JSArray.h
r179862 r179887 133 133 134 134 JS_EXPORT_PRIVATE void fillArgList(ExecState*, MarkedArgumentBuffer&); 135 JS_EXPORT_PRIVATE void copyToArguments(ExecState*, VirtualRegister firstElementDest, u int32_t length, int32_t firstVarArgOffset);135 JS_EXPORT_PRIVATE void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length); 136 136 137 137 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, IndexingType indexingType) -
trunk/Source/JavaScriptCore/runtime/VM.h
r179609 r179887 411 411 412 412 JSValue hostCallReturnValue; 413 unsigned varargsLength; 413 414 ExecState* newCallFrameReturnValue; 414 415 VMEntryFrame* vmEntryFrameForThrow;
Note:
See TracChangeset
for help on using the changeset viewer.