From f10f3efa900c9a8bf360f719e46bc615fb290afc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Tue, 1 Jan 2013 16:44:17 +0100
Subject: [PATCH] Mappings: Compat: Reduce aggressiveness of rehash gc.

Non-reference counted values are now counted as multi-referenced
by the rehash gc. This fixes issues where elements are lost in
double-weak mappings due to either the index or the value being
a non-reference counted value.
---
 src/mapping.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/src/mapping.c b/src/mapping.c
index 3946447fe6..c45c59e528 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -350,10 +350,13 @@ static void mapping_rehash_backwards_evil(struct mapping_data *md,
 	}
 	break;
       case MAPPING_WEAK:
-	if ((TYPEOF(from->ind) <= MAX_REF_TYPE) &&
-	    (*from->ind.u.refs > 1) &&
-	    (TYPEOF(from->val) <= MAX_REF_TYPE) &&
-	    (*from->val.u.refs > 1)) {
+	/* NB: Compat: Unreference counted values are counted
+	 *             as multi-referenced here.
+	 */
+	if (((TYPEOF(from->ind) > MAX_REF_TYPE) ||
+	     (*from->ind.u.refs > 1)) &&
+	    ((TYPEOF(from->val) > MAX_REF_TYPE) ||
+	     (*from->val.u.refs > 1))) {
 	  goto keep_keypair;
 	}
 	break;
@@ -440,10 +443,13 @@ static void mapping_rehash_backwards_good(struct mapping_data *md,
 	}
 	break;
       case MAPPING_WEAK:
-	if ((TYPEOF(from->ind) <= MAX_REF_TYPE) &&
-	    (*from->ind.u.refs > 1) &&
-	    (TYPEOF(from->val) <= MAX_REF_TYPE) &&
-	    (*from->val.u.refs > 1)) {
+	/* NB: Compat: Unreference counted values are counted
+	 *             as multi-referenced here.
+	 */
+	if (((TYPEOF(from->ind) > MAX_REF_TYPE) ||
+	     (*from->ind.u.refs > 1)) &&
+	    ((TYPEOF(from->val) > MAX_REF_TYPE) ||
+	     (*from->val.u.refs > 1))) {
 	  goto keep_keypair;
 	}
 	break;
-- 
GitLab