fluids are tc7 objects
authorAndy Wingo <wingo@pobox.com>
Sat, 5 Dec 2009 09:52:18 +0000 (10:52 +0100)
committerAndy Wingo <wingo@pobox.com>
Sat, 5 Dec 2009 09:52:18 +0000 (10:52 +0100)
If you're wondering what I'm doing, I'm trying to eventually reimplement
smobs in terms of structs, so that applicable smobs can just follow the
applicable struct dispatch path. But to do that I have to get structs
initialized before things that use smobs, which means transforming a
bunch of smobby things to tc7 things. But this transformation is good
for performance anyway, and we currently have a glut of unused tc7s,
so here we go...

* libguile/tags.h (scm_tc7_fluid, scm_tc7_dynamic_state): Fluids (and
  dynamic states) now have tc7s.

* libguile/fluids.h: Remove scm_fluids_prehistory, and add internal
  scm_i_fluid_print. Update a comment.

* libguile/fluids.c: Update for tc7 representation. Also remove the next
  pointers while we're at it, as they aren't used in the new BDW GC.

* libguile/eq.c (scm_equal_p): Remove the hashtable case. Hashtables
  could never be equal? before, I don't see why to add stubs doing the
  same thing now.

* libguile/print.c (iprin1):
* libguile/gc.c (scm_i_tag_name):
* libguile/evalext.c (scm_self_evaluating_p): Add fluid and
  dynamic_state cases.

* libguile/goops.h: Remove scm_class_hashtable; it will be static.
* libguile/goops.c: Make <hashtable> static, and add <fluid> and
  <dynamic-state> classes.

* libguile/hashtab.h:
* libguile/hashtab.c: Remove scm_i_hashtable_equal_p.

* libguile/init.c (scm_i_init_guile): Remove call to fluids_prehistory.

12 files changed:
libguile/eq.c
libguile/evalext.c
libguile/fluids.c
libguile/fluids.h
libguile/gc.c
libguile/goops.c
libguile/goops.h
libguile/hashtab.c
libguile/hashtab.h
libguile/init.c
libguile/print.c
libguile/tags.h

index 9aa86a5..eaf1acc 100644 (file)
@@ -343,9 +343,6 @@ scm_equal_p (SCM x, SCM y)
     case scm_tc7_vector:
     case scm_tc7_wvect:
       return scm_i_vector_equal_p (x, y);
-
-    case scm_tc7_hashtable:
-      return scm_i_hashtable_equal_p (x, y);
     }
   /* Check equality between structs of equal type (see cell-type test above). */
   if (SCM_STRUCTP (x))
index 5a0c0e9..9af8383 100644 (file)
@@ -78,6 +78,8 @@ SCM_DEFINE (scm_self_evaluating_p, "self-evaluating?", 1, 0, 0,
        case scm_tc7_vector:
        case scm_tc7_wvect:
        case scm_tc7_hashtable:
+       case scm_tc7_fluid:
+       case scm_tc7_dynamic_state:
        case scm_tc7_number:
        case scm_tc7_string:
        case scm_tc7_smob:
index 75dcccf..bb9447f 100644 (file)
@@ -26,7 +26,6 @@
 
 #include "libguile/_scm.h"
 #include "libguile/print.h"
-#include "libguile/smob.h"
 #include "libguile/dynwind.h"
 #include "libguile/fluids.h"
 #include "libguile/alist.h"
@@ -66,22 +65,12 @@ static size_t allocated_fluids_len = 0;
 static size_t allocated_fluids_num = 0;
 static char *allocated_fluids = NULL;
 
-static scm_t_bits tc16_fluid;
+#define IS_FLUID(x)         (!SCM_IMP (x) && SCM_TYP7 (x) == scm_tc7_fluid)
+#define FLUID_NUM(x)        ((size_t)SCM_CELL_WORD_1(x))
 
-#define IS_FLUID(x)         SCM_SMOB_PREDICATE(tc16_fluid, (x))
-#define FLUID_NUM(x)        ((size_t)SCM_SMOB_DATA(x))
-#define FLUID_NEXT(x)       SCM_SMOB_OBJECT_2(x)
-#define FLUID_NEXT_LOC(x)       SCM_SMOB_OBJECT_2_LOC(x)
-#define SET_FLUID_NEXT(x,y) SCM_SET_SMOB_OBJECT_2((x), (y))
-
-static scm_t_bits tc16_dynamic_state;
-
-#define IS_DYNAMIC_STATE(x)        SCM_SMOB_PREDICATE(tc16_dynamic_state, (x))
-#define DYNAMIC_STATE_FLUIDS(x)        SCM_SMOB_OBJECT(x)
-#define SET_DYNAMIC_STATE_FLUIDS(x, y) SCM_SET_SMOB_OBJECT((x), (y))
-#define DYNAMIC_STATE_NEXT(x)          SCM_SMOB_OBJECT_2(x)
-#define DYNAMIC_STATE_NEXT_LOC(x)          SCM_SMOB_OBJECT_2_LOC(x)
-#define SET_DYNAMIC_STATE_NEXT(x, y)   SCM_SET_SMOB_OBJECT_2((x), (y))
+#define IS_DYNAMIC_STATE(x) (!SCM_IMP (x) && SCM_TYP7 (x) == scm_tc7_dynamic_state)
+#define DYNAMIC_STATE_FLUIDS(x)        SCM_PACK (SCM_CELL_WORD_1 (x))
+#define SET_DYNAMIC_STATE_FLUIDS(x, y) SCM_SET_CELL_WORD_1 ((x), (SCM_UNPACK (y)))
 
 
 \f
@@ -115,13 +104,12 @@ grow_dynamic_state (SCM state)
   scm_i_pthread_mutex_unlock (&fluid_admin_mutex);
 }
 
