source: webkit/trunk/Source/JavaScriptCore/dfg/DFGArgumentsUtilities.cpp

Last change on this file was 261755, checked in by Ross Kirsling, 5 years ago

[IWYU] Remove unnecessary includes from JSC implementation files
https://bugs.webkit.org/show_bug.cgi?id=211867

Reviewed by Keith Miller.

  • API/:
  • assembler/:
  • b3/:
  • bindings/:
  • builtins/BuiltinExecutables.cpp:
  • bytecode/:
  • bytecompiler/:
  • debugger/:
  • dfg/:
  • disassembler/:
  • ftl/:
  • heap/:
  • inspector/:
  • interpreter/:
  • jit/:
  • jsc.cpp:
  • llint/:
  • parser/:
  • profiler/:
  • runtime/:
  • testRegExp.cpp:
  • tools/:
  • wasm/:
  • yarr/:
File size: 7.0 KB
Line 
1/*
2 * Copyright (C) 2015 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "DFGArgumentsUtilities.h"
28
29#if ENABLE(DFG_JIT)
30
31#include "JSImmutableButterfly.h"
32
33namespace JSC { namespace DFG {
34
35bool argumentsInvolveStackSlot(InlineCallFrame* inlineCallFrame, Operand operand)
36{
37 if (operand.isTmp())
38 return false;
39
40 VirtualRegister reg = operand.virtualRegister();
41 if (!inlineCallFrame)
42 return (reg.isArgument() && reg.toArgument()) || reg.isHeader();
43
44 if (inlineCallFrame->isClosureCall
45 && reg == VirtualRegister(inlineCallFrame->stackOffset + CallFrameSlot::callee))
46 return true;
47
48 if (inlineCallFrame->isVarargs()
49 && reg == VirtualRegister(inlineCallFrame->stackOffset + CallFrameSlot::argumentCountIncludingThis))
50 return true;
51
52 // We do not include fixups here since it is not related to |arguments|, rest parameters, and varargs.
53 unsigned numArguments = static_cast<unsigned>(inlineCallFrame->argumentCountIncludingThis - 1);
54 VirtualRegister argumentStart =
55 VirtualRegister(inlineCallFrame->stackOffset) + CallFrame::argumentOffset(0);
56 return reg >= argumentStart && reg < argumentStart + numArguments;
57}
58
59bool argumentsInvolveStackSlot(Node* candidate, Operand operand)
60{
61 return argumentsInvolveStackSlot(candidate->origin.semantic.inlineCallFrame(), operand);
62}
63
64Node* emitCodeToGetArgumentsArrayLength(
65 InsertionSet& insertionSet, Node* arguments, unsigned nodeIndex, NodeOrigin origin, bool addThis)
66{
67 Graph& graph = insertionSet.graph();
68
69 DFG_ASSERT(
70 graph, arguments,
71 arguments->op() == CreateDirectArguments || arguments->op() == CreateScopedArguments
72 || arguments->op() == CreateClonedArguments || arguments->op() == CreateRest
73 || arguments->op() == NewArrayBuffer
74 || arguments->op() == PhantomDirectArguments || arguments->op() == PhantomClonedArguments
75 || arguments->op() == PhantomCreateRest || arguments->op() == PhantomNewArrayBuffer
76 || arguments->op() == PhantomNewArrayWithSpread || arguments->op() == PhantomSpread,
77 arguments->op());
78
79 if (arguments->op() == PhantomSpread)
80 return emitCodeToGetArgumentsArrayLength(insertionSet, arguments->child1().node(), nodeIndex, origin, addThis);
81
82 if (arguments->op() == PhantomNewArrayWithSpread) {
83 unsigned numberOfNonSpreadArguments = addThis;
84 BitVector* bitVector = arguments->bitVector();
85 Node* currentSum = nullptr;
86 for (unsigned i = 0; i < arguments->numChildren(); i++) {
87 if (bitVector->get(i)) {
88 Node* child = graph.varArgChild(arguments, i).node();
89 DFG_ASSERT(graph, child, child->op() == PhantomSpread, child->op());
90 DFG_ASSERT(graph, child->child1().node(),
91 child->child1()->op() == PhantomCreateRest || child->child1()->op() == PhantomNewArrayBuffer,
92 child->child1()->op());
93 Node* lengthOfChild = emitCodeToGetArgumentsArrayLength(insertionSet, child->child1().node(), nodeIndex, origin);
94 if (currentSum)
95 currentSum = insertionSet.insertNode(nodeIndex, SpecInt32Only, ArithAdd, origin, OpInfo(Arith::CheckOverflow), Edge(currentSum, Int32Use), Edge(lengthOfChild, Int32Use));
96 else
97 currentSum = lengthOfChild;
98 } else
99 numberOfNonSpreadArguments++;
100 }
101 if (currentSum) {
102 if (!numberOfNonSpreadArguments)
103 return currentSum;
104 return insertionSet.insertNode(
105 nodeIndex, SpecInt32Only, ArithAdd, origin, OpInfo(Arith::CheckOverflow), Edge(currentSum, Int32Use),
106 insertionSet.insertConstantForUse(nodeIndex, origin, jsNumber(numberOfNonSpreadArguments), Int32Use));
107 }
108 return insertionSet.insertConstant(nodeIndex, origin, jsNumber(numberOfNonSpreadArguments));
109 }
110
111 if (arguments->op() == NewArrayBuffer || arguments->op() == PhantomNewArrayBuffer) {
112 return insertionSet.insertConstant(
113 nodeIndex, origin, jsNumber(arguments->castOperand<JSImmutableButterfly*>()->length() + addThis));
114 }
115
116 InlineCallFrame* inlineCallFrame = arguments->origin.semantic.inlineCallFrame();
117
118 unsigned numberOfArgumentsToSkip = 0;
119 if (arguments->op() == CreateRest || arguments->op() == PhantomCreateRest)
120 numberOfArgumentsToSkip = arguments->numberOfArgumentsToSkip();
121
122 if (inlineCallFrame && !inlineCallFrame->isVarargs()) {
123 unsigned argumentsSize = inlineCallFrame->argumentCountIncludingThis - !addThis;
124 if (argumentsSize >= numberOfArgumentsToSkip)
125 argumentsSize -= numberOfArgumentsToSkip;
126 else
127 argumentsSize = 0;
128 return insertionSet.insertConstant(
129 nodeIndex, origin, jsNumber(argumentsSize));
130 }
131
132 Node* argumentCount = insertionSet.insertNode(nodeIndex,
133 SpecInt32Only, GetArgumentCountIncludingThis, origin, OpInfo(inlineCallFrame));
134
135 Node* result = insertionSet.insertNode(
136 nodeIndex, SpecInt32Only, ArithSub, origin, OpInfo(Arith::Unchecked),
137 Edge(argumentCount, Int32Use),
138 insertionSet.insertConstantForUse(
139 nodeIndex, origin, jsNumber(numberOfArgumentsToSkip + !addThis), Int32Use));
140
141 if (numberOfArgumentsToSkip) {
142 // The above subtraction may produce a negative number if this number is non-zero. We correct that here.
143 result = insertionSet.insertNode(
144 nodeIndex, SpecInt32Only, ArithMax, origin,
145 Edge(result, Int32Use),
146 insertionSet.insertConstantForUse(nodeIndex, origin, jsNumber(static_cast<unsigned>(addThis)), Int32Use));
147 result->setResult(NodeResultInt32);
148 }
149
150 return result;
151}
152
153} } // namespace JSC::DFG
154
155#endif // ENABLE(DFG_JIT)
156
Note: See TracBrowser for help on using the repository browser.