(scm_must_malloc, scm_must_realloc, scm_must_strdup, scm_must_strndup,
authorMarius Vollmer <mvo@zagadka.de>
Thu, 14 Feb 2002 15:32:12 +0000 (15:32 +0000)
committerMarius Vollmer <mvo@zagadka.de>
Thu, 14 Feb 2002 15:32:12 +0000 (15:32 +0000)
scm_done_malloc, scm_done_free, scm_must_free): Reimplemented using
the new scm_gc_malloc, etc., functions and deprecated.

libguile/gc.c
libguile/gc.h

index 86a1a91..82bc71e 100644 (file)
@@ -359,7 +359,7 @@ scm_t_freelist scm_master_freelist2 = {
 };
 
 /* scm_mtrigger
- * is the number of bytes of must_malloc allocation needed to trigger gc.
+ * is the number of bytes of malloc allocation needed to trigger gc.
  */
 unsigned long scm_mtrigger;
 
@@ -1920,7 +1920,8 @@ scm_gc_register_collectable_memory (void *mem, size_t size, const char *what)
     }
 
 #ifdef GUILE_DEBUG_MALLOC
-  scm_malloc_register (mem, what);
+  if (mem)
+    scm_malloc_register (mem, what);
 #endif
 }
 
@@ -1930,7 +1931,8 @@ scm_gc_unregister_collectable_memory (void *mem, size_t size, const char *what)
   scm_mallocated -= size;
 
 #ifdef GUILE_DEBUG_MALLOC
-  scm_malloc_unregister (mem);
+  if (mem)
+    scm_malloc_unregister (mem);
 #endif
 }
 
@@ -1940,7 +1942,7 @@ scm_gc_malloc (size_t size, const char *what)
   /* XXX - The straightforward implementation below has the problem
      that it might call the GC twice, once in scm_malloc and then
      again in scm_gc_register_collectable_memory.  We don't really
-     want the second GC.
+     want the second GC since it will not find new garbage.
   */
 
   void *ptr = scm_malloc (size);
@@ -1981,6 +1983,8 @@ scm_gc_strdup (const char *str, const char *what)
   return scm_gc_strndup (str, strlen (str), what);
 }
 
+#if SCM_ENABLE_DEPRECATED == 1
+
 /* {Deprecated front end to malloc}
  *
  * scm_must_malloc, scm_must_realloc, scm_must_free, scm_done_malloc,
@@ -1990,166 +1994,67 @@ scm_gc_strdup (const char *str, const char *what)
  * free.  They should be used when allocating memory that will be under
  * control of the garbage collector, i.e., if the memory may be freed
  * during garbage collection.
- */
-
-/* scm_must_malloc
- * Return newly malloced storage or throw an error.
- *
- * The parameter WHAT is a string for error reporting.
- * If the threshold scm_mtrigger will be passed by this
- * allocation, or if the first call to malloc fails,
- * garbage collect -- on the presumption that some objects
- * using malloced storage may be collected.
  *
- * The limit scm_mtrigger may be raised by this allocation.
+ * They are deprecated because they weren't really used the way
+ * outlined above, and making sure to return the right amount from
+ * smob free routines was sometimes difficult when dealing with nested
+ * data structures.  We basically want everybody to review their code
+ * and use the more symmetrical scm_gc_malloc/scm_gc_free functions
+ * instead.  In some cases, where scm_must_malloc has been used
+ * incorrectly (i.e. for non-GC-able memory), use scm_malloc/free.
  */
+
 void *
 scm_must_malloc (size_t size, const char *what)
 {
-  void *ptr;
-  unsigned long nm = scm_mallocated + size;
-
-  if (nm < size)
-    /* The byte count of allocated objects has overflowed.  This is
-       probably because you forgot to report the correct size of freed
-       memory in some of your smob free methods. */
-    abort ();
+  scm_c_issue_deprecation_warning
+    ("scm_must_malloc is deprecated.  "
+     "Use scm_gc_malloc and scm_gc_free instead.");
 
-  if (nm <= scm_mtrigger)
-    {
-      SCM_SYSCALL (ptr = malloc (size));
-      if (NULL != ptr)
-       {
-         scm_mallocated = nm;
-#ifdef GUILE_DEBUG_MALLOC
-         scm_malloc_register (ptr, what);
-#endif
-         return ptr;
-       }
-    }
-
-  scm_igc (what);
-
-  nm = scm_mallocated + size;
-
-  if (nm < size)
-    /* The byte count of allocated objects has overflowed.  This is
-       probably because you forgot to report the correct size of freed
-       memory in some of your smob free methods. */
-    abort ();
-
-  SCM_SYSCALL (ptr = malloc (size));
-  if (NULL != ptr)
-    {
-      scm_mallocated = nm;
-      
-      if (nm > scm_mtrigger - SCM_MTRIGGER_HYSTERESIS) {
-       unsigned long old_trigger = scm_mtrigger;
-       if (nm > scm_mtrigger)
-         scm_mtrigger = nm + nm / 2;
-       else
-         scm_mtrigger += scm_mtrigger / 2;
-       if (scm_mtrigger < old_trigger)
-         abort ();
-      }
-#ifdef GUILE_DEBUG_MALLOC
-      scm_malloc_register (ptr, what);
-#endif
-
-      return ptr;
-    }
-
-  scm_memory_error (what);
+  return scm_gc_malloc (size, what);
 }
 
