home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sa104os2.zip / SATHR104.ZIP / SATHER / SYSTEM / GC / NEW_HBLK.C < prev    next >
C/C++ Source or Header  |  1994-05-19  |  6KB  |  240 lines

  1. /*
  2.  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  3.  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
  4.  *
  5.  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  6.  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
  7.  *
  8.  * Permission is hereby granted to use or copy this program
  9.  * for any purpose,  provided the above notices are retained on all copies.
  10.  * Permission to modify the code and to distribute modified code is granted,
  11.  * provided the above notices are retained, and a notice that the code was
  12.  * modified is included with the above copyright notice.
  13.  *
  14.  * This file contains the functions:
  15.  *    ptr_t GC_build_flXXX(h, old_fl)
  16.  *    void GC_new_hblk(n)
  17.  */
  18. /* Boehm, May 19, 1994 2:09 pm PDT */
  19.  
  20.  
  21. # include <stdio.h>
  22. # include "gc_priv.h"
  23.  
  24. #ifndef SMALL_CONFIG
  25. /*
  26.  * Build a free list for size 1 objects inside hblk h.  Set the last link to
  27.  * be ofl.  Return a pointer tpo the first free list entry.
  28.  */
  29. ptr_t GC_build_fl1(h, ofl)
  30. struct hblk *h;
  31. ptr_t ofl;
  32. {
  33.     register word * p = (word *)h;
  34.     register word * lim = (word *)(h + 1);
  35.     
  36.     p[0] = (word)ofl;
  37.     p[1] = (word)(p);
  38.     p[2] = (word)(p+1);
  39.     p[3] = (word)(p+2);
  40.     p += 4;
  41.     for (; p < lim; p += 4) {
  42.         p[0] = (word)(p-1);
  43.         p[1] = (word)(p);
  44.         p[2] = (word)(p+1);
  45.         p[3] = (word)(p+2);
  46.     };
  47.     return((ptr_t)(p-1));
  48. }
  49.  
  50. /* The same for size 2 cleared objects */
  51. ptr_t GC_build_fl_clear2(h, ofl)
  52. struct hblk *h;
  53. ptr_t ofl;
  54. {
  55.     register word * p = (word *)h;
  56.     register word * lim = (word *)(h + 1);
  57.     
  58.     p[0] = (word)ofl;
  59.     p[1] = 0;
  60.     p[2] = (word)p;
  61.     p[3] = 0;
  62.     p += 4;
  63.     for (; p < lim; p += 4) {
  64.         p[0] = (word)(p-2);
  65.         p[1] = 0;
  66.         p[2] = (word)p;
  67.         p[3] = 0;
  68.     };
  69.     return((ptr_t)(p-2));
  70. }
  71.  
  72. /* The same for size 3 cleared objects */
  73. ptr_t GC_build_fl_clear3(h, ofl)
  74. struct hblk *h;
  75. ptr_t ofl;
  76. {
  77.     register word * p = (word *)h;
  78.     register word * lim = (word *)(h + 1) - 2;
  79.     
  80.     p[0] = (word)ofl;
  81.     p[1] = 0;
  82.     p[2] = 0;
  83.     p += 3;
  84.     for (; p < lim; p += 3) {
  85.         p[0] = (word)(p-3);
  86.         p[1] = 0;
  87.         p[2] = 0;
  88.     };
  89.     return((ptr_t)(p-3));
  90. }
  91.  
  92. /* The same for size 4 cleared objects */
  93. ptr_t GC_build_fl_clear4(h, ofl)
  94. struct hblk *h;
  95. ptr_t ofl;
  96. {
  97.     register word * p = (word *)h;
  98.     register word * lim = (word *)(h + 1);
  99.     
  100.     p[0] = (word)ofl;
  101.     p[1] = 0;
  102.     p[2] = 0;
  103.     p[3] = 0;
  104.     p += 4;
  105.     for (; p < lim; p += 4) {
  106.         p[0] = (word)(p-4);
  107.         p[1] = 0;
  108.         p[2] = 0;
  109.         p[3] = 0;
  110.     };
  111.     return((ptr_t)(p-4));
  112. }
  113.  
  114. /* The same for size 2 uncleared objects */
  115. ptr_t GC_build_fl2(h, ofl)
  116. struct hblk *h;
  117. ptr_t ofl;
  118. {
  119.     register word * p = (word *)h;
  120.     register word * lim = (word *)(h + 1);
  121.     
  122.     p[0] = (word)ofl;
  123.     p[2] = (word)p;
  124.     p += 4;
  125.     for (; p < lim; p += 4) {
  126.         p[0] = (word)(p-2);
  127.         p[2] = (word)p;
  128.     };
  129.     return((ptr_t)(p-2));
  130. }
  131.  
  132. /* The same for size 4 uncleared objects */
  133. ptr_t GC_build_fl4(h, ofl)
  134. struct hblk *h;
  135. ptr_t ofl;
  136. {
  137.     register word * p = (word *)h;
  138.     register word * lim = (word *)(h + 1);
  139.     
  140.     p[0] = (word)ofl;
  141.     p[4] = (word)p;
  142.     p += 8;
  143.     for (; p < lim; p += 8) {
  144.         p[0] = (word)(p-4);
  145.         p[4] = (word)p;
  146.     };
  147.     return((ptr_t)(p-4));
  148. }
  149.  
  150. #endif /* !SMALL_CONFIG */
  151.  
  152. /*
  153.  * Allocate a new heapblock for small objects of size n.
  154.  * Add all of the heapblock's objects to the free list for objects
  155.  * of that size.  Will fail to do anything if we are out of memory.
  156.  */
  157. void GC_new_hblk(sz, kind)
  158. register word sz;
  159. int kind;
  160. {
  161.     register word *p,
  162.           *prev;
  163.     word *last_object;        /* points to last object in new hblk    */
  164.     register struct hblk *h;    /* the new heap block            */
  165.     register bool clear = GC_obj_kinds[kind].ok_init;
  166.  
  167. #   ifdef PRINTSTATS
  168.     if ((sizeof (struct hblk)) > HBLKSIZE) {
  169.         ABORT("HBLK SZ inconsistency");
  170.         }
  171. #   endif
  172.  
  173.   /* Allocate a new heap block */
  174.     h = GC_allochblk(sz, kind, 0);
  175.     if (h == 0) return;
  176.  
  177.   /* Handle small objects sizes more efficiently.  For larger objects     */
  178.   /* the difference is less significant.                */
  179. #  ifndef SMALL_CONFIG
  180.     switch (sz) {
  181.         case 1: GC_obj_kinds[kind].ok_freelist[1] =
  182.               GC_build_fl1(h, GC_obj_kinds[kind].ok_freelist[1]);
  183.             return;
  184.         case 2: if (clear) {
  185.                  GC_obj_kinds[kind].ok_freelist[2] =
  186.                   GC_build_fl_clear2(h, GC_obj_kinds[kind].ok_freelist[2]);
  187.             } else {
  188.                 GC_obj_kinds[kind].ok_freelist[2] =
  189.                   GC_build_fl2(h, GC_obj_kinds[kind].ok_freelist[2]);
  190.             }
  191.             return;
  192.         case 3: if (clear) {
  193.                  GC_obj_kinds[kind].ok_freelist[3] =
  194.                   GC_build_fl_clear3(h, GC_obj_kinds[kind].ok_freelist[3]);
  195.                 return;
  196.             } else {
  197.                 /* It's messy to do better than the default here. */
  198.                 break;
  199.             }
  200.         case 4: if (clear) {
  201.                 GC_obj_kinds[kind].ok_freelist[4] =
  202.                   GC_build_fl_clear4(h, GC_obj_kinds[kind].ok_freelist[4]);
  203.             } else {
  204.                 GC_obj_kinds[kind].ok_freelist[4] =
  205.                   GC_build_fl4(h, GC_obj_kinds[kind].ok_freelist[4]);
  206.             }
  207.             return;
  208.         default:
  209.             break;
  210.     }
  211. #  endif /* !SMALL_CONFIG */
  212.     
  213.   /* Clear the page if necessary. */
  214.     if (clear) BZERO(h, HBLKSIZE);
  215.     
  216.   /* Add objects to free list */
  217.     p = &(h -> hb_body[sz]);    /* second object in *h    */
  218.     prev = &(h -> hb_body[0]);           /* One object behind p    */
  219.     last_object = (word *)((char *)h + HBLKSIZE);
  220.     last_object -= sz;
  221.                 /* Last place for last object to start */
  222.  
  223.   /* make a list of all objects in *h with head as last object */
  224.     while (p <= last_object) {
  225.       /* current object's link points to last object */
  226.         obj_link(p) = (ptr_t)prev;
  227.     prev = p;
  228.     p += sz;
  229.     }
  230.     p -= sz;            /* p now points to last object */
  231.  
  232.   /*
  233.    * put p (which is now head of list of objects in *h) as first
  234.    * pointer in the appropriate free list for this size.
  235.    */
  236.       obj_link(h -> hb_body) = GC_obj_kinds[kind].ok_freelist[sz];
  237.       GC_obj_kinds[kind].ok_freelist[sz] = ((ptr_t)p);
  238. }
  239.  
  240.