2
Copyright (C) 1994 M. Hagiya, W. Schelter, T. Yuasa
4
This file is part of GNU Common Lisp, herein referred to as GCL
6
GCL is free software; you can redistribute it and/or modify it under
7
the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by
8
the Free Software Foundation; either version 2, or (at your option)
11
GCL is distributed in the hope that it will be useful, but WITHOUT
12
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14
License for more details.
16
You should have received a copy of the GNU Library General Public License
17
along with GCL; see the file COPYING. If not, write to the Free Software
18
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24
IMPLEMENTATION-DEPENDENT
30
DEFVAR("*AFTER-GBC-HOOK*",sSAafter_gbc_hookA,SI,sLnil,"");
31
DEFVAR("*IGNORE-MAXIMUM-PAGES*",sSAignore_maximum_pagesA,SI,sLt,"");
32
#define IGNORE_MAX_PAGES (sSAignore_maximum_pagesA ==0 || sSAignore_maximum_pagesA->s.s_dbind !=sLnil)
34
void call_after_gbc_hook();
43
printf("\n{sbrk(%d)",n);
47
printf("->[0x%x]", ans);
49
printf("core_end=0x%x,sbrk(0)=0x%x}",core_end,sbrk(0));
54
#endif /* DEBUG_SBRK */
56
int real_maxpage = MAXPAGE;
59
#define available_pages \
60
(real_maxpage-page(heap_end)-new_holepage-2*nrbpage-real_maxpage/32)
69
#include <sys/resource.h>
71
struct rlimit data_rlimit;
73
/* extern char etext; */
76
int reserve_pages_for_signal_handler =30;
78
/* If (n >= 0 ) return pointer to n pages starting at heap end,
79
These must come from the hole, so if that is exhausted you have
80
to gc and move the hole.
81
if (n < 0) return pointer to n pages starting at heap end,
82
but don't worry about the hole. Basically just make sure
83
the space is available from the Operating system.
84
If not in_signal_handler then try to keep a minimum of
85
reserve_pages_for_signal_handler pages on hand in the hole
96
(holepage - (in_signal_handler? 0 :
97
reserve_pages_for_signal_handler
100
holepage = new_holepage + n;
102
{int in_sgc=sgc_enabled;
103
if (in_sgc) sgc_quit();
104
if(in_signal_handler)
106
"Cant do relocatable gc in signal handler. \
107
Try to allocate more space to save for allocation during signals: \
108
eg to add 20 more do (si::set-hole-size %d %d)\n...start over ", new_holepage, 20+ reserve_pages_for_signal_handler); fflush(stderr); exit(1);}
113
/* starting sgc can use up some pages
114
and may move heap end, so start over
116
return alloc_page(n);}
120
if (heap_end == core_end)
121
/* can happen when mallocs occur before rel block set up..*/
123
core_end += PAGESIZE*n;
125
heap_end += PAGESIZE*n;
129
/* n < 0 , then this says ensure there are -n pages
130
starting at heap_end, and return pointer to heap_end */
133
m = (core_end - heap_end)/PAGESIZE;
137
IF_ALLOCATE_ERR error("Can't allocate. Good-bye!");
140
make_writable(page(core_end),page(core_end)+n-m);
143
core_end += PAGESIZE*(n - m);
148
add_page_to_freelist(p,tm)
150
struct typemanager *tm;
152
int i=tm->tm_nppage,fw;
159
{ if (!WRITABLE_PAGE_P(nn)) make_writable(nn,nn+1);}
161
type_map[page(p)]= t;
168
if (sgc_enabled && tm->tm_sgc)
170
sgc_type_map[page(x)] = (SGC_PAGE_FLAG | SGC_TEMP_WRITABLE);}
171
else x->d.s = SGC_NORMAL;
173
/* array headers must be always writable, since a write to the
174
body does not touch the header. It may be desirable if there
175
are many arrays in a system to make the headers not writable,
176
but just SGC_TOUCH the header each time you write to it. this
177
is what is done with t_structure */
178
if (t== (tm_of(t_array)->tm_type))
179
sgc_type_map[page(x)] |= SGC_PERM_WRITABLE;
187
x= (object) ((char *)x + size);
190
tm->tm_nfree += tm->tm_nppage;
197
{ return make_simple_string(tm_table[(int)t].tm_name+1);}
201
call_after_gbc_hook(t)
202
{ if (sSAafter_gbc_hookA && sSAafter_gbc_hookA->s.s_dbind!= Cnil)
203
{ set_up_string_register(tm_table[(int)t].tm_name+1);
204
ifuncall1(sSAafter_gbc_hookA->s.s_dbind,intern(string_register,system_package));
208
#define PERCENT_FREE(tm) ((tm->tm_percent_free ? tm->tm_percent_free : 10)/100.0)
216
struct typemanager *tm;
227
if (obj == OBJNULL) {
228
if (tm->tm_npage >= tm->tm_maxpage)
230
if (available_pages < 1) {
231
if (sSAignore_maximum_pagesA) {
232
sSAignore_maximum_pagesA->s.s_dbind = Cnil;
237
add_page_to_freelist(p,tm);
239
if (tm->tm_npage >= tm->tm_maxpage)
242
tm->tm_free = OBJ_LINK(obj);
248
#define TOTAL_THIS_TYPE(tm) \
249
(tm->tm_nppage * (sgc_enabled ? sgc_count_type(tm->tm_type) : tm->tm_npage))
252
if (tm->tm_nfree == 0 ||
253
((float)tm->tm_nfree) < (PERCENT_FREE(tm) * TOTAL_THIS_TYPE(tm)))
255
call_after_gbc_hook(t);
259
if (IGNORE_MAX_PAGES) {
260
if (tm->tm_maxpage/2 <= 0)
263
tm->tm_maxpage += tm->tm_maxpage/2;
264
call_after_gbc_hook(t);
268
vs_push(type_name(t));
269
vs_push(make_fixnum(tm->tm_npage));
271
CEerror("The storage for ~A is exhausted.~%\
272
Currently, ~D pages are allocated.~%\
273
Use ALLOCATE to expand the space.",
274
"Continues execution.",
275
2, vs_top[-2], vs_top[-1]);
278
call_after_gbc_hook(t);
282
grow_linear(old,fract,grow_min,grow_max)
283
int old,grow_min,grow_max,fract;
285
if(fract==0) fract=50;
286
if(grow_min==0) grow_min=1;
287
if(grow_max==0) grow_max=1000;
288
delt=(old*fract)/100;
289
delt= (delt < grow_min ? grow_min:
290
delt > grow_max ? grow_max:
302
struct typemanager *tm=(&tm_table[(int)t_cons]);
303
/* #define tm (&tm_table[(int)t_cons])*/
308
if (obj == OBJNULL) {
309
if (tm->tm_npage >= tm->tm_maxpage)
311
if (available_pages < 1) {
312
if(sSAignore_maximum_pagesA) {
313
sSAignore_maximum_pagesA->s.s_dbind = Cnil;
318
add_page_to_freelist(p,tm);
320
if (tm->tm_npage >= tm->tm_maxpage)
323
tm->tm_free = OBJ_LINK(obj);
326
obj->c.t = (short)t_cons;
334
if (tm->tm_nfree == 0 ||
335
(float)tm->tm_nfree < PERCENT_FREE(tm) * TOTAL_THIS_TYPE(tm))
337
call_after_gbc_hook(t_cons);
341
if (IGNORE_MAX_PAGES) {
343
grow_linear(tm->tm_maxpage,tm->tm_growth_percent,
344
tm->tm_min_grow,tm->tm_max_grow);
345
call_after_gbc_hook(t_cons);
349
vs_push(make_fixnum(tm->tm_npage));
351
CEerror("The storage for CONS is exhausted.~%\
352
Currently, ~D pages are allocated.~%\
353
Use ALLOCATE to expand the space.",
354
"Continues execution.",
357
call_after_gbc_hook(t_cons);
363
object on_stack_cons(x,y)
365
{object p = (object) alloca_val;
366
p->c.t= (short)t_cons;
374
DEFUN("ALLOCATED",object,fSallocated,SI
375
,2,2,NONE,OO,OO,OO,OO,"")(typ)
377
{ struct typemanager *tm=(&tm_table[t_from_type(typ)]);
378
tm = & tm_table[tm->tm_type];
379
if (tm->tm_type == t_relocatable)
380
{ tm->tm_npage = (rb_end-rb_start)/PAGESIZE;
381
tm->tm_nfree = rb_end -rb_pointer;
383
else if (tm->tm_type == t_contiguous)
385
struct contblock **cbpp;
386
for(cbpp= &cb_pointer; (*cbpp)!=NULL; cbpp= &(*cbpp)->cb_link)
387
cbfree += (*cbpp)->cb_size ;
388
tm->tm_nfree = cbfree;
391
RETURN(6,object,make_fixnum(tm->tm_nfree),
392
(RV(make_fixnum(tm->tm_npage)),
393
RV(make_fixnum(tm->tm_maxpage)),
394
RV(make_fixnum(tm->tm_nppage)),
395
RV(make_fixnum(tm->tm_gbccount)),
396
RV(make_fixnum(tm->tm_nused))
400
DEFUN("RESET-NUMBER-USED",object,fSreset_number_used,SI,0,1,NONE,OO,OO,OO,OO,"")(typ)
404
{ tm_table[t_from_type(typ)].tm_nused = 0;}
406
for (i=0; i <= t_relocatable ; i++)
407
{ tm_table[i].tm_nused = 0;}
417
struct contblock **cbpp;
424
printf("allocating %d-byte contiguous block...\n", n);
432
for(cbpp= &cb_pointer; (*cbpp)!=NULL; cbpp= &(*cbpp)->cb_link)
433
if ((*cbpp)->cb_size >= n) {
435
i = (*cbpp)->cb_size - n;
436
*cbpp = (*cbpp)->cb_link;
438
insert_contblock(p+n, i);
441
m = (n + PAGESIZE - 1)/PAGESIZE;
442
if(sSAignore_maximum_pagesA) {
443
if (ncbpage + m > maxcbpage || available_pages < m) {
444
if (available_pages < m)
445
sSAignore_maximum_pagesA->s.s_dbind = Cnil;
449
call_after_gbc_hook(t_contiguous);
452
if (IGNORE_MAX_PAGES)
453
{struct typemanager *tm = &tm_table[(int)t_contiguous];
454
maxcbpage=grow_linear(maxcbpage,tm->tm_growth_percent,
455
tm->tm_min_grow, tm->tm_max_grow);
457
call_after_gbc_hook(t_contiguous);
460
vs_push(make_fixnum(ncbpage));
461
CEerror("Contiguous blocks exhausted.~%\
462
Currently, ~D pages are allocated.~%\
463
Use ALLOCATE-CONTIGUOUS-PAGES to expand the space.",
464
"Continues execution.", 1, vs_head);
467
call_after_gbc_hook(t_contiguous);
473
for (i = 0; i < m; i++)
474
type_map[page(p) + i] = (char)t_contiguous;
476
insert_contblock(p+n, PAGESIZE*m - n);
481
insert_contblock(p, s)
485
struct contblock **cbpp, *cbp;
490
cbp = (struct contblock *)p;
492
for (cbpp = &cb_pointer; *cbpp; cbpp = &((*cbpp)->cb_link))
493
if ((*cbpp)->cb_size >= s) {
494
cbp->cb_link = *cbpp;
512
printf("allocating %d-byte relocatable block...\n", n);
521
if (rb_limit - rb_pointer < n) {
522
if (!g && in_signal_handler == 0) {
525
{ float f1 = (float)(rb_limit - rb_pointer),
526
f2 = (float)(rb_limit - rb_start);
528
if ((float)f1 < PERCENT_FREE(tm_of(t_relocatable)) * f2)
531
{ call_after_gbc_hook(t_relocatable);
535
if (IGNORE_MAX_PAGES)
536
{struct typemanager *tm = &tm_table[(int)t_relocatable];
537
nrbpage=grow_linear(i=nrbpage,tm->tm_growth_percent,
538
tm->tm_min_grow, tm->tm_max_grow);
539
if (available_pages < 0)
542
rb_end += (PAGESIZE* (nrbpage -i));
543
rb_limit = rb_end - 2*RB_GETA;
544
if (page(rb_end) - page(heap_end) !=
546
FEerror("bad rb_end",0);
547
alloc_page(-( nrbpage + holepage));
549
call_after_gbc_hook(t_relocatable);
553
if (rb_limit > rb_end - 2*RB_GETA)
554
error("relocatable blocks exhausted");
556
vs_push(make_fixnum(nrbpage));
557
CEerror("Relocatable blocks exhausted.~%\
558
Currently, ~D pages are allocated.~%\
559
Use ALLOCATE-RELOCATABLE-PAGES to expand the space.",
560
"Continues execution.", 1, vs_head);
563
call_after_gbc_hook(t_relocatable);
571
init_tm(t, name, elsize, nelts,sgc)
578
/* round up to next number of pages */
579
maxpage = (((nelts * elsize) + PAGESIZE -1)/PAGESIZE);
580
tm_table[(int)t].tm_name = name;
581
for (j = -1, i = 0; i < (int)t_end; i++)
582
if (tm_table[i].tm_size != 0 &&
583
tm_table[i].tm_size >= elsize &&
584
(j < 0 || tm_table[j].tm_size > tm_table[i].tm_size))
587
tm_table[(int)t].tm_type = (enum type)j;
588
tm_table[j].tm_maxpage += maxpage;
590
tm_table[j].tm_sgc += sgc;
594
tm_table[(int)t].tm_type = t;
595
tm_table[(int)t].tm_size = ROUND_UP_PTR(elsize);
596
tm_table[(int)t].tm_nppage = PAGESIZE/ROUND_UP_PTR(elsize);
597
tm_table[(int)t].tm_free = OBJNULL;
598
tm_table[(int)t].tm_nfree = 0;
599
tm_table[(int)t].tm_nused = 0;
600
/*tm_table[(int)t].tm_npage = 0; */ /* dont zero nrbpage.. */
601
tm_table[(int)t].tm_maxpage = maxpage;
602
tm_table[(int)t].tm_gbccount = 0;
604
tm_table[(int)t].tm_sgc = sgc;
605
tm_table[(int)t].tm_sgc_max = 3000;
606
tm_table[(int)t].tm_sgc_minfree = (int)
607
(0.4 * tm_table[(int)t].tm_nppage);
614
/* This is run in init. Various initializations including getting
617
page_multiple=getpagesize()/PAGESIZE;
618
if (page_multiple==0) error("PAGESIZE must be factor of getpagesize()");
621
if (~(-MAXPAGE) != MAXPAGE-1) error("MAXPAGE must be power of 2");
623
bzero(&sgc_type_map[ page(core_end)],MAXPAGE- page(core_end));
639
struct typemanager *tm;
645
if (initialized) return;
649
#ifndef DONT_NEED_MALLOC
652
extern object malloc_list;
654
enter_mark_origin(&malloc_list);
658
holepage = INIT_HOLEPAGE;
659
new_holepage = HOLEPAGE;
660
nrbpage = INIT_NRBPAGE;
665
/* Some versions of the Linux startup code are broken.
666
For these, the first call to sbrk() fails, but
667
subsequent calls are o.k.
669
if ( (int)sbrk(0) == -1 )
671
if ( (int)sbrk(0) == -1 )
673
fputs("FATAL Linux sbrk() error\n", stderr);
676
fputs("WARNING: Non-fatal Linux sbrk() error\n", stderr);
682
alloc_page(-(holepage + nrbpage));
684
rb_start = rb_pointer = heap_end + PAGESIZE*holepage;
685
rb_end = rb_start + PAGESIZE*nrbpage;
686
rb_limit = rb_end - 2*RB_GETA;
688
tm_table[(int)t_relocatable].tm_sgc = 50;
691
for (i = 0; i < MAXPAGE; i++)
692
type_map[i] = (char)t_other;
694
init_tm(t_fixnum, "NFIXNUM",
695
sizeof(struct fixnum_struct), 8192,20);
696
init_tm(t_cons, ".CONS", sizeof(struct cons), 65536 ,50 );
697
init_tm(t_structure, "SSTRUCTURE", sizeof(struct structure), 5461,0 );
698
init_tm(t_cfun, "fCFUN", sizeof(struct cfun), 4096,0 );
699
init_tm(t_sfun, "gSFUN", sizeof(struct sfun),409,0 );
700
init_tm(t_string, "\"STRING", sizeof(struct string), 5461,1 );
701
init_tm(t_array, "aARRAY", sizeof(struct array), 4681,1 );
702
init_tm(t_symbol, "|SYMBOL", sizeof(struct symbol), 3640,1 );
703
init_tm(t_bignum, "BBIGNUM", sizeof(struct bignum), 2730,0 );
704
init_tm(t_ratio, "RRATIONAL", sizeof(struct ratio), 170,0 );
705
init_tm(t_shortfloat, "FSHORT-FLOAT",
706
sizeof(struct shortfloat_struct), 256 ,1);
707
init_tm(t_longfloat, "LLONG-FLOAT",
708
sizeof(struct longfloat_struct), 170 ,0);
709
init_tm(t_complex, "CCOMPLEX", sizeof(struct complex), 170 ,0);
710
init_tm(t_character,"#CHARACTER",sizeof(struct character), 256 ,0);
711
init_tm(t_package, ":PACKAGE", sizeof(struct package), 2*PAGESIZE / sizeof(struct package),0);
712
init_tm(t_hashtable, "hHASH-TABLE", sizeof(struct hashtable), 78,0 );
713
init_tm(t_vector, "vVECTOR", sizeof(struct vector), 146 ,0);
714
init_tm(t_bitvector, "bBIT-VECTOR", sizeof(struct bitvector), 73 ,0);
715
init_tm(t_stream, "sSTREAM", sizeof(struct stream), 78 ,0);
716
init_tm(t_random, "$RANDOM-STATE", sizeof(struct random), 256 ,0);
717
init_tm(t_readtable, "rREADTABLE", sizeof(struct readtable), 256 ,0);
718
init_tm(t_pathname, "pPATHNAME", sizeof(struct pathname), 73 ,0);
719
init_tm(t_cclosure, "cCCLOSURE", sizeof(struct cclosure), 85 ,0);
720
init_tm(t_closure, "cCLOSURE", sizeof(struct cclosure), 85 ,0);
721
init_tm(t_vfun, "VVFUN", sizeof(struct vfun), 102 ,0);
722
init_tm(t_gfun, "gGFUN", sizeof(struct sfun), 0 ,0);
723
init_tm(t_afun, "AAFUN", sizeof(struct sfun), 0 ,0);
724
init_tm(t_cfdata, "cCFDATA", sizeof(struct cfdata), 102 ,0);
725
init_tm(t_spice, "!SPICE", sizeof(struct spice), 4096 ,0);
726
init_tm(t_relocatable, "%RELOCATABLE-BLOCKS", 1000,0,20);
727
init_tm(t_contiguous, "_CONTIGUOUS-BLOCKS", 1001,0,20);
728
tm_table[t_relocatable].tm_nppage = PAGESIZE;
729
tm_table[t_contiguous].tm_nppage = PAGESIZE;
738
DEFUN("STATICP",object,fSstaticp,SI,1,1,NONE,OO,OO,OO,OO,"Tell if the string or vector is static") (x)
740
{ RETURN1((inheap(x->ust.ust_self) ? sLt : sLnil));
745
FEerror("Can't get a type.", 0);
748
DEFUNO("ALLOCATE",object,fSallocate,SI
749
,2,3,NONE,OO,IO,OO,OO,siLallocate,"")(type,npages,va_alist)
753
{ int nargs=VFUN_NARGS;
756
struct typemanager *tm;
763
if (nargs>=3) really_do=va_arg(ap,object);else goto LDEFAULT3;
765
LDEFAULT3: really_do = Cnil;
766
LEND_VARARG: va_end(ap);}
770
CHECK_ARG_RANGE(2,3);
771
t= t_from_type(type);
773
FEerror("Allocate takes positive argument.", 1,
774
make_fixnum(npages));
776
if (tm->tm_npage > npages) {npages=tm->tm_npage;}
777
tm->tm_maxpage = npages;
778
if (really_do != Cnil &&
779
tm->tm_maxpage > tm->tm_npage)
784
if (t == t_contiguous)
785
FUNCALL(2,fSallocate_contiguous_pages(npages,really_do));
788
if (t==t_relocatable)
789
FUNCALL(2,fSallocate_relocatable_pages(npages,really_do));
792
if (available_pages < tm->tm_maxpage - tm->tm_npage ||
793
(pp = alloc_page(tm->tm_maxpage - tm->tm_npage)) == NULL) {
794
FEerror("Can't allocate ~D pages for ~A.", 2,
795
make_fixnum(npages), (make_simple_string(tm->tm_name+1)));
797
for (; tm->tm_npage < tm->tm_maxpage; pp += PAGESIZE)
798
add_page_to_freelist(pp,tm);}
808
check_type_or_symbol_string(&type);
809
for (i= (int)t_start ; i < (int)t_other ; i++)
810
{struct typemanager *tm = &tm_table[i];
812
0==strncmp((tm->tm_name)+1,type->st.st_self,type->st.st_fillp)
815
FEerror("Unrecognized type",0);
817
/* When sgc is enabled the TYPE should have at least MIN pages of sgc type,
818
and at most MAX of them. Each page should be FREE_PERCENT free
819
when the sgc is turned on. FREE_PERCENT is an integer between 0 and 100.
822
DEFUN("ALLOCATE-SGC",object,fSallocate_sgc,SI
823
,4,4,NONE,OO,II,II,OO,"")(type,min,max,free_percent)
825
int min,max,free_percent;
826
{int m,t=t_from_type(type);
827
struct typemanager *tm;
830
res= list(3,make_fixnum(tm->tm_sgc),
831
make_fixnum(tm->tm_sgc_max),
832
make_fixnum((100*tm->tm_sgc_minfree)/tm->tm_nppage));
834
if(min<0 || max< min || min > 3000 || free_percent < 0 || free_percent > 100)
838
tm->tm_sgc_minfree= (tm->tm_nppage *free_percent) /100;
843
/* Growth of TYPE will be by at least MIN pages and at most MAX pages.
844
It will try to grow PERCENT of the current pages.
846
DEFUN("ALLOCATE-GROWTH",object,fSallocate_growth,SI,5,5,NONE,OO,II,II,OO,"")
847
(type,min,max,percent,percent_free)
848
int min,max,percent,percent_free;
850
{int t=t_from_type(type);
851
struct typemanager *tm=tm_of(t);
853
res= list(4,make_fixnum(tm->tm_min_grow),
854
make_fixnum(tm->tm_max_grow),
855
make_fixnum(tm->tm_growth_percent),
856
make_fixnum(tm->tm_percent_free));
858
if(min<0 || max< min || min > 3000 || percent < 0 || percent > 500
859
|| percent_free <0 || percent_free > 100
864
tm->tm_growth_percent= percent;
865
tm->tm_percent_free= percent_free;
872
DEFUNO("ALLOCATE-CONTIGUOUS-PAGES",object,fSallocate_contiguous_pages,SI
873
,1,2,NONE,OI,OO,OO,OO,siLalloc_contpage,"")(npages,va_alist)
876
{ int nargs=VFUN_NARGS;
883
if (nargs>=2) really_do=va_arg(ap,object);else goto LDEFAULT2;
885
LDEFAULT2: really_do = Cnil ;
886
LEND_VARARG: va_end(ap);}
889
CHECK_ARG_RANGE(1,2);
891
FEerror("Allocate requires positive argument.", 0);
892
if (ncbpage > npages)
893
{ printf("Allocate contiguous %d: %d already there pages",npages,ncbpage);
896
if (really_do == Cnil) { RETURN1(Ct);}
897
m = maxcbpage - ncbpage;
898
if (available_pages < m || (p = alloc_page(m)) == NULL)
899
FEerror("Can't allocate ~D pages for contiguous blocks.",
900
1, make_fixnum(npages));
902
for (i = 0; i < m; i++)
903
type_map[page(p + PAGESIZE*i)] = (char)t_contiguous;
906
insert_contblock(p, PAGESIZE*m);
911
DEFUNO("ALLOCATED-CONTIGUOUS-PAGES",object,fSallocated_contiguous_pages,SI
912
,0,0,NONE,OO,OO,OO,OO,siLncbpage,"")()
915
RETURN1((make_fixnum(ncbpage)));
918
DEFUNO("MAXIMUM-CONTIGUOUS-PAGES",object,fSmaximum_contiguous_pages,SI
919
,0,0,NONE,OO,OO,OO,OO,siLmaxcbpage,"")()
922
RETURN1((make_fixnum(maxcbpage)));
926
DEFUNO("ALLOCATE-RELOCATABLE-PAGES",object,fSallocate_relocatable_pages,SI
927
,1,2,NONE,OI,OO,OO,OO,siLalloc_relpage,"")(npages,va_alist)
930
{ int nargs=VFUN_NARGS;
937
if (nargs>=2) really_do=va_arg(ap,object);else goto LDEFAULT2;
939
LDEFAULT2: really_do = Cnil ;
940
LEND_VARARG: va_end(ap);}
942
CHECK_ARG_RANGE(1,2);
944
FEerror("Requires positive arg",0);
945
if (nrbpage > npages && rb_pointer >= rb_start + PAGESIZE*npages - 2*RB_GETA
946
|| 2*npages > real_maxpage-page(heap_end)-new_holepage-real_maxpage/32)
947
FEerror("Can't set the limit for relocatable blocks to ~D.",
948
1, make_fixnum(npages));
949
rb_end += (npages-nrbpage)*PAGESIZE;
951
rb_limit = rb_end - 2*RB_GETA;
952
alloc_page(-(holepage + nrbpage));
955
RETURN1(make_fixnum(npages));
958
DEFUNO("ALLOCATED-RELOCATABLE-PAGES",object,fSallocated_relocatable_pages,SI
959
,0,0,NONE,OO,OO,OO,OO,siLnrbpage,"")()
962
RETURN1(make_fixnum(nrbpage));
965
DEFUNO("GET-HOLE-SIZE",object,fSget_hole_size,SI
966
,0,0,NONE,OO,OO,OO,OO,siLget_hole_size,"")()
969
RETURN1((make_fixnum(new_holepage)));
972
DEFUNO("SET-HOLE-SIZE",object,fSset_hole_size,SI
973
,1,2,NONE,OI,IO,OO,OO,siLset_hole_size,"")(npages,va_alist)
976
{ int nargs=VFUN_NARGS;
980
if (nargs>=2) reserve=va_arg(ap,int);else goto LDEFAULT2;
982
LDEFAULT2: reserve = 30;
983
LEND_VARARG: va_end(ap);}
986
npages > real_maxpage - page(heap_end)
987
- 2*nrbpage - real_maxpage/32)
988
FEerror("Illegal value for the hole size.", 0);
989
new_holepage = npages;
992
if (reserve <0 || reserve > new_holepage)
993
FEerror("Illegal value for the hole size.", 0);
994
reserve_pages_for_signal_handler = reserve;}
996
RETURN2(make_fixnum(npages),
997
make_fixnum(reserve_pages_for_signal_handler));
1001
init_alloc_function()
1007
#ifndef DONT_NEED_MALLOC
1010
UNIX malloc simulator.
1018
/* If this is defined, substitute the fast gnu malloc for the slower
1019
version below. If you have many calls to malloc this is worth
1020
your while. I have only tested it slightly under 4.3Bsd. There
1021
the difference in a test run with 120K mallocs and frees,
1022
was 29 seconds to 1.9 seconds */
1028
/* a very young malloc may use this simple baby malloc, for the init
1029
code before we even get to main.c. If this is not defined, then
1030
malloc will try to run the init code which will work on many machines
1031
but some such as WindowsNT under cygwin need this.
1034
#ifdef BABY_MALLOC_SIZE
1036
/* by giving an initialization, make it not be in bss, since
1037
bss may not get loaded until main is reached. We may
1038
not even know our own name at this stage. */
1039
static char baby_malloc_data[BABY_MALLOC_SIZE]={1,0};
1040
static char *last_baby= baby_malloc_data;
1042
static char *baby_malloc(n)
1045
char *res= last_baby;
1047
n = ROUND_UP_PTR(n);
1049
if ((res +m-baby_malloc_data) > sizeof(baby_malloc_data))
1051
printf("failed in baby malloc");
1056
return res+sizeof(int);
1064
/* configure size, static init ? */
1065
static char bfd_buf[/* 4392 */5000];
1066
static char *bfd_buf_p=bfd_buf;
1077
if (c+n>bfd_buf+sizeof(bfd_buf)) {
1078
fprintf(stderr,"Not enough space in bfd_buf %d %d\n",n,sizeof(bfd_buf)-(bfd_buf_p-bfd_buf));
1095
return bfd_malloc(size);
1098
#ifdef BABY_MALLOC_SIZE
1099
if (GBC_enable == 0) return baby_malloc(size);
1101
if (GBC_enable==0) {
1105
#ifdef RECREATE_HEAP
1115
x = alloc_simple_string(size);
1117
x->st.st_self = alloc_contblock(size);
1119
perm_writable(x->st.st_self,size);
1121
malloc_list = make_cons(x, malloc_list);
1123
return(x->st.st_self);
1129
#ifndef NO_VOID_STAR
1140
#ifdef BABY_MALLOC_SIZE
1141
if ((void *)ptr < (void *) &baby_malloc_data[sizeof(baby_malloc_data)])
1144
for (p = &malloc_list; *p && !endp(*p); p = &((*p)->c.c_cdr))
1145
if ((*p)->c.c_car->st.st_self == ptr) {
1146
insert_contblock((*p)->c.c_car->st.st_self,
1147
(*p)->c.c_car->st.st_dim);
1148
(*p)->c.c_car->st.st_self = NULL;
1155
FEerror("free(3) error.",0);
1168
/* was allocated by baby_malloc */
1169
#ifdef BABY_MALLOC_SIZE
1170
if (ptr >= baby_malloc_data && ptr -baby_malloc_data <BABY_MALLOC_SIZE)
1172
int dim = ((int *)ptr)[-1];
1176
{ char *new= malloc(size);
1182
#endif /* BABY_MALLOC_SIZE */
1185
if(ptr == NULL) return malloc(size);
1186
for (x = malloc_list; !endp(x); x = x->c.c_cdr)
1187
if (x->c.c_car->st.st_self == ptr) {
1189
if (x->st.st_dim >= size) {
1190
x->st.st_fillp = size;
1194
x->st.st_self = alloc_contblock(size);
1195
x->st.st_fillp = x->st.st_dim = size;
1196
for (i = 0; i < size; i++)
1197
x->st.st_self[i] = ptr[i];
1198
insert_contblock(ptr, j);
1199
return(x->st.st_self);
1202
FEerror("realloc(3) error.", 0);
1205
#endif /* gnumalloc */
1209
calloc(nelem, elsize)
1215
ptr = malloc(i = nelem*elsize);
1234
memalign(align,size)
1236
{ object x = alloc_simple_string(size);
1237
x->st.st_self = ALLOC_ALIGNED(alloc_contblock,size,align);
1238
malloc_list = make_cons(x, malloc_list);
1239
return x->st.st_self;
1245
{ return memalign(getpagesize(),size);}