diff options
author | Magnus Lång <[email protected]> | 2016-05-11 13:39:53 +0200 |
---|---|---|
committer | Magnus Lång <[email protected]> | 2016-05-11 13:39:53 +0200 |
commit | 7814ec18b095d40af95f362ff668a68915982e45 (patch) | |
tree | 50f16b9f246275c12843bbc8270cb0529aa86bd6 /erts | |
parent | 0f489445070cf65d96db7938f80ad118921c1f6a (diff) | |
download | otp-7814ec18b095d40af95f362ff668a68915982e45.tar.gz otp-7814ec18b095d40af95f362ff668a68915982e45.tar.bz2 otp-7814ec18b095d40af95f362ff668a68915982e45.zip |
hipe_llvm: Allow LLVM-generated constants
Since 3.7, LLVM sometimes generates SSE constants in a special constant
section with the requisite alignment (".rodata.cst16"). This broke
hipe_llvm since it assumed that all constants that were linked from the
text section were constants generated by hipe_llvm.
As this is the first time alignments larger than 8 have been required,
some small changes were required to hipe_consttab and
hipe_bifs:alloc_data/2. Note that hipe_bifs:alloc_data/2 still assumes
that erl_alloc will provide the requisite alignment.
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/hipe/hipe_bif0.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/erts/emulator/hipe/hipe_bif0.c b/erts/emulator/hipe/hipe_bif0.c index 48cfafb8c5..3f95fb67eb 100644 --- a/erts/emulator/hipe/hipe_bif0.c +++ b/erts/emulator/hipe/hipe_bif0.c @@ -418,6 +418,8 @@ BIF_RETTYPE hipe_bifs_enter_code_2(BIF_ALIST_2) BIF_RET(make_tuple(hp)); } +#define IS_POWER_OF_TWO(Val) (((Val) > 0) && (((Val) & ((Val)-1)) == 0)) + /* * Allocate memory for arbitrary non-Erlang data. */ @@ -427,16 +429,18 @@ BIF_RETTYPE hipe_bifs_alloc_data_2(BIF_ALIST_2) void *block; if (is_not_small(BIF_ARG_1) || is_not_small(BIF_ARG_2) || - (align = unsigned_val(BIF_ARG_1), - align != sizeof(long) && align != sizeof(double))) + (align = unsigned_val(BIF_ARG_1), !IS_POWER_OF_TWO(align))) BIF_ERROR(BIF_P, BADARG); nrbytes = unsigned_val(BIF_ARG_2); if (nrbytes == 0) BIF_RET(make_small(0)); block = erts_alloc(ERTS_ALC_T_HIPE, nrbytes); - if ((unsigned long)block & (align-1)) + if ((unsigned long)block & (align-1)) { fprintf(stderr, "%s: erts_alloc(%lu) returned %p which is not %lu-byte aligned\r\n", __FUNCTION__, (unsigned long)nrbytes, block, (unsigned long)align); + erts_free(ERTS_ALC_T_HIPE, block); + BIF_ERROR(BIF_P, EXC_NOTSUP); + } BIF_RET(address_to_term(block, BIF_P)); } |