2 * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "DFGPredictionPropagationPhase.h"
33 #include "JSCInlines.h"
35 namespace JSC { namespace DFG {
39 bool verboseFixPointLoops = false;
41 class PredictionPropagationPhase : public Phase {
43 PredictionPropagationPhase(Graph& graph)
44 : Phase(graph, "prediction propagation")
50 ASSERT(m_graph.m_form == ThreadedCPS);
51 ASSERT(m_graph.m_unificationState == GloballyUnified);
53 propagateThroughArgumentPositions();
58 propagateToFixpoint();
60 m_pass = RareCasePass;
61 propagateToFixpoint();
63 m_pass = DoubleVotingPass;
66 if (verboseFixPointLoops)
70 doRoundOfDoubleVoting();
77 if (verboseFixPointLoops)
78 dataLog("Iterated ", counter, " times in double voting fixpoint.\n");
84 void propagateToFixpoint()
88 if (verboseFixPointLoops)
93 // Forward propagation is near-optimal for both topologically-sorted and
99 // Backward propagation reduces the likelihood that pathological code will
100 // cause slowness. Loops (especially nested ones) resemble backward flow.
101 // This pass captures two cases: (1) it detects if the forward fixpoint
102 // found a sound solution and (2) short-circuits backward flow.
107 if (verboseFixPointLoops)
108 dataLog("Iterated ", counter, " times in propagateToFixpoint.\n");
111 bool setPrediction(SpeculatedType prediction)
113 ASSERT(m_currentNode->hasResult());
115 // setPrediction() is used when we know that there is no way that we can change
116 // our minds about what the prediction is going to be. There is no semantic
117 // difference between setPrediction() and mergeSpeculation() other than the
118 // increased checking to validate this property.
119 ASSERT(m_currentNode->prediction() == SpecNone || m_currentNode->prediction() == prediction);
121 return m_currentNode->predict(prediction);
124 bool mergePrediction(SpeculatedType prediction)
126 ASSERT(m_currentNode->hasResult());
128 return m_currentNode->predict(prediction);
131 SpeculatedType speculatedDoubleTypeForPrediction(SpeculatedType value)
133 SpeculatedType result = SpecDoubleReal;
134 if (value & SpecDoubleImpureNaN)
135 result |= SpecDoubleImpureNaN;
136 if (value & SpecDoublePureNaN)
137 result |= SpecDoublePureNaN;
138 if (!isFullNumberOrBooleanSpeculation(value))
139 result |= SpecDoublePureNaN;
143 SpeculatedType speculatedDoubleTypeForPredictions(SpeculatedType left, SpeculatedType right)
145 return speculatedDoubleTypeForPrediction(mergeSpeculations(left, right));
148 void propagate(Node* node)
150 NodeType op = node->op();
152 bool changed = false;
156 VariableAccessData* variable = node->variableAccessData();
157 SpeculatedType prediction = variable->prediction();
158 if (!variable->couldRepresentInt52() && (prediction & SpecInt52Only))
159 prediction = (prediction | SpecAnyIntAsDouble) & ~SpecInt52Only;
161 changed |= mergePrediction(prediction);
166 VariableAccessData* variableAccessData = node->variableAccessData();
167 changed |= variableAccessData->predict(node->child1()->prediction());
171 case UInt32ToNumber: {
172 if (node->canSpeculateInt32(m_pass))
173 changed |= mergePrediction(SpecInt32Only);
174 else if (enableInt52())
175 changed |= mergePrediction(SpecAnyInt);
177 changed |= mergePrediction(SpecBytecodeNumber);
182 SpeculatedType left = node->child1()->prediction();
183 SpeculatedType right = node->child2()->prediction();
186 if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
187 && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
188 if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
189 changed |= mergePrediction(SpecInt32Only);
190 else if (m_graph.addShouldSpeculateAnyInt(node))
191 changed |= mergePrediction(SpecInt52Only);
193 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
194 } else if (isStringOrStringObjectSpeculation(left) || isStringOrStringObjectSpeculation(right)) {
195 // left or right is definitely something other than a number.
196 changed |= mergePrediction(SpecString);
198 changed |= mergePrediction(SpecInt32Only);
199 if (node->mayHaveDoubleResult())
200 changed |= mergePrediction(SpecBytecodeDouble);
201 if (node->mayHaveNonNumberResult())
202 changed |= mergePrediction(SpecString);
209 SpeculatedType left = node->child1()->prediction();
210 SpeculatedType right = node->child2()->prediction();
213 if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
214 changed |= mergePrediction(SpecInt32Only);
215 else if (m_graph.addShouldSpeculateAnyInt(node))
216 changed |= mergePrediction(SpecInt52Only);
217 else if (isFullNumberOrBooleanSpeculation(left) && isFullNumberOrBooleanSpeculation(right))
218 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
219 else if (node->mayHaveNonIntResult() || (left & SpecBytecodeDouble) || (right & SpecBytecodeDouble))
220 changed |= mergePrediction(SpecInt32Only | SpecBytecodeDouble);
222 changed |= mergePrediction(SpecInt32Only);
228 SpeculatedType left = node->child1()->prediction();
229 SpeculatedType right = node->child2()->prediction();
232 if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
233 && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
234 if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
235 changed |= mergePrediction(SpecInt32Only);
236 else if (m_graph.addShouldSpeculateAnyInt(node))
237 changed |= mergePrediction(SpecInt52Only);
239 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
240 } else if (node->mayHaveNonIntResult() || (left & SpecBytecodeDouble) || (right & SpecBytecodeDouble))
241 changed |= mergePrediction(SpecInt32Only | SpecBytecodeDouble);
243 changed |= mergePrediction(SpecInt32Only);
249 SpeculatedType prediction = node->child1()->prediction();
251 if (isInt32OrBooleanSpeculation(prediction) && node->canSpeculateInt32(m_pass))
252 changed |= mergePrediction(SpecInt32Only);
253 else if (m_graph.unaryArithShouldSpeculateAnyInt(node, m_pass))
254 changed |= mergePrediction(SpecInt52Only);
255 else if (isBytecodeNumberSpeculation(prediction))
256 changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction()));
258 changed |= mergePrediction(SpecInt32Only);
259 if (node->mayHaveDoubleResult())
260 changed |= mergePrediction(SpecBytecodeDouble);
267 SpeculatedType left = node->child1()->prediction();
268 SpeculatedType right = node->child2()->prediction();
271 if (Node::shouldSpeculateInt32OrBooleanForArithmetic(node->child1().node(), node->child2().node())
272 && node->canSpeculateInt32(m_pass))
273 changed |= mergePrediction(SpecInt32Only);
275 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
281 SpeculatedType left = node->child1()->prediction();
282 SpeculatedType right = node->child2()->prediction();
285 // FIXME: We're currently relying on prediction propagation and backwards propagation
286 // whenever we can, and only falling back on result flags if that fails. And the result
287 // flags logic doesn't know how to use backwards propagation. We should get rid of the
288 // prediction propagation logic and rely solely on the result type.
289 if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
290 && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
291 if (m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
292 changed |= mergePrediction(SpecInt32Only);
293 else if (m_graph.binaryArithShouldSpeculateAnyInt(node, m_pass))
294 changed |= mergePrediction(SpecInt52Only);
296 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
298 if (node->mayHaveNonIntResult()
299 || (left & SpecBytecodeDouble)
300 || (right & SpecBytecodeDouble))
301 changed |= mergePrediction(SpecInt32Only | SpecBytecodeDouble);
303 changed |= mergePrediction(SpecInt32Only);
311 SpeculatedType left = node->child1()->prediction();
312 SpeculatedType right = node->child2()->prediction();
315 if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
316 && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
317 if (m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
318 changed |= mergePrediction(SpecInt32Only);
320 changed |= mergePrediction(SpecBytecodeDouble);
322 changed |= mergePrediction(SpecInt32Only | SpecBytecodeDouble);
328 SpeculatedType childPrediction = node->child1()->prediction();
329 if (isInt32OrBooleanSpeculation(childPrediction)
330 && node->canSpeculateInt32(m_pass))
331 changed |= mergePrediction(SpecInt32Only);
333 changed |= mergePrediction(SpecBytecodeDouble);
340 case AtomicsCompareExchange:
341 case AtomicsExchange:
347 Edge child1 = m_graph.child(node, 0);
348 if (!child1->prediction())
351 Edge child2 = m_graph.child(node, 1);
352 ArrayMode arrayMode = node->arrayMode().refine(
354 child1->prediction(),
355 child2->prediction(),
358 switch (arrayMode.type()) {
360 if (arrayMode.isOutOfBounds())
361 changed |= mergePrediction(node->getHeapPrediction() | SpecInt32Only);
363 changed |= mergePrediction(SpecInt32Only);
366 if (arrayMode.isOutOfBounds())
367 changed |= mergePrediction(node->getHeapPrediction() | SpecDoubleReal);
368 else if (node->getHeapPrediction() & SpecNonIntAsDouble)
369 changed |= mergePrediction(SpecDoubleReal);
371 changed |= mergePrediction(SpecAnyIntAsDouble);
373 case Array::Float32Array:
374 case Array::Float64Array:
375 changed |= mergePrediction(SpecFullDouble);
377 case Array::Uint32Array:
378 if (isInt32SpeculationForArithmetic(node->getHeapPrediction()) && node->op() == GetByVal)
379 changed |= mergePrediction(SpecInt32Only);
380 else if (enableInt52())
381 changed |= mergePrediction(SpecAnyInt);
383 changed |= mergePrediction(SpecInt32Only | SpecAnyIntAsDouble);
385 case Array::Int8Array:
386 case Array::Uint8Array:
387 case Array::Int16Array:
388 case Array::Uint16Array:
389 case Array::Int32Array:
390 changed |= mergePrediction(SpecInt32Only);
393 changed |= mergePrediction(node->getHeapPrediction());
400 // ToThis in methods for primitive types should speculate primitive types in strict mode.
401 ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
402 if (ecmaMode == StrictMode) {
403 if (node->child1()->shouldSpeculateBoolean()) {
404 changed |= mergePrediction(SpecBoolean);
408 if (node->child1()->shouldSpeculateInt32()) {
409 changed |= mergePrediction(SpecInt32Only);
413 if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
414 changed |= mergePrediction(SpecAnyInt);
418 if (node->child1()->shouldSpeculateNumber()) {
419 changed |= mergePrediction(SpecBytecodeNumber);
423 if (node->child1()->shouldSpeculateSymbol()) {
424 changed |= mergePrediction(SpecSymbol);
428 if (node->child1()->shouldSpeculateStringIdent()) {
429 changed |= mergePrediction(SpecStringIdent);
433 if (node->child1()->shouldSpeculateString()) {
434 changed |= mergePrediction(SpecString);
438 if (node->child1()->shouldSpeculateString()) {
439 changed |= mergePrediction(SpecStringObject);
444 SpeculatedType prediction = node->child1()->prediction();
446 if (prediction & ~SpecObject) {
447 // Wrapper objects are created only in sloppy mode.
448 if (ecmaMode != StrictMode) {
449 prediction &= SpecObject;
450 prediction = mergeSpeculations(prediction, SpecObjectOther);
453 changed |= mergePrediction(prediction);
459 SpeculatedType child = node->child1()->prediction();
461 changed |= mergePrediction(resultOfToPrimitive(child));
465 case NormalizeMapKey: {
466 SpeculatedType prediction = node->child1()->prediction();
468 changed |= mergePrediction(prediction);
476 m_changed |= changed;
479 void propagateForward()
481 for (Node* node : m_dependentNodes) {
482 m_currentNode = node;
483 propagate(m_currentNode);
487 void propagateBackward()
489 for (unsigned i = m_dependentNodes.size(); i--;) {
490 m_currentNode = m_dependentNodes[i];
491 propagate(m_currentNode);
495 void doDoubleVoting(Node* node, float weight)
497 // Loop pre-headers created by OSR entrypoint creation may have NaN weight to indicate
498 // that we actually don't know they weight. Assume that they execute once. This turns
499 // out to be an OK assumption since the pre-header doesn't have any meaningful code.
500 if (weight != weight)
503 switch (node->op()) {
507 SpeculatedType left = node->child1()->prediction();
508 SpeculatedType right = node->child2()->prediction();
512 if (isFullNumberSpeculation(left)
513 && isFullNumberSpeculation(right)
514 && !m_graph.addShouldSpeculateInt32(node, m_pass)
515 && !m_graph.addShouldSpeculateAnyInt(node))
520 m_graph.voteNode(node->child1(), ballot, weight);
521 m_graph.voteNode(node->child2(), ballot, weight);
526 SpeculatedType left = node->child1()->prediction();
527 SpeculatedType right = node->child2()->prediction();
531 if (isFullNumberSpeculation(left)
532 && isFullNumberSpeculation(right)
533 && !m_graph.binaryArithShouldSpeculateInt32(node, m_pass)
534 && !m_graph.binaryArithShouldSpeculateAnyInt(node, m_pass))
539 m_graph.voteNode(node->child1(), ballot, weight);
540 m_graph.voteNode(node->child2(), ballot, weight);
548 SpeculatedType left = node->child1()->prediction();
549 SpeculatedType right = node->child2()->prediction();
553 if (isFullNumberSpeculation(left)
554 && isFullNumberSpeculation(right)
555 && !m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
560 m_graph.voteNode(node->child1(), ballot, weight);
561 m_graph.voteNode(node->child2(), ballot, weight);
567 if (node->child1()->shouldSpeculateNumber()
568 && !m_graph.unaryArithShouldSpeculateInt32(node, m_pass))
573 m_graph.voteNode(node->child1(), ballot, weight);
578 if (node->child1()->shouldSpeculateNumber())
579 m_graph.voteNode(node->child1(), VoteDouble, weight);
581 m_graph.voteNode(node->child1(), VoteValue, weight);
585 SpeculatedType prediction = node->child1()->prediction();
586 if (isDoubleSpeculation(prediction))
587 node->variableAccessData()->vote(VoteDouble, weight);
588 else if (!isFullNumberSpeculation(prediction)
589 || isInt32Speculation(prediction) || isAnyIntSpeculation(prediction))
590 node->variableAccessData()->vote(VoteValue, weight);
596 case PutByValAlias: {
597 Edge child1 = m_graph.varArgChild(node, 0);
598 Edge child2 = m_graph.varArgChild(node, 1);
599 Edge child3 = m_graph.varArgChild(node, 2);
600 m_graph.voteNode(child1, VoteValue, weight);
601 m_graph.voteNode(child2, VoteValue, weight);
602 switch (node->arrayMode().type()) {
604 m_graph.voteNode(child3, VoteDouble, weight);
607 m_graph.voteNode(child3, VoteValue, weight);
614 // Ignore these since they have no effect on in-DFG execution.
618 m_graph.voteChildren(node, VoteValue, weight);
623 void doRoundOfDoubleVoting()
625 for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i)
626 m_graph.m_variableAccessData[i].find()->clearVotes();
627 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
628 BasicBlock* block = m_graph.block(blockIndex);
631 ASSERT(block->isReachable);
632 for (unsigned i = 0; i < block->size(); ++i) {
633 m_currentNode = block->at(i);
634 doDoubleVoting(m_currentNode, block->executionCount);
637 for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
638 VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
639 if (!variableAccessData->isRoot())
641 m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat();
643 propagateThroughArgumentPositions();
644 for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
645 VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
646 if (!variableAccessData->isRoot())
648 m_changed |= variableAccessData->makePredictionForDoubleFormat();
652 void propagateThroughArgumentPositions()
654 for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
655 m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
658 // Sets any predictions that do not depends on other nodes.
659 void processInvariants()
661 for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
662 for (Node* node : *block) {
663 m_currentNode = node;
664 processInvariantsForNode();
669 void processInvariantsForNode()
671 switch (m_currentNode->op()) {
673 SpeculatedType type = speculationFromValue(m_currentNode->asJSValue());
674 if (type == SpecAnyIntAsDouble && enableInt52())
675 type = SpecInt52Only;
679 case DoubleConstant: {
680 SpeculatedType type = speculationFromValue(m_currentNode->asJSValue());
692 setPrediction(SpecInt32Only);
701 case StringReplaceRegExp:
704 case GetByIdWithThis:
706 case GetByValWithThis:
708 case MultiGetByOffset:
712 case TailCallInlinedCaller:
713 case DirectTailCallInlinedCaller:
715 case DirectConstruct:
718 case TailCallVarargsInlinedCaller:
719 case ConstructVarargs:
720 case CallForwardVarargs:
721 case ConstructForwardVarargs:
722 case TailCallForwardVarargsInlinedCaller:
724 case GetGlobalLexicalVariable:
726 case GetFromArguments:
727 case LoadKeyFromMapBucket:
728 case LoadValueFromMapBucket:
731 case CallObjectConstructor:
736 case GetPrototypeOf: {
737 setPrediction(m_currentNode->getHeapPrediction());
741 case ResolveScopeForHoistingFuncDeclInEval: {
742 setPrediction(SpecBytecodeTop);
746 case GetGetterSetterByOffset:
747 case GetExecutable: {
748 setPrediction(SpecCellOther);
756 case NewGeneratorFunction:
757 case NewAsyncGeneratorFunction:
758 case NewAsyncFunction: {
759 setPrediction(SpecFunction);
763 case GetArgumentCountIncludingThis: {
764 setPrediction(SpecInt32Only);
769 setPrediction(SpecInt32Only);
773 case GetMapBucketHead:
774 case GetMapBucketNext:
775 setPrediction(SpecCellOther);
780 setPrediction(SpecInt32Only);
784 case GetTypedArrayByteOffset:
786 case GetVectorLength: {
787 setPrediction(SpecInt32Only);
791 case StringCharCodeAt: {
792 setPrediction(SpecInt32Only);
798 setPrediction(SpecString);
805 setPrediction(SpecBytecodeDouble);
813 if (isInt32OrBooleanSpeculation(m_currentNode->getHeapPrediction())
814 && m_graph.roundShouldSpeculateInt32(m_currentNode, m_pass))
815 setPrediction(SpecInt32Only);
817 setPrediction(SpecBytecodeDouble);
822 setPrediction(SpecDoubleReal);
831 case CompareGreaterEq:
835 case CompareStrictEq:
837 case OverridesHasInstance:
839 case InstanceOfCustom:
848 case IsTypedArrayView: {
849 setPrediction(SpecBoolean);
854 setPrediction(SpecStringIdent);
858 case GetButterflyWithoutCaging:
859 case GetIndexedPropertyStorage:
860 case AllocatePropertyStorage:
861 case ReallocatePropertyStorage: {
862 setPrediction(SpecOther);
870 case GetGlobalObject: {
871 setPrediction(SpecObjectOther);
876 setPrediction(SpecObject);
880 setPrediction(SpecObjectOther);
886 setPrediction(SpecFinalObject);
891 case NewArrayWithSpread:
893 case NewArrayWithSize:
895 case NewArrayBuffer: {
896 setPrediction(SpecArray);
901 setPrediction(SpecCellOther);
904 case NewTypedArray: {
905 setPrediction(speculationFromTypedArrayType(m_currentNode->typedArrayType()));
910 setPrediction(SpecRegExpObject);
915 case CreateActivation: {
916 setPrediction(SpecObjectOther);
920 case StringFromCharCode: {
921 setPrediction(SpecString);
922 m_currentNode->child1()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsInt);
926 case CallStringConstructor:
928 case NumberToStringWithRadix:
929 case NumberToStringWithValidRadixConstant:
932 setPrediction(SpecString);
935 case NewStringObject: {
936 setPrediction(SpecStringObject);
940 case CreateDirectArguments: {
941 setPrediction(SpecDirectArguments);
945 case CreateScopedArguments: {
946 setPrediction(SpecScopedArguments);
950 case CreateClonedArguments: {
951 setPrediction(SpecObjectOther);
956 RELEASE_ASSERT(enableInt52());
957 setPrediction(SpecAnyInt);
962 setPrediction(SpecObjectOther);
966 setPrediction(SpecBoolean);
970 setPrediction(SpecBoolean);
973 case GetEnumerableLength: {
974 setPrediction(SpecInt32Only);
977 case HasGenericProperty:
978 case HasStructureProperty:
979 case HasIndexedProperty: {
980 setPrediction(SpecBoolean);
983 case GetPropertyEnumerator: {
984 setPrediction(SpecCell);
987 case GetEnumeratorStructurePname: {
988 setPrediction(SpecCell | SpecOther);
991 case GetEnumeratorGenericPname: {
992 setPrediction(SpecCell | SpecOther);
995 case ToIndexString: {
996 setPrediction(SpecString);
1000 // We expect this node to almost always produce an int32. However,
1001 // it's possible it produces NaN or integers out of int32 range. We
1002 // rely on the heap prediction since the parseInt() call profiled
1004 setPrediction(m_currentNode->getHeapPrediction());
1008 case IdentityWithProfile: {
1009 setPrediction(m_currentNode->getForcedPrediction());
1013 case ExtractCatchLocal: {
1014 setPrediction(m_currentNode->catchLocalPrediction());
1020 case UInt32ToNumber:
1034 case NormalizeMapKey:
1037 case AtomicsCompareExchange:
1038 case AtomicsExchange:
1044 m_dependentNodes.append(m_currentNode);
1048 case AtomicsIsLockFree: {
1049 setPrediction(SpecBoolean);
1053 case CPUIntrinsic: {
1054 if (m_currentNode->intrinsic() == CPURdtscIntrinsic)
1055 setPrediction(SpecInt32Only);
1057 setPrediction(SpecOther);
1064 case CheckTypeInfoFlags:
1066 case ArrayifyToStructure:
1067 case CheckTierUpInLoop:
1068 case CheckTierUpAtReturn:
1069 case CheckTierUpAndOSREnter:
1070 case InvalidationPoint:
1078 case BooleanToNumber:
1079 case PhantomNewObject:
1080 case PhantomNewFunction:
1081 case PhantomNewGeneratorFunction:
1082 case PhantomNewAsyncGeneratorFunction:
1083 case PhantomNewAsyncFunction:
1084 case PhantomCreateActivation:
1085 case PhantomDirectArguments:
1086 case PhantomCreateRest:
1088 case PhantomNewArrayWithSpread:
1089 case PhantomClonedArguments:
1090 case GetMyArgumentByVal:
1091 case GetMyArgumentByValOutOfBounds:
1093 case CheckStructureImmediate:
1094 case CheckStructureOrEmpty:
1095 case MaterializeNewObject:
1096 case MaterializeCreateActivation:
1100 case FencedStoreBarrier:
1102 case GetRegExpObjectLastIndex:
1103 case SetRegExpObjectLastIndex:
1104 case RecordRegExpCachedResult:
1105 case LazyJSConstant:
1107 // This node should never be visible at this stage of compilation.
1108 DFG_CRASH(m_graph, m_currentNode, "Unexpected node during prediction propagation");
1113 // Phis should not be visible here since we're iterating the all-but-Phi's
1114 // part of basic blocks.
1115 RELEASE_ASSERT_NOT_REACHED();
1120 // These don't get inserted until we go into SSA.
1121 RELEASE_ASSERT_NOT_REACHED();
1125 // These get ignored because they don't return anything.
1126 case PutByValDirect:
1127 case PutByValWithThis:
1128 case PutByIdWithThis:
1131 case PutToArguments:
1134 case ThrowStaticError:
1136 case DirectTailCall:
1137 case TailCallVarargs:
1138 case TailCallForwardVarargs:
1143 case MultiPutByOffset:
1146 case PutGetterSetterById:
1147 case PutGetterByVal:
1148 case PutSetterByVal:
1149 case DefineDataProperty:
1150 case DefineAccessorProperty:
1155 case ProfileControlFlow:
1158 case SetFunctionName:
1159 case CheckStructure:
1162 case CheckStringIdent:
1167 case PutGlobalVariable:
1169 case LogShadowChickenPrologue:
1170 case LogShadowChickenTail:
1174 case ConstantStoragePointer:
1179 case ForwardVarargs:
1181 case NukeStructureAndSetButterfly:
1182 case InitializeEntrypointArguments:
1187 // This gets ignored because it only pretends to produce a value.
1191 // This gets ignored because it already has a prediction.
1192 case ExtractOSREntryLocal:
1195 // These gets ignored because it doesn't do anything.
1196 case CountExecution:
1197 case SuperSamplerBegin:
1198 case SuperSamplerEnd:
1204 RELEASE_ASSERT_NOT_REACHED();
1213 SpeculatedType resultOfToPrimitive(SpeculatedType type)
1215 if (type & SpecObject) {
1216 // We try to be optimistic here about StringObjects since it's unlikely that
1217 // someone overrides the valueOf or toString methods.
1218 if (type & SpecStringObject && m_graph.canOptimizeStringObjectAccess(m_currentNode->origin.semantic))
1219 return mergeSpeculations(type & ~SpecObject, SpecString);
1221 return mergeSpeculations(type & ~SpecObject, SpecPrimitive);
1227 Vector<Node*> m_dependentNodes;
1228 Node* m_currentNode;
1230 PredictionPass m_pass; // We use different logic for considering predictions depending on how far along we are in propagation.
1233 } // Anonymous namespace.
1235 bool performPredictionPropagation(Graph& graph)
1237 return runPhase<PredictionPropagationPhase>(graph);
1240 } } // namespace JSC::DFG
1242 #endif // ENABLE(DFG_JIT)