Make the LLINT and Baseline JIT's op_create_arguments and op_get_argument_by_val...
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Jan 2015 00:10:01 +0000 (00:10 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Jan 2015 00:10:01 +0000 (00:10 +0000)
<https://webkit.org/b/140236>

Reviewed by Geoffrey Garen.

Will change the DFG to use the operand on a subsequent pass.  For now,
the DFG uses a temporary thunk (operationCreateArgumentsForDFG()) to
retain the old behavior of getting the lexicalEnviroment from the
ExecState.

* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitGetArgumentByVal):
(JSC::BytecodeGenerator::createArgumentsIfNecessary):
- When the lexicalEnvironment is not available, pass the invalid VirtualRegister
  instead of an empty JSValue as the lexicalEnvironment operand.

* dfg/DFGOperations.cpp:
- Use the lexicalEnvironment from the ExecState for now.

* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
- Use the operationCreateArgumentsForDFG() thunk for now.

* interpreter/CallFrame.cpp:
(JSC::CallFrame::lexicalEnvironmentOrNullptr):
* interpreter/CallFrame.h:
- Added this convenience function to return either the
  lexicalEnvironment or a nullptr so that we don't need to do a
  conditional check on codeBlock->needsActivation() at multiple sites.

* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::Frame::createArguments):
* jit/JIT.h:
* jit/JITInlines.h:
(JSC::JIT::callOperation):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_create_arguments):
(JSC::JIT::emitSlow_op_get_argument_by_val):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_create_arguments):
(JSC::JIT::emitSlow_op_get_argument_by_val):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/Arguments.h:
(JSC::Arguments::create):
(JSC::Arguments::finishCreation):
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/JSLexicalEnvironment.cpp:
(JSC::JSLexicalEnvironment::argumentsGetter):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@178143 268f45cc-cd09-0410-ab3c-d52691b4dbfc

18 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
Source/JavaScriptCore/interpreter/CallFrame.cpp
Source/JavaScriptCore/interpreter/CallFrame.h
Source/JavaScriptCore/interpreter/StackVisitor.cpp
Source/JavaScriptCore/jit/JIT.h
Source/JavaScriptCore/jit/JITInlines.h
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/jit/JITOperations.h
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/runtime/Arguments.h
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp

index 039993e..9d98e0e 100644 (file)
@@ -1,3 +1,61 @@
+2015-01-08  Mark Lam  <mark.lam@apple.com>
+
+        Make the LLINT and Baseline JIT's op_create_arguments and op_get_argument_by_val use their lexicalEnvironment operand.
+        <https://webkit.org/b/140236>
+
+        Reviewed by Geoffrey Garen.
+
+        Will change the DFG to use the operand on a subsequent pass.  For now,
+        the DFG uses a temporary thunk (operationCreateArgumentsForDFG()) to
+        retain the old behavior of getting the lexicalEnviroment from the
+        ExecState.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitGetArgumentByVal):
+        (JSC::BytecodeGenerator::createArgumentsIfNecessary):
+        - When the lexicalEnvironment is not available, pass the invalid VirtualRegister
+          instead of an empty JSValue as the lexicalEnvironment operand.
+
+        * dfg/DFGOperations.cpp:
+        - Use the lexicalEnvironment from the ExecState for now.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        - Use the operationCreateArgumentsForDFG() thunk for now.
+
+        * interpreter/CallFrame.cpp:
+        (JSC::CallFrame::lexicalEnvironmentOrNullptr):
+        * interpreter/CallFrame.h:
+        - Added this convenience function to return either the
+          lexicalEnvironment or a nullptr so that we don't need to do a
+          conditional check on codeBlock->needsActivation() at multiple sites.
+
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::createArguments):
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_create_arguments):
+        (JSC::JIT::emitSlow_op_get_argument_by_val):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_create_arguments):
+        (JSC::JIT::emitSlow_op_get_argument_by_val):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/Arguments.h:
+        (JSC::Arguments::create):
+        (JSC::Arguments::finishCreation):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/JSLexicalEnvironment.cpp:
+        (JSC::JSLexicalEnvironment::argumentsGetter):
+
 2015-01-08  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: Pause Reason Improvements (Breakpoint, Debugger Statement, Pause on Next Statement)
