⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 amigaos.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
字号:
/******************************************************************  AmigaOS-spesific routines for GC.  This file is normally included from os_dep.c******************************************************************/#if !defined(GC_AMIGA_DEF) && !defined(GC_AMIGA_SB) && !defined(GC_AMIGA_DS) && !defined(GC_AMIGA_AM)# include "gc_priv.h"# include <stdio.h># include <signal.h># define GC_AMIGA_DEF# define GC_AMIGA_SB# define GC_AMIGA_DS# define GC_AMIGA_AM#endif#ifdef GC_AMIGA_DEF# ifndef __GNUC__#   include <exec/exec.h># endif# include <proto/exec.h># include <proto/dos.h># include <dos/dosextens.h># include <workbench/startup.h>#endif#ifdef GC_AMIGA_SB/******************************************************************   Find the base of the stack.******************************************************************/ptr_t GC_get_stack_base(){    struct Process *proc = (struct Process*)SysBase->ThisTask;     /* Reference: Amiga Guru Book Pages: 42,567,574 */    if (proc->pr_Task.tc_Node.ln_Type==NT_PROCESS        && proc->pr_CLI != NULL) {	/* first ULONG is StackSize */	/*longPtr = proc->pr_ReturnAddr;	size = longPtr[0];*/	return (char *)proc->pr_ReturnAddr + sizeof(ULONG);    } else {	return (char *)proc->pr_Task.tc_SPUpper;    }}#if 0 /* old version */ptr_t GC_get_stack_base(){    extern struct WBStartup *_WBenchMsg;    extern long __base;    extern long __stack;    struct Task *task;    struct Process *proc;    struct CommandLineInterface *cli;    long size;    if ((task = FindTask(0)) == 0) {	GC_err_puts("Cannot find own task structure\n");	ABORT("task missing");    }    proc = (struct Process *)task;    cli = BADDR(proc->pr_CLI);    if (_WBenchMsg != 0 || cli == 0) {	size = (char *)task->tc_SPUpper - (char *)task->tc_SPLower;    } else {	size = cli->cli_DefaultStack * 4;    }    return (ptr_t)(__base + GC_max(size, __stack));}#endif#endif#ifdef GC_AMIGA_DS/******************************************************************   Register data segments.******************************************************************/   void GC_register_data_segments()   {     struct Process	*proc;     struct CommandLineInterface *cli;     BPTR myseglist;     ULONG *data;      int	num;#    ifdef __GNUC__        ULONG dataSegSize;        GC_bool found_segment = FALSE;	extern char __data_size[];	dataSegSize=__data_size+8;	/* Can`t find the Location of __data_size, because           it`s possible that is it, inside the segment. */#     endif	proc= (struct Process*)SysBase->ThisTask;	/* Reference: Amiga Guru Book Pages: 538ff,565,573		     and XOper.asm */	if (proc->pr_Task.tc_Node.ln_Type==NT_PROCESS) {	  if (proc->pr_CLI == NULL) {	    myseglist = proc->pr_SegList;	  } else {	    /* ProcLoaded	'Loaded as a command: '*/	    cli = BADDR(proc->pr_CLI);	    myseglist = cli->cli_Module;	  }	} else {	  ABORT("Not a Process."); 	}	if (myseglist == NULL) {	    ABORT("Arrrgh.. can't find segments, aborting"); 	}	/* xoper hunks Shell Process */	num=0;        for (data = (ULONG *)BADDR(myseglist); data != NULL;             data = (ULONG *)BADDR(data[0])) {	  if (((ULONG) GC_register_data_segments < (ULONG) &data[1]) ||	      ((ULONG) GC_register_data_segments > (ULONG) &data[1] + data[-1])) {#             ifdef __GNUC__		if (dataSegSize == data[-1]) {		  found_segment = TRUE;		}# 	      endif	      GC_add_roots_inner((char *)&data[1],				 ((char *)&data[1]) + data[-1], FALSE);          }          ++num;        } /* for */# 	ifdef __GNUC__	   if (!found_segment) {	     ABORT("Can`t find correct Segments.\nSolution: Use an newer version of ixemul.library");	   }# 	endif  }#if 0 /* old version */  void GC_register_data_segments()  {    extern struct WBStartup *_WBenchMsg;    struct Process	*proc;    struct CommandLineInterface *cli;    BPTR myseglist;    ULONG *data;    if ( _WBenchMsg != 0 ) {	if ((myseglist = _WBenchMsg->sm_Segment) == 0) {	    GC_err_puts("No seglist from workbench\n");	    return;	}    } else {	if ((proc = (struct Process *)FindTask(0)) == 0) {	    GC_err_puts("Cannot find process structure\n");	    return;	}	if ((cli = BADDR(proc->pr_CLI)) == 0) {	    GC_err_puts("No CLI\n");	    return;	}	if ((myseglist = cli->cli_Module) == 0) {	    GC_err_puts("No seglist from CLI\n");	    return;	}    }    for (data = (ULONG *)BADDR(myseglist); data != 0;         data = (ULONG *)BADDR(data[0])) {#        ifdef AMIGA_SKIP_SEG           if (((ULONG) GC_register_data_segments < (ULONG) &data[1]) ||           ((ULONG) GC_register_data_segments > (ULONG) &data[1] + data[-1])) {#	 else      	   {#	 endif /* AMIGA_SKIP_SEG */          GC_add_roots_inner((char *)&data[1],          		     ((char *)&data[1]) + data[-1], FALSE);         }    }  }#endif /* old version */#endif#ifdef GC_AMIGA_AM#ifndef GC_AMIGA_FASTALLOCvoid *GC_amiga_allocwrapper(size_t size,void *(*AllocFunction)(size_t size2)){	return (*AllocFunction)(size);}void *(*GC_amiga_allocwrapper_do)(size_t size,void *(*AllocFunction)(size_t size2))	=GC_amiga_allocwrapper;#elsevoid *GC_amiga_allocwrapper_firsttime(size_t size,void *(*AllocFunction)(size_t size2));void *(*GC_amiga_allocwrapper_do)(size_t size,void *(*AllocFunction)(size_t size2))	=GC_amiga_allocwrapper_firsttime;/******************************************************************   Amiga-spesific routines to obtain memory, and force GC to give   back fast-mem whenever possible.	These hacks makes gc-programs go many times faster when   the amiga is low on memory, and are therefore strictly necesarry.   -Kjetil S. Matheussen, 2000.******************************************************************//* List-header for all allocated memory. */struct GC_Amiga_AllocedMemoryHeader{	ULONG size;	struct GC_Amiga_AllocedMemoryHeader *next;};struct GC_Amiga_AllocedMemoryHeader *GC_AMIGAMEM=(struct GC_Amiga_AllocedMemoryHeader *)(int)~(NULL);/* Type of memory. Once in the execution of a program, this might change to MEMF_ANY|MEMF_CLEAR */ULONG GC_AMIGA_MEMF = MEMF_FAST | MEMF_CLEAR;/* Prevents GC_amiga_get_mem from allocating memory if this one is TRUE. */#ifndef GC_AMIGA_ONLYFASTBOOL GC_amiga_dontalloc=FALSE;#endif#ifdef GC_AMIGA_PRINTSTATSint succ=0,succ2=0;int nsucc=0,nsucc2=0;int nullretries=0;int numcollects=0;int chipa=0;int allochip=0;int allocfast=0;int cur0=0;int cur1=0;int cur10=0;int cur50=0;int cur150=0;int cur151=0;int ncur0=0;int ncur1=0;int ncur10=0;int ncur50=0;int ncur150=0;int ncur151=0;#endif/* Free everything at program-end. */void GC_amiga_free_all_mem(void){	struct GC_Amiga_AllocedMemoryHeader *gc_am=(struct GC_Amiga_AllocedMemoryHeader *)(~(int)(GC_AMIGAMEM));	struct GC_Amiga_AllocedMemoryHeader *temp;#ifdef GC_AMIGA_PRINTSTATS	printf("\n\n"		"%d bytes of chip-mem, and %d bytes of fast-mem where allocated from the OS.\n",		allochip,allocfast	);	printf(		"%d bytes of chip-mem were returned from the GC_AMIGA_FASTALLOC supported allocating functions.\n",		chipa	);	printf("\n");	printf("GC_gcollect was called %d times to avoid returning NULL or start allocating with the MEMF_ANY flag.\n",numcollects);	printf("%d of them was a success. (the others had to use allocation from the OS.)\n",nullretries);	printf("\n");	printf("Succeded forcing %d gc-allocations (%d bytes) of chip-mem to be fast-mem.\n",succ,succ2);	printf("Failed forcing %d gc-allocations (%d bytes) of chip-mem to be fast-mem.\n",nsucc,nsucc2);	printf("\n");	printf(		"Number of retries before succeding a chip->fast force:\n"		"0: %d, 1: %d, 2-9: %d, 10-49: %d, 50-149: %d, >150: %d\n",		cur0,cur1,cur10,cur50,cur150,cur151	);	printf(		"Number of retries before giving up a chip->fast force:\n"		"0: %d, 1: %d, 2-9: %d, 10-49: %d, 50-149: %d, >150: %d\n",		ncur0,ncur1,ncur10,ncur50,ncur150,ncur151	);#endif	while(gc_am!=NULL){		temp=gc_am->next;		FreeMem(gc_am,gc_am->size);		gc_am=(struct GC_Amiga_AllocedMemoryHeader *)(~(int)(temp));	}}#ifndef GC_AMIGA_ONLYFAST/* All memory with address lower than this one is chip-mem. */char *chipmax;/* * Allways set to the last size of memory tried to be allocated. * Needed to ensure allocation when the size is bigger than 100000. * */size_t latestsize;#endif/* * The actual function that is called with the GET_MEM macro. * */void *GC_amiga_get_mem(size_t size){	struct GC_Amiga_AllocedMemoryHeader *gc_am;#ifndef GC_AMIGA_ONLYFAST	if(GC_amiga_dontalloc==TRUE){//		printf("rejected, size: %d, latestsize: %d\n",size,latestsize);		return NULL;	}	// We really don't want to use chip-mem, but if we must, then as little as possible.	if(GC_AMIGA_MEMF==(MEMF_ANY|MEMF_CLEAR) && size>100000 && latestsize<50000) return NULL;#endif	gc_am=AllocMem((ULONG)(size + sizeof(struct GC_Amiga_AllocedMemoryHeader)),GC_AMIGA_MEMF);	if(gc_am==NULL) return NULL;	gc_am->next=GC_AMIGAMEM;	gc_am->size=size + sizeof(struct GC_Amiga_AllocedMemoryHeader);	GC_AMIGAMEM=(struct GC_Amiga_AllocedMemoryHeader *)(~(int)(gc_am));//	printf("Allocated %d (%d) bytes at address: %x. Latest: %d\n",size,tot,gc_am,latestsize);#ifdef GC_AMIGA_PRINTSTATS	if((char *)gc_am<chipmax){		allochip+=size;	}else{		allocfast+=size;	}#endif	return gc_am+1;}#ifndef GC_AMIGA_ONLYFAST/* Tries very hard to force GC to find fast-mem to return. Done recursively * to hold the rejected memory-pointers reachable from the collector in an * easy way. * */#ifdef GC_AMIGA_RETRYvoid *GC_amiga_rec_alloc(size_t size,void *(*AllocFunction)(size_t size2),const int rec){	void *ret;	ret=(*AllocFunction)(size);#ifdef GC_AMIGA_PRINTSTATS	if((char *)ret>chipmax || ret==NULL){		if(ret==NULL){			nsucc++;			nsucc2+=size;			if(rec==0) ncur0++;			if(rec==1) ncur1++;			if(rec>1 && rec<10) ncur10++;			if(rec>=10 && rec<50) ncur50++;			if(rec>=50 && rec<150) ncur150++;			if(rec>=150) ncur151++;		}else{			succ++;			succ2+=size;			if(rec==0) cur0++;			if(rec==1) cur1++;			if(rec>1 && rec<10) cur10++;			if(rec>=10 && rec<50) cur50++;			if(rec>=50 && rec<150) cur150++;			if(rec>=150) cur151++;		}	}#endif	if (((char *)ret)<=chipmax && ret!=NULL && (rec<(size>500000?9:size/5000))){		ret=GC_amiga_rec_alloc(size,AllocFunction,rec+1);//		GC_free(ret2);	}	return ret;}#endif/* The allocating-functions defined inside the amiga-blocks in gc.h is called * via these functions. */void *GC_amiga_allocwrapper_any(size_t size,void *(*AllocFunction)(size_t size2)){	void *ret,*ret2;	GC_amiga_dontalloc=TRUE;	// Pretty tough thing to do, but its indeed necesarry.	latestsize=size;	ret=(*AllocFunction)(size);	if(((char *)ret) <= chipmax){		if(ret==NULL){			//Give GC access to allocate memory.#ifdef GC_AMIGA_GC			if(!GC_dont_gc){				GC_gcollect();#ifdef GC_AMIGA_PRINTSTATS				numcollects++;#endif				ret=(*AllocFunction)(size);			}#endif			if(ret==NULL){				GC_amiga_dontalloc=FALSE;				ret=(*AllocFunction)(size);				if(ret==NULL){					WARN("Out of Memory!  Returning NIL!\n", 0);				}			}#ifdef GC_AMIGA_PRINTSTATS			else{				nullretries++;			}			if(ret!=NULL && (char *)ret<=chipmax) chipa+=size;#endif		}#ifdef GC_AMIGA_RETRY		else{			/* We got chip-mem. Better try again and again and again etc., we might get fast-mem sooner or later... */			/* Using gctest to check the effectiviness of doing this, does seldom give a very good result. */			/* However, real programs doesn't normally rapidly allocate and deallocate. *///			printf("trying to force... %d bytes... ",size);			if(				AllocFunction!=GC_malloc_uncollectable#ifdef ATOMIC_UNCOLLECTABLE				&& AllocFunction!=GC_malloc_atomic_uncollectable#endif			){				ret2=GC_amiga_rec_alloc(size,AllocFunction,0);			}else{				ret2=(*AllocFunction)(size);#ifdef GC_AMIGA_PRINTSTATS				if((char *)ret2<chipmax || ret2==NULL){					nsucc++;					nsucc2+=size;					ncur0++;				}else{					succ++;					succ2+=size;					cur0++;				}#endif			}			if(((char *)ret2)>chipmax){//				printf("Succeeded.\n");				GC_free(ret);				ret=ret2;			}else{				GC_free(ret2);//				printf("But did not succeed.\n");			}		}#endif	}	GC_amiga_dontalloc=FALSE;	return ret;}void (*GC_amiga_toany)(void)=NULL;void GC_amiga_set_toany(void (*func)(void)){	GC_amiga_toany=func;}#endif // !GC_AMIGA_ONLYFASTvoid *GC_amiga_allocwrapper_fast(size_t size,void *(*AllocFunction)(size_t size2)){	void *ret;	ret=(*AllocFunction)(size);	if(ret==NULL){		// Enable chip-mem allocation.//		printf("ret==NULL\n");#ifdef GC_AMIGA_GC		if(!GC_dont_gc){			GC_gcollect();#ifdef GC_AMIGA_PRINTSTATS			numcollects++;#endif			ret=(*AllocFunction)(size);		}#endif		if(ret==NULL){#ifndef GC_AMIGA_ONLYFAST			GC_AMIGA_MEMF=MEMF_ANY | MEMF_CLEAR;			if(GC_amiga_toany!=NULL) (*GC_amiga_toany)();			GC_amiga_allocwrapper_do=GC_amiga_allocwrapper_any;			return GC_amiga_allocwrapper_any(size,AllocFunction);#endif		}#ifdef GC_AMIGA_PRINTSTATS		else{			nullretries++;		}#endif	}	return ret;}void *GC_amiga_allocwrapper_firsttime(size_t size,void *(*AllocFunction)(size_t size2)){	atexit(&GC_amiga_free_all_mem);	chipmax=(char *)SysBase->MaxLocMem;		// For people still having SysBase in chip-mem, this might speed up a bit.	GC_amiga_allocwrapper_do=GC_amiga_allocwrapper_fast;	return GC_amiga_allocwrapper_fast(size,AllocFunction);}#endif //GC_AMIGA_FASTALLOC/* * The wrapped realloc function. * */void *GC_amiga_realloc(void *old_object,size_t new_size_in_bytes){#ifndef GC_AMIGA_FASTALLOC	return GC_realloc(old_object,new_size_in_bytes);#else	void *ret;	latestsize=new_size_in_bytes;	ret=GC_realloc(old_object,new_size_in_bytes);	if(ret==NULL && GC_AMIGA_MEMF==(MEMF_FAST | MEMF_CLEAR)){		/* Out of fast-mem. */#ifdef GC_AMIGA_GC		if(!GC_dont_gc){			GC_gcollect();#ifdef GC_AMIGA_PRINTSTATS			numcollects++;#endif			ret=GC_realloc(old_object,new_size_in_bytes);		}#endif		if(ret==NULL){#ifndef GC_AMIGA_ONLYFAST			GC_AMIGA_MEMF=MEMF_ANY | MEMF_CLEAR;			if(GC_amiga_toany!=NULL) (*GC_amiga_toany)();			GC_amiga_allocwrapper_do=GC_amiga_allocwrapper_any;			ret=GC_realloc(old_object,new_size_in_bytes);#endif		}#ifdef GC_AMIGA_PRINTSTATS		else{			nullretries++;		}#endif	}	if(ret==NULL){		WARN("Out of Memory!  Returning NIL!\n", 0);	}#ifdef GC_AMIGA_PRINTSTATS	if(((char *)ret)<chipmax && ret!=NULL){		chipa+=new_size_in_bytes;	}#endif	return ret;#endif}#endif //GC_AMIGA_AM

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -