Title: [179887] trunk/Source/_javascript_Core
Revision
179887
Author
[email protected]
Date
2015-02-10 15:16:36 -0800 (Tue, 10 Feb 2015)

Log Message

op_call_varargs should only load the length once
https://bugs.webkit.org/show_bug.cgi?id=141440
rdar://problem/19761683

Reviewed by Michael Saboff.
        
Refactors the pair of calls that set up the varargs frame so that the first call returns the
length, and the second call uses the length returned by the first one. It turns out that this
gave me an opportunity to shorten a lot of the code.

* interpreter/Interpreter.cpp:
(JSC::sizeFrameForVarargs):
(JSC::loadVarargs):
(JSC::setupVarargsFrame):
(JSC::setupVarargsFrameAndSetThis):
* interpreter/Interpreter.h:
(JSC::calleeFrameForVarargs):
* jit/CCallHelpers.h:
(JSC::CCallHelpers::setupArgumentsWithExecState):
* jit/JIT.h:
* jit/JITCall.cpp:
(JSC::JIT::compileSetupVarargsFrame):
* jit/JITCall32_64.cpp:
(JSC::JIT::compileSetupVarargsFrame):
* jit/JITInlines.h:
(JSC::JIT::callOperation):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* jit/SetupVarargsFrame.cpp:
(JSC::emitSetVarargsFrame):
(JSC::emitSetupVarargsFrameFastCase):
* jit/SetupVarargsFrame.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/Arguments.cpp:
(JSC::Arguments::copyToArguments):
* runtime/Arguments.h:
* runtime/JSArray.cpp:
(JSC::JSArray::copyToArguments):
* runtime/JSArray.h:
* runtime/VM.h:
* tests/stress/call-varargs-length-effects.js: Added.
(foo):
(bar):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (179886 => 179887)


--- trunk/Source/_javascript_Core/ChangeLog	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-02-10 23:16:36 UTC (rev 179887)
@@ -1,3 +1,50 @@
+2015-02-10  Filip Pizlo  <[email protected]>
+
+        op_call_varargs should only load the length once
+        https://bugs.webkit.org/show_bug.cgi?id=141440
+        rdar://problem/19761683
+
+        Reviewed by Michael Saboff.
+        
+        Refactors the pair of calls that set up the varargs frame so that the first call returns the
+        length, and the second call uses the length returned by the first one. It turns out that this
+        gave me an opportunity to shorten a lot of the code.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::sizeFrameForVarargs):
+        (JSC::loadVarargs):
+        (JSC::setupVarargsFrame):
+        (JSC::setupVarargsFrameAndSetThis):
+        * interpreter/Interpreter.h:
+        (JSC::calleeFrameForVarargs):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/JIT.h:
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/SetupVarargsFrame.cpp:
+        (JSC::emitSetVarargsFrame):
+        (JSC::emitSetupVarargsFrameFastCase):
+        * jit/SetupVarargsFrame.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::copyToArguments):
+        * runtime/Arguments.h:
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::copyToArguments):
+        * runtime/JSArray.h:
+        * runtime/VM.h:
+        * tests/stress/call-varargs-length-effects.js: Added.
+        (foo):
+        (bar):
+
 2015-02-10  Michael Saboff  <[email protected]>
 
         Crash in JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (179886 => 179887)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2015-02-10 23:16:36 UTC (rev 179887)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2010, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2010, 2012, 2013, 2014, 2015 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Cameron Zwarich <[email protected]>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -134,158 +134,80 @@
     return interpreter->execute(eval, callFrame, thisValue, callerScopeChain);
 }
 
-CallFrame* sizeFrameForVarargs(CallFrame* callFrame, JSStack* stack, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset)
+unsigned sizeFrameForVarargs(CallFrame* callFrame, JSStack* stack, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset)
 {
-    if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
-        unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
-        if (argumentCountIncludingThis > firstVarArgOffset)
-            argumentCountIncludingThis -= firstVarArgOffset;
-        else
-            argumentCountIncludingThis = 1;
-        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize);
-        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
-        if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->ensureCapacityFor(newCallFrame->registers())) {
-            throwStackOverflowError(callFrame);
-            return 0;
-        }
-        return newCallFrame;
-    }
-
-    if (arguments.isUndefinedOrNull()) {
-        unsigned argumentCountIncludingThis = 1;
-        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(),  numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize);
-        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
-        if (!stack->ensureCapacityFor(newCallFrame->registers())) {
-            throwStackOverflowError(callFrame);
-            return 0;
-        }
-        return newCallFrame;
-    }
-
-    if (!arguments.isObject()) {
+    unsigned length;
+    if (!arguments)
+        length = callFrame->argumentCount();
+    else if (arguments.isUndefinedOrNull())
+        length = 0;
+    else if (!arguments.isObject()) {
         callFrame->vm().throwException(callFrame, createInvalidParameterError(callFrame, "Function.prototype.apply", arguments));
         return 0;
-    }
-
-    if (asObject(arguments)->classInfo() == Arguments::info()) {
-        Arguments* argsObject = asArguments(arguments);
-        unsigned argCount = argsObject->length(callFrame);
-        if (argCount >= firstVarArgOffset)
-            argCount -= firstVarArgOffset;
-        else
-            argCount = 0;
-        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argCount + 1 + JSStack::CallFrameHeaderSize);
-        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
-        if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
-            throwStackOverflowError(callFrame);
-            return 0;
-        }
-        return newCallFrame;
-    }
-
-    if (isJSArray(arguments)) {
-        JSArray* array = asArray(arguments);
-        unsigned argCount = array->length();
-        if (argCount >= firstVarArgOffset)
-            argCount -= firstVarArgOffset;
-        else
-            argCount = 0;
-        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argCount + 1 + JSStack::CallFrameHeaderSize);
-        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
-        if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
-            throwStackOverflowError(callFrame);
-            return 0;
-        }
-        return newCallFrame;
-    }
-
-    JSObject* argObject = asObject(arguments);
-    unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
-    if (argCount >= firstVarArgOffset)
-        argCount -= firstVarArgOffset;
+    } else if (asObject(arguments)->classInfo() == Arguments::info())
+        length = asArguments(arguments)->length(callFrame);
+    else if (isJSArray(arguments))
+        length = asArray(arguments)->length();
     else
