Optimize 'string-hash'.
[bpt/guile.git] / libguile / struct.h
index de216af..0b31cf5 100644 (file)
@@ -3,7 +3,7 @@
 #ifndef SCM_STRUCT_H
 #define SCM_STRUCT_H
 
-/* Copyright (C) 1995,1997,1999,2000,2001, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 1995,1997,1999,2000,2001, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 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
    in turn means we need support for changing the "class" (vtable) of an
    "instance" (struct). This necessitates some indirection and trickery.
 
-   I would like to write this all up here, but for now:
+   To summarize, structs are laid out this way:
+
+                  .-------.
+                  |       |
+     .----------------+---v------------- -
+     | vtable | data  | slot0 | slot1 |
+     `----------------+----------------- -
+         |        .-------.
+         |        |       |
+     .---v------------+---v------------- -
+     | vtable | data  | slot0 | slot1 |
+     `----------------+----------------- -
+         |
+         v
+
+        ...
+                  .-------.
+         |        |       |
+     .---v------------+---v------------- -
+   .-| vtable | data  | slot0 | slot1 |
+   | `----------------+----------------- -
+   |     ^
+   `-----'
+
+   The DATA indirection (which corresponds to `SCM_STRUCT_DATA ()') is necessary
+   to implement class redefinition.
+
+   For more details, see:
 
      http://wingolog.org/archives/2009/11/09/class-redefinition-in-guile
+
  */
 
 /* All vtables have the following fields. */
 #define SCM_VTABLE_BASE_LAYOUT                                          \
   "pr" /* layout */                                                     \
-  "uh" /* flags */                                                      \
+  "uh" /* flags */                                                     \
   "sr" /* self */                                                       \
   "uh" /* finalizer */                                                  \
   "pw" /* printer */                                                    \
   "ph" /* name (hidden from make-struct for back-compat reasons) */     \
-  "uh" /* reserved */                                                   \
+  "uh" /* size */                                                      \
   "uh" /* reserved */
 
 #define scm_vtable_index_layout            0 /* A symbol describing the physical arrangement of this type. */
@@ -55,7 +83,7 @@
 #define scm_vtable_index_instance_finalize 3 /* Finalizer for instances of this struct type. */
 #define scm_vtable_index_instance_printer  4 /* A printer for this struct type. */
 #define scm_vtable_index_name              5 /* Name of this vtable. */
-#define scm_vtable_index_reserved_6        6
+#define scm_vtable_index_size              6 /* Number of fields, for simple structs.  */
 #define scm_vtable_index_reserved_7        7
 #define scm_vtable_offset_user             8 /* Where do user fields start in the vtable? */
 
                                                    struct's vtable has the
                                                    setter flag set. */
 
-#define SCM_VTABLE_FLAG_VTABLE (1L << 0) /* instances of this vtable are themselves vtables? */
-#define SCM_VTABLE_FLAG_APPLICABLE_VTABLE (1L << 1) /* instances of this vtable are applicable vtables? */
-#define SCM_VTABLE_FLAG_APPLICABLE (1L << 2) /* instances of this vtable are applicable? */
-#define SCM_VTABLE_FLAG_SETTER_VTABLE (1L << 3) /* instances of this vtable are applicable-with-setter vtables? */
-#define SCM_VTABLE_FLAG_SETTER (1L << 4) /* instances of this vtable are applicable-with-setters? */
-#define SCM_VTABLE_FLAG_RESERVED_0 (1L << 5)
-#define SCM_VTABLE_FLAG_RESERVED_1 (1L << 6)
-#define SCM_VTABLE_FLAG_RESERVED_2 (1L << 7)
-#define SCM_VTABLE_FLAG_GOOPS_0 (1L << 8)
-#define SCM_VTABLE_FLAG_GOOPS_1 (1L << 9)
-#define SCM_VTABLE_FLAG_GOOPS_2 (1L << 10)
-#define SCM_VTABLE_FLAG_GOOPS_3 (1L << 11)
-#define SCM_VTABLE_FLAG_GOOPS_4 (1L << 12)
-#define SCM_VTABLE_FLAG_GOOPS_5 (1L << 13)
-#define SCM_VTABLE_FLAG_GOOPS_6 (1L << 14)
-#define SCM_VTABLE_FLAG_GOOPS_7 (1L << 15)
+#define SCM_VTABLE_FLAG_VALIDATED (1L << 0) /* the layout of this vtable been validated? */
+#define SCM_VTABLE_FLAG_VTABLE (1L << 1) /* instances of this vtable are themselves vtables? */
+#define SCM_VTABLE_FLAG_APPLICABLE_VTABLE (1L << 2) /* instances of this vtable are applicable vtables? */
+#define SCM_VTABLE_FLAG_APPLICABLE (1L << 3) /* instances of this vtable are applicable? */
+#define SCM_VTABLE_FLAG_SETTER_VTABLE (1L << 4) /* instances of this vtable are applicable-with-setter vtables? */
+#define SCM_VTABLE_FLAG_SETTER (1L << 5) /* instances of this vtable are applicable-with-setters? */
+#define SCM_VTABLE_FLAG_SIMPLE (1L << 6) /* instances of this vtable have only "p" fields and no tail array*/
+#define SCM_VTABLE_FLAG_SIMPLE_RW (1L << 7) /* instances of this vtable have only "pw" fields and no tail array */
+#define SCM_VTABLE_FLAG_RESERVED_0 (1L << 8)
+#define SCM_VTABLE_FLAG_RESERVED_1 (1L << 9)
+#define SCM_VTABLE_FLAG_RESERVED_2 (1L << 10)
+#define SCM_VTABLE_FLAG_SMOB_0 (1L << 11)
+#define SCM_VTABLE_FLAG_GOOPS_0 (1L << 12)
+#define SCM_VTABLE_FLAG_GOOPS_1 (1L << 13)
+#define SCM_VTABLE_FLAG_GOOPS_2 (1L << 14)
+#define SCM_VTABLE_FLAG_GOOPS_3 (1L << 15)
 #define SCM_VTABLE_USER_FLAG_SHIFT 16
 
 typedef void (*scm_t_struct_finalize) (SCM obj);
