]> granicus.if.org Git - gc/commitdiff
Define public GC_GENERIC_OR_SPECIAL_MALLOC and GC_get_kind_and_size
authorIvan Maidanski <ivmai@mail.ru>
Mon, 10 Mar 2014 16:04:58 +0000 (20:04 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 10 Mar 2014 16:34:21 +0000 (20:34 +0400)
* dbg_mlc.c (GC_debug_generic_malloc,
GC_debug_generic_or_special_malloc): New function.
* mallocx.c (GC_get_kind_and_size): Likewise.
* tests/test.c (test_generic_malloc_or_special): Likewise.
* include/gc_mark.h (GC_generic_or_special_malloc,
GC_debug_generic_or_special_malloc, GC_get_kind_and_size): New API
prototype.
* include/gc_mark.h (GC_GENERIC_OR_SPECIAL_MALLOC): New public macro.
* mallocx.c (GC_generic_or_special_malloc): Turn into API function.
* tests/test.c (reverse_test_inner, run_one_test): Invoke
test_generic_malloc_or_special (to test GC_GENERIC_OR_SPECIAL_MALLOC
and GC_get_kind_and_size).

dbg_mlc.c
include/gc_mark.h
mallocx.c
tests/test.c

index a0423e97e58849020b4921aa142520278ec4675c..da4b86f34758b9816ee9d5f5fb3c23fa7f832581 100644 (file)
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -565,6 +565,23 @@ GC_API void * GC_CALL GC_debug_malloc_atomic_ignore_off_page(size_t lb,
     return (GC_store_debug_info(result, (word)lb, s, i));
 }
 
+STATIC void * GC_debug_generic_malloc(size_t lb, int knd, GC_EXTRA_PARAMS)
+{
+    void * result = GC_generic_malloc(lb + DEBUG_BYTES, knd);
+
+    if (NULL == result) {
+        GC_err_printf(
+                "GC_debug_generic_malloc(%lu, %d) returning NULL (%s:%d)\n",
+                (unsigned long)lb, knd, s, i);
+        return NULL;
+    }
+    if (!GC_debugging_started) {
+        GC_start_debugging();
+    }
+    ADD_CALL_CHAIN(result, ra);
+    return GC_store_debug_info(result, (word)lb, s, i);
+}
+
 #ifdef DBG_HDRS_ALL
   /* An allocation function for internal use.  Normally internally      */
   /* allocated objects do not have debug information.  But in this      */
@@ -924,6 +941,29 @@ GC_API void * GC_CALL GC_debug_realloc(void * p, size_t lb, GC_EXTRA_PARAMS)
     return(result);
 }
 
+GC_API void * GC_CALL GC_debug_generic_or_special_malloc(size_t lb, int knd,
+                                                         GC_EXTRA_PARAMS)
+{
+    switch (knd) {
+#     ifdef STUBBORN_ALLOC
+        case STUBBORN:
+            return GC_debug_malloc_stubborn(lb, OPT_RA s, i);
+#     endif
+        case PTRFREE:
+            return GC_debug_malloc_atomic(lb, OPT_RA s, i);
+        case NORMAL:
+            return GC_debug_malloc(lb, OPT_RA s, i);
+        case UNCOLLECTABLE:
+            return GC_debug_malloc_uncollectable(lb, OPT_RA s, i);
+#     ifdef ATOMIC_UNCOLLECTABLE
+        case AUNCOLLECTABLE:
+            return GC_debug_malloc_atomic_uncollectable(lb, OPT_RA s, i);
+#     endif
+        default:
+            return GC_debug_generic_malloc(lb, knd, OPT_RA s, i);
+    }
+}
+
 #ifndef SHORT_DBG_HDRS
 
 /* List of smashed (clobbered) locations.  We defer printing these,     */
index 56bee5833cb39014e08c014f921d75cfac1c00de..dcadf42ef3e2bbcc7e955514c3c49e5ee8cda788 100644 (file)
@@ -204,6 +204,30 @@ GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL
                                 /* first page of the resulting object   */
                                 /* are ignored.                         */
 