-        argCount = 0;
-    unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argCount + 1 + JSStack::CallFrameHeaderSize);
-    CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
-    if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
+        length = asObject(arguments)->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
+    
+    if (length >= firstVarArgOffset)
+        length -= firstVarArgOffset;
+    else
+        length = 0;
+    
+    CallFrame* calleeFrame = calleeFrameForVarargs(callFrame, numUsedStackSlots, length + 1);
+    if (length > Arguments::MaxArguments || !stack->ensureCapacityFor(calleeFrame->registers())) {
         throwStackOverflowError(callFrame);
         return 0;
     }
-    return newCallFrame;
+    
+    return length;
 }
 
-void loadVarargs(CallFrame* callFrame, VirtualRegister firstElementDest, VirtualRegister countDest, JSValue arguments, uint32_t firstVarArgOffset)
+void loadVarargs(CallFrame* callFrame, VirtualRegister firstElementDest, JSValue arguments, uint32_t offset, uint32_t length)
 {
     if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
-        unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
-        if (argumentCountIncludingThis > firstVarArgOffset)
-            argumentCountIncludingThis -= firstVarArgOffset;
-        else
-            argumentCountIncludingThis = 1;
-        callFrame->r(countDest).payload() = argumentCountIncludingThis;
-        for (size_t i = firstVarArgOffset; i < callFrame->argumentCount(); ++i)
-            callFrame->r(firstElementDest + i - firstVarArgOffset) = callFrame->argumentAfterCapture(i);
+        for (size_t i = 0; i < length; ++i)
+            callFrame->r(firstElementDest + i) = callFrame->argumentAfterCapture(i + offset);
         return;
     }
     
-    if (arguments.isUndefinedOrNull()) {
-        callFrame->r(countDest).payload() = 1;
+    if (arguments.isUndefinedOrNull())
         return;
-    }
     
     if (asObject(arguments)->classInfo() == Arguments::info()) {
-        Arguments* argsObject = asArguments(arguments);
-        unsigned argCount = argsObject->length(callFrame);
-        if (argCount >= firstVarArgOffset) {
-            argCount -= firstVarArgOffset;
-            callFrame->r(countDest).payload() = argCount + 1;
-            argsObject->copyToArguments(callFrame, firstElementDest, argCount, firstVarArgOffset);
-        } else
-            callFrame->r(countDest).payload() = 1;
+        asArguments(arguments)->copyToArguments(callFrame, firstElementDest, offset, length);
         return;
     }
     
     if (isJSArray(arguments)) {
-        JSArray* array = asArray(arguments);
-        unsigned argCount = array->length();
-        if (argCount >= firstVarArgOffset) {
-            argCount -= firstVarArgOffset;
-            callFrame->r(countDest).payload() = argCount + 1;
-            array->copyToArguments(callFrame, firstElementDest, argCount, firstVarArgOffset);
-        } else
-            callFrame->r(countDest).payload() = 1;
+        asArray(arguments)->copyToArguments(callFrame, firstElementDest, offset, length);
         return;
     }
     
-    JSObject* argObject = asObject(arguments);
-    unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
-    if (argCount >= firstVarArgOffset) {
-        argCount -= firstVarArgOffset;
-        callFrame->r(countDest).payload() = argCount + 1;
-    } else
-        callFrame->r(countDest).payload() = 1;
-
-    for (size_t i = 0; i < argCount; ++i) {
-        callFrame->r(firstElementDest + i) = asObject(arguments)->get(callFrame, i + firstVarArgOffset);
+    for (unsigned i = 0; i < length; ++i) {
+        callFrame->r(firstElementDest + i) = asObject(arguments)->get(callFrame, i + offset);
         if (UNLIKELY(callFrame->vm().exception()))
             return;
     }
 }
 
