home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sa104os2.zip / SATHR104.ZIP / SATHER / SYSTEM / GC / PTR_CHCK.C < prev    next >
C/C++ Source or Header  |  1994-11-02  |  8KB  |  277 lines

  1. /* 
  2.  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
  3.  *
  4.  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  5.  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
  6.  *
  7.  * Permission is hereby granted to use or copy this program
  8.  * for any purpose,  provided the above notices are retained on all copies.
  9.  * Permission to modify the code and to distribute modified code is granted,
  10.  * provided the above notices are retained, and a notice that the code was
  11.  * modified is included with the above copyright notice.
  12.  */
  13. /* Boehm, September 20, 1994 11:51 am PDT */
  14.  
  15. #include "gc_priv.h"
  16. #include "gc_mark.h"
  17.  
  18. void GC_default_same_obj_print_proc(p,q)
  19. ptr_t p, q;
  20. {
  21.     GC_err_printf2("0x%lx and 0x%lx are not in the same object\n",
  22.                (unsigned long)p, (unsigned long)q);
  23.     ABORT("GC_same_obj test failed");
  24. }
  25.  
  26. void (*GC_same_obj_print_proc)() = GC_default_same_obj_print_proc;
  27.  
  28. /* Check that p and q point to the same object.  Call        */
  29. /* *GC_same_obj_print_proc if they don't.            */
  30. /* Returns the first argument.  (Return value may be hard     */
  31. /* to use,due to typing issues.  But if we had a suitable     */
  32. /* preprocessor ...)                        */
  33. /* Succeeds if neither p nor q points to the heap.        */
  34. /* We assume this is performance critical.  (It shouldn't    */
  35. /* be called by production code, but this can easily make    */
  36. /* debugging intolerably slow.)                    */
  37. #ifdef __STDC__
  38.   void * GC_same_obj(register void *p, register void *q)
  39. #else
  40.   char * GC_same_obj(p, q)
  41.   register char *p, *q;
  42. #endif
  43. {
  44.     register struct hblk *h;
  45.     register hdr *hhdr;
  46.     register ptr_t base, limit;
  47.     register word sz;
  48.     
  49.     if (!GC_is_initialized) GC_init();
  50.     hhdr = HDR((word)p);
  51.     if (hhdr == 0) {
  52.        if (divHBLKSZ((word)p) != divHBLKSZ((word)q)
  53.            && HDR((word)q) != 0) {
  54.            goto fail;
  55.        }
  56.        return(p);
  57.     }
  58.     /* If it's a pointer to the middle of a large object, move it    */
  59.     /* to the beginning.                        */
  60.     if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
  61.         h = HBLKPTR(p) - (int)hhdr;
  62.         hhdr = HDR(h);
  63.     while (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
  64.        h = FORWARDED_ADDR(h, hhdr);
  65.        hhdr = HDR(h);
  66.     }
  67.     limit = (ptr_t)((word *)h + HDR_WORDS + hhdr -> hb_sz);
  68.     if ((ptr_t)p >= limit || (ptr_t)q >= limit || (ptr_t)q < (ptr_t)h ) {
  69.         goto fail;
  70.     }
  71.     return(p);
  72.     }
  73.     sz = WORDS_TO_BYTES(hhdr -> hb_sz);
  74.     if (sz > WORDS_TO_BYTES(MAXOBJSZ)) {
  75.       base = (ptr_t)HBLKPTR(p);
  76.       limit = base + sz;
  77.       if ((ptr_t)p >= limit) {
  78.         goto fail;
  79.       }
  80.     } else {
  81. #     ifdef ALL_INTERIOR_POINTERS
  82.     register map_entry_type map_entry;
  83.     register int pdispl;
  84.     
  85.     pdispl = HBLKDISPL(p);
  86.     map_entry = MAP_ENTRY((hhdr -> hb_map), pdispl);
  87.     if (map_entry == OBJ_INVALID) {
  88.             goto fail;
  89.         } else {
  90.             base = (char *)((word)p & ~(WORDS_TO_BYTES(1) - 1));
  91.             base -= WORDS_TO_BYTES(map_entry);
  92.     }
  93. #     else
  94.     register int offset = HBLKDISPL(p) - HDR_BYTES;
  95.     register word correction = offset % sz;
  96.     
  97.     if (HBLKPTR(p) != HBLKPTR(q)) {
  98.         /* The following computation otherwise fails in this case */
  99.         goto fail;
  100.     }
  101.     base = (ptr_t)p - correction;
  102. #     endif
  103.       limit = base + sz;
  104.     }
  105.     /* [base, limit) delimits the object containing p, if any.    */
  106.     /* If p is not inside a valid object, then either q is    */
  107.     /* also outside any valid object, or it is outside         */
  108.     /* [base, limit).                        */
  109.     if ((ptr_t)q >= limit || (ptr_t)q < base) {
  110.         goto fail;
  111.     }
  112.     return(p);
  113. fail:
  114.     (*GC_same_obj_print_proc)((ptr_t)p, (ptr_t)q);
  115.     return(p);
  116. }
  117.  
  118.  
  119. void GC_default_is_valid_displacement_print_proc(p)
  120. ptr_t p;
  121. {
  122.     GC_err_printf1("0x%lx does not point to valid object displacement\n",
  123.                (unsigned long)p);
  124.     ABORT("GC_is_valid_displacement test failed");
  125. }
  126.  
  127. void (*GC_is_valid_displacement_print_proc)() = 
  128.     GC_default_is_valid_displacement_print_proc;
  129.  
  130. /* Check that if p is a pointer to a heap page, then it points to    */
  131. /* a valid displacement within a heap object.                */
  132. /* Uninteresting with ALL_INTERIOR_POINTERS.                */
  133. /* Always returns its argument.                        */
  134. /* Note that we don't lock, since nothing relevant about the header    */
  135. /* should change while we have a valid object pointer to the block.    */
  136. #ifdef __STDC__
  137.   void * GC_is_valid_displacement(void *p)
  138. #else
  139.   char *GC_is_valid_displacement(p)
  140.   char *p;
  141. #endif
  142. {
  143.     register hdr *hhdr;
  144.     register word pdispl;
  145.     register struct hblk *h;
  146.     register map_entry_type map_entry;
  147.     register word sz;
  148.     
  149.     if (!GC_is_initialized) GC_init();
  150.     hhdr = HDR((word)p);
  151.     if (hhdr == 0) return(p);
  152.     h = HBLKPTR(p);
  153. #   ifdef ALL_INTERIOR_POINTERS
  154.     while (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
  155.        h = FORWARDED_ADDR(h, hhdr);
  156.        hhdr = HDR(h);
  157.     }
  158. #   endif
  159.     if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
  160.         goto fail;
  161.     }
  162.     sz = WORDS_TO_BYTES(hhdr -> hb_sz);
  163.     pdispl = HBLKDISPL(p);
  164.     map_entry = MAP_ENTRY((hhdr -> hb_map), pdispl);
  165.     if (map_entry == OBJ_INVALID
  166.         || sz > MAXOBJSZ && (ptr_t)p >= (ptr_t)h + sz) {
  167.         goto fail;
  168.     }
  169.     return(p);
  170. fail:
  171.     (*GC_is_valid_displacement_print_proc)((ptr_t)p);
  172.     return(p);
  173. }
  174.  
  175.  
  176. void GC_default_is_visible_print_proc(p)
  177. ptr_t p;
  178. {
  179.     GC_err_printf1("0x%lx is not a GC visible pointer location\n",
  180.                (unsigned long)p);
  181.     ABORT("GC_is_visible test failed");
  182. }
  183.  
  184. void (*GC_is_visible_print_proc)() = 
  185.     GC_default_is_visible_print_proc;
  186.  
  187. /* Check that p is visible                        */
  188. /* to the collector as a possibly pointer containing location.        */
  189. /* If it isn't invoke *GC_is_visible_print_proc.            */
  190. /* Returns the argument in all cases.  May erroneously succeed        */
  191. /* in hard cases.  (This is intended for debugging use with        */
  192. /* untyped allocations.  The idea is that it should be possible, though    */
  193. /* slow, to add such a call to all indirect pointer stores.)        */
  194. /* Currently useless for multithreaded worlds.                */
  195. #ifdef __STDC__
  196.   void * GC_is_visible(void *p)
  197. #else
  198.   char *GC_is_visible(p)
  199.   char *p;
  200. #endif
  201. {
  202.     register hdr *hhdr;
  203.     int dummy;
  204.     
  205.     if ((word)p & (ALIGNMENT - 1)) goto fail;
  206.     if (!GC_is_initialized) GC_init();
  207. #   ifdef THREADS
  208.     hhdr = HDR((word)p);
  209.         if (hhdr != 0 && GC_base(p) == 0) {
  210.             goto fail;
  211.         } else {
  212.             /* May be inside thread stack.  We can't do much. */
  213.             return(p);
  214.         }
  215. #   else
  216.     /* Check stack first: */
  217. #         ifdef STACK_GROWS_DOWN
  218.         if ((ptr_t)p >= (ptr_t)(&dummy) && (ptr_t)p < GC_stackbottom ) {
  219.             return(p);
  220.         }
  221. #      else
  222.         if ((ptr_t)p <= (ptr_t)(&dummy) && (ptr_t)p > GC_stackbottom ) {
  223.             return(p);
  224.         }
  225. #      endif
  226.     hhdr = HDR((word)p);
  227.         if (hhdr == 0) {
  228.             bool result;
  229.             
  230.             if (GC_is_static_root(p)) return(p);
  231.             /* Else do it again correctly:    */
  232. #           if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(PCR)) \
  233.                 && !defined(SRC_M3)
  234.                 DISABLE_SIGNALS();
  235.                 GC_register_dynamic_libraries();
  236.                 result = GC_is_static_root(p);
  237.                 ENABLE_SIGNALS();
  238.                 if (result) return(p);
  239. #        endif
  240.             goto fail;
  241.         } else {
  242.             /* p points to the heap. */
  243.             word descr;
  244.             ptr_t base = GC_base(p);    /* Should be manually inlined? */
  245.             
  246.             if (base == 0) goto fail;
  247.             if (HBLKPTR(base) != HBLKPTR(p)) hhdr = HDR((word)p);
  248.             descr = hhdr -> hb_descr;
  249.     retry:
  250.             switch(descr & DS_TAGS) {
  251.                 case DS_LENGTH:
  252.                     if ((ptr_t)p - (ptr_t)base > (word)descr) goto fail;
  253.                     break;
  254.                 case DS_BITMAP:
  255.                     if ((ptr_t)p - (ptr_t)base
  256.                          >= WORDS_TO_BYTES(BITMAP_BITS)
  257.                          || ((word)p & (sizeof(word) - 1))) goto fail;
  258.                     if (!((1 << (WORDSZ - ((ptr_t)p - (ptr_t)base) - 1))
  259.                           & descr)) goto fail;
  260.                     break;
  261.                 case DS_PROC:
  262.                     /* We could try to decipher this partially.     */
  263.                     /* For now we just punt.                */
  264.                     break;
  265.                 case DS_PER_OBJECT:
  266.                     descr = *(word *)((ptr_t)base + (descr & ~DS_TAGS));
  267.                     goto retry;
  268.             }
  269.             return(p);
  270.         }
  271. #   endif
  272. fail:
  273.     (*GC_is_visible_print_proc)((ptr_t)p);
  274.     return(p);
  275. }
  276.  
  277.