index 34e4982..5378ee8 100644 (file)
@@ -282,8 +282,7 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
         if (shouldCreateArgumentsEagerly() || shouldTearOffArgumentsEagerly()) {
             emitOpcode(op_create_arguments);
             instructions().append(argumentsRegister->index());
-            ASSERT(!m_codeBlock->hasActivationRegister() || m_codeBlock->activationRegister().isValid());
-            instructions().append(m_codeBlock->hasActivationRegister() ? m_codeBlock->activationRegister().offset() : addConstantValue(JSValue())->index());
+            instructions().append(m_codeBlock->activationRegister().offset());
 
             if (m_codeBlock->hasActivationRegister()) {
                 RegisterID* argumentsRegister = &registerFor(m_codeBlock->argumentsRegister().offset());
@@ -1525,8 +1524,7 @@ RegisterID* BytecodeGenerator::emitGetArgumentByVal(RegisterID* dst, RegisterID*
     ASSERT(base->virtualRegister() == m_codeBlock->argumentsRegister());
     instructions().append(base->index());
     instructions().append(property->index());
-    ASSERT(!m_codeBlock->hasActivationRegister() || m_codeBlock->activationRegister().isValid());
-    instructions().append(m_codeBlock->hasActivationRegister() ? m_codeBlock->activationRegister().offset() : addConstantValue(JSValue())->index());
+    instructions().append(m_codeBlock->activationRegister().offset());
     instructions().append(arrayProfile);
     instructions().append(profile);
     return dst;
@@ -1777,8 +1775,7 @@ void BytecodeGenerator::createArgumentsIfNecessary()
     emitOpcode(op_create_arguments);
     instructions().append(m_codeBlock->argumentsRegister().offset());
     ASSERT(!hasWatchableVariable(m_codeBlock->argumentsRegister().offset()));
-    ASSERT(!m_codeBlock->hasActivationRegister() || m_codeBlock->activationRegister().isValid());
-    instructions().append(m_codeBlock->hasActivationRegister() ? m_codeBlock->activationRegister().offset() : addConstantValue(JSValue())->index());
+    instructions().append(m_codeBlock->activationRegister().offset());
 }
 
 RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
index 9dca32a..e864825 100644 (file)
@@ -796,8 +796,10 @@ EncodedJSValue JIT_OPERATION operationGetArgumentByVal(ExecState* exec, int32_t
     
     // If there are no arguments, and we're accessing out of bounds, then we have to create the
     // arguments in case someone has installed a getter on a numeric property.
-    if (!argumentsValue)
-        exec->uncheckedR(argumentsRegister) = argumentsValue = Arguments::create(exec->vm(), exec);
+    if (!argumentsValue) {
+        JSLexicalEnvironment* lexicalEnvironment = exec->lexicalEnvironmentOrNullptr();
+        exec->uncheckedR(argumentsRegister) = argumentsValue = Arguments::create(exec->vm(), exec, lexicalEnvironment);
+    }
     
     return JSValue::encode(argumentsValue.get(exec, index));
 }
index a449fab..45cdd60 100644 (file)
@@ -4225,7 +4225,7 @@ void SpeculativeJIT::compile(Node* node)
             || !executable->parameterCount()) {
             JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
             addSlowPathGenerator(
-                slowPathCall(notCreated, this, operationCreateArguments, resultGPR));
+                slowPathCall(notCreated, this, operationCreateArgumentsForDFG, resultGPR));
             cellResult(resultGPR, node);
             break;
         }
@@ -4235,7 +4235,7 @@ void SpeculativeJIT::compile(Node* node)
         MacroAssembler::JumpList slowPaths;
         emitAllocateArguments(resultGPR, scratch1GPR, scratch2GPR, slowPaths);
             addSlowPathGenerator(
-                slowPathCall(slowPaths, this, operationCreateArguments, resultGPR));
+                slowPathCall(slowPaths, this, operationCreateArgumentsForDFG, resultGPR));
 
         alreadyCreated.link(&m_jit); 
         cellResult(resultGPR, node);
