00001 # define SILENT
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 # ifndef GC_PRIVATE_H
00015 # define GC_PRIVATE_H
00016
00017 # ifndef GC_H
00018 # include "gc.h"
00019 # endif
00020
00021 # ifndef CONFIG_H
00022 # include "config.h"
00023 # endif
00024
00025 # ifndef HEADERS_H
00026 # include "gc_headers.h"
00027 # endif
00028
00029 # ifndef bool
00030 typedef int bool;
00031 # endif
00032 # define TRUE 1
00033 # define FALSE 0
00034
00035 typedef char * ptr_t;
00036
00037
00038 #ifdef __STDC__
00039 # if !(defined( sony_news ) )
00040 # include <stddef.h>
00041 # endif
00042 typedef void * extern_ptr_t;
00043 #else
00044 typedef char * extern_ptr_t;
00045 #endif
00046
00047 # ifndef OS2
00048 # include <sys/types.h>
00049 # endif
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #define ALL_INTERIOR_POINTERS
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 #undef ALL_INTERIOR_POINTERS
00091
00092 #define PRINTSTATS
00093
00094
00095 #define PRINTTIMES
00096
00097
00098 #define PRINTBLOCKS
00099
00100
00101
00102
00103 #undef PRINTBLOCKS
00104
00105 #define PRINTBLACKLIST
00106
00107
00108
00109 #undef PRINTBLACKLIST
00110
00111 #ifdef SILENT
00112 # ifdef PRINTSTATS
00113 # undef PRINTSTATS
00114 # endif
00115 # ifdef PRINTTIMES
00116 # undef PRINTTIMES
00117 # endif
00118 # ifdef PRINTNBLOCKS
00119 # undef PRINTNBLOCKS
00120 # endif
00121 #endif
00122
00123 #if defined(PRINTSTATS) && !defined(GATHERSTATS)
00124 # define GATHERSTATS
00125 #endif
00126
00127
00128 #ifdef SPARC
00129 # define ALIGN_DOUBLE
00130
00131
00132 #endif
00133
00134 #if defined(SPARC) || defined(M68K) && defined(SUNOS)
00135 # if !defined(PCR)
00136 # define DYNAMIC_LOADING
00137 # else
00138
00139 # endif
00140 #endif
00141
00142 #define MERGE_SIZES
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 # if defined(ALIGN_DOUBLE) && !defined(MERGE_SIZES)
00155 # define MERGE_SIZES
00156 # endif
00157
00158
00159 # define HINCR 16
00160 # define MAXHINCR 512
00161 # define HINCR_MULT 3
00162 # define HINCR_DIV 2
00163 # define GC_MULT 3
00164
00165
00166 # define GC_DIV 4
00167
00168 # define NON_GC_HINCR ((word)8)
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 #include <time.h>
00180 #if !defined(CLOCKS_PER_SEC)
00181 # define CLOCKS_PER_SEC 1000000
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 #endif
00193 #define CLOCK_TYPE clock_t
00194 #define GET_TIME(x) x = clock()
00195 #define MS_TIME_DIFF(a,b) ((unsigned long) \
00196 (1000.0*(double)((a)-(b))/(double)CLOCKS_PER_SEC))
00197
00198
00199 # if defined(SPARC) && defined(SUNOS4)
00200 # define BCOPY_EXISTS
00201 # endif
00202 # if defined(M68K) && defined(SUNOS)
00203 # define BCOPY_EXISTS
00204 # endif
00205 # if defined(VAX)
00206 # define BCOPY_EXISTS
00207 # endif
00208
00209 # ifndef BCOPY_EXISTS
00210 # include <string.h>
00211 # define bcopy(x,y,n) memcpy(y,x,n)
00212 # define bzero(x,n) memset(x, 0, n)
00213 # endif
00214
00215
00216
00217 # ifdef PCR
00218 char * real_malloc();
00219 # define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)bytes + HBLKSIZE) \
00220 + HBLKSIZE-1)
00221 # define THREADS
00222 # else
00223 # ifdef OS2
00224 void * os2_alloc(size_t bytes);
00225 # define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc((size_t)bytes + HBLKSIZE) \
00226 + HBLKSIZE-1)
00227 # else
00228 caddr_t sbrk();
00229 # ifdef __STDC__
00230 # define GET_MEM(bytes) HBLKPTR(sbrk((size_t)(bytes + HBLKSIZE)) \
00231 + HBLKSIZE-1)
00232 # else
00233 # define GET_MEM(bytes) HBLKPTR(sbrk((int)(bytes + HBLKSIZE)) \
00234 + HBLKSIZE-1)
00235 # endif
00236 # endif
00237 # endif
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 # ifdef PCR
00255 # include "pcr/th/PCR_Th.h"
00256 # include "pcr/th/PCR_ThCrSec.h"
00257 extern struct PCR_Th_MLRep GC_allocate_ml;
00258 # define DCL_LOCK_STATE PCR_sigset_t GC_old_sig_mask
00259 # define LOCK() PCR_Th_ML_Acquire(&GC_allocate_ml)
00260 # define UNLOCK() PCR_Th_ML_Release(&GC_allocate_ml)
00261 # define FASTLOCK() PCR_ThCrSec_EnterSys()
00262
00263 # define FASTLOCK_SUCCEEDED() (*(int *)(&GC_allocate_ml) == 0)
00264
00265 # define FASTUNLOCK() PCR_ThCrSec_ExitSys()
00266 # else
00267 # define DCL_LOCK_STATE
00268 # define LOCK()
00269 # define UNLOCK()
00270 # define FASTLOCK() LOCK()
00271 # define FASTLOCK_SUCCEEDED() TRUE
00272 # define FASTUNLOCK() UNLOCK()
00273 # endif
00274
00275
00276
00277
00278
00279
00280
00281 # ifdef PCR
00282 # define DISABLE_SIGNALS() \
00283 PCR_Th_SetSigMask(PCR_allSigsBlocked,&GC_old_sig_mask)
00284 # define ENABLE_SIGNALS() \
00285 PCR_Th_SetSigMask(&GC_old_sig_mask, NIL)
00286 # else
00287 # if 0
00288
00289 # define DISABLE_SIGNALS()
00290 # define ENABLE_SIGNALS()
00291 # else
00292 # define DISABLE_SIGNALS() GC_disable_signals()
00293 void GC_disable_signals();
00294 # define ENABLE_SIGNALS() GC_enable_signals()
00295 void GC_enable_signals();
00296 # endif
00297 # endif
00298
00299
00300
00301
00302 # ifdef PCR
00303 # include "pcr/th/PCR_ThCtl.h"
00304 # define STOP_WORLD() \
00305 PCR_ThCtl_SetExclusiveMode(PCR_ThCtl_ExclusiveMode_stopNormal, \
00306 PCR_allSigsBlocked, \
00307 PCR_waitForever)
00308 # define START_WORLD() \
00309 PCR_ThCtl_SetExclusiveMode(PCR_ThCtl_ExclusiveMode_null, \
00310 PCR_allSigsBlocked, \
00311 PCR_waitForever);
00312 # else
00313 # define STOP_WORLD()
00314 # define START_WORLD()
00315 # endif
00316
00317
00318 # ifdef PCR
00319 void PCR_Base_Panic(const char *fmt, ...);
00320 # define ABORT(s) PCR_Base_Panic(s)
00321 # else
00322 # define ABORT(s) abort(s)
00323 # endif
00324
00325
00326 # ifdef PCR
00327 void PCR_Base_Exit(int status);
00328 # define EXIT() PCR_Base_Exit(1)
00329 # else
00330 # define EXIT() (void)exit(1)
00331 # endif
00332
00333
00334 # define WARN(s) GC_printf0(s)
00335
00336
00337
00338
00339
00340
00341
00342 #if CPP_WORDSZ == 32
00343 # define WORDS_TO_BYTES(x) ((x)<<2)
00344 # define BYTES_TO_WORDS(x) ((x)>>2)
00345 # define LOGWL ((word)5)
00346 # define modWORDSZ(n) ((n) & 0x1f)
00347 #endif
00348
00349 #if CPP_WORDSZ == 64
00350 # define WORDS_TO_BYTES(x) ((x)<<3)
00351 # define BYTES_TO_WORDS(x) ((x)>>3)
00352 # define LOGWL ((word)6)
00353 # define modWORDSZ(n) ((n) & 0x3f)
00354 #endif
00355
00356 #define WORDSZ ((word)CPP_WORDSZ)
00357 #define SIGNB ((word)1 << (WORDSZ-1))
00358 #define BYTES_PER_WORD ((word)(sizeof (word)))
00359 #define ONES ((word)(-1))
00360 #define divWORDSZ(n) ((n) >> LOGWL)
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 #define CPP_LOG_HBLKSIZE 12
00371 #define LOG_HBLKSIZE ((word)CPP_LOG_HBLKSIZE)
00372 #define CPP_HBLKSIZE (1 << CPP_LOG_HBLKSIZE)
00373 #define HBLKSIZE ((word)CPP_HBLKSIZE)
00374
00375
00376
00377
00378
00379 #define CPP_MAXOBJSZ BYTES_TO_WORDS(CPP_HBLKSIZE/2)
00380 #define MAXOBJSZ ((word)CPP_MAXOBJSZ)
00381
00382 # define divHBLKSZ(n) ((n) >> LOG_HBLKSIZE)
00383
00384 # define modHBLKSZ(n) ((n) & (HBLKSIZE-1))
00385
00386 # define HBLKPTR(objptr) ((struct hblk *)(((word) (objptr)) & ~(HBLKSIZE-1)))
00387
00388 # define HBLKDISPL(objptr) (((word) (objptr)) & (HBLKSIZE-1))
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 #define HBLKMASK (HBLKSIZE-1)
00399
00400 #define BITS_PER_HBLK (HBLKSIZE * 8)
00401
00402 #define MARK_BITS_PER_HBLK (BITS_PER_HBLK/CPP_WORDSZ)
00403
00404
00405
00406
00407 # ifdef ALIGN_DOUBLE
00408 # define MARK_BITS_SZ (((MARK_BITS_PER_HBLK + 2*CPP_WORDSZ - 1) \
00409 / (2*CPP_WORDSZ))*2)
00410 # else
00411 # define MARK_BITS_SZ ((MARK_BITS_PER_HBLK + CPP_WORDSZ - 1)/CPP_WORDSZ)
00412 # endif
00413
00414
00415
00416 typedef struct ms_entry {
00417 word * mse_start;
00418 word * mse_end;
00419 } mse;
00420
00421 typedef mse * (*mark_proc)();
00422
00423
00424
00425
00426
00427
00428 struct hblkhdr {
00429 word hb_sz;
00430
00431 struct hblk * hb_next;
00432
00433
00434 mark_proc hb_mark_proc;
00435
00436
00437
00438 char* hb_map;
00439
00440
00441
00442 int hb_obj_kind;
00443
00444
00445
00446 word hb_marks[MARK_BITS_SZ];
00447
00448
00449
00450 };
00451
00452
00453
00454 # define DISCARD_WORDS 0
00455
00456
00457
00458
00459
00460
00461 # define BODY_SZ ((HBLKSIZE-WORDS_TO_BYTES(DISCARD_WORDS))/sizeof(word))
00462
00463 struct hblk {
00464 # if (DISCARD_WORDS != 0)
00465 word garbage[DISCARD_WORDS];
00466 # endif
00467 word hb_body[BODY_SZ];
00468 };
00469
00470 # define HDR_WORDS ((word)DISCARD_WORDS)
00471 # define HDR_BYTES ((word)WORDS_TO_BYTES(DISCARD_WORDS))
00472
00473
00474 # define obj_link(p) (*(ptr_t *)(p))
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 struct _GC_arrays {
00488 word _heapsize;
00489 ptr_t _last_heap_addr;
00490 ptr_t _prev_heap_addr;
00491 word _words_allocd_before_gc;
00492
00493
00494 # ifdef GATHERSTATS
00495 word _composite_in_use;
00496
00497
00498 word _atomic_in_use;
00499
00500
00501 # endif
00502 word _words_allocd;
00503
00504 word _non_gc_bytes_at_gc;
00505
00506
00507 word _mem_freed;
00508
00509
00510
00511 ptr_t _objfreelist[MAXOBJSZ+1];
00512
00513 # ifdef MERGE_SIZES
00514 unsigned _size_map[WORDS_TO_BYTES(MAXOBJSZ+1)];
00515
00516
00517 # endif
00518 ptr_t _aobjfreelist[MAXOBJSZ+1];
00519
00520 ptr_t _obj_map[MAXOBJSZ+1];
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536 # ifdef ALL_INTERIOR_POINTERS
00537 # define map_entry_type short
00538 # define OBJ_INVALID 0x7fff
00539 # define MAP_ENTRY(map, bytes) \
00540 (((map_entry_type *)(map))[BYTES_TO_WORDS(bytes)])
00541 # define MAP_ENTRIES BYTES_TO_WORDS(HBLKSIZE)
00542 # define MAP_SIZE (MAP_ENTRIES * sizeof(map_entry_type))
00543 # define OFFSET_VALID(displ) TRUE
00544 # define CPP_MAX_OFFSET (HBLKSIZE - HDR_BYTES - 1)
00545 # define MAX_OFFSET ((word)CPP_MAX_OFFSET)
00546 # else
00547 # define map_entry_type char
00548 # define OBJ_INVALID 0x7f
00549 # define MAP_ENTRY(map, bytes) \
00550 (map)[bytes]
00551 # define MAP_ENTRIES HBLKSIZE
00552 # define MAP_SIZE MAP_ENTRIES
00553 # define CPP_MAX_OFFSET (WORDS_TO_BYTES(OBJ_INVALID) - 1)
00554 # define MAX_OFFSET ((word)CPP_MAX_OFFSET)
00555 # define VALID_OFFSET_SZ \
00556 (CPP_MAX_OFFSET > WORDS_TO_BYTES(CPP_MAXOBJSZ)? \
00557 CPP_MAX_OFFSET+1 \
00558 : WORDS_TO_BYTES(CPP_MAXOBJSZ)+1)
00559 char _valid_offsets[VALID_OFFSET_SZ];
00560
00561
00562 # define OFFSET_VALID(displ) GC_valid_offsets[displ]
00563 char _modws_valid_offsets[sizeof(word)];
00564
00565
00566 # endif
00567 struct hblk * _reclaim_list[MAXOBJSZ+1];
00568 struct hblk * _areclaim_list[MAXOBJSZ+1];
00569 };
00570
00571 extern struct _GC_arrays GC_arrays;
00572
00573 # define GC_objfreelist GC_arrays._objfreelist
00574 # define GC_aobjfreelist GC_arrays._aobjfreelist
00575 # define GC_valid_offsets GC_arrays._valid_offsets
00576 # define GC_modws_valid_offsets GC_arrays._modws_valid_offsets
00577 # define GC_reclaim_list GC_arrays._reclaim_list
00578 # define GC_areclaim_list GC_arrays._areclaim_list
00579 # define GC_obj_map GC_arrays._obj_map
00580 # define GC_last_heap_addr GC_arrays._last_heap_addr
00581 # define GC_prev_heap_addr GC_arrays._prev_heap_addr
00582 # define GC_words_allocd GC_arrays._words_allocd
00583 # define GC_non_gc_bytes_at_gc GC_arrays._non_gc_bytes_at_gc
00584 # define GC_mem_freed GC_arrays._mem_freed
00585 # define GC_heapsize GC_arrays._heapsize
00586 # define GC_words_allocd_before_gc GC_arrays._words_allocd_before_gc
00587 # ifdef GATHERSTATS
00588 # define GC_composite_in_use GC_arrays._composite_in_use
00589 # define GC_atomic_in_use GC_arrays._atomic_in_use
00590 # endif
00591 # ifdef MERGE_SIZES
00592 # define GC_size_map GC_arrays._size_map
00593 # endif
00594
00595 # define beginGC_arrays ((ptr_t)(&GC_arrays))
00596 # define endGC_arrays (((ptr_t)(&GC_arrays)) + (sizeof GC_arrays))
00597
00598
00599 # define MAXOBJKINDS 16
00600
00601
00602 extern struct obj_kind {
00603 ptr_t *ok_freelist;
00604
00605
00606 struct hblk **ok_reclaim_list;
00607
00608
00609 mark_proc ok_mark_proc;
00610
00611 bool ok_init;
00612 } GC_obj_kinds[MAXOBJKINDS];
00613
00614 # define PTRFREE 0
00615 # define NORMAL 1
00616
00617 extern int GC_n_kinds;
00618
00619 extern char * GC_invalid_map;
00620
00621
00622
00623 extern struct hblk * GC_hblkfreelist;
00624
00625
00626
00627
00628
00629 extern bool GC_is_initialized;
00630
00631 # ifndef PCR
00632 extern ptr_t GC_stackbottom;
00633 # endif
00634
00635 extern word GC_hincr;
00636
00637 extern word GC_root_size;
00638
00639 extern bool GC_debugging_started;
00640
00641 extern ptr_t GC_least_plausible_heap_addr;
00642 extern ptr_t GC_greatest_plausible_heap_addr;
00643
00644
00645
00646
00647 # define update_GC_hincr GC_hincr = (GC_hincr * HINCR_MULT)/HINCR_DIV; \
00648 if (GC_hincr > MAXHINCR) {GC_hincr = MAXHINCR;}
00649 # ifndef abs
00650 # define abs(x) ((x) < 0? (-(x)) : (x))
00651 # endif
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676 # define mark_bit_from_hdr(hhdr,n) (((hhdr)->hb_marks[divWORDSZ(n)] \
00677 >> (modWORDSZ(n))) & 1)
00678 # define set_mark_bit_from_hdr(hhdr,n) (hhdr)->hb_marks[divWORDSZ(n)] \
00679 |= 1 << modWORDSZ(n)
00680
00681 # define clear_mark_bit_from_hdr(hhdr,n) (hhdr)->hb_marks[divWORDSZ(n)] \
00682 &= ~(1 << modWORDSZ(n))
00683
00684
00685
00686 void GC_apply_to_all_blocks();
00687
00688
00689 mse * GC_no_mark_proc();
00690
00691 mse * GC_normal_mark_proc();
00692
00693 void GC_mark_init();
00694 void GC_mark();
00695 void GC_mark_reliable();
00696
00697 void GC_mark_all();
00698 void GC_mark_all_stack();
00699
00700 void GC_remark();
00701
00702 void GC_tl_mark();
00703 void GC_clear_hdr_marks();
00704 void GC_add_roots_inner();
00705 void GC_register_dynamic_libraries();
00706
00707
00708
00709 ptr_t GC_get_stack_base();
00710 void GC_register_data_segments();
00711
00712 # ifndef ALL_INTERIOR_POINTERS
00713 void GC_add_to_black_list_normal();
00714
00715
00716 # define GC_ADD_TO_BLACK_LIST_NORMAL(bits) GC_add_to_black_list_normal(bits)
00717 # else
00718 # define GC_ADD_TO_BLACK_LIST_NORMAL(bits) GC_add_to_black_list_stack(bits)
00719 # endif
00720
00721 void GC_add_to_black_list_stack();
00722 struct hblk * GC_is_black_listed();
00723
00724
00725
00726
00727
00728 void GC_promote_black_lists();
00729
00730
00731 ptr_t GC_scratch_alloc();
00732
00733
00734
00735
00736 void GC_invalidate_map();
00737
00738
00739
00740
00741 void GC_add_map_entry();
00742
00743
00744 void GC_register_displacement_inner();
00745
00746
00747
00748
00749 void GC_init_inner();
00750
00751 void GC_new_hblk();
00752
00753
00754 struct hblk * GC_allochblk();
00755
00756
00757
00758
00759
00760 void GC_freehblk();
00761
00762
00763 void GC_start_reclaim();
00764
00765
00766
00767
00768
00769 void GC_continue_reclaim();
00770
00771
00772
00773
00774 bool GC_gcollect_inner();
00775
00776
00777
00778
00779 void GC_collect_or_expand();
00780
00781
00782
00783
00784 void GC_init();
00785
00786 ptr_t GC_generic_malloc();
00787
00788
00789
00790
00791
00792
00793
00794
00795 ptr_t GC_generic_malloc_words_small();
00796
00797
00798
00799 ptr_t GC_allocobj();
00800
00801
00802
00803
00804 void GC_install_header();
00805
00806 void GC_install_counts();
00807
00808
00809 void GC_remove_header();
00810
00811 void GC_remove_counts();
00812
00813 hdr * GC_find_header();
00814
00815 void GC_finalize();
00816
00817
00818 void GC_add_to_heap();
00819
00820
00821 void GC_print_obj();
00822
00823
00824
00825 void GC_check_heap();
00826
00827
00828
00829
00830 void GC_printf();
00831
00832
00833
00834
00835
00836
00837
00838 # define GC_printf0(f) GC_printf(f, 0l, 0l, 0l, 0l, 0l, 0l)
00839 # define GC_printf1(f,a) GC_printf(f, (long)a, 0l, 0l, 0l, 0l, 0l)
00840 # define GC_printf2(f,a,b) GC_printf(f, (long)a, (long)b, 0l, 0l, 0l, 0l)
00841 # define GC_printf3(f,a,b,c) GC_printf(f, (long)a, (long)b, (long)c, 0l, 0l, 0l)
00842 # define GC_printf4(f,a,b,c,d) GC_printf(f, (long)a, (long)b, (long)c, \
00843 (long)d, 0l, 0l)
00844 # define GC_printf5(f,a,b,c,d,e) GC_printf(f, (long)a, (long)b, (long)c, \
00845 (long)d, (long)e, 0l)
00846 # define GC_printf6(f,a,b,c,d,e,g) GC_printf(f, (long)a, (long)b, (long)c, \
00847 (long)d, (long)e, (long)g)
00848
00849 void GC_err_printf();
00850 # define GC_err_printf0(f) GC_err_puts(f)
00851 # define GC_err_printf1(f,a) GC_err_printf(f, (long)a, 0l, 0l, 0l, 0l, 0l)
00852 # define GC_err_printf2(f,a,b) GC_err_printf(f, (long)a, (long)b, 0l, 0l, 0l, 0l)
00853 # define GC_err_printf3(f,a,b,c) GC_err_printf(f, (long)a, (long)b, (long)c, \
00854 0l, 0l, 0l)
00855 # define GC_err_printf4(f,a,b,c,d) GC_err_printf(f, (long)a, (long)b, \
00856 (long)c, (long)d, 0l, 0l)
00857 # define GC_err_printf5(f,a,b,c,d,e) GC_err_printf(f, (long)a, (long)b, \
00858 (long)c, (long)d, \
00859 (long)e, 0l)
00860 # define GC_err_printf6(f,a,b,c,d,e,g) GC_err_printf(f, (long)a, (long)b, \
00861 (long)c, (long)d, \
00862 (long)e, (long)g)
00863
00864
00865 void GC_err_puts();
00866
00867
00868
00869 # endif