-void setupVarargsFrame(CallFrame* callFrame, CallFrame* newCallFrame, JSValue arguments, uint32_t firstVarArgOffset)
+void setupVarargsFrame(CallFrame* callFrame, CallFrame* newCallFrame, JSValue arguments, uint32_t offset, uint32_t length)
 {
     VirtualRegister calleeFrameOffset(newCallFrame - callFrame);
     
     loadVarargs(
         callFrame,
         calleeFrameOffset + CallFrame::argumentOffset(0),
-        calleeFrameOffset + JSStack::ArgumentCount,
-        arguments, firstVarArgOffset);
+        arguments, offset, length);
+    
+    newCallFrame->setArgumentCountIncludingThis(length + 1);
 }
 
-void setupVarargsFrameAndSetThis(CallFrame* callFrame, CallFrame* newCallFrame, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset)
+void setupVarargsFrameAndSetThis(CallFrame* callFrame, CallFrame* newCallFrame, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length)
 {
-    setupVarargsFrame(callFrame, newCallFrame, arguments, firstVarArgOffset);
+    setupVarargsFrame(callFrame, newCallFrame, arguments, firstVarArgOffset, length);
     newCallFrame->setThisValue(thisValue);
 }
 

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.h (179886 => 179887)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.h	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.h	2015-02-10 23:16:36 UTC (rev 179887)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013, 2015 Apple Inc. All rights reserved.
  * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -39,6 +39,7 @@
 #include "LLIntData.h"
 #include "Opcode.h"
 #include "SourceProvider.h"
+#include "StackAlignment.h"
 
 #include <wtf/HashMap.h>
 #include <wtf/text/StringBuilder.h>
@@ -298,10 +299,19 @@
     };
 
     JSValue eval(CallFrame*);
-    CallFrame* sizeFrameForVarargs(CallFrame* exec, JSStack*, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset);
-    void loadVarargs(CallFrame* execCaller, VirtualRegister firstElementDest, VirtualRegister countDest, JSValue source, uint32_t offset);
-    void setupVarargsFrame(CallFrame* execCaller, CallFrame* execCallee, JSValue arguments, uint32_t firstVarArgOffset);
-    void setupVarargsFrameAndSetThis(CallFrame* execCaller, CallFrame* execCallee, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset);
+
+    inline CallFrame* calleeFrameForVarargs(CallFrame* callFrame, unsigned numUsedStackSlots, unsigned argumentCountIncludingThis)
+    {
+        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(
+            stackAlignmentRegisters(),
+            numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize);
+        return CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
+    }
+
+    unsigned sizeFrameForVarargs(CallFrame* exec, JSStack*, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset);
+    void loadVarargs(CallFrame* execCaller, VirtualRegister firstElementDest, JSValue source, uint32_t offset, uint32_t length);
+    void setupVarargsFrame(CallFrame* execCaller, CallFrame* execCallee, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length);
+    void setupVarargsFrameAndSetThis(CallFrame* execCaller, CallFrame* execCallee, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length);
     
 } // namespace JSC
 

Modified: trunk/Source/_javascript_Core/jit/CCallHelpers.h (179886 => 179887)


--- trunk/Source/_javascript_Core/jit/CCallHelpers.h	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/jit/CCallHelpers.h	2015-02-10 23:16:36 UTC (rev 179887)
@@ -435,6 +435,17 @@
         addCallArgument(arg4);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, GPRReg arg5)
+    {
+        resetCallArguments();
+        addCallArgument(GPRInfo::callFrameRegister);
+        addCallArgument(arg1);
+        addCallArgument(arg2);
+        addCallArgument(arg3);
+        addCallArgument(arg4);
+        addCallArgument(arg5);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3)
     {
         resetCallArguments();
@@ -1381,6 +1392,12 @@
         setupArgumentsWithExecState(arg1, arg2, arg3);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, GPRReg arg5)
+    {
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3,  GPRReg arg4)
     {
         poke(arg4, POKE_ARGUMENT_OFFSET);
@@ -1528,6 +1545,12 @@
         setupArgumentsWithExecState(arg1, arg2, arg3);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4)
