2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 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 +----------------------------------------------------------------------+
16 #include "hphp/runtime/vm/jit/local-effects.h"
18 #include "hphp/runtime/vm/jit/ir-instruction.h"
19 #include "hphp/runtime/vm/jit/frame-state.h"
20 #include "hphp/runtime/vm/jit/analysis.h"
21 #include "hphp/runtime/vm/jit/minstr-effects.h"
23 namespace HPHP
{ namespace jit
{
25 //////////////////////////////////////////////////////////////////////
27 void local_effects(const FrameStateMgr
& frameState
,
28 const IRInstruction
* inst
,
29 LocalStateHook
& hook
) {
30 auto killIterLocals
= [&](const std::initializer_list
<uint32_t>& ids
) {
32 hook
.setLocalValue(id
, nullptr);
38 if (inst
->extra
<CallBuiltin
>()->destroyLocals
) hook
.clearLocals();
45 auto const callDestroysLocals
=
46 (inst
->is(CallArray
) && inst
->extra
<CallArray
>()->destroyLocals
) ||
47 (inst
->is(Call
) && inst
->extra
<Call
>()->destroyLocals
);
48 hook
.killLocalsForCall(callDestroysLocals
);
53 hook
.updateLocalRefPredictions(inst
->src(0), inst
->src(1));
58 hook
.setLocalValue(inst
->extra
<LocalId
>()->locId
, inst
->src(1));
62 hook
.setLocalValue(inst
->extra
<LdLoc
>()->locId
, inst
->dst());
66 hook
.predictLocalType(inst
->extra
<LocalId
>()->locId
,
67 inst
->src(1)->type());
73 auto id
= inst
->extra
<LocalId
>()->locId
;
74 if (inst
->marker().func()->isPseudoMain()) {
75 hook
.predictLocalType(id
, inst
->typeParam());
77 hook
.refineLocalType(id
,
79 TypeSource::makeGuard(inst
));
85 hook
.setBoxedLocalPrediction(inst
->extra
<HintLocInner
>()->locId
,
91 hook
.refineLocalValues(inst
->src(0), inst
->dst());
96 // kill the locals to which this instruction stores iter's key and value
97 killIterLocals({inst
->extra
<IterData
>()->keyId
,
98 inst
->extra
<IterData
>()->valId
});
103 // kill the local to which this instruction stores iter's value
104 killIterLocals({inst
->extra
<IterData
>()->valId
});
109 // kill the locals to which this instruction stores iter's key and value
110 killIterLocals({inst
->extra
<IterData
>()->keyId
,
111 inst
->extra
<IterData
>()->valId
});
116 // kill the local to which this instruction stores iter's value
117 killIterLocals({inst
->extra
<IterData
>()->valId
});
122 auto const& id
= *inst
->extra
<InterpOneData
>();
123 assert(!id
.smashesAllLocals
|| id
.nChangedLocals
== 0);
124 if (id
.smashesAllLocals
|| inst
->marker().func()->isPseudoMain()) {
127 auto it
= id
.changedLocals
;
128 auto const end
= it
+ id
.nChangedLocals
;
129 for (; it
!= end
; ++it
) {
131 // If changing the inner type of a boxed local, also drop the
132 // information about inner types for any other boxed locals.
133 if (loc
.type
.isBoxed()) hook
.dropLocalRefsInnerTypes();
134 hook
.setLocalType(loc
.id
, loc
.type
);
143 if (MInstrEffects::supported(inst
)) {
144 MInstrEffects::get(inst
, frameState
, hook
);
148 //////////////////////////////////////////////////////////////////////