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

  1. /* 
  2.  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  3.  * Copyright (c) 1991, 1992 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. /* Boehm, May 19, 1994 1:59 pm PDT */
  15.   
  16. /* Routines for maintaining maps describing heap block
  17.  * layouts for various object sizes.  Allows fast pointer validity checks
  18.  * and fast location of object start locations on machines (such as SPARC)
  19.  * with slow division.
  20.  */
  21.  
  22. # include "gc_priv.h"
  23.  
  24. char * GC_invalid_map = 0;
  25.  
  26. /* Invalidate the object map associated with a block.    Free blocks    */
  27. /* are identified by invalid maps.                    */
  28. void GC_invalidate_map(hhdr)
  29. hdr *hhdr;
  30. {
  31.     register int displ;
  32.     
  33.     if (GC_invalid_map == 0) {
  34.         GC_invalid_map = GC_scratch_alloc(MAP_SIZE);
  35.         if (GC_invalid_map == 0) {
  36.             GC_err_printf0(
  37.                 "Cant initialize GC_invalid_map: insufficient memory\n");
  38.             EXIT();
  39.         }
  40.         for (displ = 0; displ < HBLKSIZE; displ++) {
  41.             MAP_ENTRY(GC_invalid_map, displ) = OBJ_INVALID;
  42.         }
  43.     }
  44.     hhdr -> hb_map = GC_invalid_map;
  45. }
  46.  
  47. /* Consider pointers that are offset bytes displaced from the beginning */
  48. /* of an object to be valid.                                            */
  49. void GC_register_displacement(offset) 
  50. word offset;
  51. {
  52. # ifndef ALL_INTERIOR_POINTERS
  53.     DCL_LOCK_STATE;
  54.     
  55.     DISABLE_SIGNALS();
  56.     LOCK();
  57.     GC_register_displacement_inner(offset);
  58.     UNLOCK();
  59.     ENABLE_SIGNALS();
  60. # endif
  61. }
  62.  
  63. void GC_register_displacement_inner(offset) 
  64. word offset;
  65. {
  66. # ifndef ALL_INTERIOR_POINTERS
  67.     register unsigned i;
  68.     
  69.     if (offset > MAX_OFFSET) {
  70.         ABORT("Bad argument to GC_register_displacement");
  71.     }
  72.     if (!GC_valid_offsets[offset]) {
  73.       GC_valid_offsets[offset] = TRUE;
  74.       GC_modws_valid_offsets[offset % sizeof(word)] = TRUE;
  75.       for (i = 0; i <= MAXOBJSZ; i++) {
  76.           if (GC_obj_map[i] != 0) {
  77.              if (i == 0) {
  78.                GC_obj_map[i][offset + HDR_BYTES] = (char)BYTES_TO_WORDS(offset);
  79.              } else {
  80.                register unsigned j;
  81.                register unsigned lb = WORDS_TO_BYTES(i);
  82.                
  83.                if (offset < lb) {
  84.                  for (j = offset + HDR_BYTES; j < HBLKSIZE; j += lb) {
  85.                    GC_obj_map[i][j] = (char)BYTES_TO_WORDS(offset);
  86.                  }
  87.                }
  88.              }
  89.           }
  90.       }
  91.     }
  92. # endif
  93. }
  94.  
  95.  
  96. /* Add a heap block map for objects of size sz to obj_map.    */
  97. /* Return FALSE on failure.                    */
  98. bool GC_add_map_entry(sz)
  99. word sz;
  100. {
  101.     register unsigned obj_start;
  102.     register unsigned displ;
  103.     register char * new_map;
  104.     
  105.     if (sz > MAXOBJSZ) sz = 0;
  106.     if (GC_obj_map[sz] != 0) {
  107.         return(TRUE);
  108.     }
  109.     new_map = GC_scratch_alloc(MAP_SIZE);
  110.     if (new_map == 0) return(FALSE);
  111. #   ifdef PRINTSTATS
  112.         GC_printf1("Adding block map for size %lu\n", (unsigned long)sz);
  113. #   endif
  114.     for (displ = 0; displ < HBLKSIZE; displ++) {
  115.         MAP_ENTRY(new_map,displ) = OBJ_INVALID;
  116.     }
  117.     if (sz == 0) {
  118.         for(displ = 0; displ <= MAX_OFFSET; displ++) {
  119.             if (OFFSET_VALID(displ)) {
  120.                 MAP_ENTRY(new_map,displ+HDR_BYTES) = BYTES_TO_WORDS(displ);
  121.             }
  122.         }
  123.     } else {
  124.         for (obj_start = HDR_BYTES;
  125.              obj_start + WORDS_TO_BYTES(sz) <= HBLKSIZE;
  126.              obj_start += WORDS_TO_BYTES(sz)) {
  127.              for (displ = 0; displ < WORDS_TO_BYTES(sz); displ++) {
  128.                  if (OFFSET_VALID(displ)) {
  129.                      MAP_ENTRY(new_map, obj_start + displ) =
  130.                                      BYTES_TO_WORDS(displ);
  131.                  }
  132.              }
  133.         }
  134.     }
  135.     GC_obj_map[sz] = new_map;
  136.     return(TRUE);
  137. }
  138.