+    {
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
     {
         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
@@ -1769,6 +1792,13 @@
         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4)
+    {
+        setupThreeStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, GPRInfo::argumentGPR4>(arg1, arg2, arg4);
+        move(arg3, GPRInfo::argumentGPR3);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
     ALWAYS_INLINE void setupArguments(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5)
     {
         setupThreeStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg1, arg3, arg4);

Modified: trunk/Source/_javascript_Core/jit/JIT.h (179886 => 179887)


--- trunk/Source/_javascript_Core/jit/JIT.h	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/jit/JIT.h	2015-02-10 23:16:36 UTC (rev 179887)
@@ -679,7 +679,7 @@
         MacroAssembler::Call callOperation(C_JITOperation_EL, TrustedImmPtr);
         MacroAssembler::Call callOperation(C_JITOperation_ESt, Structure*);
         MacroAssembler::Call callOperation(C_JITOperation_EZ, int32_t);
-        MacroAssembler::Call callOperation(F_JITOperation_EJZZ, GPRReg, int32_t, int32_t);
+        MacroAssembler::Call callOperation(Z_JITOperation_EJZZ, GPRReg, int32_t, int32_t);
         MacroAssembler::Call callOperation(J_JITOperation_E, int);
         MacroAssembler::Call callOperation(J_JITOperation_EAapJ, int, ArrayAllocationProfile*, GPRReg);
         MacroAssembler::Call callOperation(J_JITOperation_EAapJcpZ, int, ArrayAllocationProfile*, GPRReg, int32_t);
@@ -730,7 +730,7 @@
 #endif
         MacroAssembler::Call callOperation(V_JITOperation_EJIdJJ, RegisterID, const Identifier*, RegisterID, RegisterID);
 #if USE(JSVALUE64)
-        MacroAssembler::Call callOperation(F_JITOperation_EFJZ, RegisterID, RegisterID, int32_t);
+        MacroAssembler::Call callOperation(F_JITOperation_EFJZZ, RegisterID, RegisterID, int32_t, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_ESsiJJI, StructureStubInfo*, RegisterID, RegisterID, StringImpl*);
 #else
         MacroAssembler::Call callOperation(V_JITOperation_ESsiJJI, StructureStubInfo*, RegisterID, RegisterID, RegisterID, RegisterID, StringImpl*);
@@ -745,8 +745,8 @@
         MacroAssembler::Call callOperationWithCallFrameRollbackOnException(V_JITOperation_ECb, CodeBlock*);
         MacroAssembler::Call callOperationWithCallFrameRollbackOnException(Z_JITOperation_E);
 #if USE(JSVALUE32_64)
-        MacroAssembler::Call callOperation(F_JITOperation_EFJZ, RegisterID, RegisterID, RegisterID, int32_t);
-        MacroAssembler::Call callOperation(F_JITOperation_EJZZ, GPRReg, GPRReg, int32_t, int32_t);
+        MacroAssembler::Call callOperation(F_JITOperation_EFJZZ, RegisterID, RegisterID, RegisterID, int32_t, RegisterID);
+        MacroAssembler::Call callOperation(Z_JITOperation_EJZZ, GPRReg, GPRReg, int32_t, int32_t);
         MacroAssembler::Call callOperation(J_JITOperation_EAapJ, int, ArrayAllocationProfile*, GPRReg, GPRReg);
         MacroAssembler::Call callOperation(J_JITOperation_EJ, int, GPRReg, GPRReg);
         MacroAssembler::Call callOperation(J_JITOperation_EJIdc, int, GPRReg, GPRReg, const Identifier*);

Modified: trunk/Source/_javascript_Core/jit/JITCall.cpp (179886 => 179887)


--- trunk/Source/_javascript_Core/jit/JITCall.cpp	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/jit/JITCall.cpp	2015-02-10 23:16:36 UTC (rev 179887)
@@ -80,9 +80,11 @@
 
     emitGetVirtualRegister(arguments, regT1);
     callOperation(operationSizeFrameForVarargs, regT1, -firstFreeRegister, firstVarArgOffset);
-    move(returnValueGPR, stackPointerRegister);
-    emitGetVirtualRegister(arguments, regT1);
-    callOperation(operationSetupVarargsFrame, returnValueGPR, regT1, firstVarArgOffset);
+    move(TrustedImm32(-firstFreeRegister), regT1);
+    emitSetVarargsFrame(*this, returnValueGPR, false, regT1, regT1);
+    addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 5 * sizeof(void*)))), regT1, stackPointerRegister);
+    emitGetVirtualRegister(arguments, regT2);
+    callOperation(operationSetupVarargsFrame, regT1, regT2, firstVarArgOffset, regT0);
     move(returnValueGPR, regT1);
 
     if (canOptimize)

Modified: trunk/Source/_javascript_Core/jit/JITCall32_64.cpp (179886 => 179887)


--- trunk/Source/_javascript_Core/jit/JITCall32_64.cpp	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/jit/JITCall32_64.cpp	2015-02-10 23:16:36 UTC (rev 179887)
@@ -140,16 +140,11 @@
 
     emitLoad(arguments, regT1, regT0);
     callOperation(operationSizeFrameForVarargs, regT1, regT0, -firstFreeRegister, firstVarArgOffset);