-
-/* scm_must_realloc
- * is similar to scm_must_malloc.
- */
 void *
 scm_must_realloc (void *where,
                  size_t old_size,
                  size_t size,
                  const char *what)
 {
-  void *ptr;
-  unsigned long nm;
-
-  if (size <= old_size)
-    return where;
-
-  nm = scm_mallocated + size - old_size;
-
-  if (nm < (size - old_size))
-    /* The byte count of allocated objects has overflowed.  This is
-       probably because you forgot to report the correct size of freed
-       memory in some of your smob free methods. */
-    abort ();
-
-  if (nm <= scm_mtrigger)
-    {
-      SCM_SYSCALL (ptr = realloc (where, size));
-      if (NULL != ptr)
-       {
-         scm_mallocated = nm;
-#ifdef GUILE_DEBUG_MALLOC
-         scm_malloc_reregister (where, ptr, what);
-#endif
-         return ptr;
-       }
-    }
-
-  scm_igc (what);
-
-  nm = scm_mallocated + size - old_size;
-
-  if (nm < (size - old_size))
-    /* The byte count of allocated objects has overflowed.  This is
-       probably because you forgot to report the correct size of freed
-       memory in some of your smob free methods. */
-    abort ();
+  scm_c_issue_deprecation_warning
+    ("scm_must_realloc is deprecated.  "
+     "Use scm_gc_realloc and scm_gc_free instead.");
 
-  SCM_SYSCALL (ptr = realloc (where, size));
-  if (NULL != ptr)
-    {
-      scm_mallocated = nm;
-      if (nm > scm_mtrigger - SCM_MTRIGGER_HYSTERESIS) {
-       unsigned long old_trigger = scm_mtrigger;
-       if (nm > scm_mtrigger)
-         scm_mtrigger = nm + nm / 2;
-       else
-         scm_mtrigger += scm_mtrigger / 2;
-       if (scm_mtrigger < old_trigger)
-         abort ();
-      }
-#ifdef GUILE_DEBUG_MALLOC
-      scm_malloc_reregister (where, ptr, what);
-#endif
-      return ptr;
-    }
-
-  scm_memory_error (what);
+  return scm_gc_realloc (where, old_size, size, what);
 }
 
 char *
 scm_must_strndup (const char *str, size_t length)
 {
-  char * dst = scm_must_malloc (length + 1, "scm_must_strndup");
-  memcpy (dst, str, length);
-  dst[length] = 0;
-  return dst;
+  scm_c_issue_deprecation_warning
+    ("scm_must_strndup is deprecated.  "
+     "Use scm_gc_strndup and scm_gc_free instead.");
+
+  return scm_gc_strndup (str, length, "string");
 }
 
 char *
 scm_must_strdup (const char *str)
 {
-  return scm_must_strndup (str, strlen (str));
+  scm_c_issue_deprecation_warning
+    ("scm_must_strdup is deprecated.  "
+     "Use scm_gc_strdup and scm_gc_free instead.");
+
+  return scm_gc_strdup (str, "string");
 }
 
 void
 scm_must_free (void *obj)
 #define FUNC_NAME "scm_must_free"
 {
+  scm_c_issue_deprecation_warning
+    ("scm_must_free is deprecated.  "
+     "Use scm_gc_malloc and scm_gc_free instead.");
+
 #ifdef GUILE_DEBUG_MALLOC
   scm_malloc_unregister (obj);
 #endif
@@ -2161,78 +2066,27 @@ scm_must_free (void *obj)
 #undef FUNC_NAME
 
 
-/* Announce that there has been some malloc done that will be freed
- * during gc.  A typical use is for a smob that uses some malloced
- * memory but can not get it from scm_must_malloc (for whatever
- * reason).  When a new object of this smob is created you call
- * scm_done_malloc with the size of the object.  When your smob free
- * function is called, be sure to include this size in the return
- * value.
- *
- * If you can't actually free the memory in the smob free function,
- * for whatever reason (like reference counting), you still can (and
- * should) report the amount of memory freed when you actually free it.
- * Do it by calling scm_done_malloc with the _negated_ size.  Clever,
- * eh?  Or even better, call scm_done_free. */
-
 void
 scm_done_malloc (long size)
 {
-  if (size < 0) {
-    if (scm_mallocated < size)
-      /* The byte count of allocated objects has underflowed.  This is
-         probably because you forgot to report the sizes of objects you
-         have allocated, by calling scm_done_malloc or some such.  When
-         the GC freed them, it subtracted their size from
-         scm_mallocated, which underflowed.  */
-      abort ();
-  } else {
-    unsigned long nm = scm_mallocated + size;
-    if (nm < size)
-      /* The byte count of allocated objects has overflowed.  This is
-         probably because you forgot to report the correct size of freed
-         memory in some of your smob free methods. */
-      abort ();
-  }
+  scm_c_issue_deprecation_warning
+    ("scm_done_malloc is deprecated.  "
+     "Use scm_gc_register_collectable_memory instead.");
 
-  scm_mallocated += size;
-
-  if (scm_mallocated > scm_mtrigger)
-    {
-      scm_igc ("foreign mallocs");
-      if (scm_mallocated > scm_mtrigger - SCM_MTRIGGER_HYSTERESIS)
-       {
-         if (scm_mallocated > scm_mtrigger)
-           scm_mtrigger = scm_mallocated + scm_mallocated / 2;
-         else
-           scm_mtrigger += scm_mtrigger / 2;
-       }
-    }
+  scm_gc_register_collectable_memory (NULL, size, "foreign mallocs");
 }
 
 void
 scm_done_free (long size)
 {
-  if (size >= 0) {
-    if (scm_mallocated < size)
-      /* The byte count of allocated objects has underflowed.  This is
-         probably because you forgot to report the sizes of objects you
-         have allocated, by calling scm_done_malloc or some such.  When
-         the GC freed them, it subtracted their size from
-         scm_mallocated, which underflowed.  */
-      abort ();
-  } else {
-    unsigned long nm = scm_mallocated - size;
-    if (nm < size)
-      /* The byte count of allocated objects has overflowed.  This is
-         probably because you forgot to report the correct size of freed
-         memory in some of your smob free methods. */
-      abort ();
-  }
+  scm_c_issue_deprecation_warning
+    ("scm_done_free is deprecated.  "
+     "Use scm_gc_unregister_collectable_memory instead.");
 
-  scm_mallocated -= size;
+  scm_gc_unregister_collectable_memory (NULL, size, "foreign mallocs");
 }
 
+#endif /* SCM_ENABLE_DEPRECATED == 1 */
 
 \f
 /* {Heap Segments}
index 48a8d8d..7d575bc 100644 (file)
@@ -342,15 +342,6 @@ SCM_API void scm_gc_free (void *mem, size_t size, const char *what);
 SCM_API char *scm_gc_strdup (const char *str, const char *what);
 SCM_API char *scm_gc_strndup (const char *str, size_t n, const char *what);
 
-SCM_API void * scm_must_malloc (size_t len, const char *what);
-SCM_API void * scm_must_realloc (void *where,
-                                size_t olen, size_t len,
-                                const char *what);
-SCM_API char *scm_must_strdup (const char *str);
-SCM_API char *scm_must_strndup (const char *str, size_t n);
-SCM_API void scm_done_malloc (long size);
-SCM_API void scm_done_free (long size);
-SCM_API void scm_must_free (void *obj);
 SCM_API void scm_remember_upto_here_1 (SCM obj);
 SCM_API void scm_remember_upto_here_2 (SCM obj1, SCM obj2);
 SCM_API void scm_remember_upto_here (SCM obj1, ...);
@@ -377,6 +368,16 @@ SCM_API SCM scm_deprecated_newcell2 (void);
 #define SCM_NEWCELL2(_into) \
   do { _into = scm_deprecated_newcell2 (); } while (0)
 
+SCM_API void * scm_must_malloc (size_t len, const char *what);
+SCM_API void * scm_must_realloc (void *where,
+                                size_t olen, size_t len,
+                                const char *what);
+SCM_API char *scm_must_strdup (const char *str);
+SCM_API char *scm_must_strndup (const char *str, size_t n);
+SCM_API void scm_done_malloc (long size);
+SCM_API void scm_done_free (long size);
+SCM_API void scm_must_free (void *obj);
+
 #endif
 
 #endif  /* SCM_GC_H */