]> granicus.if.org Git - gc/commitdiff
GC_scratch_alloc code refactoring (and WARN message improvement)
authorIvan Maidanski <ivmai@mail.ru>
Mon, 31 Mar 2014 21:25:18 +0000 (01:25 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 31 Mar 2014 21:25:18 +0000 (01:25 +0400)
* headers.c (GC_scratch_alloc): Remove "register" keyword for "result"
local variable; replace tail recursion with a loop; adjust and add
comments.
* headers.c (GC_scratch_alloc): Adjust message and output requested
allocation size in WARN().
* include/private/gc_priv.h (_GC_arrays._scratch_last_end_ptr):
Improve comment.

headers.c
include/private/gc_priv.h

index 108adf18b7d71975868876d96727a3955f6598bc..361f19c12d18ec93f40e73940692b6947814e34d 100644 (file)
--- a/headers.c
+++ b/headers.c
@@ -108,7 +108,7 @@ GC_INNER hdr *
 }
 
 /* Routines to dynamically allocate collector data structures that will */
-/* never be freed.                                                       */
+/* never be freed.                                                      */
 
 static ptr_t scratch_free_ptr = 0;
 
@@ -117,43 +117,48 @@ static ptr_t scratch_free_ptr = 0;
 
 GC_INNER ptr_t GC_scratch_alloc(size_t bytes)
 {
-    register ptr_t result = scratch_free_ptr;
+    ptr_t result = scratch_free_ptr;
+    word bytes_to_get;
 
     bytes = ROUNDUP_GRANULE_SIZE(bytes);
-    scratch_free_ptr += bytes;
-    if ((word)scratch_free_ptr <= (word)GC_scratch_end_ptr) {
-        return(result);
-    }
-    {
-        word bytes_to_get = MINHINCR * HBLKSIZE;
+    for (;;) {
+        scratch_free_ptr += bytes;
+        if ((word)scratch_free_ptr <= (word)GC_scratch_end_ptr) {
+            /* Unallocated space of scratch buffer has enough size. */
+            return result;
+        }
 
+        bytes_to_get = MINHINCR * HBLKSIZE;
         if (bytes_to_get <= bytes) {
-          /* Undo the damage, and get memory directly */
             bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(bytes);
             result = (ptr_t)GET_MEM(bytes_to_get);
             GC_add_to_our_memory(result, bytes_to_get);
+            /* Undo scratch free area pointer update; get memory directly. */
             scratch_free_ptr -= bytes;
             if (result != NULL) {
+                /* Update end point of last obtained area (needed only  */
+                /* by GC_register_dynamic_libraries for some targets).  */
                 GC_scratch_last_end_ptr = result + bytes;
             }
-            return(result);
+            return result;
         }
 
         bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(bytes_to_get); /* for safety */
         result = (ptr_t)GET_MEM(bytes_to_get);
         GC_add_to_our_memory(result, bytes_to_get);
-        if (result == 0) {
-            WARN("Out of memory - trying to allocate less\n", 0);
-            scratch_free_ptr -= bytes;
+        if (NULL == result) {
+            WARN("Out of memory - trying to allocate requested amount"
+                 " (%" WARN_PRIdPTR " bytes)...\n", (word)bytes);
+            scratch_free_ptr -= bytes; /* Undo free area pointer update */
             bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(bytes);
             result = (ptr_t)GET_MEM(bytes_to_get);
             GC_add_to_our_memory(result, bytes_to_get);
             return result;
         }
+        /* Update scratch area pointers and retry.      */
         scratch_free_ptr = result;
         GC_scratch_end_ptr = scratch_free_ptr + bytes_to_get;
         GC_scratch_last_end_ptr = GC_scratch_end_ptr;
-        return(GC_scratch_alloc(bytes));
     }
 }
 
index c3235421459d12616de8af4a9799d96f0339f5a9..69c32e9c0dbbfef8d97c5a7ef5c6a45b5700797b 100644 (file)
@@ -1140,7 +1140,7 @@ struct _GC_arrays {
   ptr_t _scratch_end_ptr;
   ptr_t _scratch_last_end_ptr;
         /* Used by headers.c, and can easily appear to point to */
-        /* heap.                                                */
+        /* heap.  Also used by GC_register_dynamic_libraries(). */
   mse *_mark_stack;
         /* Limits of stack for GC_mark routine.  All ranges     */
         /* between GC_mark_stack (incl.) and GC_mark_stack_top  */