2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2016 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/mc-generator.h"
19 #include "hphp/util/data-block.h"
21 #include <folly/Bits.h>
24 namespace HPHP
{ namespace jit
{
26 ///////////////////////////////////////////////////////////////////////////////
30 ///////////////////////////////////////////////////////////////////////////////
32 bool is_aligned(TCA frontier
, const AlignInfo
& a
) {
33 assertx(a
.nbytes
<= a
.align
);
34 assertx(folly::isPowTwo(a
.align
));
36 auto const mask
= a
.align
- 1;
38 auto const ifrontier
= reinterpret_cast<size_t>(frontier
);
39 auto const first_byte
= ifrontier
+ a
.offset
;
40 auto const last_byte
= ifrontier
+ a
.nbytes
- 1;
42 return (first_byte
& ~mask
) == (last_byte
& ~mask
);
45 size_t align_gap(TCA frontier
, const AlignInfo
& a
) {
46 auto const ifrontier
= reinterpret_cast<size_t>(frontier
);
47 auto const gap
= a
.align
- ((a
.align
- 1) & (ifrontier
+ a
.offset
));
49 return gap
== a
.align
? 0 : gap
;
52 ///////////////////////////////////////////////////////////////////////////////
56 ///////////////////////////////////////////////////////////////////////////////
58 template <class AImpl
>
59 bool is_aligned(TCA frontier
, Alignment alignment
) {
60 auto const idx
= static_cast<uint32_t>(alignment
);
61 bool const is_jccandjmp
= alignment
== Alignment::SmashJccAndJmp
;
63 return is_aligned(frontier
, AImpl::s_table
[idx
]) &&
64 (!is_jccandjmp
|| is_aligned(frontier
, AImpl::s_table
[idx
+ 1]));
67 template <class AImpl
>
68 void align(CodeBlock
& cb
, CGMeta
* meta
,
69 Alignment alignment
, AlignContext context
) {
70 auto const idx
= static_cast<uint32_t>(alignment
);
71 bool const is_jccandjmp
= alignment
== Alignment::SmashJccAndJmp
;
73 auto const pad_for_align
= [&] (const AlignInfo
& ali
) {
74 if (is_aligned(cb
.frontier(), ali
)) return;
75 AImpl::pad(cb
, context
, align_gap(cb
.frontier(), ali
));
78 pad_for_align(AImpl::s_table
[idx
]);
80 pad_for_align(AImpl::s_table
[idx
+ 1]);
83 assertx(is_aligned(cb
.frontier(), AImpl::s_table
[idx
]));
84 assertx(IMPLIES(is_jccandjmp
,
85 is_aligned(cb
.frontier(), AImpl::s_table
[idx
+ 1])));
88 meta
->alignments
.emplace(
90 std::make_pair(alignment
, context
)
95 ///////////////////////////////////////////////////////////////////////////////