-    // This is spectacularly dirty. We want to pass four arguments to operationSetupVarargsFrame. On x86-32 we
-    // will pass them on the stack. We want four stack slots, or 16 bytes. Extending the stack by 8 bytes
-    // over where we planned on pointing the FP gives us enough room. The reason is that the FP gives an
-    // extra CallerFrameAndPC bytes beyond where SP should point prior to the call. So if we just did
-    // move(returnValueGPR, stackPointerRegister), we'd have enough room for passing two args, or 8
-    // bytes - except that we'd have a misaligned stack. So if we subtract *another* CallerFrameAndPC
-    // bytes, we are up to 16 bytes of spare room *and* we have an aligned stack. Gross, but correct!
-    addPtr(TrustedImm32(-sizeof(CallerFrameAndPC)), returnValueGPR, stackPointerRegister);
-    emitLoad(arguments, regT2, regT1);
-    callOperation(operationSetupVarargsFrame, returnValueGPR, regT2, regT1, firstVarArgOffset);
+    move(TrustedImm32(-firstFreeRegister), regT1);
+    emitSetVarargsFrame(*this, returnValueGPR, false, regT1, regT1);
+    addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 6 * sizeof(void*)))), regT1, stackPointerRegister);
+    emitLoad(arguments, regT2, regT4);
+    callOperation(operationSetupVarargsFrame, regT1, regT2, regT4, firstVarArgOffset, regT0);
     move(returnValueGPR, regT1);
 
     if (canOptimize)

Modified: trunk/Source/_javascript_Core/jit/JITInlines.h (179886 => 179887)


--- trunk/Source/_javascript_Core/jit/JITInlines.h	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/jit/JITInlines.h	2015-02-10 23:16:36 UTC (rev 179887)
@@ -369,15 +369,15 @@
 
 
 #if USE(JSVALUE64)
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EJZZ operation, GPRReg arg1, int32_t arg2, int32_t arg3)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(Z_JITOperation_EJZZ operation, GPRReg arg1, int32_t arg2, int32_t arg3)
 {
     setupArgumentsWithExecState(arg1, TrustedImm32(arg2), TrustedImm32(arg3));
     return appendCallWithExceptionCheck(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJZ operation, GPRReg arg1, GPRReg arg2, int32_t arg3)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJZZ operation, GPRReg arg1, GPRReg arg2, int32_t arg3, GPRReg arg4)
 {
-    setupArgumentsWithExecState(arg1, arg2, TrustedImm32(arg3));
+    setupArgumentsWithExecState(arg1, arg2, TrustedImm32(arg3), arg4);
     return appendCallWithExceptionCheck(operation);
 }
 
@@ -516,15 +516,15 @@
     return appendCall(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EJZZ operation, GPRReg arg1Tag, GPRReg arg1Payload, int32_t arg2, int32_t arg3)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(Z_JITOperation_EJZZ operation, GPRReg arg1Tag, GPRReg arg1Payload, int32_t arg2, int32_t arg3)
 {
     setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImm32(arg2), TrustedImm32(arg3));
     return appendCallWithExceptionCheck(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJZ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, int32_t arg3)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJZZ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, int32_t arg3, GPRReg arg4)
 {
-    setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, TrustedImm32(arg3));
+    setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, TrustedImm32(arg3), arg4);
     return appendCallWithExceptionCheck(operation);
 }
     

Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (179886 => 179887)


--- trunk/Source/_javascript_Core/jit/JITOperations.cpp	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp	2015-02-10 23:16:36 UTC (rev 179887)
@@ -1604,22 +1604,21 @@
     return JSValue::encode(jsBoolean(result));
 }
 
-CallFrame* JIT_OPERATION operationSizeFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset)
+int32_t JIT_OPERATION operationSizeFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
     JSStack* stack = &exec->interpreter()->stack();
     JSValue arguments = JSValue::decode(encodedArguments);
-    CallFrame* newCallFrame = sizeFrameForVarargs(exec, stack, arguments, numUsedStackSlots, firstVarArgOffset);
-    return newCallFrame;
+    return sizeFrameForVarargs(exec, stack, arguments, numUsedStackSlots, firstVarArgOffset);
 }
 
-CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState* exec, CallFrame* newCallFrame, EncodedJSValue encodedArguments, int32_t firstVarArgOffset)
+CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState* exec, CallFrame* newCallFrame, EncodedJSValue encodedArguments, int32_t firstVarArgOffset, int32_t length)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
     JSValue arguments = JSValue::decode(encodedArguments);
-    setupVarargsFrame(exec, newCallFrame, arguments, firstVarArgOffset);
+    setupVarargsFrame(exec, newCallFrame, arguments, firstVarArgOffset, length);
     return newCallFrame;
 }
 

Modified: trunk/Source/_javascript_Core/jit/JITOperations.h (179886 => 179887)


--- trunk/Source/_javascript_Core/jit/JITOperations.h	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/jit/JITOperations.h	2015-02-10 23:16:36 UTC (rev 179887)
@@ -87,8 +87,7 @@
     Z: int32_t
 */
 
