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
47 #define DofS(n) HasDest
48 #define DRefineS(n) HasDest
49 #define DParamMayRelax(t) HasDest
50 #define DParam(t) HasDest
51 #define DLdObjCls HasDest
52 #define DUnboxPtr HasDest
53 #define DBoxPtr HasDest
54 #define DAllocObj HasDest
55 #define DArrElem HasDest
56 #define DVecElem HasDest
57 #define DDictElem HasDest
58 #define DKeysetElem HasDest
59 #define DVecFirstElem HasDest
60 #define DVecLastElem HasDest
61 #define DVecKey HasDest
62 #define DDictFirstElem HasDest
63 #define DDictLastElem HasDest
64 #define DDictFirstKey HasDest
65 #define DDictLastKey HasDest
66 #define DKeysetFirstElem HasDest
67 #define DKeysetLastElem HasDest
68 #define DArrPacked HasDest
69 #define DArrMixed HasDest
72 #define DStaticDArr HasDest
75 #define DCtxCls HasDest
76 #define DMulti NaryDest
77 #define DSetElem HasDest
78 #define DPtrToParam HasDest
79 #define DBuiltin HasDest
81 #define DGenIter HasDest
82 #define DSubtract(n,t) HasDest
84 #define DUnion(...) HasDest
85 #define DMemoKey HasDest
86 #define DLvalOfPtr HasDest
89 template<Opcode op
, uint64_t flags
>
91 static constexpr uint64_t value
=
92 (OpHasExtraData
<op
>::value
? HasExtra
: 0) | flags
;
94 static_assert(!(value
& ProducesRC
) ||
95 (value
& (HasDest
| NaryDest
)) == HasDest
,
96 "ProducesRC instructions must have exactly one dest");
100 OpInfo g_opInfo
[] = {
101 #define O(name, dsts, srcs, flags) \
103 op_flags<name, dsts | flags>::value \
127 #undef DParamMayRelax
139 #undef DDictFirstElem
143 #undef DKeysetFirstElem
144 #undef DKeysetLastElem
166 ///////////////////////////////////////////////////////////////////////////////
168 const StringData
* findClassName(SSATmp
* cls
) {
169 assertx(cls
->isA(TCls
));
171 if (cls
->hasConstVal()) {
172 return cls
->clsVal()->preClass()->name();
174 // Try to get the class name from a LdCls
175 IRInstruction
* clsInst
= cls
->inst();
176 if (clsInst
->op() == LdCls
|| clsInst
->op() == LdClsCached
) {
177 SSATmp
* clsName
= clsInst
->src(0);
178 assertx(clsName
->isA(TStr
));
179 if (clsName
->hasConstVal()) {
180 return clsName
->strVal();
186 bool isCallOp(Opcode opc
) {
187 // CallBuiltin doesn't count because it is not a php-level call. (It will
188 // call a C++ helper and we can push/pop around it normally.)
199 bool isGuardOp(Opcode opc
) {
212 folly::Optional
<Opcode
> negateCmpOp(Opcode opc
) {
214 case GtBool
: return LteBool
;
215 case GteBool
: return LtBool
;
216 case LtBool
: return GteBool
;
217 case LteBool
: return GtBool
;
218 case EqBool
: return NeqBool
;
219 case NeqBool
: return EqBool
;
221 case GtInt
: return LteInt
;
222 case GteInt
: return LtInt
;
223 case LtInt
: return GteInt
;
224 case LteInt
: return GtInt
;
225 case EqInt
: return NeqInt
;
226 case NeqInt
: return EqInt
;
228 // Due to NaN only equality comparisons with doubles can be negated.
229 case EqDbl
: return NeqDbl
;
230 case NeqDbl
: return EqDbl
;
232 case GtStr
: return LteStr
;
233 case GteStr
: return LtStr
;
234 case LtStr
: return GteStr
;
235 case LteStr
: return GtStr
;
236 case EqStr
: return NeqStr
;
237 case NeqStr
: return EqStr
;
238 case SameStr
: return NSameStr
;
239 case NSameStr
: return SameStr
;
241 case GtStrInt
: return LteStrInt
;
242 case GteStrInt
: return LtStrInt
;
243 case LtStrInt
: return GteStrInt
;
244 case LteStrInt
: return GtStrInt
;
245 case EqStrInt
: return NeqStrInt
;
246 case NeqStrInt
: return EqStrInt
;
248 // Objects can contain a property with NaN, so only equality comparisons can
250 case EqObj
: return NeqObj
;
251 case NeqObj
: return EqObj
;
252 case SameObj
: return NSameObj
;
253 case NSameObj
: return SameObj
;
255 // Arrays/vec/dicts can contain an element with NaN, so only equality
256 // comparisons can be negated.
257 case EqArr
: return NeqArr
;
258 case NeqArr
: return EqArr
;
259 case SameArr
: return NSameArr
;
260 case NSameArr
: return SameArr
;
262 case EqShape
: return NeqShape
;
263 case NeqShape
: return EqShape
;
264 case SameShape
: return NSameShape
;
265 case NSameShape
: return SameShape
;
267 case EqVec
: return NeqVec
;
268 case NeqVec
: return EqVec
;
269 case SameVec
: return NSameVec
;
270 case NSameVec
: return SameVec
;
272 case EqDict
: return NeqDict
;
273 case NeqDict
: return EqDict
;
274 case SameDict
: return NSameDict
;
275 case NSameDict
: return SameDict
;
277 case EqKeyset
: return NeqKeyset
;
278 case NeqKeyset
: return EqKeyset
;
279 case SameKeyset
: return NSameKeyset
;
280 case NSameKeyset
: return SameKeyset
;
282 case GtRes
: return LteRes
;
283 case GteRes
: return LtRes
;
284 case LtRes
: return GteRes
;
285 case LteRes
: return GtRes
;
286 case EqRes
: return NeqRes
;
287 case NeqRes
: return EqRes
;
289 default: return folly::none
;
293 bool opcodeMayRaise(Opcode opc
) {
295 // AKExistsArr, ArrayIdx, and ArrayIsset may only raise errors when the option
296 // EvalHackArrCompatNotices is set.
300 return RuntimeOption::EvalHackArrCompatNotices
;
302 // Same thing for SameArr and NSameArr, but for EvalHackArrCompatDVCmpNotices.
311 return RuntimeOption::EvalHackArrCompatDVCmpNotices
||
312 RuntimeOption::EvalHackArrCompatCheckCompare
;
314 // Same thing for IsTypeStruct, but for EvalHackArrCompatIsArrayNotices
315 // and EvalIsExprEnableUnresolvedWarning.
317 return RuntimeOption::EvalHackArrCompatIsArrayNotices
318 || RuntimeOption::EvalIsExprEnableUnresolvedWarning
;
323 case AddNewElemKeyset
:
324 case AFWHPrepareChild
:
327 case AllocObjReified
:
345 case CheckStackOverflow
:
346 case CheckSurpriseAndStack
:
347 case CheckSurpriseFlagsEnter
:
353 case CoerceCellToBool
:
354 case CoerceCellToDbl
:
355 case CoerceCellToInt
:
365 case ConstructInstance
:
368 case ConvArrToKeyset
:
370 case ConvShapeToDict
:
378 case ConvDictToKeyset
:
380 case ConvShapeToDArr
:
381 case ConvShapeToKeyset
:
382 case ConvKeysetToArr
:
383 case ConvKeysetToDArr
:
389 case ConvObjToKeyset
:
394 case ConvVecToKeyset
:
399 case DictAddElemIntKey
:
400 case DictAddElemStrKey
:
424 case FatalMissingThis
:
452 case LdClsPropAddrOrNull
:
453 case LdClsPropAddrOrRaise
:
454 case LdReifiedGeneric
:
460 case LdSSwitchDestSlow
:
461 case LdSwitchObjIndex
:
462 case LookupClsMethod
:
463 case LookupClsMethodCache
:
464 case LookupClsMethodFCache
:
469 case LookupFuncCached
:
496 case PropTypeRedefineCheck
:
498 case RaiseArrayIndexNotice
:
499 case RaiseArrayKeyNotice
:
501 case RaiseForbiddenDynCall
:
502 case RaiseHackArrCompatNotice
:
503 case RaiseHackArrParamNotice
:
504 case RaiseHackArrPropNotice
:
505 case RaiseMissingArg
:
506 case RaiseMissingThis
:
508 case RaiseParamRefMismatchForFunc
:
509 case RaiseParamRefMismatchForFuncName
:
510 case RaiseReifiedGenericMismatch
:
513 case RaiseVarEnvDynCall
:
515 case ResolveTypeStruct
:
519 case SetNewElemArray
:
520 case SetNewElemKeyset
:
523 case SetOpCellVerify
:
531 case SuspendHookAwaitEF
:
532 case SuspendHookAwaitEG
:
533 case SuspendHookAwaitR
:
534 case SuspendHookCreateCont
:
535 case SuspendHookYield
:
536 case ThrowArithmeticError
:
537 case ThrowDivisionByZeroError
:
538 case ThrowInvalidArrayKey
:
539 case ThrowInvalidOperation
:
540 case ThrowLateInitPropError
:
541 case ThrowOutOfBounds
:
547 case VerifyParamCallable
:
549 case VerifyParamFail
:
550 case VerifyParamFailHard
:
554 case VerifyPropFailHard
:
555 case VerifyRetCallable
:
558 case VerifyRetFailHard
:
575 case AllocPackedArray
:
586 case AsyncFuncRetSlow
:
587 case AsyncSwitchFast
:
593 case CheckARMagicFlag
:
598 case CheckDictOffset
:
599 case CheckFuncStatic
:
602 case CheckKeysetOffset
:
605 case CheckMixedArrayOffset
:
608 case CheckPackedArrayDataBounds
:
610 case CheckRDSInitialized
:
616 case CheckSurpriseFlags
:
633 case ContArUpdateIdx
:
636 case ContStartedCheck
:
641 case ConvArrToNonDVArr
:
654 case ConvShapeToVArr
:
660 case ConvKeysetToDict
:
661 case ConvKeysetToVArr
:
662 case ConvKeysetToVec
:
677 case CountCollection
:
690 case DbgAssertARFunc
:
691 case DbgAssertRefCount
:
699 case DebugBacktraceFast
:
718 case EagerSyncVMRegs
:
721 case ElemMixedArrayK
:
737 case ExitPlaceholder
:
742 case FuncSupportsAsyncEagerReturn
:
743 case FwdCtxStaticCall
:
744 case GenericRetDecRefs
:
745 case GetMemoKeyScalar
:
769 case InitPackedLayoutArray
:
770 case InitPackedLayoutArrayLoop
:
772 case InitThrowableFileAndLine
:
774 case InlineReturnNoFrame
:
777 case InstanceOfBitmask
:
778 case InstanceOfIface
:
779 case InstanceOfIfaceVtable
:
780 case InterfaceSupportsArr
:
781 case InterfaceSupportsDbl
:
782 case InterfaceSupportsDict
:
783 case InterfaceSupportsInt
:
784 case InterfaceSupportsKeyset
:
785 case InterfaceSupportsStr
:
786 case InterfaceSupportsVec
:
790 case IsFuncDynCallable
:
803 case KeysetEmptyElem
:
810 case KillARReifiedGenerics
:
819 case LdARNumArgsAndFlags
:
821 case LdARReifiedGenerics
:
826 case LdClosureStaticLoc
:
827 case LdClsCachedSafe
:
834 case LdClsMethodCacheCls
:
835 case LdClsMethodCacheFunc
:
836 case LdClsMethodFCacheFunc
:
847 case LdContResumeAddr
:
850 case LdCufIterDynamic
:
852 case LdCufIterInvName
:
854 case LdFuncNumParams
:
864 case LdLocPseudoMain
:
867 case LdMIPropStateAddr
:
871 case LdPackedArrayDataElemAddr
:
878 case LdSSwitchDestFast
:
884 case LdSwitchDblIndex
:
885 case LdSwitchStrIndex
:
888 case LdUnwinderValue
:
900 case LookupSPropSlot
:
914 case MarkRDSInitialized
:
915 case MemoGetInstanceCache
:
916 case MemoGetInstanceValue
:
917 case MemoGetStaticCache
:
918 case MemoGetStaticValue
:
919 case MemoGetLSBCache
:
920 case MemoGetLSBValue
:
921 case MemoSetInstanceCache
:
922 case MemoSetInstanceValue
:
923 case MemoSetStaticCache
:
924 case MemoSetStaticValue
:
925 case MemoSetLSBCache
:
926 case MemoSetLSBValue
:
946 case NewColFromArray
:
954 case NewStructDArray
:
956 case NInstanceOfBitmask
:
965 case ProfileArrayKind
:
966 case ProfileDictOffset
:
967 case ProfileInstanceCheck
:
968 case ProfileKeysetOffset
:
971 case ProfileMixedArrayOffset
:
972 case ProfileSubClsCns
:
973 case ProfileSwitchDest
:
977 case RegisterLiveObj
:
978 case ReleaseVVAndSkip
:
981 case ReqRetranslateOpt
:
982 case ReservePackedArrayDataNewElem
:
983 case RestoreErrorLevel
:
994 case StARNumArgsAndFlags
:
995 case StARReifiedGenerics
:
1005 case StCufIterDynamic
:
1007 case StCufIterInvName
:
1010 case StLocPseudoMain
:
1017 case StrictlyIntegerConv
:
1026 case UnwindCheckSideExit
:
1032 case ZeroErrorLevel
:
1038 ///////////////////////////////////////////////////////////////////////////////