summaryrefslogtreecommitdiff
path: root/headers.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2014-04-01 01:25:18 +0400
committerIvan Maidanski <ivmai@mail.ru>2014-04-01 01:25:18 +0400
commitba620ba49ef211a849b21857084674d0305cbf8c (patch)
tree413b88424bfd4e8edf2e75af5aa0be1c2b57cda4 /headers.c
parent32f9800a5910e316c5c8656767dbd00e5ae8ba30 (diff)
downloadbdwgc-ba620ba49ef211a849b21857084674d0305cbf8c.tar.gz
GC_scratch_alloc code refactoring (and WARN message improvement)
* 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.
Diffstat (limited to 'headers.c')
-rw-r--r--headers.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/headers.c b/headers.c
index 108adf18..361f19c1 100644
--- 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));
}
}