-typedef CallFrame* JIT_OPERATION (*F_JITOperation_EFJZ)(ExecState*, CallFrame*, EncodedJSValue, int32_t);
-typedef CallFrame* JIT_OPERATION (*F_JITOperation_EJZZ)(ExecState*, EncodedJSValue, int32_t, int32_t);
+typedef CallFrame* JIT_OPERATION (*F_JITOperation_EFJZZ)(ExecState*, CallFrame*, EncodedJSValue, int32_t, int32_t);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_E)(ExecState*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EA)(ExecState*, JSArray*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EAZ)(ExecState*, JSArray*, int32_t);
@@ -151,6 +150,7 @@
 typedef int32_t JIT_OPERATION (*Z_JITOperation_D)(double);
 typedef int32_t JIT_OPERATION (*Z_JITOperation_E)(ExecState*);
 typedef int32_t JIT_OPERATION (*Z_JITOperation_EC)(ExecState*, JSCell*);
+typedef int32_t JIT_OPERATION (*Z_JITOperation_EJZZ)(ExecState*, EncodedJSValue, int32_t, int32_t);
 typedef size_t JIT_OPERATION (*S_JITOperation_ECC)(ExecState*, JSCell*, JSCell*);
 typedef size_t JIT_OPERATION (*S_JITOperation_EJ)(ExecState*, EncodedJSValue);
 typedef size_t JIT_OPERATION (*S_JITOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue);
@@ -309,8 +309,8 @@
 EncodedJSValue JIT_OPERATION operationDeleteById(ExecState*, EncodedJSValue base, const Identifier*) WTF_INTERNAL;
 JSCell* JIT_OPERATION operationGetPNames(ExecState*, JSObject*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState*, EncodedJSValue, EncodedJSValue proto) WTF_INTERNAL;
-CallFrame* JIT_OPERATION operationSizeFrameForVarargs(ExecState*, EncodedJSValue arguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset) WTF_INTERNAL;
-CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState*, CallFrame*, EncodedJSValue arguments, int32_t firstVarArgOffset) WTF_INTERNAL;
+int32_t JIT_OPERATION operationSizeFrameForVarargs(ExecState*, EncodedJSValue arguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset) WTF_INTERNAL;
+CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState*, CallFrame*, EncodedJSValue arguments, int32_t firstVarArgOffset, int32_t length) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationToObject(ExecState*, EncodedJSValue) WTF_INTERNAL;
 
 char* JIT_OPERATION operationSwitchCharWithUnknownKeyType(ExecState*, EncodedJSValue key, size_t tableIndex) WTF_INTERNAL;

Modified: trunk/Source/_javascript_Core/jit/SetupVarargsFrame.cpp (179886 => 179887)