index 3f1fb7d..e2ba37e 100644 (file)
@@ -4287,7 +4287,7 @@ void SpeculativeJIT::compile(Node* node)
             || !executable->parameterCount()) {
             JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
             addSlowPathGenerator(
-                slowPathCall(notCreated, this, operationCreateArguments, resultGPR));
+                slowPathCall(notCreated, this, operationCreateArgumentsForDFG, resultGPR));
             cellResult(resultGPR, node);
             break;
         }
@@ -4297,7 +4297,7 @@ void SpeculativeJIT::compile(Node* node)
         MacroAssembler::JumpList slowPaths;
         emitAllocateArguments(resultGPR, scratchGPR1, scratchGPR2, slowPaths);
         addSlowPathGenerator(
-            slowPathCall(slowPaths, this, operationCreateArguments, resultGPR));
+            slowPathCall(slowPaths, this, operationCreateArgumentsForDFG, resultGPR));
 
         alreadyCreated.link(&m_jit);
         cellResult(resultGPR, node);
index dcc2bc5..259061d 100644 (file)
@@ -154,6 +154,12 @@ JSLexicalEnvironment* CallFrame::lexicalEnvironment() const
     return registers()[activationRegister.offset()].Register::lexicalEnvironment();
 }
 
+JSLexicalEnvironment* CallFrame::lexicalEnvironmentOrNullptr() const
+{
+    CodeBlock* codeBlock = this->codeBlock();
+    return codeBlock->needsActivation() ? lexicalEnvironment() : nullptr;
+}
+    
 void CallFrame::setActivation(JSLexicalEnvironment* lexicalEnvironment)
 {
     CodeBlock* codeBlock = this->codeBlock();
index 22007da..b45969d 100644 (file)
@@ -53,6 +53,7 @@ namespace JSC  {
 
         bool hasActivation() const;
         JSLexicalEnvironment* lexicalEnvironment() const;
+        JSLexicalEnvironment* lexicalEnvironmentOrNullptr() const;
         JSValue uncheckedActivation() const;
 
         // Global object in which execution began.
index 6807b5a..74133f4 100644 (file)
@@ -272,7 +272,8 @@ Arguments* StackVisitor::Frame::createArguments()
     } else 
 #endif
     {
-        arguments = Arguments::create(vm, physicalFrame, mode);
+        JSLexicalEnvironment* lexicalEnvironment = physicalFrame->lexicalEnvironmentOrNullptr();
+        arguments = Arguments::create(vm, physicalFrame, lexicalEnvironment, mode);
         arguments->tearOff(physicalFrame);
     }
     return arguments;
index 85149c3..3219e47 100644 (file)
@@ -681,6 +681,8 @@ namespace JSC {
         
         MacroAssembler::Call callOperation(C_JITOperation_E);
         MacroAssembler::Call callOperation(C_JITOperation_EO, GPRReg);
+        MacroAssembler::Call callOperation(C_JITOperation_EL, GPRReg);
+        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);
index 494d2c2..67c364f 100644 (file)
@@ -216,6 +216,18 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_EJscZ opera
     return appendCallWithExceptionCheck(operation);
 }
 
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_EL operation, GPRReg arg1)
+{
+    setupArgumentsWithExecState(arg1);
+    return appendCallWithExceptionCheck(operation);
+}
+    
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_EL operation, TrustedImmPtr arg1)
+{
+    setupArgumentsWithExecState(arg1);
+    return appendCallWithExceptionCheck(operation);
+}
+    
 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_EO operation, GPRReg arg)
 {
     setupArgumentsWithExecState(arg);
index e6daf8e..866b6a0 100644 (file)
@@ -689,10 +689,15 @@ void JIT::emit_op_get_scope(Instruction* currentInstruction)
 void JIT::emit_op_create_arguments(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
+    int lexicalEnvironment = currentInstruction[2].u.operand;
 
     Jump argsCreated = branchTest64(NonZero, Address(callFrameRegister, sizeof(Register) * dst));
 
-    callOperation(operationCreateArguments);
+    if (VirtualRegister(lexicalEnvironment).isValid()) {
+        emitGetVirtualRegister(lexicalEnvironment, regT0);
+        callOperation(operationCreateArguments, regT0);
+    } else
+        callOperation(operationCreateArguments, TrustedImmPtr(nullptr));
     emitStoreCell(dst, returnValueGPR);
     emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(dst)), returnValueGPR);
 
