forked from facebook/hhvm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathalign-internal-inl.h
89 lines (64 loc) · 2.87 KB
/
align-internal-inl.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| [email protected] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include "hphp/util/data-block.h"
#include <folly/Bits.h>
#include <utility>
namespace HPHP::jit {
///////////////////////////////////////////////////////////////////////////////
namespace {
///////////////////////////////////////////////////////////////////////////////
bool is_aligned(TCA frontier, const AlignInfo& a) {
// 0 is no alignment constraint.
assertx(a.nbytes <= a.align || a.align == 0);
assertx(folly::isPowTwo(a.align) || a.align == 0);
auto const mask = a.align - 1;
auto const ifrontier = reinterpret_cast<size_t>(frontier);
auto const first_byte = ifrontier + a.offset;
auto const last_byte = ifrontier + a.nbytes - 1;
return (first_byte & ~mask) == (last_byte & ~mask);
}
size_t align_gap(TCA frontier, const AlignInfo& a) {
auto const ifrontier = reinterpret_cast<size_t>(frontier);
auto const gap = a.align - ((a.align - 1) & (ifrontier + a.offset));
return gap == a.align ? 0 : gap;
}
///////////////////////////////////////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////////////////
template <class AImpl>
bool is_aligned(TCA frontier, Alignment alignment) {
auto const idx = static_cast<uint32_t>(alignment);
return is_aligned(frontier, AImpl::s_table[idx]);
}
template <class AImpl>
void align(CodeBlock& cb, CGMeta* meta,
Alignment alignment, AlignContext context) {
auto const idx = static_cast<uint32_t>(alignment);
auto const pad_for_align = [&] (const AlignInfo& ali) {
if (is_aligned(cb.frontier(), ali)) return;
AImpl::pad(cb, context, align_gap(cb.frontier(), ali));
};
pad_for_align(AImpl::s_table[idx]);
assertx(is_aligned(cb.frontier(), AImpl::s_table[idx]));
if (meta) {
meta->alignments.emplace(
cb.frontier(),
std::make_pair(alignment, context)
);
}
}
///////////////////////////////////////////////////////////////////////////////
}