--- trunk/Source/_javascript_Core/jit/SetupVarargsFrame.cpp	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/jit/SetupVarargsFrame.cpp	2015-02-10 23:16:36 UTC (rev 179887)
@@ -34,6 +34,23 @@
 
 namespace JSC {
 
+void emitSetVarargsFrame(CCallHelpers& jit, GPRReg lengthGPR, bool lengthIncludesThis, GPRReg numUsedSlotsGPR, GPRReg resultGPR)
+{
+    jit.move(numUsedSlotsGPR, resultGPR);
+    jit.addPtr(lengthGPR, resultGPR);
+    jit.addPtr(CCallHelpers::TrustedImm32(JSStack::CallFrameHeaderSize + (lengthIncludesThis? 0 : 1)), resultGPR);
+    
+    // resultGPR now has the required frame size in Register units
+    // Round resultGPR to next multiple of stackAlignmentRegisters()
+    jit.addPtr(CCallHelpers::TrustedImm32(stackAlignmentRegisters() - 1), resultGPR);
+    jit.andPtr(CCallHelpers::TrustedImm32(~(stackAlignmentRegisters() - 1)), resultGPR);
+    
+    // Now resultGPR has the right stack frame offset in Register units.
+    jit.negPtr(resultGPR);
+    jit.lshiftPtr(CCallHelpers::Imm32(3), resultGPR);
+    jit.addPtr(GPRInfo::callFrameRegister, resultGPR);
+}
+
 void emitSetupVarargsFrameFastCase(CCallHelpers& jit, GPRReg numUsedSlotsGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, GPRReg scratchGPR3, int inlineStackOffset, unsigned firstVarArgOffset, CCallHelpers::JumpList& slowCase)
 {
     CCallHelpers::JumpList end;
@@ -48,20 +65,9 @@
         endVarArgs.link(&jit);
     }
     slowCase.append(jit.branch32(CCallHelpers::Above, scratchGPR1, CCallHelpers::TrustedImm32(Arguments::MaxArguments + 1)));
-    // scratchGPR1: argumentCountIncludingThis
-    jit.move(numUsedSlotsGPR, scratchGPR2);
-    jit.addPtr(scratchGPR1, scratchGPR2);
-    jit.addPtr(CCallHelpers::TrustedImm32(JSStack::CallFrameHeaderSize), scratchGPR2);
-    // scratchGPR2 now has the required frame size in Register units
-    // Round scratchGPR2 to next multiple of stackAlignmentRegisters()
-    jit.addPtr(CCallHelpers::TrustedImm32(stackAlignmentRegisters() - 1), scratchGPR2);
-    jit.andPtr(CCallHelpers::TrustedImm32(~(stackAlignmentRegisters() - 1)), scratchGPR2);
+    
+    emitSetVarargsFrame(jit, scratchGPR1, true, numUsedSlotsGPR, scratchGPR2);
 
-    jit.negPtr(scratchGPR2);
-    jit.lshiftPtr(CCallHelpers::Imm32(3), scratchGPR2);
-    jit.addPtr(GPRInfo::callFrameRegister, scratchGPR2);
-    // scratchGPR2: newCallFrame
-
     slowCase.append(jit.branchPtr(CCallHelpers::Above, CCallHelpers::AbsoluteAddress(jit.vm()->addressOfStackLimit()), scratchGPR2));
 
     // Initialize ArgumentCount.

Modified: trunk/Source/_javascript_Core/jit/SetupVarargsFrame.h (179886 => 179887)


--- trunk/Source/_javascript_Core/jit/SetupVarargsFrame.h	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/jit/SetupVarargsFrame.h	2015-02-10 23:16:36 UTC (rev 179887)
@@ -33,9 +33,11 @@
 
 namespace JSC {
 
+void emitSetVarargsFrame(CCallHelpers&, GPRReg lengthGPR, bool lengthIncludesThis, GPRReg numUsedSlotsGPR, GPRReg resultGPR);
+
 // Assumes that SP refers to the last in-use stack location, and after this returns SP will point to
 // the newly created frame plus the native header. scratchGPR2 may be the same as numUsedSlotsGPR.
-void emitSetupVarargsFrameFastCase(CCallHelpers& jit, GPRReg numUsedSlotsGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, GPRReg scratchGPR3, int inlineStackOffset, unsigned firstVarArgOffset, CCallHelpers::JumpList& slowCase);
+void emitSetupVarargsFrameFastCase(CCallHelpers&, GPRReg numUsedSlotsGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, GPRReg scratchGPR3, int inlineStackOffset, unsigned firstVarArgOffset, CCallHelpers::JumpList& slowCase);
 
 } // namespace JSC
 

Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (179886 => 179887)


--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2015-02-10 23:16:36 UTC (rev 179887)
@@ -1164,10 +1164,13 @@
     // This needs to:
     // - Set up a call frame while respecting the variable arguments.
     
-    ExecState* execCallee = sizeFrameForVarargs(exec, &vm.interpreter->stack(),
-        LLINT_OP_C(4).jsValue(), -pc[5].u.operand, pc[6].u.operand);
+    unsigned numUsedStackSlots = -pc[5].u.operand;
+    unsigned length = sizeFrameForVarargs(exec, &vm.interpreter->stack(),
+        LLINT_OP_C(4).jsValue(), numUsedStackSlots, pc[6].u.operand);
     LLINT_CALL_CHECK_EXCEPTION(exec, exec);
     
+    ExecState* execCallee = calleeFrameForVarargs(exec, numUsedStackSlots, length + 1);
+    vm.varargsLength = length;
     vm.newCallFrameReturnValue = execCallee;
 
     LLINT_RETURN_CALLEE_FRAME(execCallee);
@@ -1184,7 +1187,7 @@
     
     ExecState* execCallee = vm.newCallFrameReturnValue;
 
-    setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
+    setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand, vm.varargsLength);
     LLINT_CALL_CHECK_EXCEPTION(exec, exec);
     
     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
@@ -1205,7 +1208,7 @@
     
     ExecState* execCallee = vm.newCallFrameReturnValue;
     
-    setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
+    setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand, vm.varargsLength);
     LLINT_CALL_CHECK_EXCEPTION(exec, exec);
     
     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;

Modified: trunk/Source/_javascript_Core/runtime/Arguments.cpp (179886 => 179887)


--- trunk/Source/_javascript_Core/runtime/Arguments.cpp	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/runtime/Arguments.cpp	2015-02-10 23:16:36 UTC (rev 179887)
@@ -87,22 +87,13 @@
     
 static EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState*);
 