@@ -956,13 +961,18 @@ void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vecto
     int dst = currentInstruction[1].u.operand;
     int arguments = currentInstruction[2].u.operand;
     int property = currentInstruction[3].u.operand;
+    int lexicalEnvironment = currentInstruction[4].u.operand;
     
     linkSlowCase(iter);
     Jump skipArgumentsCreation = jump();
     
     linkSlowCase(iter);
     linkSlowCase(iter);
-    callOperation(operationCreateArguments);
+    if (VirtualRegister(lexicalEnvironment).isValid()) {
+        emitGetVirtualRegister(lexicalEnvironment, regT0);
+        callOperation(operationCreateArguments, regT0);
+    } else
+        callOperation(operationCreateArguments, TrustedImmPtr(nullptr));
     emitStoreCell(arguments, returnValueGPR);
     emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(arguments)), returnValueGPR);
     
index a3dead2..7dfe859 100644 (file)
@@ -918,11 +918,18 @@ void JIT::emit_op_get_scope(Instruction* currentInstruction)
 void JIT::emit_op_create_arguments(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
+    int lexicalEnvironment = currentInstruction[2].u.operand;
 
     Jump argsCreated = branch32(NotEqual, tagFor(dst), TrustedImm32(JSValue::EmptyValueTag));
-    callOperation(operationCreateArguments);
+
+    if (VirtualRegister(lexicalEnvironment).isValid()) {
+        emitLoadPayload(lexicalEnvironment, regT0);
+        callOperation(operationCreateArguments, regT0);
+    } else
+        callOperation(operationCreateArguments, TrustedImmPtr(nullptr));
     emitStoreCell(dst, returnValueGPR);
     emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(dst)).offset(), returnValueGPR);
+
     argsCreated.link(this);
 }
 
@@ -1064,6 +1071,7 @@ void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vecto
     int dst = currentInstruction[1].u.operand;
     int arguments = currentInstruction[2].u.operand;
     int property = currentInstruction[3].u.operand;
+    int lexicalEnvironment = currentInstruction[4].u.operand;
 
     linkSlowCase(iter);
     Jump skipArgumentsCreation = jump();
@@ -1071,7 +1079,11 @@ void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vecto
     linkSlowCase(iter);
     linkSlowCase(iter);
 
-    callOperation(operationCreateArguments);
+    if (VirtualRegister(lexicalEnvironment).isValid()) {
+        emitLoadPayload(lexicalEnvironment, regT0);
+        callOperation(operationCreateArguments, regT0);
+    } else
+        callOperation(operationCreateArguments, TrustedImmPtr(nullptr));
     emitStoreCell(arguments, returnValueGPR);
     emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(arguments)).offset(), returnValueGPR);
     
index c0bda43..eb3c895 100644 (file)
@@ -1402,13 +1402,20 @@ JSCell* JIT_OPERATION operationCreateActivation(ExecState* exec, JSScope* curren
     return lexicalEnvironment;
 }
 
-JSCell* JIT_OPERATION operationCreateArguments(ExecState* exec)
+// FIXME: This is a temporary thunk for the DFG until we add the lexicalEnvironment operand to the DFG CreateArguments node.
+JSCell* JIT_OPERATION operationCreateArgumentsForDFG(ExecState* exec)
+{
+    JSLexicalEnvironment* lexicalEnvironment = exec->lexicalEnvironmentOrNullptr();
+    return operationCreateArguments(exec, lexicalEnvironment);
+}
+    
+JSCell* JIT_OPERATION operationCreateArguments(ExecState* exec, JSLexicalEnvironment* lexicalEnvironment)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
     // NB: This needs to be exceedingly careful with top call frame tracking, since it
     // may be called from OSR exit, while the state of the call stack is bizarre.
