Rename RefcountProfile to IncRefProfile
[hiphop-php.git] / hphp / runtime / vm / jit / func-guard-arm.cpp
blobf742d7cdf01b42fc904b8efc652d01f8e777d880
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
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/func-guard-arm.h"
19 #include "hphp/runtime/vm/jit/abi-arm.h"
20 #include "hphp/runtime/vm/jit/translator.h"
21 #include "hphp/runtime/vm/jit/smashable-instr-arm.h"
22 #include "hphp/runtime/vm/jit/tc.h"
23 #include "hphp/runtime/vm/jit/unique-stubs.h"
24 #include "hphp/runtime/vm/jit/vasm-reg.h"
26 #include "hphp/util/data-block.h"
28 #include "hphp/vixl/a64/constants-a64.h"
29 #include "hphp/vixl/a64/macro-assembler-a64.h"
31 namespace HPHP { namespace jit { namespace arm {
33 ///////////////////////////////////////////////////////////////////////////////
35 namespace {
37 ///////////////////////////////////////////////////////////////////////////////
39 ALWAYS_INLINE bool isPrologueStub(TCA addr) {
40 return addr == tc::ustubs().fcallHelperThunk;
43 vixl::Register X(Vreg64 r) {
44 PhysReg pr(r.asReg());
45 return x2a(pr);
48 vixl::MemOperand M(Vptr p) {
49 assertx(p.base.isValid() && !p.index.isValid());
50 return X(p.base)[p.disp];
53 ///////////////////////////////////////////////////////////////////////////////
57 ///////////////////////////////////////////////////////////////////////////////
59 void emitFuncGuard(const Func* func, CodeBlock& cb, CGMeta& fixups) {
60 vixl::MacroAssembler a { cb };
61 vixl::Label after;
62 vixl::Label target_data;
63 auto const begin = cb.frontier();
65 assertx(arm::abi(CodeKind::Prologue).gpUnreserved.contains(vixl::x0));
67 emitSmashableMovq(cb, fixups, uint64_t(func), vixl::x0);
68 a. Ldr (rAsm, M(rvmfp()[AROFF(m_func)]));
69 a. Cmp (vixl::x0, rAsm);
70 a. B (&after, convertCC(CC_Z));
72 // Although an address this unique stub should never change, so we don't
73 // need to mark it as an address.
74 poolLiteral(cb, fixups,
75 (uint64_t)makeTarget32(tc::ustubs().funcPrologueRedispatch),
76 32, false);
77 a. bind (&target_data);
78 a. Ldr (rAsm_w, &target_data);
79 a. Br (rAsm);
81 a. bind (&after);
83 cb.sync(begin);
86 TCA funcGuardFromPrologue(TCA prologue, const Func* /*func*/) {
87 if (!isPrologueStub(prologue)) {
88 // Typically a func guard is a smashable movq followed by an ldr, cmp, b.eq,
89 // ldr, and a br. However, relocation can shorten the sequence, or even
90 // increase it (turning the ldr into mov+movk), so search backwards until
91 // the smashable movq is found.
92 for (int length = 0; length <= vixl::kInstructionSize * 6; length += 4) {
93 TCA inst = prologue - (smashableMovqLen() + length);
94 if (possiblySmashableMovq(inst)) return inst;
96 always_assert(false);
98 return prologue;
101 bool funcGuardMatches(TCA guard, const Func* func) {
102 if (isPrologueStub(guard)) return false;
103 return smashableMovqImm(guard) == reinterpret_cast<uintptr_t>(func);
106 void clobberFuncGuard(TCA guard, const Func* /*func*/) {
107 smashMovq(guard, 0);
110 ///////////////////////////////////////////////////////////////////////////////