2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/vm/jit/ir-opcode.h"
19 #include "hphp/runtime/base/string-data.h"
20 #include "hphp/runtime/vm/jit/cfg.h"
21 #include "hphp/runtime/vm/jit/extra-data.h"
22 #include "hphp/runtime/vm/jit/ir-instruction.h"
23 #include "hphp/runtime/vm/jit/ir-unit.h"
24 #include "hphp/runtime/vm/jit/ssa-tmp.h"
25 #include "hphp/runtime/vm/jit/print.h"
26 #include "hphp/runtime/vm/jit/type.h"
27 #include "hphp/runtime/vm/runtime.h"
29 #include "hphp/util/trace.h"
31 namespace HPHP
{ namespace jit
{
32 ///////////////////////////////////////////////////////////////////////////////
37 #define PRc ProducesRC
38 #define CRc ConsumesRC
42 #define MProp MInstrProp
43 #define MElem MInstrElem
44 #define LA LayoutAgnostic
45 #define LP (LayoutPreserving|LayoutAgnostic)
49 #define DofS(n) HasDest
50 #define DRefineS(n) HasDest
51 #define DParam(t) HasDest
52 #define DLdObjCls HasDest
53 #define DAllocObj HasDest
54 #define DBespokeElem HasDest
55 #define DBespokeElemUninit HasDest
56 #define DBespokePosKey HasDest
57 #define DBespokePosVal HasDest
58 #define DVecElem HasDest
59 #define DDictElem HasDest
60 #define DModified(n) HasDest
61 #define DArrLikeSet HasDest
62 #define DArrLikeAppend HasDest
63 #define DKeysetElem HasDest
64 #define DBespokeElemLval HasDest
65 #define DVecKey HasDest
66 #define DFirstElem HasDest
67 #define DLastElem HasDest
68 #define DFirstKey HasDest
69 #define DLastKey HasDest
70 #define DLoggingArrLike HasDest
71 #define DStructDict HasDest
73 #define DMulti NaryDest
74 #define DSetElem HasDest
75 #define DPtrToParam HasDest
76 #define DBuiltin HasDest
78 #define DGenIter HasDest
79 #define DSubtract(n,t) HasDest
80 #define DUnion(...) HasDest
81 #define DMemoKey HasDest
82 #define DLvalOfPtr HasDest
83 #define DPtrIter HasDest
84 #define DPtrIterVal HasDest
85 #define DEscalateToVanilla HasDest
88 template<Opcode op
, uint64_t flags
>
90 static constexpr uint64_t value
=
91 (OpHasExtraData
<op
>::value
? HasExtra
: 0) | flags
;
93 static_assert(!(value
& ProducesRC
) ||
94 (value
& (HasDest
| NaryDest
)) == HasDest
,
95 "ProducesRC instructions must have exactly one dest");
100 #define O(name, dsts, srcs, flags) \
102 op_flags<name, dsts | flags>::value \
128 #undef DBespokeElemUninit
130 #undef DBespokePosKey
131 #undef DBespokePosVal
135 #undef DEscalateToVanilla
136 #undef DBespokeElemLval
140 #undef DDictFirstElem
144 #undef DKeysetFirstElem
145 #undef DKeysetLastElem
146 #undef DLoggingArrLike
161 ///////////////////////////////////////////////////////////////////////////////
163 const StringData
* findClassName(SSATmp
* cls
) {
164 assertx(cls
->isA(TCls
));
166 if (cls
->hasConstVal()) {
167 return cls
->clsVal()->preClass()->name();
169 // Try to get the class name from a LdCls
170 IRInstruction
* clsInst
= cls
->inst();
171 if (clsInst
->op() == LdCls
|| clsInst
->op() == LdClsCached
) {
172 SSATmp
* clsName
= clsInst
->src(0);
173 assertx(clsName
->isA(TStr
));
174 if (clsName
->hasConstVal()) {
175 return clsName
->strVal();
181 bool isCallOp(Opcode opc
) {
182 // CallBuiltin doesn't count because it is not a php-level call. (It will
183 // call a C++ helper and we can push/pop around it normally.)
193 bool isGuardOp(Opcode opc
) {
206 folly::Optional
<Opcode
> negateCmpOp(Opcode opc
) {
208 case GtBool
: return LteBool
;
209 case GteBool
: return LtBool
;
210 case LtBool
: return GteBool
;
211 case LteBool
: return GtBool
;
212 case EqBool
: return NeqBool
;
213 case NeqBool
: return EqBool
;
215 case GtInt
: return LteInt
;
216 case GteInt
: return LtInt
;
217 case LtInt
: return GteInt
;
218 case LteInt
: return GtInt
;
219 case EqInt
: return NeqInt
;
220 case NeqInt
: return EqInt
;
222 // Due to NaN only equality comparisons with doubles can be negated.
223 case EqDbl
: return NeqDbl
;
224 case NeqDbl
: return EqDbl
;
226 case GtStr
: return LteStr
;
227 case GteStr
: return LtStr
;
228 case LtStr
: return GteStr
;
229 case LteStr
: return GtStr
;
230 case EqStr
: return NeqStr
;
231 case NeqStr
: return EqStr
;
232 case SameStr
: return NSameStr
;
233 case NSameStr
: return SameStr
;
235 case GtStrInt
: return LteStrInt
;
236 case GteStrInt
: return LtStrInt
;
237 case LtStrInt
: return GteStrInt
;
238 case LteStrInt
: return GtStrInt
;
239 case EqStrInt
: return NeqStrInt
;
240 case NeqStrInt
: return EqStrInt
;
242 // Objects can contain a property with NaN, so only equality comparisons can
244 case EqObj
: return NeqObj
;
245 case NeqObj
: return EqObj
;
246 case SameObj
: return NSameObj
;
247 case NSameObj
: return SameObj
;
249 // Arrays/vec/dicts can contain an element with NaN, so only equality
250 // comparisons can be negated.
251 case EqArrLike
: return NeqArrLike
;
252 case NeqArrLike
: return EqArrLike
;
253 case SameArrLike
: return NSameArrLike
;
254 case NSameArrLike
: return SameArrLike
;
256 case GtRes
: return LteRes
;
257 case GteRes
: return LtRes
;
258 case LtRes
: return GteRes
;
259 case LteRes
: return GtRes
;
260 case EqRes
: return NeqRes
;
261 case NeqRes
: return EqRes
;
263 default: return folly::none
;
267 bool opcodeMayRaise(Opcode opc
) {
271 return RuntimeOption::EvalHackArrCompatCheckCompare
;
274 return RuntimeOption::EvalHackArrIsShapeTupleNotices
||
275 RuntimeOption::EvalIsExprEnableUnresolvedWarning
||
276 RuntimeOption::EvalIsVecNotices
;
280 return (bool)RuntimeOption::EvalNoticeOnCoerceForEq
;
282 case AddNewElemKeyset
:
283 case AFWHPrepareChild
:
286 case AllocObjReified
:
287 case ArrayMarkLegacyShallow
:
288 case ArrayMarkLegacyRecursive
:
289 case ArrayUnmarkLegacyShallow
:
290 case ArrayUnmarkLegacyRecursive
:
294 case BespokeGetThrow
:
301 case CheckClsMethFunc
:
302 case CheckClsReifiedGenericMismatch
:
303 case CheckFunReifiedGenericMismatch
:
304 case CheckStackOverflow
:
305 case CheckSurpriseAndStack
:
306 case CheckSurpriseFlagsEnter
:
316 case ConstructInstance
:
318 case ConvArrLikeToDict
:
319 case ConvArrLikeToKeyset
:
320 case ConvArrLikeToVec
:
325 case ConvClsMethToDict
:
326 case ConvClsMethToKeyset
:
327 case ConvClsMethToVec
:
332 case ConvObjToKeyset
:
357 case HandleRequestSurprise
:
375 case LdClsPropAddrOrNull
:
376 case LdClsPropAddrOrRaise
:
378 case LdClsTypeCnsClsName
:
383 case LdRecDescCached
:
386 case LdSSwitchDestSlow
:
387 case LdSwitchObjIndex
:
389 case LookupClsCtxCns
:
390 case LookupClsMethod
:
391 case LookupClsMethodCache
:
392 case LookupClsMethodFCache
:
394 case LookupFuncCached
:
415 case ProfileSubClsCns
:
418 case PropTypeRedefineCheck
:
420 case RaiseBadComparisonViolation
:
421 case RaiseClsMethPropConvertNotice
:
422 case RaiseCoeffectsCallViolation
:
423 case RaiseCoeffectsFunParamCoeffectRulesViolation
:
424 case RaiseCoeffectsFunParamTypeViolation
:
426 case RaiseErrorOnInvalidIsAsExpressionType
:
427 case RaiseForbiddenDynCall
:
428 case RaiseForbiddenDynConstruct
:
429 case RaiseHackArrCompatNotice
:
431 case RaiseStrToClassNotice
:
432 case RaiseTooManyArg
:
436 case RecordReifiedGenericsAndGetTSList
:
437 case ResolveTypeStruct
:
442 case SetNewElemKeyset
:
451 case SuspendHookAwaitEF
:
452 case SuspendHookAwaitEG
:
453 case SuspendHookAwaitR
:
454 case SuspendHookCreateCont
:
455 case SuspendHookYield
:
456 case ThrowAsTypeStructException
:
457 case ThrowArrayIndexException
:
458 case ThrowArrayKeyException
:
459 case ThrowCallReifiedFunctionWithoutGenerics
:
460 case ThrowDivisionByZeroException
:
461 case ThrowHasThisNeedStatic
:
462 case ThrowInvalidArrayKey
:
463 case ThrowInvalidOperation
:
464 case ThrowLateInitPropError
:
465 case ThrowMissingArg
:
466 case ThrowMissingThis
:
467 case ThrowOutOfBounds
:
468 case ThrowParameterWrongType
:
469 case ThrowParamInOutMismatch
:
470 case ThrowParamInOutMismatchRange
:
471 case ThrowMustBeMutableException
:
472 case ThrowMustBeReadOnlyException
:
477 case VerifyParamCallable
:
479 case VerifyParamFail
:
480 case VerifyParamFailHard
:
484 case VerifyPropCoerce
:
485 case VerifyPropCoerceAll
:
487 case VerifyPropFailHard
:
488 case VerifyReifiedLocalType
:
489 case VerifyReifiedReturnType
:
490 case VerifyRetCallable
:
493 case VerifyRetFailHard
:
494 case VerifyParamRecDesc
:
495 case VerifyRetRecDesc
:
496 case VerifyPropRecDesc
:
504 case AdvanceDictPtrIter
:
506 case AFWHPushTailFrame
:
509 case AllocBespokeStructDict
:
510 case AllocStructDict
:
519 case AsyncFuncRetSlow
:
520 case AsyncSwitchFast
:
523 case BespokeEscalateToVanilla
:
525 case BespokeIterFirstPos
:
526 case BespokeIterLastPos
:
528 case BespokeIterGetKey
:
529 case BespokeIterGetVal
:
534 case CheckDictOffset
:
535 case CheckFuncNeedsCoverage
:
536 case CheckImplicitContextNull
:
541 case CheckKeysetOffset
:
544 case CheckMissingKeyInArrLike
:
548 case CheckRDSInitialized
:
549 case CheckSmashableClass
:
552 case CheckSurpriseFlags
:
567 case ConstructClosure
:
570 case ContArUpdateIdx
:
573 case ContStartedCheck
:
589 case CountCollection
:
600 case DbgAssertRefCount
:
601 case DbgCheckLocalsDecRefd
:
628 case DirFromFilepath
:
631 case EagerSyncVMRegs
:
656 case GenericRetDecRefs
:
658 case GetMemoKeyScalar
:
671 case HasReifiedGenerics
:
678 case InitObjMemoSlots
:
681 case InitStructPositions
:
682 case InitThrowableFileAndLine
:
684 case InitVecElemLoop
:
688 case InstanceOfBitmask
:
689 case InstanceOfIface
:
690 case InstanceOfIfaceVtable
:
691 case InstanceOfRecDesc
:
692 case InterfaceSupportsArrLike
:
693 case InterfaceSupportsDbl
:
694 case InterfaceSupportsInt
:
695 case InterfaceSupportsStr
:
698 case IsFunReifiedGenericsMatched
:
701 case IsLegacyArrLike
:
704 case IsTypeStructCached
:
725 case LdClsCachedSafe
:
728 case LdClsFromClsMeth
:
729 case LdClsFromRClsMeth
:
733 case LdClsMethodCacheCls
:
734 case LdClsMethodCacheFunc
:
735 case LdClsMethodFCacheFunc
:
744 case LdContResumeAddr
:
749 case LdFuncFromClsMeth
:
750 case LdFuncFromRClsMeth
:
751 case LdFuncFromRFunc
:
753 case LdFuncNumParams
:
754 case LdFuncRequiredCoeffects
:
756 case LdGenericsFromRClsMeth
:
757 case LdGenericsFromRFunc
:
771 case LdMethCallerName
:
782 case LdRecDescCachedSafe
:
785 case LdSmashableFunc
:
786 case LdSSwitchDestFast
:
791 case LdSubClsCnsClsName
:
792 case LdSwitchDblIndex
:
793 case LdSwitchStrIndex
:
796 case LdUnitPerRequestFilepath
:
797 case LdUnwinderValue
:
798 case LdMonotypeDictTombstones
:
799 case LdMonotypeDictKey
:
800 case LdMonotypeDictVal
:
801 case LdMonotypeVecElem
:
804 case LdStructDictElem
:
817 case LogGuardFailure
:
819 case LookupSPropSlot
:
832 case MarkRDSInitialized
:
833 case MemoGetInstanceCache
:
834 case MemoGetInstanceValue
:
835 case MemoGetStaticCache
:
836 case MemoGetStaticValue
:
837 case MemoGetLSBCache
:
838 case MemoGetLSBValue
:
839 case MemoSetInstanceCache
:
840 case MemoSetInstanceValue
:
841 case MemoSetStaticCache
:
842 case MemoSetStaticValue
:
843 case MemoSetLSBCache
:
844 case MemoSetLSBValue
:
858 case NewColFromArray
:
861 case NewLoggingArray
:
865 case NewBespokeStructDict
:
866 case NInstanceOfBitmask
:
873 case ProfileArrLikeProps
:
876 case ProfileDictAccess
:
877 case ProfileInstanceCheck
:
878 case ProfileIsTypeStruct
:
879 case ProfileKeysetAccess
:
882 case ProfileSwitchDest
:
889 case ReqRetranslateOpt
:
890 case ReserveVecNewElem
:
891 case RestoreErrorLevel
:
908 case StImplicitContext
:
918 case StrictlyIntegerConv
:
920 case StructDictGetWithColor
:
928 case UnwindCheckSideExit
:
940 ///////////////////////////////////////////////////////////////////////////////