+/* Same as above but primary for allocating an object of the same kind  */
+/* as an existing one (kind obtained by GC_get_kind_and_size).          */
+/* Not suitable for GCJ and typed-malloc kinds.                         */
+GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL
+                                        GC_generic_or_special_malloc(
+                                            size_t /* size */, int /* knd */);
+GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL
+                                        GC_debug_generic_or_special_malloc(
+                                            size_t /* size */, int /* knd */,
+                                            GC_EXTRA_PARAMS);
+
+#ifdef GC_DEBUG
+# define GC_GENERIC_OR_SPECIAL_MALLOC(sz, knd) \
+                GC_debug_generic_or_special_malloc(sz, knd, GC_EXTRAS)
+#else
+# define GC_GENERIC_OR_SPECIAL_MALLOC(sz, knd) \
+                GC_generic_or_special_malloc(sz, knd)
+#endif /* !GC_DEBUG */
+
+/* Similar to GC_size but returns object kind.  Size is returned too    */
+/* if psize is not NULL.                                                */
+GC_API int GC_CALL GC_get_kind_and_size(const void *, size_t * /* psize */)
+                                                        GC_ATTR_NONNULL(1);
+
 typedef void (GC_CALLBACK * GC_describe_type_fn)(void * /* p */,
                                                  char * /* out_buf */);
                                 /* A procedure which                    */
index de9fd931fadb669c71fe295dfcec3e278773e333..75ee0e28dc2f22178686befbbcb474f9eab2707d 100644 (file)
--- a/mallocx.c
+++ b/mallocx.c
@@ -46,8 +46,17 @@ void ** const GC_uobjfreelist_ptr = GC_uobjfreelist;
     void ** const GC_auobjfreelist_ptr = GC_auobjfreelist;
 # endif
 
+GC_API int GC_CALL GC_get_kind_and_size(const void * p, size_t * psize)
+{
+    hdr * hhdr = HDR(p);
+
+    if (psize != NULL) {
+        *psize = hhdr -> hb_sz;
+    }
+    return hhdr -> hb_obj_kind;
+}
 
-STATIC void * GC_generic_or_special_malloc(size_t lb, int knd)
+GC_API void * GC_CALL GC_generic_or_special_malloc(size_t lb, int knd)
 {
     switch(knd) {
 #     ifdef STUBBORN_ALLOC
index 34c6307b355a5a1cdcc82ede4c47421fbaf62859..6f412c8f048666695dc0b94d08e800bc9d6891d4 100644 (file)
@@ -548,6 +548,25 @@ void check_marks_int_list(sexpr x)
 
 #endif
 
+void test_generic_malloc_or_special(void *p) {
+  size_t size;
+  int kind = GC_get_kind_and_size(p, &size);
+  void *p2;
+
+  if (size != GC_size(p)) {
+    GC_printf("GC_get_kind_and_size returned size not matching GC_size\n");
+    FAIL;
+  }
+  p2 = GC_GENERIC_OR_SPECIAL_MALLOC(10, kind);
+  CHECK_OUT_OF_MEMORY(p2);
+  if (GC_get_kind_and_size(p2, NULL) != kind) {
+    GC_printf("GC_generic_or_special_malloc:"
+              " unexpected kind of returned object\n");
+    FAIL;
+  }
+  GC_FREE(p2);
+}
+
 /* Try to force a to be strangely aligned */
 struct {
   char dummy;
@@ -596,6 +615,7 @@ void *GC_CALLBACK reverse_test_inner(void *data)
     b = ints(1, 50);
     c = ints(1, BIG);
     d = uncollectable_ints(1, 100);
+    test_generic_malloc_or_special(d);
     e = uncollectable_ints(1, 1);
     /* Check that realloc updates object descriptors correctly */
     collectable_count++;
@@ -606,6 +626,7 @@ void *GC_CALLBACK reverse_test_inner(void *data)
     f[5] = ints(1,17);
     collectable_count++;
     g = (sexpr *)GC_MALLOC(513 * sizeof(sexpr));
+    test_generic_malloc_or_special(g);
     realloc_count++;
     g = (sexpr *)GC_REALLOC((void *)g, 800 * sizeof(sexpr));
     CHECK_OUT_OF_MEMORY(g);
@@ -1283,6 +1304,7 @@ void run_one_test(void)
              GC_FREE(GC_MALLOC(0));
              (void)GC_MALLOC_ATOMIC(0);
              GC_FREE(GC_MALLOC_ATOMIC(0));
+             test_generic_malloc_or_special(GC_malloc_atomic(1));
            }
          }
 #   ifdef GC_GCJ_SUPPORT