unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
From: Clinton Ebadi <clinton@unknownlamer.org>
To: ludo@gnu.org (Ludovic Courtès)
Cc: bug-guile@gnu.org
Subject: Re: Weak Vectors Patch
Date: Sat, 17 Apr 2010 14:36:01 -0400	[thread overview]
Message-ID: <874ojarkoe.fsf@rvannith.home.unknownlamer.org> (raw)
In-Reply-To: <87k4sln86s.fsf@inria.fr> ("Ludovic Courtès"'s message of "Mon, 05 Apr 2010 19:03:07 +0200")


[-- Attachment #1.1: Type: text/plain, Size: 1449 bytes --]

ludo@gnu.org (Ludovic Courtès) writes:

> For these last two things, we’d need to modify the ‘vector-ref’ and
> ‘vector-set’ instructions so that they do the right thing.  The best
> solution would be to just call scm_c_vector_{ref,set_x} when
> SCM_I_WVECTP, so that the overhead remains low for regular vectors.  Can
> you look into this?

Wingo did this.

>> I'm not sure that weak vectors should have their allocated memory marked
>> as containing no pointers, but it seems to work so I left that alone in
>> case there was some magic going on that I didn't quite grok.
>
> Yes, weak vectors are to live in pointerless memory, otherwise the
> disappearing links would not disappear.
>
> The patch looks good to me, modulo a few things:
>
>   - Could you make it 3 (or 4?) different patches, each with a test case
>     showing what is being fixed?
>
>   - If that’s fine with you, you’ll need to assign copyright to the
>     FSF.  We can arrange this off-list.

I have attached a series of three patches with reformatted GNU style
commit logs and the gnu coding style violations fixed.

I talked to wingo, and he suggested that (equal? WEAK-VECTOR VECTOR) =>
#f; I have made this so by unregistering weak vectors as arrays, and
doing additional type checking in scm_eq. I am unsure if this has
ramifications for the rest of the system however.

How do you want to handle copyright assignment?


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: 0001-Forbid-comparison-of-weak-and-normal-vectors.patch --]
[-- Type: text/x-diff, Size: 3148 bytes --]

From 51c78363c827ff7433bf619a4dd0c9afdbd79696 Mon Sep 17 00:00:00 2001
From: Clinton Ebadi <clinton@unknownlamer.org>
Date: Sat, 17 Apr 2010 14:16:30 -0400
Subject: [PATCH 1/3] Forbid comparison of weak and normal vectors

* libguile/vectors.c (scm_i_weak_vector_equal_p): New Function.

* libguile/eq.c (scm_equal_p): Dispatch scm_tc7_wvect to
  `scm_i_weak_vector_equal_p', and forbid comparison of normal and weak
  vectors.
---
 libguile/eq.c      |   11 +++++++++--
 libguile/vectors.c |   15 ++++++++++++++-
 libguile/vectors.h |    1 +
 3 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/libguile/eq.c b/libguile/eq.c
index 923fa77..7debae7 100644
--- a/libguile/eq.c
+++ b/libguile/eq.c
@@ -342,9 +342,16 @@ scm_equal_p (SCM x, SCM y)
 	case scm_tc16_fraction:
           return scm_i_fraction_equalp (x, y);
         }
-    case scm_tc7_vector:
     case scm_tc7_wvect:
-      return scm_i_vector_equal_p (x, y);
+      if (SCM_LIKELY (SCM_TYP7 (y) == scm_tc7_wvect))
+	return scm_i_weak_vector_equal_p (x, y);
+      else
+	return SCM_BOOL_F;
+    case scm_tc7_vector:
+      if (SCM_LIKELY (SCM_TYP7 (y) == scm_tc7_vector))
+	return scm_i_vector_equal_p (x, y);
+      else
+	return SCM_BOOL_F;
     }
   /* Check equality between structs of equal type (see cell-type test above). */
   if (SCM_STRUCTP (x))
diff --git a/libguile/vectors.c b/libguile/vectors.c
index 321b499..e60e2c3 100644
--- a/libguile/vectors.c
+++ b/libguile/vectors.c
@@ -509,6 +509,19 @@ scm_i_vector_equal_p (SCM x, SCM y)
   return SCM_BOOL_T;
 }
 
+SCM
+scm_i_weak_vector_equal_p (SCM x, SCM y)
+{
+  /* This is slower, but necessary to catch NULLified weak references and
+     correctly hold the collector lock when accessing each element. */
+  long i;
+  for (i = SCM_I_VECTOR_LENGTH (x) - 1; i >= 0; i--)
+    if (scm_is_false (scm_equal_p (scm_c_vector_ref (x, i),
+				   scm_c_vector_ref (y, i))))
+      return SCM_BOOL_F;
+  return SCM_BOOL_T;
+}
+
 
 SCM_DEFINE (scm_vector_move_left_x, "vector-move-left!", 5, 0, 0, 
             (SCM vec1, SCM start1, SCM end1, SCM vec2, SCM start2),
@@ -622,7 +635,7 @@ vector_get_handle (SCM v, scm_t_array_handle *h)
 
 /* the & ~2 allows catching scm_tc7_wvect as well. needs changing if you change
    tags.h. */
-SCM_ARRAY_IMPLEMENTATION (scm_tc7_vector, 0x7f & ~2,
+SCM_ARRAY_IMPLEMENTATION (scm_tc7_vector, 0x7f,
                           vector_handle_ref, vector_handle_set,
                           vector_get_handle)
 SCM_VECTOR_IMPLEMENTATION (SCM_ARRAY_ELEMENT_TYPE_SCM, scm_make_vector)
diff --git a/libguile/vectors.h b/libguile/vectors.h
index 3746e90..f426d0c 100644
--- a/libguile/vectors.h
+++ b/libguile/vectors.h
@@ -74,6 +74,7 @@ SCM_API SCM *scm_vector_writable_elements (SCM vec,
 #define SCM_I_VECTOR_LENGTH(x) (((size_t) SCM_CELL_WORD_0 (x)) >> 8)
 
 SCM_INTERNAL SCM  scm_i_vector_equal_p (SCM x, SCM y);
+SCM_INTERNAL SCM  scm_i_weak_vector_equal_p (SCM x, SCM y);
 
 /* Weak vectors share implementation details with ordinary vectors,
    but no one else should.  */
-- 
1.6.5.7


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.3: 0002-Register-disappearing-links-when-initializing-weak-v.patch --]
[-- Type: text/x-diff, Size: 2350 bytes --]

From cecef73d94a59f5932e28e938145700019203801 Mon Sep 17 00:00:00 2001
From: Clinton Ebadi <clinton@unknownlamer.org>
Date: Sat, 17 Apr 2010 14:21:43 -0400
Subject: [PATCH 2/3] Register disappearing links when initializing weak vectors

* libguile/vectors.c (scm_c_vector_set_x): Unregister old weak
  link when assigning to a weak vector.
  (scm_i_make_weak_vector): Register elements as disappearing links
  to fill value.
  (scm_i_make_weak_vector_from_list): Register elements as
  disappearing links.
---
 libguile/vectors.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/libguile/vectors.c b/libguile/vectors.c
index e60e2c3..cca57cd 100644
--- a/libguile/vectors.c
+++ b/libguile/vectors.c
@@ -274,10 +274,11 @@ scm_c_vector_set_x (SCM v, size_t k, SCM obj)
       if (k >= SCM_I_VECTOR_LENGTH (v))
 	scm_out_of_range (NULL, scm_from_size_t (k)); 
       (SCM_I_VECTOR_WELTS(v))[k] = obj;
-      if (SCM_I_WVECTP (v))
+      if (SCM_I_WVECTP (v) && !SCM_IS_WHVEC (v))
 	{
 	  /* Make it a weak pointer.  */
 	  GC_PTR link = (GC_PTR) & ((SCM_I_VECTOR_WELTS (v))[k]);
+	  GC_unregister_disappearing_link (link);
 	  SCM_I_REGISTER_DISAPPEARING_LINK (link, obj);
 	}
     }
@@ -292,10 +293,11 @@ scm_c_vector_set_x (SCM v, size_t k, SCM obj)
 	  k = SCM_I_ARRAY_BASE (v) + k*dim->inc;
 	  (SCM_I_VECTOR_WELTS (vv))[k] = obj;
 
-	  if (SCM_I_WVECTP (vv))
+	  if (SCM_I_WVECTP (vv) && !SCM_IS_WHVEC (vv))
 	    {
 	      /* Make it a weak pointer.  */
 	      GC_PTR link = (GC_PTR) & ((SCM_I_VECTOR_WELTS (vv))[k]);
+	      GC_unregister_disappearing_link (link);
 	      SCM_I_REGISTER_DISAPPEARING_LINK (link, obj);
 	    }
 	}
@@ -420,7 +422,10 @@ scm_i_make_weak_vector (scm_t_bits type, SCM size, SCM fill)
   base = SCM_I_WVECT_GC_WVELTS (wv);
 
   for (j = 0; j != c_size; ++j)
-    base[j] = fill;
+    {
+      base[j] = fill;
+      SCM_I_REGISTER_DISAPPEARING_LINK ((GC_PTR) base + j, (GC_PTR) SCM_UNPACK(fill));
+    }
 
   return wv;
 }
@@ -442,6 +447,7 @@ scm_i_make_weak_vector_from_list (scm_t_bits type, SCM lst)
        scm_is_pair (lst);
        lst = SCM_CDR (lst), elt++)
     {
+      SCM_I_REGISTER_DISAPPEARING_LINK((GC_PTR) elt, (GC_PTR) SCM_UNPACK(SCM_CAR(lst)));
       *elt = SCM_CAR (lst);
     }
 
-- 
1.6.5.7


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.4: 0003-Reference-weak-vectors-with-the-allocator-lock-held.patch --]
[-- Type: text/x-diff, Size: 2906 bytes --]

From af6252f00326542cfa052ec9c2a99477cd1b1d7e Mon Sep 17 00:00:00 2001
From: Clinton Ebadi <clinton@unknownlamer.org>
Date: Sat, 17 Apr 2010 14:23:16 -0400
Subject: [PATCH 3/3] Reference weak vectors with the allocator lock held

* libguile/vectors.c (do_weak_vector_ref): New function.
  (scm_c_vector_ref): Call `do_weak_vector_ref' with the allocator
  lock held when referencing weak vectors.
---
 libguile/vectors.c |   54 ++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 40 insertions(+), 14 deletions(-)

diff --git a/libguile/vectors.c b/libguile/vectors.c
index cca57cd..5788ec1 100644
--- a/libguile/vectors.c
+++ b/libguile/vectors.c
@@ -202,22 +202,46 @@ scm_vector_ref (SCM v, SCM k)
 }
 #undef FUNC_NAME
 
