123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- Kjetil S. Matheussen's notes (28-11-2000)
- Compiles under SAS/C again. Should also still compile under other
- Amiga compilers without big changes. I haven't checked if it still
- works under gcc, because I don't have gcc for Amiga. But I have
- updated Makefile.direct, and hope it compiles fine.
- WHATS NEW:
- 1.
- Made a pretty big effort in preventing GC allocating-functions from
- returning chip-mem.
- The lower part of the new file AmigaOS.c does this in various ways, mainly by
- wrapping GC_malloc, GC_malloc_atomic, GC_malloc_uncollectable,
- GC_malloc_atomic_uncollectable, GC_malloc_ignore_off_page
- and GC_malloc_atomic_ignore_off_page. GC_realloc is also wrapped, but
- doesn't do the same effort in preventing to return chip-mem.
- Other allocating-functions (e.g., GC_*_typed) can probably be
- used without any problems, but beware that the warn hook will not be called.
- In case of problems, don't define GC_AMIGA_FASTALLOC.
- Programs using more time actually using the memory allocated
- (instead of just allocate and free rapidly) have
- the most to earn on this, but even gctest now normally runs twice
- as fast and uses less memory, on my poor 8 MB machine.
- The changes have only effect when there is no more
- fast-mem left. But with the way GC works, it
- could happen quite often. Beware that an atexit handler had to be added,
- so using the abort() function will make a big memory-loss.
- If you absolutely must call abort() instead of exit(), try calling
- the GC_amiga_free_all_mem function before abort().
- New Amiga-specific compilation flags:
- GC_AMIGA_FASTALLOC - By NOT defining this option, GC will work like before,
- it will not try to force fast-mem out of the OS, and
- it will use normal calloc for allocation, and the rest
- of the following flags will have no effect.
- GC_AMIGA_ONLYFAST - Makes GC never to return chip-mem. GC_AMIGA_RETRY have
- no effect if this flag is set.
- GC_AMIGA_GC - If gc returns NULL, do a GC_gcollect, and try again. This
- usually is a success with the standard GC configuration.
- It is also the most important flag to set to prevent
- GC from returning chip-mem. Beware that it slows down a lot
- when a program is rapidly allocating/deallocating when
- there's either very little fast-memory left or very little
- chip-memory left. Its not a very common situation, but gctest
- sometimes (very rare) use many minutes because of this.
- GC_AMIGA_RETRY - If gc succeed allocating memory, but it is chip-mem,
- try again and see if it is fast-mem. Most of the time,
- it will actually return fast-mem for the second try.
- I have set max number of retries to 9 or size/5000. You
- can change this if you like. (see GC_amiga_rec_alloc())
- GC_AMIGA_PRINTSTATS - Gather some statistics during the execution of a
- program, and prints out the info when the atexit-handler
- is called.
- My recommendation is to set all this flags, except GC_AMIGA_PRINTSTATS and
- GC_AMIGA_ONLYFAST.
- If your program demands high response-time, you should
- not define GC_AMIGA_GC, and possible also define GC_AMIGA_ONLYFAST.
- GC_AMIGA_RETRY does not seem to slow down much.
- Also, when compiling up programs, and GC_AMIGA_FASTALLOC was not defined when
- compiling gc, you can define GC_AMIGA_MAKINGLIB to avoid having these allocation-
- functions wrapped. (see gc.h)
- Note that GC_realloc must not be called before any of
- the other above mentioned allocating-functions have been called. (shouldn't be
- any programs doing so either, I hope).
- Another note. The allocation-function is wrapped when defining
- GC_AMIGA_FASTALLOC by letting the function go thru the new
- GC_amiga_allocwrapper_do function-pointer (see gc.h). Means that
- sending function-pointers, such as GC_malloc, GC_malloc_atomic, etc.,
- for later to be called, e.g., like this, (*GC_malloc_function_pointer)(size),
- will not wrap the function. This is normally not a big problem, unless
- all allocation function is called like this, which will cause the
- atexit un-allocating function never to be called. Then you either
- have to manually add the atexit handler, or call the allocation-
- functions function-pointer functions like this;
- (*GC_amiga_allocwrapper_do)(size,GC_malloc_function_pointer).
- There are probably better ways this problem could be handled, unfortunately,
- I didn't find any without rewriting or replacing a lot of the GC-code, which
- I really didn't want to. (Making new GC_malloc_* functions, and just
- defining, e.g., GC_malloc as GC_amiga_malloc should work too).
- New Amiga-specific function:
- void GC_amiga_set_toany(void (*func)(void));
- 'func' is a function that will be called right before gc has to change
- allocation-method from MEMF_FAST to MEMF_ANY. I.e., when it is likely
- it will return chip-mem.
- 2. A few small compiler-specific additions to make it compile with SAS/C again.
- 3. To build the collector with SAS/C, create SMakefile including the following
- specific content:
- IGNORE= IGNORE=85 IGNORE=154 IGNORE=161 IGNORE=100
- OPTIMIZE=optimize optimizetime optglobal optimizerdepth=100 optimizerpeephole optloop OPTSCHED optimizerinlocal optimizerrecurdepth=100
- OPT= $(OPTIMIZE) NOSTACKCHECK MAPHUNK NOVERSION NOICONS nodebug parm=reg
- DEFINE __USE_SYSBASE DEFINE AMIGA_SKIP_SEG DEFINE GC_ATOMIC_UNCOLLECTABLE
- DEFINE GC_AMIGA_FASTALLOC GC_AMIGA_RETRY GC_AMIGA_PRINTSTATS GC_AMIGA_GC
- DEFINE GC_AMIGA_MAKINGLIB
- DEFINE AMIGA IGNORE=100 IGNORE=161
- STILL MISSING:
- Programs can not be started from workbench, at least not for SAS/C. (Martin
- Tauchmanns note about that it now works with workbench is definitely wrong
- when concerning SAS/C). An iconx-script solves this problem.
- BEWARE!
- -To run gctest, set the stack to around 200000 bytes first.
- -SAS/C-specific: cord will crash if you compile gc.lib with
- either parm=reg or parm=both. (missing legal prototypes for
- function-pointers someplace is the reason I guess.).
- tested with software: Radium, http://www.stud.ifi.uio.no/~ksvalast/radium/
- tested with hardware: MC68060
- Martin Tauchmann's notes (1-Apr-99)
- Works now, also with the GNU-C compiler V2.7.2.1. <ftp://ftp.unina.it/pub/amiga/geekgadgets/amiga/m68k/snapshots/971125/amiga-bin/>
- Modify the `Makefile.direct`
- CC=cc $(ABI_FLAG)
- to
- CC=gcc $(ABI_FLAG)
- TECHNICAL NOTES
- - `GC_get_stack_base()`, `GC_register_data_segments()` works now with every
- C compiler; also Workbench.
- - Removed AMIGA_SKIP_SEG, but the Code-Segment must not be scanned by GC.
- PROBLEMS
- - When the Linker, does`t merge all Code-Segments to an single one. LD of GCC
- do it always.
- - With ixemul.library V47.3, when an GC program launched from another program
- (example: `Make` or `if_mach M68K AMIGA gctest`), `GC_register_data_segments()`
- found the Segment-List of the caller program.
- Can be fixed, if the run-time initialization code (for C programs, usually *crt0*)
- support `__data` and `__bss`.
- - PowerPC Amiga currently not supported.
- - Dynamic libraries (dyn_load.c) not supported.
- TESTED WITH SOFTWARE
- `Optimized Oberon 2 C` (oo2c) <http://cognac.informatik.uni-kl.de/download/index.html>
- TESTED WITH HARDWARE
- MC68030
- Michel Schinz's notes
- WHO DID WHAT
- The original Amiga port was made by Jesper Peterson. I (Michel Schinz)
- modified it slightly to reflect the changes made in the new official
- distributions, and to take advantage of the new SAS/C 6.x features. I also
- created a makefile to compile the "cord" package (see the cord
- subdirectory).
- TECHNICAL NOTES
- In addition to Jesper's notes, I have the following to say:
- - gctest checks to see if the code segment is added to the root set or not,
- and complains if it is. The only problem is that, as far as I know, it is
- impossible to know which segments are code segments and which are data
- segments (there are indeed solutions to this problem, like scanning the
- program on disk or patch the LoadSeg functions, but they are rather
- complicated). The solution I have chosen (see os_dep.c) is to test whether
- the program counter is in the segment we are about to add to the root set,
- and if it is, to skip the segment. The problems are that this solution is
- rather awkward and that it works only for one code segment. This means that
- if your program has more than one code segment, all of them but one will be
- added to the root set. This isn't a big problem in fact, since the
- collector will continue to work correctly, but it may be slower.
- Anyway, the code which decides whether to skip a segment or not can be
- removed simply by not defining AMIGA_SKIP_SEG. But notice that if you do
- so, gctest will complain (it will say that "GC_is_visible produced wrong
- failure indication"). However, it may be useful if you happen to have
- pointers stored in a code segment (you really shouldn't).
- If anyone has a good solution to the problem of finding, when a program
- is loaded in memory, whether a segment is a code or a data segment,
- please let me know.
- Jesper Peterson's notes
- ADDITIONAL NOTES FOR AMIGA PORT
- These notes assume some familiarity with Amiga internals.
- WHY I PORTED TO THE AMIGA
- The sole reason why I made this port was as a first step in getting
- the Sather(*) language on the Amiga. A port of this language will
- be done as soon as the Sather 1.0 sources are made available to me.
- Given this motivation, the garbage collection (GC) port is rather
- minimal.
- (*) For information on Sather read the comp.lang.sather newsgroup.
- LIMITATIONS
- This port assumes that the startup code linked with target programs
- is that supplied with SAS/C versions 6.0 or later. This allows
- assumptions to be made about where to find the stack base pointer
- and data segments when programs are run from WorkBench, as opposed
- to running from the CLI. The compiler dependent code is all in the
- GC_get_stack_base() and GC_register_data_segments() functions, but
- may spread as I add Amiga specific features.
- Given that SAS/C was assumed, the port is set up to be built with
- "smake" using the "SMakefile". Compiler options in "SCoptions" can
- be set with "scopts" program. Both "smake" and "scopts" are part of
- the SAS/C commercial development system.
- In keeping with the porting philosophy outlined above, this port
- will not behave well with Amiga specific code. Especially not inter-
- process communications via messages, and setting up public structures like
- Intuition objects or anything else in the system lists. For the
- time being the use of this library is limited to single threaded
- ANSI/POSIX compliant or near-compliant code. (i.e., stick to stdio
- for now). Given this limitation there is currently no mechanism for
- allocating "CHIP" or "PUBLIC" memory under the garbage collector.
- I'll add this after giving it considerable thought. The major
- problem is the entire physical address space may have to me scanned,
- since there is no telling who we may have passed memory to.
- If you allocate your own stack in client code, you will have to
- assign the pointer plus stack size to GC_stackbottom.
- The initial stack size of the target program can be compiled in by
- setting the __stack symbol (see SAS documentation). It can be over-
- ridden from the CLI by running the AmigaDOS "stack" program, or from
- the WorkBench by setting the stack size in the tool types window.
- SAS/C COMPILER OPTIONS (SCoptions)
- You may wish to check the "CPU" code option is appropriate for your
- intended target system.
- Under no circumstances set the "StackExtend" code option in either
- compiling the library or *ANY* client code.
- All benign compiler warnings have been suppressed. These mainly
- involve lack of prototypes in the code, and dead assignments
- detected by the optimizer.
- THE GOOD NEWS
- The library as it stands is compatible with the GigaMem commercial
- virtual memory software, and probably similar PD software.
- The performance of "gctest" on an Amiga 2630 (68030 @ 25 MHz)
- compares favorably with an HP9000 with similar architecture (a 325
- with a 68030 I think).
|