-    Arguments* result = Arguments::create(vm, exec);
+    Arguments* result = Arguments::create(vm, exec, lexicalEnvironment);
     ASSERT(!vm.exception());
     return result;
 }
@@ -1416,7 +1423,8 @@ JSCell* JIT_OPERATION operationCreateArguments(ExecState* exec)
 JSCell* JIT_OPERATION operationCreateArgumentsDuringOSRExit(ExecState* exec)
 {
     DeferGCForAWhile(exec->vm().heap);
-    return operationCreateArguments(exec);
+    JSLexicalEnvironment* lexicalEnvironment = exec->lexicalEnvironmentOrNullptr();
+    return operationCreateArguments(exec, lexicalEnvironment);
 }
 
 EncodedJSValue JIT_OPERATION operationGetArgumentsLength(ExecState* exec, int32_t argumentsRegister)
index ae20147..804291e 100644 (file)
@@ -71,6 +71,7 @@ extern "C" {
     Jcp: const JSValue*
     Jsc: JSScope*
     Jss: JSString*
+    L: JSLexicalEnvironment*
     O: JSObject*
     P: pointer (char*)
     Pc: Instruction* i.e. bytecode PC
@@ -136,6 +137,7 @@ typedef JSCell* JIT_OPERATION (*C_JITOperation_EJscZ)(ExecState*, JSScope*, int3
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJssSt)(ExecState*, JSString*, Structure*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJssJss)(ExecState*, JSString*, JSString*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJssJssJss)(ExecState*, JSString*, JSString*, JSString*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EL)(ExecState*, JSLexicalEnvironment*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EO)(ExecState*, JSObject*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EOZ)(ExecState*, JSObject*, int32_t);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_ESt)(ExecState*, Structure*);
@@ -294,7 +296,8 @@ void JIT_OPERATION operationProfileDidCall(ExecState*, EncodedJSValue) WTF_INTER
 void JIT_OPERATION operationProfileWillCall(ExecState*, EncodedJSValue) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationCheckHasInstance(ExecState*, EncodedJSValue, EncodedJSValue baseVal) WTF_INTERNAL;
 JSCell* JIT_OPERATION operationCreateActivation(ExecState*, JSScope* currentScope, int32_t offset) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationCreateArguments(ExecState*) WTF_INTERNAL;
