diff options
author | Kjell Winblad <[email protected]> | 2019-02-06 11:29:41 +0100 |
---|---|---|
committer | Kjell Winblad <[email protected]> | 2019-05-27 12:21:18 +0200 |
commit | b72e9d38110aac082cd98084dcb507a61b1bc3ad (patch) | |
tree | 0c380c5f8a722e72950c5d71664419caefa90acb /erts/emulator/beam/bif.c | |
parent | fe77a98f2e76b8e577df8fc68cb2a68adabc413c (diff) | |
download | otp-b72e9d38110aac082cd98084dcb507a61b1bc3ad.tar.gz otp-b72e9d38110aac082cd98084dcb507a61b1bc3ad.tar.bz2 otp-b72e9d38110aac082cd98084dcb507a61b1bc3ad.zip |
Make erlang:phash2/1 and erlang:phash2/2 yield
The erlang:phash2 functions did not yield even if the input was very
large and a call to one of the functions did only consume a single
reduction. This commit fixes these problems.
Diffstat (limited to 'erts/emulator/beam/bif.c')
-rw-r--r-- | erts/emulator/beam/bif.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index b81056c774..b35fe2fc02 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -4866,9 +4866,13 @@ BIF_RETTYPE phash_2(BIF_ALIST_2) BIF_RETTYPE phash2_1(BIF_ALIST_1) { Uint32 hash; - - hash = make_hash2(BIF_ARG_1); - BIF_RET(make_small(hash & ((1L << 27) - 1))); + Eterm trap_state = THE_NON_VALUE; + hash = trapping_make_hash2(BIF_ARG_1, &trap_state, BIF_P); + if (trap_state == THE_NON_VALUE) { + BIF_RET(make_small(hash & ((1L << 27) - 1))); + } else { + BIF_TRAP1(bif_export[BIF_phash2_1], BIF_P, trap_state); + } } BIF_RETTYPE phash2_2(BIF_ALIST_2) @@ -4876,6 +4880,7 @@ BIF_RETTYPE phash2_2(BIF_ALIST_2) Uint32 hash; Uint32 final_hash; Uint32 range; + Eterm trap_state = THE_NON_VALUE; /* Check for special case 2^32 */ if (term_equals_2pow32(BIF_ARG_2)) { @@ -4887,7 +4892,10 @@ BIF_RETTYPE phash2_2(BIF_ALIST_2) } range = (Uint32) u; } - hash = make_hash2(BIF_ARG_1); + hash = trapping_make_hash2(BIF_ARG_1, &trap_state, BIF_P); + if (trap_state != THE_NON_VALUE) { + BIF_TRAP2(bif_export[BIF_phash2_2], BIF_P, trap_state, BIF_ARG_2); + } if (range) { final_hash = hash % range; /* [0..range-1] */ } else { |