+struct t_weak_vector_ref_args
+{
+  SCM vector;
+  size_t k;
+};
+
+/* Accessing weak pointers *must* be done with the allocator lock held. */
+static void * 
+do_weak_vector_ref (void* data)
+{
+  struct t_weak_vector_ref_args *args = (struct t_weak_vector_ref_args *) data;
+  register SCM elt = (SCM_I_VECTOR_ELTS(args->vector))[args->k];
+
+  if (elt == SCM_PACK (NULL))
+    /* ELT was a weak pointer and got nullified by the GC.  */
+    return SCM_BOOL_F;  
+
+  return elt;
+}
+
 SCM
 scm_c_vector_ref (SCM v, size_t k)
 {
   if (SCM_I_IS_VECTOR (v))
     {
-      register SCM elt;
-
       if (k >= SCM_I_VECTOR_LENGTH (v))
 	scm_out_of_range (NULL, scm_from_size_t (k));
-      elt = (SCM_I_VECTOR_ELTS(v))[k];
 
-      if ((elt == SCM_PACK (NULL)) && SCM_I_WVECTP (v))
-	/* ELT was a weak pointer and got nullified by the GC.  */
-	return SCM_BOOL_F;
+      if (SCM_I_WVECTP (v) && !SCM_IS_WHVEC (v))
+	{
+	  struct t_weak_vector_ref_args args;
+	  args.vector = v;
+	  args.k = k;
 
-      return elt;
+	  return GC_call_with_alloc_lock (do_weak_vector_ref, &args);
+	}
+      else
+	{
+	  return (SCM_I_VECTOR_ELTS(v))[k];
+	}
     }
   else if (SCM_I_ARRAYP (v) && SCM_I_ARRAY_NDIM (v) == 1)
     {
@@ -225,18 +249,20 @@ scm_c_vector_ref (SCM v, size_t k)
       SCM vv = SCM_I_ARRAY_V (v);
       if (SCM_I_IS_VECTOR (vv))
 	{
-	  register SCM elt;
-
 	  if (k >= dim->ubnd - dim->lbnd + 1)
 	    scm_out_of_range (NULL, scm_from_size_t (k));
 	  k = SCM_I_ARRAY_BASE (v) + k*dim->inc;
-	  elt = (SCM_I_VECTOR_ELTS (vv))[k];
 
-	  if ((elt == SCM_PACK (NULL)) && (SCM_I_WVECTP (vv)))
-	    /* ELT was a weak pointer and got nullified by the GC.  */
-	    return SCM_BOOL_F;
+	  if (SCM_I_WVECTP (vv) && !SCM_IS_WHVEC (vv))
+	    {
+	      struct t_weak_vector_ref_args args;
+	      args.vector = vv;
+	      args.k = k;
+
+	      return GC_call_with_alloc_lock (do_weak_vector_ref, &args);
+	    }
 
-	  return elt;
+	  return (SCM_I_VECTOR_ELTS (vv))[k];
 	}
       scm_wrong_type_arg_msg (NULL, 0, v, "non-uniform vector");
     }
-- 
1.6.5.7


[-- Attachment #1.5: Type: text/plain, Size: 267 bytes --]





-- 
Corinne: this is why we should have designated bath buddies
Corinne: to get places you cant reach because youre slippery and in
         case you get a lil tooo slippery and crack your head open
         someone can call the coast guard and save you

[-- Attachment #2: Type: application/pgp-signature, Size: 229 bytes --]

  parent reply	other threads:[~2010-04-17 18:36 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-01 17:18 Weak Vectors Patch Clinton Ebadi
2010-04-05 17:03 ` Ludovic Courtès
2010-04-05 17:26   ` Andy Wingo
2010-04-17 18:36   ` Clinton Ebadi [this message]
2010-04-17 20:48     ` Ludovic Courtès
2010-04-18 11:48       ` Andy Wingo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=874ojarkoe.fsf@rvannith.home.unknownlamer.org \
    --to=clinton@unknownlamer.org \
    --cc=bug-guile@gnu.org \
    --cc=ludo@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).