@@ -55,31 +55,33 @@ class ByteCodeParser {
5555 , m_constantUndefined(UINT_MAX)
5656 , m_constantNull(UINT_MAX)
5757 , m_constant1(UINT_MAX)
58+ , m_constants(codeBlock->numberOfConstantRegisters ())
59+ , m_arguments(codeBlock->m_numParameters)
60+ , m_variables(codeBlock->m_numVars)
61+ , m_temporaries(codeBlock->m_numCalleeRegisters - codeBlock->m_numVars)
5862 {
59- unsigned numberOfConstants = codeBlock->numberOfConstantRegisters ();
60- m_constantRecords.grow (numberOfConstants);
61-
62- unsigned numberOfParameters = codeBlock->m_numParameters ;
63- m_arguments.grow (numberOfParameters);
64- for (unsigned i = 0 ; i < numberOfParameters; ++i)
63+ for (unsigned i = 0 ; i < m_arguments.size (); ++i)
6564 m_arguments[i] = NoNode;
66-
67- unsigned numberOfRegisters = codeBlock->m_numCalleeRegisters ;
68- m_calleeRegisters.grow (numberOfRegisters);
69- for (unsigned i = 0 ; i < numberOfRegisters; ++i)
70- m_calleeRegisters[i] = NoNode;
65+ for (unsigned i = 0 ; i < m_variables.size (); ++i)
66+ m_variables[i] = NoNode;
67+ for (unsigned i = 0 ; i < m_temporaries.size (); ++i)
68+ m_temporaries[i] = NoNode;
7169 }
7270
71+ // Parse a full CodeBlock of bytecode.
7372 bool parse ();
7473
7574private:
75+ // Parse a single basic block of bytecode instructions.
76+ bool parseBlock ();
77+
7678 // Get/Set the operands/result of a bytecode instruction.
7779 NodeIndex get (int operand)
7880 {
7981 // Is this a constant?
8082 if (operand >= FirstConstantRegisterIndex) {
8183 unsigned constant = operand - FirstConstantRegisterIndex;
82- ASSERT (constant < m_constantRecords .size ());
84+ ASSERT (constant < m_constants .size ());
8385 return getJSConstant (constant);
8486 }
8587
@@ -90,9 +92,15 @@ class ByteCodeParser {
9092 return getArgument (argument);
9193 }
9294
93- // Must be a local or temporary.
94- ASSERT ((unsigned )operand < m_calleeRegisters.size ());
95- return getRegister ((unsigned )operand);
95+ // Is this a variable?
96+ unsigned numVariables = m_variables.size ();
97+ if ((unsigned )operand < numVariables)
98+ return getVariable ((unsigned )operand);
99+
100+ // Must be a temporary.
101+ unsigned temporary = (unsigned )operand - numVariables;
102+ ASSERT (temporary < m_temporaries.size ());
103+ return getTemporary (temporary);
96104 }
97105 void set (int operand, NodeIndex value)
98106 {
@@ -103,15 +111,23 @@ class ByteCodeParser {
103111 return setArgument (argument, value);
104112 }
105113
106- // Must be a local or temporary.
107- ASSERT ((unsigned )operand < m_calleeRegisters.size ());
108- return setRegister ((unsigned )operand, value);
114+ // Is this a variable?
115+ unsigned numVariables = m_variables.size ();
116+ if ((unsigned )operand < numVariables) {
117+ setVariable ((unsigned )operand, value);
118+ return ;
119+ }
120+
121+ // Must be a temporary.
122+ unsigned temporary = (unsigned )operand - numVariables;
123+ ASSERT (temporary < m_temporaries.size ());
124+ setTemporary (temporary, value);
109125 }
110126
111- // Used in implementing get/set, above, where the operand is a local or temporary .
112- NodeIndex getRegister (unsigned operand)
127+ // Used in implementing get/set, above, where the operand is a local variable .
128+ NodeIndex getVariable (unsigned operand)
113129 {
114- NodeIndex index = m_calleeRegisters [operand];
130+ NodeIndex index = m_variables [operand];
115131 if (index != NoNode)
116132 return index;
117133 // We have not yet seen a definition for this value in this block.
@@ -121,9 +137,25 @@ class ByteCodeParser {
121137 // function f() { var x; return x; }
122138 return constantUndefined ();
123139 }
124- void setRegister (int operand, NodeIndex value)
140+ void setVariable (int operand, NodeIndex value)
125141 {
126- m_calleeRegisters[operand] = value;
142+ m_variables[operand] = value;
143+ }
144+
145+ // Used in implementing get/set, above, where the operand is a temporary.
146+ NodeIndex getTemporary (unsigned operand)
147+ {
148+ NodeIndex index = m_temporaries[operand];
149+ if (index != NoNode)
150+ return index;
151+
152+ // Detect a read of an temporary that is not a yet defined within this block (e.g. use of ?:).
153+ m_parseFailed = true ;
154+ return constantUndefined ();
155+ }
156+ void setTemporary (int operand, NodeIndex value)
157+ {
158+ m_temporaries[operand] = value;
127159 }
128160
129161 // Used in implementing get/set, above, where the operand is an argument.
@@ -132,8 +164,7 @@ class ByteCodeParser {
132164 NodeIndex index = m_arguments[argument];
133165 if (index != NoNode)
134166 return index;
135- NodeIndex resultIndex = (NodeIndex)m_graph.size ();
136- m_graph.append (Node (Argument, m_currentIndex, OpInfo (argument)));
167+ NodeIndex resultIndex = addToGraph (Argument, OpInfo (argument));
137168 return m_arguments[argument] = resultIndex;
138169 }
139170 void setArgument (int operand, NodeIndex value)
@@ -237,35 +268,32 @@ class ByteCodeParser {
237268 // Used in implementing get, above, where the operand is a constant.
238269 NodeIndex getInt32Constant (int32_t value, unsigned constant)
239270 {
240- NodeIndex index = m_constantRecords [constant].asInt32 ;
271+ NodeIndex index = m_constants [constant].asInt32 ;
241272 if (index != NoNode)
242273 return index;
243- NodeIndex resultIndex = (NodeIndex)m_graph.size ();
244- m_graph.append (Node (Int32Constant, m_currentIndex, OpInfo (constant)));
274+ NodeIndex resultIndex = addToGraph (Int32Constant, OpInfo (constant));
245275 m_graph[resultIndex].setInt32Constant (value);
246- m_constantRecords [constant].asInt32 = resultIndex;
276+ m_constants [constant].asInt32 = resultIndex;
247277 return resultIndex;
248278 }
249279 NodeIndex getDoubleConstant (double value, unsigned constant)
250280 {
251- NodeIndex index = m_constantRecords [constant].asNumeric ;
281+ NodeIndex index = m_constants [constant].asNumeric ;
252282 if (index != NoNode)
253283 return index;
254- NodeIndex resultIndex = (NodeIndex)m_graph.size ();
255- m_graph.append (Node (DoubleConstant, m_currentIndex, OpInfo (constant)));
284+ NodeIndex resultIndex = addToGraph (DoubleConstant, OpInfo (constant));
256285 m_graph[resultIndex].setDoubleConstant (value);
257- m_constantRecords [constant].asNumeric = resultIndex;
286+ m_constants [constant].asNumeric = resultIndex;
258287 return resultIndex;
259288 }
260289 NodeIndex getJSConstant (unsigned constant)
261290 {
262- NodeIndex index = m_constantRecords [constant].asJSValue ;
291+ NodeIndex index = m_constants [constant].asJSValue ;
263292 if (index != NoNode)
264293 return index;
265294
266- NodeIndex resultIndex = (NodeIndex)m_graph.size ();
267- m_graph.append (Node (JSConstant, m_currentIndex, OpInfo (constant)));
268- m_constantRecords[constant].asJSValue = resultIndex;
295+ NodeIndex resultIndex = addToGraph (JSConstant, OpInfo (constant));
296+ m_constants[constant].asJSValue = resultIndex;
269297 return resultIndex;
270298 }
271299
@@ -323,11 +351,11 @@ class ByteCodeParser {
323351 return getJSConstant (m_constantUndefined);
324352 }
325353
326- // Add undefined to the CodeBlock's constants, and add a corresponding slot in m_constantRecords .
327- ASSERT (m_constantRecords .size () == numberOfConstants);
354+ // Add undefined to the CodeBlock's constants, and add a corresponding slot in m_constants .
355+ ASSERT (m_constants .size () == numberOfConstants);
328356 m_codeBlock->addConstant (jsUndefined ());
329- m_constantRecords .append (ConstantRecord ());
330- ASSERT (m_constantRecords .size () == m_codeBlock->numberOfConstantRegisters ());
357+ m_constants .append (ConstantRecord ());
358+ ASSERT (m_constants .size () == m_codeBlock->numberOfConstantRegisters ());
331359 }
332360
333361 // m_constantUndefined must refer to an entry in the CodeBlock's constant pool that has the value 'undefined'.
@@ -348,11 +376,11 @@ class ByteCodeParser {
348376 return getJSConstant (m_constantNull);
349377 }
350378
351- // Add null to the CodeBlock's constants, and add a corresponding slot in m_constantRecords .
352- ASSERT (m_constantRecords .size () == numberOfConstants);
379+ // Add null to the CodeBlock's constants, and add a corresponding slot in m_constants .
380+ ASSERT (m_constants .size () == numberOfConstants);
353381 m_codeBlock->addConstant (jsNull ());
354- m_constantRecords .append (ConstantRecord ());
355- ASSERT (m_constantRecords .size () == m_codeBlock->numberOfConstantRegisters ());
382+ m_constants .append (ConstantRecord ());
383+ ASSERT (m_constants .size () == m_codeBlock->numberOfConstantRegisters ());
356384 }
357385
358386 // m_constantNull must refer to an entry in the CodeBlock's constant pool that has the value 'null'.
@@ -373,11 +401,11 @@ class ByteCodeParser {
373401 return getDoubleConstant (1 , m_constant1);
374402 }
375403
376- // Add the value 1 to the CodeBlock's constants, and add a corresponding slot in m_constantRecords .
377- ASSERT (m_constantRecords .size () == numberOfConstants);
404+ // Add the value 1 to the CodeBlock's constants, and add a corresponding slot in m_constants .
405+ ASSERT (m_constants .size () == numberOfConstants);
378406 m_codeBlock->addConstant (jsNumber (1 ));
379- m_constantRecords .append (ConstantRecord ());
380- ASSERT (m_constantRecords .size () == m_codeBlock->numberOfConstantRegisters ());
407+ m_constants .append (ConstantRecord ());
408+ ASSERT (m_constants .size () == m_codeBlock->numberOfConstantRegisters ());
381409 }
382410
383411 // m_constant1 must refer to an entry in the CodeBlock's constant pool that has the integer value 1.
@@ -441,12 +469,13 @@ class ByteCodeParser {
441469 NodeIndex asNumeric;
442470 NodeIndex asJSValue;
443471 };
444- Vector <ConstantRecord, 32 > m_constantRecords ;
472+ Vector <ConstantRecord, 32 > m_constants ;
445473
446474 // Track the index of the node whose result is the current value for every
447475 // register value in the bytecode - argument, local, and temporary.
448476 Vector <NodeIndex, 32 > m_arguments;
449- Vector <NodeIndex, 32 > m_calleeRegisters;
477+ Vector <NodeIndex, 32 > m_variables;
478+ Vector <NodeIndex, 32 > m_temporaries;
450479
451480 // These maps are used to unique ToNumber and ToInt32 operations.
452481 typedef HashMap<NodeIndex, NodeIndex> UnaryOpMap;
@@ -462,7 +491,7 @@ class ByteCodeParser {
462491 m_currentIndex += OPCODE_LENGTH(name); \
463492 return !m_parseFailed
464493
465- bool ByteCodeParser::parse ()
494+ bool ByteCodeParser::parseBlock ()
466495{
467496 AliasTracker aliases (m_graph);
468497
@@ -799,17 +828,15 @@ bool ByteCodeParser::parse()
799828 }
800829}
801830
802- bool parse (Graph& graph, JSGlobalData* globalData, CodeBlock* codeBlock )
831+ bool ByteCodeParser:: parse ()
803832{
804- // Call ByteCodeParser::parse to build the dataflow for the basic block at 'startIndex'.
805- ByteCodeParser state (globalData, codeBlock, graph);
806- if (!state.parse ())
833+ if (!parseBlock ())
807834 return false ;
808835
809836 // Assign VirtualRegisters.
810- ScoreBoard scoreBoard (graph );
811- Node* nodes = graph .begin ();
812- size_t size = graph .size ();
837+ ScoreBoard scoreBoard (m_graph, m_variables. size () );
838+ Node* nodes = m_graph .begin ();
839+ size_t size = m_graph .size ();
813840 for (size_t i = 0 ; i < size; ++i) {
814841 Node& node = nodes[i];
815842 if (node.refCount ) {
@@ -831,15 +858,29 @@ bool parse(Graph& graph, JSGlobalData* globalData, CodeBlock* codeBlock)
831858 // 'm_numCalleeRegisters' is the number of locals and temporaries allocated
832859 // for the function (and checked for on entry). Since we perform a new and
833860 // different allocation of temporaries, more registers may now be required.
834- if ((unsigned )codeBlock->m_numCalleeRegisters < scoreBoard.allocatedCount ())
835- codeBlock->m_numCalleeRegisters = scoreBoard.allocatedCount ();
861+ unsigned calleeRegisters = scoreBoard.allocatedCount () + m_variables.size ();
862+ if ((unsigned )m_codeBlock->m_numCalleeRegisters < calleeRegisters)
863+ m_codeBlock->m_numCalleeRegisters = calleeRegisters;
836864
837865#if DFG_DEBUG_VERBOSE
838- graph .dump (codeBlock );
866+ m_graph .dump (m_codeBlock );
839867#endif
868+
840869 return true ;
841870}
842871
872+ bool parse (Graph& graph, JSGlobalData* globalData, CodeBlock* codeBlock)
873+ {
874+ #if DFG_DEBUG_LOCAL_DISBALE
875+ UNUSED_PARAM (graph);
876+ UNUSED_PARAM (globalData);
877+ UNUSED_PARAM (codeBlock);
878+ return false ;
879+ #else
880+ return ByteCodeParser (globalData, codeBlock, graph).parse ();
881+ #endif
882+ }
883+
843884} } // namespace JSC::DFG
844885
845886#endif
0 commit comments