+JSCell* JIT_OPERATION operationCreateArgumentsForDFG(ExecState*) WTF_INTERNAL; // FIXME: This is a temporary thunk for the DFG until we add the lexicalEnvironment operand to the DFG CreateArguments node.
+JSCell* JIT_OPERATION operationCreateArguments(ExecState*, JSLexicalEnvironment*) WTF_INTERNAL;
 JSCell* JIT_OPERATION operationCreateArgumentsDuringOSRExit(ExecState*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationGetArgumentsLength(ExecState*, int32_t) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationGetByValDefault(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
index c75253c..aaa3edf 100644 (file)
@@ -762,7 +762,11 @@ LLINT_SLOW_PATH_DECL(slow_path_get_argument_by_val)
     LLINT_BEGIN();
     JSValue arguments = LLINT_OP(2).jsValue();
     if (!arguments) {
-        arguments = Arguments::create(vm, exec);
+        int lexicalEnvironmentReg = pc[4].u.operand;
+        JSLexicalEnvironment* lexicalEnvironment = VirtualRegister(lexicalEnvironmentReg).isValid() ?
+            exec->uncheckedR(lexicalEnvironmentReg).lexicalEnvironment() : nullptr;
+        arguments = JSValue(Arguments::create(vm, exec, lexicalEnvironment));
+
         LLINT_CHECK_EXCEPTION();
         LLINT_OP(2) = arguments;
         exec->uncheckedR(unmodifiedArgumentsRegister(VirtualRegister(pc[2].u.operand)).offset()) = arguments;
index 6172519..b5b1ee1 100644 (file)
@@ -46,10 +46,10 @@ class Arguments : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
 
-    static Arguments* create(VM& vm, CallFrame* callFrame, ArgumentsMode mode = NormalArgumentsCreationMode)
+    static Arguments* create(VM& vm, CallFrame* callFrame, JSLexicalEnvironment* lexicalEnvironment, ArgumentsMode mode = NormalArgumentsCreationMode)
     {
         Arguments* arguments = new (NotNull, allocateCell<Arguments>(vm.heap, offsetOfInlineRegisterArray() + registerArraySizeInBytes(callFrame))) Arguments(callFrame);
-        arguments->finishCreation(callFrame, mode);
+        arguments->finishCreation(callFrame, lexicalEnvironment, mode);
         return arguments;
     }
         
@@ -105,7 +105,7 @@ public:
 protected:
     static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSObject::StructureFlags;
 
-    void finishCreation(CallFrame*, ArgumentsMode);
+    void finishCreation(CallFrame*, JSLexicalEnvironment*, ArgumentsMode);
     void finishCreation(CallFrame*, InlineCallFrame*, ArgumentsMode);
 
 private:
@@ -271,7 +271,7 @@ inline WriteBarrierBase<Unknown>& Arguments::argument(size_t argument)
     return m_lexicalEnvironment->registerAt(index - m_slowArgumentData->bytecodeToMachineCaptureOffset());
 }
 
-inline void Arguments::finishCreation(CallFrame* callFrame, ArgumentsMode mode)
+inline void Arguments::finishCreation(CallFrame* callFrame, JSLexicalEnvironment* lexicalEnvironment, ArgumentsMode mode)
 {
     Base::finishCreation(callFrame->vm());
     ASSERT(inherits(info()));
@@ -300,8 +300,8 @@ inline void Arguments::finishCreation(CallFrame* callFrame, ArgumentsMode mode)
                 codeBlock->framePointerOffsetToGetActivationRegisters());
         }
         if (codeBlock->needsActivation()) {
-            RELEASE_ASSERT(callFrame->lexicalEnvironment());
-            m_lexicalEnvironment.set(callFrame->vm(), this, callFrame->lexicalEnvironment());
+            RELEASE_ASSERT(lexicalEnvironment && lexicalEnvironment == callFrame->lexicalEnvironment());
+            m_lexicalEnvironment.set(callFrame->vm(), this, lexicalEnvironment);
         }
         // The bytecode generator omits op_tear_off_lexical_environment in cases of no
         // declared parameters, so we need to tear off immediately.
index 5ba1efb..08091a8 100644 (file)
@@ -221,7 +221,10 @@ SLOW_PATH_DECL(slow_path_get_callee)
 SLOW_PATH_DECL(slow_path_create_arguments)
 {
     BEGIN();
-    JSValue arguments = JSValue(Arguments::create(vm, exec));
+    int lexicalEnvironmentReg = pc[2].u.operand;
+    JSLexicalEnvironment* lexicalEnvironment = VirtualRegister(lexicalEnvironmentReg).isValid() ?
+        exec->uncheckedR(lexicalEnvironmentReg).lexicalEnvironment() : nullptr;
+    JSValue arguments = JSValue(Arguments::create(vm, exec, lexicalEnvironment));
     CHECK_EXCEPTION();
     exec->uncheckedR(pc[1].u.operand) = arguments;
     exec->uncheckedR(unmodifiedArgumentsRegister(VirtualRegister(pc[1].u.operand)).offset()) = arguments;
index d5cd189..b14a479 100644 (file)
@@ -208,7 +208,7 @@ EncodedJSValue JSLexicalEnvironment::argumentsGetter(ExecState*, JSObject* slotB
         return JSValue::encode(arguments);
     int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister).offset();
 
-    JSValue arguments = JSValue(Arguments::create(callFrame->vm(), callFrame));
+    JSValue arguments = JSValue(Arguments::create(callFrame->vm(), callFrame, lexicalEnvironment));
     callFrame->uncheckedR(argumentsRegister.offset()) = arguments;
     callFrame->uncheckedR(realArgumentsRegister) = arguments;