diff options
author | Björn Gustavsson <[email protected]> | 2019-03-04 14:38:28 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2019-03-06 15:42:43 +0100 |
commit | db9a338a0480067a6f05551ce62c33f3aaf1a08a (patch) | |
tree | 7e7949a0ab8d0d71d7bf1bc2e20e14bc023941db /erts | |
parent | 82431098ec653fc98ab5a9114609f6c8a5a646e0 (diff) | |
download | otp-db9a338a0480067a6f05551ce62c33f3aaf1a08a.tar.gz otp-db9a338a0480067a6f05551ce62c33f3aaf1a08a.tar.bz2 otp-db9a338a0480067a6f05551ce62c33f3aaf1a08a.zip |
Optimize field size calculation on a 64-bit architecture
On a 64-bit architecture, the size of any binary that would fit in the
memory must fit in a small, so we can fail immediately if the size
term is not a small.
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/beam/bs_instrs.tab | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/erts/emulator/beam/bs_instrs.tab b/erts/emulator/beam/bs_instrs.tab index 714f1d49ce..4cf7faffb7 100644 --- a/erts/emulator/beam/bs_instrs.tab +++ b/erts/emulator/beam/bs_instrs.tab @@ -21,12 +21,50 @@ %if ARCH_64 BS_SAFE_MUL(A, B, Fail, Dst) { - Uint64 res = ($A) * ($B); - if (res / $B != $A) { + Uint a = $A; + Uint b = $B; + Uint res = a * b; + if (res / b != a) { $Fail; } $Dst = res; } + +BS_GET_FIELD_SIZE(Bits, Unit, Fail, Dst) { + if (is_small($Bits)) { + Uint uint_size; + Sint signed_size = signed_val($Bits); + if (signed_size < 0) { + $Fail; + } + uint_size = (Uint) signed_size; + $BS_SAFE_MUL(uint_size, $Unit, $Fail, $Dst); + } else { + /* + * On a 64-bit architecture, the size of any binary + * that would fit in the memory fits in a small. + */ + $Fail; + } +} + +BS_GET_UNCHECKED_FIELD_SIZE(Bits, Unit, Fail, Dst) { + if (is_small($Bits)) { + Uint uint_size; + Sint signed_size = signed_val($Bits); + if (signed_size < 0) { + $Fail; + } + uint_size = (Uint) signed_size; + $Dst = uint_size * $Unit; + } else { + /* + * On a 64-bit architecture, the size of any binary + * that would fit in the memory fits in a small. + */ + $Fail; + } +} %else BS_SAFE_MUL(A, B, Fail, Dst) { Uint64 res = (Uint64)($A) * (Uint64)($B); @@ -35,7 +73,6 @@ BS_SAFE_MUL(A, B, Fail, Dst) { } $Dst = res; } -%endif BS_GET_FIELD_SIZE(Bits, Unit, Fail, Dst) { Sint signed_size; @@ -76,6 +113,7 @@ BS_GET_UNCHECKED_FIELD_SIZE(Bits, Unit, Fail, Dst) { } $Dst = uint_size * $Unit; } +%endif TEST_BIN_VHEAP(VNh, Nh, Live) { Uint need = $Nh; |