LCOV - code coverage report
Current view: top level - mm/boehm-gc - new_hblk.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 82 82 100.0 %
Date: 2017-07-14 10:03:36 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
       3             :  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
       4             :  * Copyright (c) 2000 by Hewlett-Packard Company.  All rights reserved.
       5             :  *
       6             :  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
       7             :  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
       8             :  *
       9             :  * Permission is hereby granted to use or copy this program
      10             :  * for any purpose,  provided the above notices are retained on all copies.
      11             :  * Permission to modify the code and to distribute modified code is granted,
      12             :  * provided the above notices are retained, and a notice that the code was
      13             :  * modified is included with the above copyright notice.
      14             :  */
      15             : 
      16             : #include "private/gc_priv.h"
      17             : 
      18             : /*
      19             :  * This file contains the functions:
      20             :  *      ptr_t GC_build_flXXX(h, old_fl)
      21             :  *      void GC_new_hblk(size)
      22             :  */
      23             : 
      24             : #include <stdio.h>
      25             : 
      26             : #ifndef SMALL_CONFIG
      27             :   /* Build a free list for size 2 (words) cleared objects inside        */
      28             :   /* hblk h.  Set the last link to be ofl.  Return a pointer tpo the    */
      29             :   /* first free list entry.                                             */
      30         332 :   STATIC ptr_t GC_build_fl_clear2(struct hblk *h, ptr_t ofl)
      31             :   {
      32         332 :     word * p = (word *)(h -> hb_body);
      33         332 :     word * lim = (word *)(h + 1);
      34             : 
      35         332 :     p[0] = (word)ofl;
      36         332 :     p[1] = 0;
      37         332 :     p[2] = (word)p;
      38         332 :     p[3] = 0;
      39         332 :     p += 4;
      40       42496 :     for (; (word)p < (word)lim; p += 4) {
      41       42164 :         p[0] = (word)(p-2);
      42       42164 :         p[1] = 0;
      43       42164 :         p[2] = (word)p;
      44       42164 :         p[3] = 0;
      45             :     };
      46         332 :     return((ptr_t)(p-2));
      47             :   }
      48             : 
      49             :   /* The same for size 4 cleared objects.       */
      50         941 :   STATIC ptr_t GC_build_fl_clear4(struct hblk *h, ptr_t ofl)
      51             :   {
      52         941 :     word * p = (word *)(h -> hb_body);
      53         941 :     word * lim = (word *)(h + 1);
      54             : 
      55         941 :     p[0] = (word)ofl;
      56         941 :     p[1] = 0;
      57         941 :     p[2] = 0;
      58         941 :     p[3] = 0;
      59         941 :     p += 4;
      60      120448 :     for (; (word)p < (word)lim; p += 4) {
      61      119507 :         PREFETCH_FOR_WRITE((ptr_t)(p+64));
      62      119507 :         p[0] = (word)(p-4);
      63      119507 :         p[1] = 0;
      64      119507 :         CLEAR_DOUBLE(p+2);
      65             :     };
      66         941 :     return((ptr_t)(p-4));
      67             :   }
      68             : 
      69             :   /* The same for size 2 uncleared objects.     */
      70         242 :   STATIC ptr_t GC_build_fl2(struct hblk *h, ptr_t ofl)
      71             :   {
      72         242 :     word * p = (word *)(h -> hb_body);
      73         242 :     word * lim = (word *)(h + 1);
      74             : 
      75         242 :     p[0] = (word)ofl;
      76         242 :     p[2] = (word)p;
      77         242 :     p += 4;
      78       30976 :     for (; (word)p < (word)lim; p += 4) {
      79       30734 :         p[0] = (word)(p-2);
      80       30734 :         p[2] = (word)p;
      81             :     };
      82         242 :     return((ptr_t)(p-2));
      83             :   }
      84             : 
      85             :   /* The same for size 4 uncleared objects.     */
      86        2829 :   STATIC ptr_t GC_build_fl4(struct hblk *h, ptr_t ofl)
      87             :   {
      88        2829 :     word * p = (word *)(h -> hb_body);
      89        2829 :     word * lim = (word *)(h + 1);
      90             : 
      91        2829 :     p[0] = (word)ofl;
      92        2829 :     p[4] = (word)p;
      93        2829 :     p += 8;
      94      181056 :     for (; (word)p < (word)lim; p += 8) {
      95      178227 :         PREFETCH_FOR_WRITE((ptr_t)(p+64));
      96      178227 :         p[0] = (word)(p-4);
      97      178227 :         p[4] = (word)p;
      98             :     };
      99        2829 :     return((ptr_t)(p-4));
     100             :   }
     101             : #endif /* !SMALL_CONFIG */
     102             : 
     103             : /* Build a free list for objects of size sz inside heap block h.        */
     104             : /* Clear objects inside h if clear is set.  Add list to the end of      */
     105             : /* the free list we build.  Return the new free list.                   */
     106             : /* This could be called without the main GC lock, if we ensure that     */
     107             : /* there is no concurrent collection which might reclaim objects that   */
     108             : /* we have not yet allocated.                                           */
     109       51037 : GC_INNER ptr_t GC_build_fl(struct hblk *h, size_t sz, GC_bool clear,
     110             :                            ptr_t list)
     111             : {
     112             :   word *p, *prev;
     113             :   word *last_object;            /* points to last object in new hblk    */
     114             : 
     115             :   /* Do a few prefetches here, just because its cheap.          */
     116             :   /* If we were more serious about it, these should go inside   */
     117             :   /* the loops.  But write prefetches usually don't seem to     */
     118             :   /* matter much.                                               */
     119       51037 :     PREFETCH_FOR_WRITE((ptr_t)h);
     120       51037 :     PREFETCH_FOR_WRITE((ptr_t)h + 128);
     121       51037 :     PREFETCH_FOR_WRITE((ptr_t)h + 256);
     122       51037 :     PREFETCH_FOR_WRITE((ptr_t)h + 378);
     123             : # ifndef SMALL_CONFIG
     124             :     /* Handle small objects sizes more efficiently.  For larger objects */
     125             :     /* the difference is less significant.                              */
     126       51037 :     switch (sz) {
     127         574 :         case 2: if (clear) {
     128         332 :                     return GC_build_fl_clear2(h, list);
     129             :                 } else {
     130         242 :                     return GC_build_fl2(h, list);
     131             :                 }
     132        3770 :         case 4: if (clear) {
     133         941 :                     return GC_build_fl_clear4(h, list);
     134             :                 } else {
     135        2829 :                     return GC_build_fl4(h, list);
     136             :                 }
     137             :         default:
     138             :                 break;
     139             :     }
     140             : # endif /* !SMALL_CONFIG */
     141             : 
     142             :   /* Clear the page if necessary. */
     143       46693 :     if (clear) BZERO(h, HBLKSIZE);
     144             : 
     145             :   /* Add objects to free list */
     146       46693 :     p = (word *)(h -> hb_body) + sz;    /* second object in *h  */
     147       46693 :     prev = (word *)(h -> hb_body);              /* One object behind p  */
     148       46693 :     last_object = (word *)((char *)h + HBLKSIZE);
     149       46693 :     last_object -= sz;
     150             :                             /* Last place for last object to start */
     151             : 
     152             :   /* make a list of all objects in *h with head as last object */
     153     1560000 :     while ((word)p <= (word)last_object) {
     154             :       /* current object's link points to last object */
     155     1466614 :         obj_link(p) = (ptr_t)prev;
     156     1466614 :         prev = p;
     157     1466614 :         p += sz;
     158             :     }
     159       46693 :     p -= sz;                    /* p now points to last object */
     160             : 
     161             :   /* Put p (which is now head of list of objects in *h) as first    */
     162             :   /* pointer in the appropriate free list for this size.            */
     163       46693 :     *(ptr_t *)h = list;
     164       46693 :     return ((ptr_t)p);
     165             : }
     166             : 
     167             : /* Allocate a new heapblock for small objects of size gran granules.    */
     168             : /* Add all of the heapblock's objects to the free list for objects      */
     169             : /* of that size.  Set all mark bits if objects are uncollectible.       */
     170             : /* Will fail to do anything if we are out of memory.                    */
     171       17517 : GC_INNER void GC_new_hblk(size_t gran, int kind)
     172             : {
     173             :   struct hblk *h;       /* the new heap block */
     174       17517 :   GC_bool clear = GC_obj_kinds[kind].ok_init;
     175             : 
     176             :   GC_STATIC_ASSERT((sizeof (struct hblk)) == HBLKSIZE);
     177             : 
     178       17517 :   if (GC_debugging_started) clear = TRUE;
     179             : 
     180             :   /* Allocate a new heap block */
     181       17517 :     h = GC_allochblk(GRANULES_TO_BYTES(gran), kind, 0);
     182       17517 :     if (h == 0) return;
     183             : 
     184             :   /* Mark all objects if appropriate. */
     185       17457 :       if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h));
     186             : 
     187             :   /* Build the free list */
     188       34914 :       GC_obj_kinds[kind].ok_freelist[gran] =
     189       17457 :         GC_build_fl(h, GRANULES_TO_WORDS(gran), clear,
     190       17457 :                     GC_obj_kinds[kind].ok_freelist[gran]);
     191             : }

Generated by: LCOV version 1.11