51488
|
1
|
|
2
|
|
3 /******************************************************************
|
|
4
|
|
5 AmigaOS-spesific routines for GC.
|
|
6 This file is normally included from os_dep.c
|
|
7
|
|
8 ******************************************************************/
|
|
9
|
|
10
|
|
11 #if !defined(GC_AMIGA_DEF) && !defined(GC_AMIGA_SB) && !defined(GC_AMIGA_DS) && !defined(GC_AMIGA_AM)
|
|
12 # include "gc_priv.h"
|
|
13 # include <stdio.h>
|
|
14 # include <signal.h>
|
|
15 # define GC_AMIGA_DEF
|
|
16 # define GC_AMIGA_SB
|
|
17 # define GC_AMIGA_DS
|
|
18 # define GC_AMIGA_AM
|
|
19 #endif
|
|
20
|
|
21
|
|
22 #ifdef GC_AMIGA_DEF
|
|
23
|
|
24 # ifndef __GNUC__
|
|
25 # include <exec/exec.h>
|
|
26 # endif
|
|
27 # include <proto/exec.h>
|
|
28 # include <proto/dos.h>
|
|
29 # include <dos/dosextens.h>
|
|
30 # include <workbench/startup.h>
|
|
31
|
|
32 #endif
|
|
33
|
|
34
|
|
35
|
|
36
|
|
37 #ifdef GC_AMIGA_SB
|
|
38
|
|
39 /******************************************************************
|
|
40 Find the base of the stack.
|
|
41 ******************************************************************/
|
|
42
|
|
43 ptr_t GC_get_stack_base()
|
|
44 {
|
|
45 struct Process *proc = (struct Process*)SysBase->ThisTask;
|
|
46
|
|
47 /* Reference: Amiga Guru Book Pages: 42,567,574 */
|
|
48 if (proc->pr_Task.tc_Node.ln_Type==NT_PROCESS
|
|
49 && proc->pr_CLI != NULL) {
|
|
50 /* first ULONG is StackSize */
|
|
51 /*longPtr = proc->pr_ReturnAddr;
|
|
52 size = longPtr[0];*/
|
|
53
|
|
54 return (char *)proc->pr_ReturnAddr + sizeof(ULONG);
|
|
55 } else {
|
|
56 return (char *)proc->pr_Task.tc_SPUpper;
|
|
57 }
|
|
58 }
|
|
59
|
|
60 #if 0 /* old version */
|
|
61 ptr_t GC_get_stack_base()
|
|
62 {
|
|
63 extern struct WBStartup *_WBenchMsg;
|
|
64 extern long __base;
|
|
65 extern long __stack;
|
|
66 struct Task *task;
|
|
67 struct Process *proc;
|
|
68 struct CommandLineInterface *cli;
|
|
69 long size;
|
|
70
|
|
71 if ((task = FindTask(0)) == 0) {
|
|
72 GC_err_puts("Cannot find own task structure\n");
|
|
73 ABORT("task missing");
|
|
74 }
|
|
75 proc = (struct Process *)task;
|
|
76 cli = BADDR(proc->pr_CLI);
|
|
77
|
|
78 if (_WBenchMsg != 0 || cli == 0) {
|
|
79 size = (char *)task->tc_SPUpper - (char *)task->tc_SPLower;
|
|
80 } else {
|
|
81 size = cli->cli_DefaultStack * 4;
|
|
82 }
|
|
83 return (ptr_t)(__base + GC_max(size, __stack));
|
|
84 }
|
|
85 #endif
|
|
86
|
|
87
|
|
88 #endif
|
|
89
|
|
90
|
|
91 #ifdef GC_AMIGA_DS
|
|
92 /******************************************************************
|
|
93 Register data segments.
|
|
94 ******************************************************************/
|
|
95
|
|
96 void GC_register_data_segments()
|
|
97 {
|
|
98 struct Process *proc;
|
|
99 struct CommandLineInterface *cli;
|
|
100 BPTR myseglist;
|
|
101 ULONG *data;
|
|
102
|
|
103 int num;
|
|
104
|
|
105
|
|
106 # ifdef __GNUC__
|
|
107 ULONG dataSegSize;
|
|
108 GC_bool found_segment = FALSE;
|
|
109 extern char __data_size[];
|
|
110
|
|
111 dataSegSize=__data_size+8;
|
|
112 /* Can`t find the Location of __data_size, because
|
|
113 it`s possible that is it, inside the segment. */
|
|
114
|
|
115 # endif
|
|
116
|
|
117 proc= (struct Process*)SysBase->ThisTask;
|
|
118
|
|
119 /* Reference: Amiga Guru Book Pages: 538ff,565,573
|
|
120 and XOper.asm */
|
|
121 if (proc->pr_Task.tc_Node.ln_Type==NT_PROCESS) {
|
|
122 if (proc->pr_CLI == NULL) {
|
|
123 myseglist = proc->pr_SegList;
|
|
124 } else {
|
|
125 /* ProcLoaded 'Loaded as a command: '*/
|
|
126 cli = BADDR(proc->pr_CLI);
|
|
127 myseglist = cli->cli_Module;
|
|
128 }
|
|
129 } else {
|
|
130 ABORT("Not a Process.");
|
|
131 }
|
|
132
|
|
133 if (myseglist == NULL) {
|
|
134 ABORT("Arrrgh.. can't find segments, aborting");
|
|
135 }
|
|
136
|
|
137 /* xoper hunks Shell Process */
|
|
138
|
|
139 num=0;
|
|
140 for (data = (ULONG *)BADDR(myseglist); data != NULL;
|
|
141 data = (ULONG *)BADDR(data[0])) {
|
|
142 if (((ULONG) GC_register_data_segments < (ULONG) &data[1]) ||
|
|
143 ((ULONG) GC_register_data_segments > (ULONG) &data[1] + data[-1])) {
|
|
144 # ifdef __GNUC__
|
|
145 if (dataSegSize == data[-1]) {
|
|
146 found_segment = TRUE;
|
|
147 }
|
|
148 # endif
|
|
149 GC_add_roots_inner((char *)&data[1],
|
|
150 ((char *)&data[1]) + data[-1], FALSE);
|
|
151 }
|
|
152 ++num;
|
|
153 } /* for */
|
|
154 # ifdef __GNUC__
|
|
155 if (!found_segment) {
|
|
156 ABORT("Can`t find correct Segments.\nSolution: Use an newer version of ixemul.library");
|
|
157 }
|
|
158 # endif
|
|
159 }
|
|
160
|
|
161 #if 0 /* old version */
|
|
162 void GC_register_data_segments()
|
|
163 {
|
|
164 extern struct WBStartup *_WBenchMsg;
|
|
165 struct Process *proc;
|
|
166 struct CommandLineInterface *cli;
|
|
167 BPTR myseglist;
|
|
168 ULONG *data;
|
|
169
|
|
170 if ( _WBenchMsg != 0 ) {
|
|
171 if ((myseglist = _WBenchMsg->sm_Segment) == 0) {
|
|
172 GC_err_puts("No seglist from workbench\n");
|
|
173 return;
|
|
174 }
|
|
175 } else {
|
|
176 if ((proc = (struct Process *)FindTask(0)) == 0) {
|
|
177 GC_err_puts("Cannot find process structure\n");
|
|
178 return;
|
|
179 }
|
|
180 if ((cli = BADDR(proc->pr_CLI)) == 0) {
|
|
181 GC_err_puts("No CLI\n");
|
|
182 return;
|
|
183 }
|
|
184 if ((myseglist = cli->cli_Module) == 0) {
|
|
185 GC_err_puts("No seglist from CLI\n");
|
|
186 return;
|
|
187 }
|
|
188 }
|
|
189
|
|
190 for (data = (ULONG *)BADDR(myseglist); data != 0;
|
|
191 data = (ULONG *)BADDR(data[0])) {
|
|
192 # ifdef AMIGA_SKIP_SEG
|
|
193 if (((ULONG) GC_register_data_segments < (ULONG) &data[1]) ||
|
|
194 ((ULONG) GC_register_data_segments > (ULONG) &data[1] + data[-1])) {
|
|
195 # else
|
|
196 {
|
|
197 # endif /* AMIGA_SKIP_SEG */
|
|
198 GC_add_roots_inner((char *)&data[1],
|
|
199 ((char *)&data[1]) + data[-1], FALSE);
|
|
200 }
|
|
201 }
|
|
202 }
|
|
203 #endif /* old version */
|
|
204
|
|
205
|
|
206 #endif
|
|
207
|
|
208
|
|
209
|
|
210 #ifdef GC_AMIGA_AM
|
|
211
|
|
212 #ifndef GC_AMIGA_FASTALLOC
|
|
213
|
|
214 void *GC_amiga_allocwrapper(size_t size,void *(*AllocFunction)(size_t size2)){
|
|
215 return (*AllocFunction)(size);
|
|
216 }
|
|
217
|
|
218 void *(*GC_amiga_allocwrapper_do)(size_t size,void *(*AllocFunction)(size_t size2))
|
|
219 =GC_amiga_allocwrapper;
|
|
220
|
|
221 #else
|
|
222
|
|
223
|
|
224
|
|
225
|
|
226 void *GC_amiga_allocwrapper_firsttime(size_t size,void *(*AllocFunction)(size_t size2));
|
|
227
|
|
228 void *(*GC_amiga_allocwrapper_do)(size_t size,void *(*AllocFunction)(size_t size2))
|
|
229 =GC_amiga_allocwrapper_firsttime;
|
|
230
|
|
231
|
|
232 /******************************************************************
|
|
233 Amiga-spesific routines to obtain memory, and force GC to give
|
|
234 back fast-mem whenever possible.
|
|
235 These hacks makes gc-programs go many times faster when
|
|
236 the amiga is low on memory, and are therefore strictly necesarry.
|
|
237
|
|
238 -Kjetil S. Matheussen, 2000.
|
|
239 ******************************************************************/
|
|
240
|
|
241
|
|
242
|
|
243 /* List-header for all allocated memory. */
|
|
244
|
|
245 struct GC_Amiga_AllocedMemoryHeader{
|
|
246 ULONG size;
|
|
247 struct GC_Amiga_AllocedMemoryHeader *next;
|
|
248 };
|
|
249 struct GC_Amiga_AllocedMemoryHeader *GC_AMIGAMEM=(struct GC_Amiga_AllocedMemoryHeader *)(int)~(NULL);
|
|
250
|
|
251
|
|
252
|
|
253 /* Type of memory. Once in the execution of a program, this might change to MEMF_ANY|MEMF_CLEAR */
|
|
254
|
|
255 ULONG GC_AMIGA_MEMF = MEMF_FAST | MEMF_CLEAR;
|
|
256
|
|
257
|
|
258 /* Prevents GC_amiga_get_mem from allocating memory if this one is TRUE. */
|
|
259 #ifndef GC_AMIGA_ONLYFAST
|
|
260 BOOL GC_amiga_dontalloc=FALSE;
|
|
261 #endif
|
|
262
|
|
263 #ifdef GC_AMIGA_PRINTSTATS
|
|
264 int succ=0,succ2=0;
|
|
265 int nsucc=0,nsucc2=0;
|
|
266 int nullretries=0;
|
|
267 int numcollects=0;
|
|
268 int chipa=0;
|
|
269 int allochip=0;
|
|
270 int allocfast=0;
|
|
271 int cur0=0;
|
|
272 int cur1=0;
|
|
273 int cur10=0;
|
|
274 int cur50=0;
|
|
275 int cur150=0;
|
|
276 int cur151=0;
|
|
277 int ncur0=0;
|
|
278 int ncur1=0;
|
|
279 int ncur10=0;
|
|
280 int ncur50=0;
|
|
281 int ncur150=0;
|
|
282 int ncur151=0;
|
|
283 #endif
|
|
284
|
|
285 /* Free everything at program-end. */
|
|
286
|
|
287 void GC_amiga_free_all_mem(void){
|
|
288 struct GC_Amiga_AllocedMemoryHeader *gc_am=(struct GC_Amiga_AllocedMemoryHeader *)(~(int)(GC_AMIGAMEM));
|
|
289 struct GC_Amiga_AllocedMemoryHeader *temp;
|
|
290
|
|
291 #ifdef GC_AMIGA_PRINTSTATS
|
|
292 printf("\n\n"
|
|
293 "%d bytes of chip-mem, and %d bytes of fast-mem where allocated from the OS.\n",
|
|
294 allochip,allocfast
|
|
295 );
|
|
296 printf(
|
|
297 "%d bytes of chip-mem were returned from the GC_AMIGA_FASTALLOC supported allocating functions.\n",
|
|
298 chipa
|
|
299 );
|
|
300 printf("\n");
|
|
301 printf("GC_gcollect was called %d times to avoid returning NULL or start allocating with the MEMF_ANY flag.\n",numcollects);
|
|
302 printf("%d of them was a success. (the others had to use allocation from the OS.)\n",nullretries);
|
|
303 printf("\n");
|
|
304 printf("Succeded forcing %d gc-allocations (%d bytes) of chip-mem to be fast-mem.\n",succ,succ2);
|
|
305 printf("Failed forcing %d gc-allocations (%d bytes) of chip-mem to be fast-mem.\n",nsucc,nsucc2);
|
|
306 printf("\n");
|
|
307 printf(
|
|
308 "Number of retries before succeding a chip->fast force:\n"
|
|
309 "0: %d, 1: %d, 2-9: %d, 10-49: %d, 50-149: %d, >150: %d\n",
|
|
310 cur0,cur1,cur10,cur50,cur150,cur151
|
|
311 );
|
|
312 printf(
|
|
313 "Number of retries before giving up a chip->fast force:\n"
|
|
314 "0: %d, 1: %d, 2-9: %d, 10-49: %d, 50-149: %d, >150: %d\n",
|
|
315 ncur0,ncur1,ncur10,ncur50,ncur150,ncur151
|
|
316 );
|
|
317 #endif
|
|
318
|
|
319 while(gc_am!=NULL){
|
|
320 temp=gc_am->next;
|
|
321 FreeMem(gc_am,gc_am->size);
|
|
322 gc_am=(struct GC_Amiga_AllocedMemoryHeader *)(~(int)(temp));
|
|
323 }
|
|
324 }
|
|
325
|
|
326 #ifndef GC_AMIGA_ONLYFAST
|
|
327
|
|
328 /* All memory with address lower than this one is chip-mem. */
|
|
329
|
|
330 char *chipmax;
|
|
331
|
|
332
|
|
333 /*
|
|
334 * Allways set to the last size of memory tried to be allocated.
|
|
335 * Needed to ensure allocation when the size is bigger than 100000.
|
|
336 *
|
|
337 */
|
|
338 size_t latestsize;
|
|
339
|
|
340 #endif
|
|
341
|
|
342
|
|
343 /*
|
|
344 * The actual function that is called with the GET_MEM macro.
|
|
345 *
|
|
346 */
|
|
347
|
|
348 void *GC_amiga_get_mem(size_t size){
|
|
349 struct GC_Amiga_AllocedMemoryHeader *gc_am;
|
|
350
|
|
351 #ifndef GC_AMIGA_ONLYFAST
|
|
352 if(GC_amiga_dontalloc==TRUE){
|
|
353 // printf("rejected, size: %d, latestsize: %d\n",size,latestsize);
|
|
354 return NULL;
|
|
355 }
|
|
356
|
|
357 // We really don't want to use chip-mem, but if we must, then as little as possible.
|
|
358 if(GC_AMIGA_MEMF==(MEMF_ANY|MEMF_CLEAR) && size>100000 && latestsize<50000) return NULL;
|
|
359 #endif
|
|
360
|
|
361 gc_am=AllocMem((ULONG)(size + sizeof(struct GC_Amiga_AllocedMemoryHeader)),GC_AMIGA_MEMF);
|
|
362 if(gc_am==NULL) return NULL;
|
|
363
|
|
364 gc_am->next=GC_AMIGAMEM;
|
|
365 gc_am->size=size + sizeof(struct GC_Amiga_AllocedMemoryHeader);
|
|
366 GC_AMIGAMEM=(struct GC_Amiga_AllocedMemoryHeader *)(~(int)(gc_am));
|
|
367
|
|
368 // printf("Allocated %d (%d) bytes at address: %x. Latest: %d\n",size,tot,gc_am,latestsize);
|
|
369
|
|
370 #ifdef GC_AMIGA_PRINTSTATS
|
|
371 if((char *)gc_am<chipmax){
|
|
372 allochip+=size;
|
|
373 }else{
|
|
374 allocfast+=size;
|
|
375 }
|
|
376 #endif
|
|
377
|
|
378 return gc_am+1;
|
|
379
|
|
380 }
|
|
381
|
|
382
|
|
383
|
|
384
|
|
385 #ifndef GC_AMIGA_ONLYFAST
|
|
386
|
|
387 /* Tries very hard to force GC to find fast-mem to return. Done recursively
|
|
388 * to hold the rejected memory-pointers reachable from the collector in an
|
|
389 * easy way.
|
|
390 *
|
|
391 */
|
|
392 #ifdef GC_AMIGA_RETRY
|
|
393 void *GC_amiga_rec_alloc(size_t size,void *(*AllocFunction)(size_t size2),const int rec){
|
|
394 void *ret;
|
|
395
|
|
396 ret=(*AllocFunction)(size);
|
|
397
|
|
398 #ifdef GC_AMIGA_PRINTSTATS
|
|
399 if((char *)ret>chipmax || ret==NULL){
|
|
400 if(ret==NULL){
|
|
401 nsucc++;
|
|
402 nsucc2+=size;
|
|
403 if(rec==0) ncur0++;
|
|
404 if(rec==1) ncur1++;
|
|
405 if(rec>1 && rec<10) ncur10++;
|
|
406 if(rec>=10 && rec<50) ncur50++;
|
|
407 if(rec>=50 && rec<150) ncur150++;
|
|
408 if(rec>=150) ncur151++;
|
|
409 }else{
|
|
410 succ++;
|
|
411 succ2+=size;
|
|
412 if(rec==0) cur0++;
|
|
413 if(rec==1) cur1++;
|
|
414 if(rec>1 && rec<10) cur10++;
|
|
415 if(rec>=10 && rec<50) cur50++;
|
|
416 if(rec>=50 && rec<150) cur150++;
|
|
417 if(rec>=150) cur151++;
|
|
418 }
|
|
419 }
|
|
420 #endif
|
|
421
|
|
422 if (((char *)ret)<=chipmax && ret!=NULL && (rec<(size>500000?9:size/5000))){
|
|
423 ret=GC_amiga_rec_alloc(size,AllocFunction,rec+1);
|
|
424 // GC_free(ret2);
|
|
425 }
|
|
426
|
|
427 return ret;
|
|
428 }
|
|
429 #endif
|
|
430
|
|
431
|
|
432 /* The allocating-functions defined inside the amiga-blocks in gc.h is called
|
|
433 * via these functions.
|
|
434 */
|
|
435
|
|
436
|
|
437 void *GC_amiga_allocwrapper_any(size_t size,void *(*AllocFunction)(size_t size2)){
|
|
438 void *ret,*ret2;
|
|
439
|
|
440 GC_amiga_dontalloc=TRUE; // Pretty tough thing to do, but its indeed necesarry.
|
|
441 latestsize=size;
|
|
442
|
|
443 ret=(*AllocFunction)(size);
|
|
444
|
|
445 if(((char *)ret) <= chipmax){
|
|
446 if(ret==NULL){
|
|
447 //Give GC access to allocate memory.
|
|
448 #ifdef GC_AMIGA_GC
|
|
449 if(!GC_dont_gc){
|
|
450 GC_gcollect();
|
|
451 #ifdef GC_AMIGA_PRINTSTATS
|
|
452 numcollects++;
|
|
453 #endif
|
|
454 ret=(*AllocFunction)(size);
|
|
455 }
|
|
456 #endif
|
|
457 if(ret==NULL){
|
|
458 GC_amiga_dontalloc=FALSE;
|
|
459 ret=(*AllocFunction)(size);
|
|
460 if(ret==NULL){
|
|
461 WARN("Out of Memory! Returning NIL!\n", 0);
|
|
462 }
|
|
463 }
|
|
464 #ifdef GC_AMIGA_PRINTSTATS
|
|
465 else{
|
|
466 nullretries++;
|
|
467 }
|
|
468 if(ret!=NULL && (char *)ret<=chipmax) chipa+=size;
|
|
469 #endif
|
|
470 }
|
|
471 #ifdef GC_AMIGA_RETRY
|
|
472 else{
|
|
473 /* We got chip-mem. Better try again and again and again etc., we might get fast-mem sooner or later... */
|
|
474 /* Using gctest to check the effectiviness of doing this, does seldom give a very good result. */
|
|
475 /* However, real programs doesn't normally rapidly allocate and deallocate. */
|
|
476 // printf("trying to force... %d bytes... ",size);
|
|
477 if(
|
|
478 AllocFunction!=GC_malloc_uncollectable
|
|
479 #ifdef ATOMIC_UNCOLLECTABLE
|
|
480 && AllocFunction!=GC_malloc_atomic_uncollectable
|
|
481 #endif
|
|
482 ){
|
|
483 ret2=GC_amiga_rec_alloc(size,AllocFunction,0);
|
|
484 }else{
|
|
485 ret2=(*AllocFunction)(size);
|
|
486 #ifdef GC_AMIGA_PRINTSTATS
|
|
487 if((char *)ret2<chipmax || ret2==NULL){
|
|
488 nsucc++;
|
|
489 nsucc2+=size;
|
|
490 ncur0++;
|
|
491 }else{
|
|
492 succ++;
|
|
493 succ2+=size;
|
|
494 cur0++;
|
|
495 }
|
|
496 #endif
|
|
497 }
|
|
498 if(((char *)ret2)>chipmax){
|
|
499 // printf("Succeeded.\n");
|
|
500 GC_free(ret);
|
|
501 ret=ret2;
|
|
502 }else{
|
|
503 GC_free(ret2);
|
|
504 // printf("But did not succeed.\n");
|
|
505 }
|
|
506 }
|
|
507 #endif
|
|
508 }
|
|
509
|
|
510 GC_amiga_dontalloc=FALSE;
|
|
511
|
|
512 return ret;
|
|
513 }
|
|
514
|
|
515
|
|
516
|
|
517 void (*GC_amiga_toany)(void)=NULL;
|
|
518
|
|
519 void GC_amiga_set_toany(void (*func)(void)){
|
|
520 GC_amiga_toany=func;
|
|
521 }
|
|
522
|
|
523 #endif // !GC_AMIGA_ONLYFAST
|
|
524
|
|
525
|
|
526 void *GC_amiga_allocwrapper_fast(size_t size,void *(*AllocFunction)(size_t size2)){
|
|
527 void *ret;
|
|
528
|
|
529 ret=(*AllocFunction)(size);
|
|
530
|
|
531 if(ret==NULL){
|
|
532 // Enable chip-mem allocation.
|
|
533 // printf("ret==NULL\n");
|
|
534 #ifdef GC_AMIGA_GC
|
|
535 if(!GC_dont_gc){
|
|
536 GC_gcollect();
|
|
537 #ifdef GC_AMIGA_PRINTSTATS
|
|
538 numcollects++;
|
|
539 #endif
|
|
540 ret=(*AllocFunction)(size);
|
|
541 }
|
|
542 #endif
|
|
543 if(ret==NULL){
|
|
544 #ifndef GC_AMIGA_ONLYFAST
|
|
545 GC_AMIGA_MEMF=MEMF_ANY | MEMF_CLEAR;
|
|
546 if(GC_amiga_toany!=NULL) (*GC_amiga_toany)();
|
|
547 GC_amiga_allocwrapper_do=GC_amiga_allocwrapper_any;
|
|
548 return GC_amiga_allocwrapper_any(size,AllocFunction);
|
|
549 #endif
|
|
550 }
|
|
551 #ifdef GC_AMIGA_PRINTSTATS
|
|
552 else{
|
|
553 nullretries++;
|
|
554 }
|
|
555 #endif
|
|
556 }
|
|
557
|
|
558 return ret;
|
|
559 }
|
|
560
|
|
561 void *GC_amiga_allocwrapper_firsttime(size_t size,void *(*AllocFunction)(size_t size2)){
|
|
562 atexit(&GC_amiga_free_all_mem);
|
|
563 chipmax=(char *)SysBase->MaxLocMem; // For people still having SysBase in chip-mem, this might speed up a bit.
|
|
564 GC_amiga_allocwrapper_do=GC_amiga_allocwrapper_fast;
|
|
565 return GC_amiga_allocwrapper_fast(size,AllocFunction);
|
|
566 }
|
|
567
|
|
568
|
|
569 #endif //GC_AMIGA_FASTALLOC
|
|
570
|
|
571
|
|
572
|
|
573 /*
|
|
574 * The wrapped realloc function.
|
|
575 *
|
|
576 */
|
|
577 void *GC_amiga_realloc(void *old_object,size_t new_size_in_bytes){
|
|
578 #ifndef GC_AMIGA_FASTALLOC
|
|
579 return GC_realloc(old_object,new_size_in_bytes);
|
|
580 #else
|
|
581 void *ret;
|
|
582 latestsize=new_size_in_bytes;
|
|
583 ret=GC_realloc(old_object,new_size_in_bytes);
|
|
584 if(ret==NULL && GC_AMIGA_MEMF==(MEMF_FAST | MEMF_CLEAR)){
|
|
585 /* Out of fast-mem. */
|
|
586 #ifdef GC_AMIGA_GC
|
|
587 if(!GC_dont_gc){
|
|
588 GC_gcollect();
|
|
589 #ifdef GC_AMIGA_PRINTSTATS
|
|
590 numcollects++;
|
|
591 #endif
|
|
592 ret=GC_realloc(old_object,new_size_in_bytes);
|
|
593 }
|
|
594 #endif
|
|
595 if(ret==NULL){
|
|
596 #ifndef GC_AMIGA_ONLYFAST
|
|
597 GC_AMIGA_MEMF=MEMF_ANY | MEMF_CLEAR;
|
|
598 if(GC_amiga_toany!=NULL) (*GC_amiga_toany)();
|
|
599 GC_amiga_allocwrapper_do=GC_amiga_allocwrapper_any;
|
|
600 ret=GC_realloc(old_object,new_size_in_bytes);
|
|
601 #endif
|
|
602 }
|
|
603 #ifdef GC_AMIGA_PRINTSTATS
|
|
604 else{
|
|
605 nullretries++;
|
|
606 }
|
|
607 #endif
|
|
608 }
|
|
609 if(ret==NULL){
|
|
610 WARN("Out of Memory! Returning NIL!\n", 0);
|
|
611 }
|
|
612 #ifdef GC_AMIGA_PRINTSTATS
|
|
613 if(((char *)ret)<chipmax && ret!=NULL){
|
|
614 chipa+=new_size_in_bytes;
|
|
615 }
|
|
616 #endif
|
|
617 return ret;
|
|
618 #endif
|
|
619 }
|
|
620
|
|
621 #endif //GC_AMIGA_AM
|
|
622
|
|
623
|