-static int
-fluid_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED)
+void
+scm_i_fluid_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED)
 {
   scm_puts ("#<fluid ", port);
   scm_intprint ((int) FLUID_NUM (exp), 10, port);
   scm_putc ('>', port);
-  return 1;
 }
 
 static size_t
@@ -190,12 +178,7 @@ SCM_DEFINE (scm_make_fluid, "make-fluid", 0, 0, 0,
            "with its own dynamic state, you can use fluids for thread local storage.")
 #define FUNC_NAME s_scm_make_fluid
 {
-  SCM fluid;
-
-  SCM_NEWSMOB2 (fluid, tc16_fluid,
-               (scm_t_bits) next_fluid_num (), SCM_UNPACK (SCM_EOL));
-
-  return fluid;
+  return scm_cell (scm_tc7_fluid, (scm_t_bits) next_fluid_num ());
 }
 #undef FUNC_NAME
 
@@ -406,10 +389,7 @@ SCM
 scm_i_make_initial_dynamic_state ()
 {
   SCM fluids = scm_c_make_vector (allocated_fluids_len, SCM_BOOL_F);
-  SCM state;
-  SCM_NEWSMOB2 (state, tc16_dynamic_state,
-               SCM_UNPACK (fluids), SCM_UNPACK (SCM_EOL));
-  return state;
+  return scm_cell (scm_tc7_dynamic_state, SCM_UNPACK (fluids));
 }
 
 SCM_DEFINE (scm_make_dynamic_state, "make-dynamic-state", 0, 1, 0,
@@ -418,17 +398,14 @@ SCM_DEFINE (scm_make_dynamic_state, "make-dynamic-state", 0, 1, 0,
            "or of the current dynamic state when @var{parent} is omitted.")
 #define FUNC_NAME s_scm_make_dynamic_state
 {
-  SCM fluids, state;
+  SCM fluids;
 
   if (SCM_UNBNDP (parent))
     parent = scm_current_dynamic_state ();
 
-  scm_assert_smob_type (tc16_dynamic_state, parent);
+  SCM_ASSERT (IS_DYNAMIC_STATE (parent), parent, SCM_ARG1, FUNC_NAME);
   fluids = scm_vector_copy (DYNAMIC_STATE_FLUIDS (parent));
-  SCM_NEWSMOB2 (state, tc16_dynamic_state,
-               SCM_UNPACK (fluids), SCM_UNPACK (SCM_EOL));
-
-  return state;
+  return scm_cell (scm_tc7_dynamic_state, SCM_UNPACK (fluids));
 }
 #undef FUNC_NAME
 
@@ -465,7 +442,7 @@ SCM_DEFINE (scm_set_current_dynamic_state, "set-current-dynamic-state", 1,0,0,
 {
   scm_i_thread *t = SCM_I_CURRENT_THREAD;
   SCM old = t->dynamic_state;
-  scm_assert_smob_type (tc16_dynamic_state, state);
+  SCM_ASSERT (IS_DYNAMIC_STATE (state), state, SCM_ARG1, FUNC_NAME);
   t->dynamic_state = state;
   return old;
 }
@@ -481,7 +458,7 @@ void
 scm_dynwind_current_dynamic_state (SCM state)
 {
   SCM loc = scm_cons (state, SCM_EOL);
-  scm_assert_smob_type (tc16_dynamic_state, state);
+  SCM_ASSERT (IS_DYNAMIC_STATE (state), state, SCM_ARG1, NULL);
   scm_dynwind_rewind_handler_with_scm (swap_dynamic_state, loc,
                                     SCM_F_WIND_EXPLICITLY);
   scm_dynwind_unwind_handler_with_scm (swap_dynamic_state, loc,
@@ -514,14 +491,6 @@ SCM_DEFINE (scm_with_dynamic_state, "with-dynamic-state", 2, 0, 0,
 }
 #undef FUNC_NAME
 
-void
-scm_fluids_prehistory ()
-{
-  tc16_fluid = scm_make_smob_type ("fluid", 0);
-  scm_set_smob_print (tc16_fluid, fluid_print);
-
-  tc16_dynamic_state = scm_make_smob_type ("dynamic-state", 0);
-}
 
 void
 scm_init_fluids ()
index 2bfcce5..8f26c23 100644 (file)
@@ -3,7 +3,7 @@
 #ifndef SCM_FLUIDS_H
 #define SCM_FLUIDS_H
 
-/* Copyright (C) 1996,2000,2001, 2006, 2008 Free Software Foundation, Inc.
+/* Copyright (C) 1996,2000,2001, 2006, 2008, 2009 Free Software Foundation, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
 
 /* Fluids.
 
-   Fluids are objects of a certain type (a smob) that can hold one SCM
-   value per dynamic state.  That is, modifications to this value are
-   only visible to code that executes with the same dynamic state as
-   the modifying code.  When a new dynamic state is constructed, it
-   inherits the values from its parent.  Because each thread executes
-   with its own dynamic state, you can use fluids for thread local
-   storage.
-
-   Each fluid is identified by a small integer.  This integer is used
-   to index a vector that holds the values of all fluids.  A dynamic
-   state consists of this vector, wrapped in a smob so that the vector
-   can grow.
+   Fluids are objects of a certain type that can hold one SCM value per
+   dynamic state. That is, modifications to this value are only visible
+   to code that executes with the same dynamic state as the modifying
+   code. When a new dynamic state is constructed, it inherits the
+   values from its parent. Because each thread executes with its own
+   dynamic state, you can use fluids for thread local storage.
+
+   Each fluid is identified by a small integer. This integer is used to
+   index a vector that holds the values of all fluids. A dynamic state
+   consists of this vector, wrapped in an object so that the vector can
+   grow.
  */
 
 /* The fastest way to acces/modify the value of a fluid.  These macros
@@ -78,7 +77,7 @@ SCM_API SCM scm_with_dynamic_state (SCM state, SCM proc);
 
 SCM_INTERNAL SCM scm_i_make_initial_dynamic_state (void);
 
-SCM_INTERNAL void scm_fluids_prehistory (void);
+SCM_INTERNAL void scm_i_fluid_print (SCM exp, SCM port, scm_print_state *pstate);
 SCM_INTERNAL void scm_init_fluids (void);
 
 #endif  /* SCM_FLUIDS_H */
index 4bedb05..dedbd28 100644 (file)
@@ -758,6 +758,10 @@ scm_i_tag_name (scm_t_bits tag)
       return "pws";
     case scm_tc7_hashtable:
       return "hashtable";
+    case scm_tc7_fluid:
+      return "fluid";
+    case scm_tc7_dynamic_state:
+      return "dynamic state";
     case scm_tc7_wvect:
       return "weak vector";
     case scm_tc7_vector:
index d02257b..1833216 100644 (file)
@@ -133,7 +133,7 @@ static scm_t_rstate *goops_rstate;
 SCM scm_class_boolean, scm_class_char, scm_class_pair;
 SCM scm_class_procedure, scm_class_string, scm_class_symbol;
 SCM scm_class_procedure_with_setter, scm_class_primitive_generic;
-SCM scm_class_vector, scm_class_hashtable, scm_class_null;
+SCM scm_class_vector, scm_class_null;
 SCM scm_class_integer, scm_class_real, scm_class_complex, scm_class_fraction;
 SCM scm_class_unknown;
 SCM scm_class_top, scm_class_object, scm_class_class;
@@ -158,6 +158,10 @@ SCM scm_class_protected_hidden, scm_class_protected_opaque, scm_class_protected_
 SCM scm_class_scm;
 SCM scm_class_int, scm_class_float, scm_class_double;
 
+static SCM class_hashtable;
+static SCM class_fluid;
+static SCM class_dynamic_state;
+
 /* Port classes.  Allocate 3 times the maximum number of port types so that
    input ports, output ports, and in/out ports can be stored at different
    offsets.  See `SCM_IN_PCLASS_INDEX' et al.  */
@@ -211,7 +215,11 @@ SCM_DEFINE (scm_class_of, "class-of", 1, 0, 0,
        case scm_tc7_wvect:
          return scm_class_vector;
        case scm_tc7_hashtable:
-         return scm_class_hashtable;
+         return class_hashtable;
+       case scm_tc7_fluid:
+         return class_fluid;
+       case scm_tc7_dynamic_state:
+         return class_dynamic_state;
        case scm_tc7_string:
          return scm_class_string;
         case scm_tc7_number:
@@ -2402,7 +2410,11 @@ create_standard_classes (void)
               scm_class_class, scm_class_top,             SCM_EOL);
   make_stdcls (&scm_class_vector,         "<vector>",
               scm_class_class, scm_class_top,             SCM_EOL);
-  make_stdcls (&scm_class_hashtable,      "<hashtable>",
+  make_stdcls (&class_hashtable,          "<hashtable>",
+              scm_class_class, scm_class_top,             SCM_EOL);
+  make_stdcls (&class_fluid,              "<fluid>",
+              scm_class_class, scm_class_top,             SCM_EOL);
+  make_stdcls (&class_dynamic_state,      "<dynamic-state>",
               scm_class_class, scm_class_top,             SCM_EOL);
   make_stdcls (&scm_class_number,         "<number>",
               scm_class_class, scm_class_top,             SCM_EOL);
index 4c1b45b..48b94a1 100644 (file)
@@ -180,7 +180,6 @@ SCM_API SCM scm_class_symbol;
 SCM_API SCM scm_class_procedure_with_setter;
 SCM_API SCM scm_class_primitive_generic;
 SCM_API SCM scm_class_vector;
-SCM_API SCM scm_class_hashtable;
 SCM_API SCM scm_class_null;
 SCM_API SCM scm_class_real;
 SCM_API SCM scm_class_complex;
index 608d534..059be6f 100644 (file)
@@ -355,12 +355,6 @@ scm_i_hashtable_print (SCM exp, SCM port, scm_print_state *pstate)
   scm_puts (">", port);
 }
 
-SCM
-scm_i_hashtable_equal_p (SCM x, SCM y)
-{
-  return SCM_BOOL_F;
-}
-
 
 SCM
 scm_c_make_hash_table (unsigned long k)
index 3fbcb90..75b60e9 100644 (file)
@@ -157,7 +157,6 @@ SCM_API SCM scm_hash_for_each (SCM proc, SCM hash);
 SCM_API SCM scm_hash_for_each_handle (SCM proc, SCM hash);
 SCM_API SCM scm_hash_map_to_list (SCM proc, SCM hash);
 SCM_INTERNAL void scm_i_hashtable_print (SCM exp, SCM port, scm_print_state *pstate);
-SCM_INTERNAL SCM scm_i_hashtable_equal_p (SCM x, SCM y);
 SCM_INTERNAL void scm_init_hashtab (void);
 
 #endif  /* SCM_HASHTAB_H */
index bbe88e8..3bd173a 100644 (file)
@@ -438,7 +438,6 @@ scm_i_init_guile (SCM_STACKITEM *base)
   scm_threads_prehistory (base);
   scm_ports_prehistory ();
   scm_smob_prehistory ();
-  scm_fluids_prehistory ();
   scm_weaks_prehistory ();
 #ifdef GUILE_DEBUG_MALLOC
   scm_debug_malloc_prehistory ();
index ea439a6..5652139 100644 (file)
@@ -712,6 +712,9 @@ iprin1 (SCM exp, SCM port, scm_print_state *pstate)
        case scm_tc7_hashtable:
          scm_i_hashtable_print (exp, port, pstate);
          break;
+       case scm_tc7_fluid:
+         scm_i_fluid_print (exp, port, pstate);
+         break;
        case scm_tc7_wvect:
          ENTER_NESTED_DATA (pstate, exp, circref);
          if (SCM_IS_WHVEC (exp))
index c22d927..5020775 100644 (file)
@@ -411,15 +411,11 @@ typedef scm_t_uintptr scm_t_bits;
 #define scm_tc7_stringbuf       39
 #define scm_tc7_bytevector     77
 
-/* Many of the following should be turned
- * into structs or smobs.  We need back some
- * of these 7 bit tags!  */
-
 #define scm_tc7_pws            31
-
 #define scm_tc7_hashtable      29
-#define scm_tc7_unused_2       37
-#define scm_tc7_unused_3       45
+#define scm_tc7_fluid          37
+#define scm_tc7_dynamic_state  45
+
 #define scm_tc7_unused_4       47
 #define scm_tc7_unused_5       53
 #define scm_tc7_unused_6       55