From ba7d5e1fb6e8aa6a6e8d8eebde15ab9ef41e97b8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Wed, 19 Jun 2013 20:44:58 +0200
Subject: [PATCH] [runtime][amd64] Fixed some free_svalue-related bugs.

free_svalues() now survives freeing unfinished arrays.

amd64_free_svalue() now supports freeing PIKE_T_VOID svalues.
---
 src/code/amd64.c | 12 ++++++++----
 src/svalue.c     |  2 +-
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/src/code/amd64.c b/src/code/amd64.c
index 1077f9b6eb..e86e8fe597 100644
--- a/src/code/amd64.c
+++ b/src/code/amd64.c
@@ -1096,9 +1096,11 @@ static void amd64_free_svalue(enum amd64_reg src, int guaranteed_ref )
     /* load type -> RAX */
   mov_sval_type( src, REG_RAX );
 
-  /* if RAX < MIN_REF_TYPE+1 */
+  and_reg_imm(REG_RAX, ~(MIN_REF_TYPE - 1));
+
+  /* if RAX != MIN_REF_TYPE */
   cmp_reg32_imm( REG_RAX,MIN_REF_TYPE);
-  jl( &label_A );
+  jne( &label_A );
 
   /* Load pointer to refs -> RAX */
   mov_mem_reg( src, OFFSETOF(svalue, u.refs), REG_RAX);
@@ -1116,7 +1118,7 @@ static void amd64_free_svalue(enum amd64_reg src, int guaranteed_ref )
   LABEL_A;
 }
 
-/* Type already in RAX */
+/* Type already in register. Note: Clobbers the type register. */
 static void amd64_free_svalue_type(enum amd64_reg src, enum amd64_reg type,
                                    int guaranteed_ref )
 {
@@ -1125,8 +1127,10 @@ static void amd64_free_svalue_type(enum amd64_reg src, enum amd64_reg type,
   if( src == REG_RAX )
     Pike_fatal("Clobbering RAX for free-svalue\n");
 
+  and_reg_imm(type, ~(MIN_REF_TYPE - 1));
+
   cmp_reg32_imm(type,MIN_REF_TYPE);
-  jl( &label_A );
+  jne( &label_A );
 
   /* Load pointer to refs -> RAX */
   mov_mem_reg( src, OFFSETOF(svalue, u.refs), REG_RAX);
diff --git a/src/svalue.c b/src/svalue.c
index 140bceb9be..bcbc12d18d 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -204,7 +204,7 @@ PMOD_EXPORT void debug_free_svalues(struct svalue *s, size_t num, INT32 type_hin
 
 #undef DOTYPE
   default:
-    if (type_hint & (BIT_FLOAT | BIT_INT)) {
+    if (type_hint & (BIT_FLOAT | BIT_INT | BIT_UNFINISHED)) {
       while(num--)
       {
 #ifdef DEBUG_MALLOC
-- 
GitLab