summaryrefslogtreecommitdiff
path: root/erts/emulator/beam/utils.c
diff options
context:
space:
mode:
authorSverker Eriksson <sverker@erlang.org>2015-02-10 21:58:45 +0100
committerBjörn-Egil Dahlberg <egil@erlang.org>2015-03-12 19:15:23 +0100
commitaad7d6fe4e1e9fe086d275ab3ea34c5285cc8edb (patch)
tree23839267520de27c634106afe609df2c614bfb65 /erts/emulator/beam/utils.c
parent8db065e5f6c07904db0c63175c906334e2eb5c59 (diff)
downloaderlang-aad7d6fe4e1e9fe086d275ab3ea34c5285cc8edb.tar.gz
erts: Change to total ordering of keys in small maps
Diffstat (limited to 'erts/emulator/beam/utils.c')
-rw-r--r--erts/emulator/beam/utils.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index 471bce8940..908116c64c 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -2686,8 +2686,22 @@ tailrecur_ne:
}
aa += 2;
bb += 2;
- i += 1; /* increment for tuple-keys */
- goto term_array;
+ if (exact) {
+ i += 1; /* increment for tuple-keys */
+ goto term_array;
+ }
+ else {
+ /* Value array */
+ WSTACK_PUSH3(stack, i, (UWord)(bb+1), (UWord)(aa+1) | TAG_PRIMARY_HEADER);
+ /* Marker to switch back from 'exact' compare */
+ WSTACK_PUSH(stack, (UWord)NULL | TAG_PRIMARY_HEADER);
+ /* Now do 'exact' compare of key tuples */
+ a = *aa;
+ b = *bb;
+ exact = 1;
+ goto tailrecur;
+ }
+
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
if (!is_float_rel(b,b_base)) {
a_tag = FLOAT_DEF;
@@ -3061,7 +3075,13 @@ pop_next:
if (!WSTACK_ISEMPTY(stack)) {
UWord something = WSTACK_POP(stack);
if (primary_tag((Eterm) something) == TAG_PRIMARY_HEADER) { /* a term_array */
- aa = (Eterm*) something;
+ if (something == ((UWord)NULL | TAG_PRIMARY_HEADER)) {
+ /* Done with exact compare of map keys, switch back */
+ ASSERT(exact);
+ exact = 0;
+ goto pop_next;
+ }
+ aa = (Eterm *)something;
bb = (Eterm*) WSTACK_POP(stack);
i = WSTACK_POP(stack);
goto term_array;