@@ -137,12 +165,6 @@ typedef void (*scm_t_struct_finalize) (SCM obj);
 #define SCM_STRUCT_SETTER(X)            (SCM_STRUCT_SLOT_REF (X, scm_applicable_struct_index_setter))
 #define SCM_SET_STRUCT_SETTER(X,P)     (SCM_STRUCT_SLOT_SET (X, scm_applicable_struct_index_setter, P))
 
-#define SCM_STRUCT_TABLE_NAME(X) SCM_CAR (X)
-#define SCM_SET_STRUCT_TABLE_NAME(X, NAME) SCM_SETCAR (X, NAME)
-#define SCM_STRUCT_TABLE_CLASS(X) SCM_CDR (X)
-#define SCM_SET_STRUCT_TABLE_CLASS(X, CLASS) SCM_SETCDR (X, CLASS)
-SCM_API SCM scm_struct_table;
-
 SCM_API SCM scm_standard_vtable_vtable;
 SCM_API SCM scm_applicable_struct_vtable_vtable;
 SCM_API SCM scm_applicable_struct_with_setter_vtable_vtable;
@@ -158,19 +180,22 @@ SCM_API SCM scm_c_make_struct (SCM vtable, size_t n_tail, size_t n_inits,
 SCM_API SCM scm_c_make_structv (SCM vtable, size_t n_tail, size_t n_inits,
                                 scm_t_bits init[]);
 SCM_API SCM scm_make_vtable (SCM fields, SCM printer);
-SCM_API SCM scm_make_vtable_vtable (SCM extra_fields, SCM tail_array_size, SCM init);
+SCM_INTERNAL SCM scm_i_make_vtable_vtable (SCM extra_fields);
+#if SCM_ENABLE_DEPRECATED == 1
+SCM_DEPRECATED SCM scm_make_vtable_vtable (SCM extra_fields, SCM tail_array_size, SCM init);
+#endif
 SCM_API SCM scm_struct_ref (SCM handle, SCM pos);
 SCM_API SCM scm_struct_set_x (SCM handle, SCM pos, SCM val);
 SCM_API SCM scm_struct_vtable (SCM handle);
-SCM_API SCM scm_struct_vtable_tag (SCM handle);
-SCM_API SCM scm_struct_create_handle (SCM obj);
 SCM_API SCM scm_struct_vtable_name (SCM vtable);
 SCM_API SCM scm_set_struct_vtable_name_x (SCM vtable, SCM name);
 SCM_API void scm_print_struct (SCM exp, SCM port, scm_print_state *);
 
 SCM_INTERNAL SCM scm_i_struct_equalp (SCM s1, SCM s2);
 SCM_INTERNAL unsigned long scm_struct_ihashq (SCM, unsigned long, void *);
-SCM_INTERNAL SCM scm_i_alloc_struct (scm_t_bits *vtable_data, int n_words, const char *what);
+SCM_INTERNAL unsigned long scm_i_struct_hash (SCM s, unsigned long n,
+                                             size_t depth);
+SCM_INTERNAL SCM scm_i_alloc_struct (scm_t_bits *vtable_data, int n_words);
 SCM_INTERNAL void scm_i_struct_inherit_vtable_magic (SCM vtable, SCM obj);
 SCM_INTERNAL void scm_init_struct (void);