-void Arguments::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, uint32_t copyLength, int32_t firstVarArgOffset)
+void Arguments::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length)
 {
-    uint32_t length = copyLength + firstVarArgOffset;
-
-    if (UNLIKELY(m_overrodeLength)) {
-        length = min(get(exec, exec->propertyNames().length).toUInt32(exec), length);
-        for (unsigned i = firstVarArgOffset; i < length; i++)
-            exec->r(firstElementDest + i - firstVarArgOffset) = get(exec, i);
-        return;
-    }
-    ASSERT(length == this->length(exec));
-    for (size_t i = firstVarArgOffset; i < length; ++i) {
-        if (JSValue value = tryGetArgument(i))
-            exec->r(firstElementDest + i - firstVarArgOffset) = value;
+    for (unsigned i = 0; i < length; ++i) {
+        if (JSValue value = tryGetArgument(i + offset))
+            exec->r(firstElementDest + i) = value;
         else {
-            exec->r(firstElementDest + i - firstVarArgOffset) = get(exec, i);
+            exec->r(firstElementDest + i) = get(exec, i + offset);
             if (UNLIKELY(exec->vm().exception()))
                 return;
         }

Modified: trunk/Source/_javascript_Core/runtime/Arguments.h (179886 => 179887)


--- trunk/Source/_javascript_Core/runtime/Arguments.h	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/runtime/Arguments.h	2015-02-10 23:16:36 UTC (rev 179887)
@@ -84,7 +84,7 @@
         return m_numArguments; 
     }
         
-    void copyToArguments(ExecState*, VirtualRegister firstElementDest, uint32_t copyLength, int32_t firstArgumentOffset);
+    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
     void tearOff(CallFrame*);
     void tearOff(CallFrame*, InlineCallFrame*);
     void tearOffForCloning(CallFrame*);

Modified: trunk/Source/_javascript_Core/runtime/JSArray.cpp (179886 => 179887)


--- trunk/Source/_javascript_Core/runtime/JSArray.cpp	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/runtime/JSArray.cpp	2015-02-10 23:16:36 UTC (rev 179887)
@@ -1570,12 +1570,12 @@
         args.append(get(exec, i));
 }
 
-void JSArray::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, uint32_t copyLength, int32_t firstVarArgOffset)
+void JSArray::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length)
 {
-    unsigned i = firstVarArgOffset;
+    unsigned i = offset;
     WriteBarrier<Unknown>* vector;
     unsigned vectorEnd;
-    unsigned length = copyLength + firstVarArgOffset;
+    length += offset; // We like to think of the length as being our length, rather than the output length.
     ASSERT(length == this->length());
     switch (indexingType()) {
     case ArrayClass:
@@ -1602,7 +1602,7 @@
             double v = m_butterfly->contiguousDouble()[i];
             if (v != v)
                 break;
-            exec->r(firstElementDest + i - firstVarArgOffset) = JSValue(JSValue::EncodeAsDouble, v);
+            exec->r(firstElementDest + i - offset) = JSValue(JSValue::EncodeAsDouble, v);
         }
         break;
     }
@@ -1627,11 +1627,11 @@
         WriteBarrier<Unknown>& v = vector[i];
         if (!v)
             break;
-        exec->r(firstElementDest + i - firstVarArgOffset) = v.get();
+        exec->r(firstElementDest + i - offset) = v.get();
     }
     
     for (; i < length; ++i) {
-        exec->r(firstElementDest + i - firstVarArgOffset) = get(exec, i);
+        exec->r(firstElementDest + i - offset) = get(exec, i);
         if (UNLIKELY(exec->vm().exception()))
             return;
     }

Modified: trunk/Source/_javascript_Core/runtime/JSArray.h (179886 => 179887)


--- trunk/Source/_javascript_Core/runtime/JSArray.h	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/runtime/JSArray.h	2015-02-10 23:16:36 UTC (rev 179887)
@@ -132,7 +132,7 @@
     }
 
     JS_EXPORT_PRIVATE void fillArgList(ExecState*, MarkedArgumentBuffer&);
-    JS_EXPORT_PRIVATE void copyToArguments(ExecState*, VirtualRegister firstElementDest, uint32_t length, int32_t firstVarArgOffset);
+    JS_EXPORT_PRIVATE void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, IndexingType indexingType)
     {

Modified: trunk/Source/_javascript_Core/runtime/VM.h (179886 => 179887)


--- trunk/Source/_javascript_Core/runtime/VM.h	2015-02-10 23:07:47 UTC (rev 179886)
+++ trunk/Source/_javascript_Core/runtime/VM.h	2015-02-10 23:16:36 UTC (rev 179887)
@@ -410,6 +410,7 @@
     const ClassInfo* const jsFinalObjectClassInfo;
 
     JSValue hostCallReturnValue;
+    unsigned varargsLength;
     ExecState* newCallFrameReturnValue;
     VMEntryFrame* vmEntryFrameForThrow;
     ExecState* callFrameForThrow;

Added: trunk/Source/_javascript_Core/tests/stress/call-varargs-length-effects.js (0 => 179887)


--- trunk/Source/_javascript_Core/tests/stress/call-varargs-length-effects.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/call-varargs-length-effects.js	2015-02-10 23:16:36 UTC (rev 179887)
@@ -0,0 +1,24 @@
+function foo() { return arguments.length; }
+
+var o = {};
+o[0] = 42;
+var callCount = 0;
+o.__defineGetter__("length", function() {
+    callCount++;
+    return 1;
+});
+
+function bar() {
+    callCount = 0;
+    var result = foo.apply(this, o);
+    if (result != 1)
+        throw "Error: bad result: " + result;
+    if (callCount != 1)
+        throw "Error: bad call count: " + callCount;
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i)
+    bar();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to