Mon Feb 20 01:46:34 PST 2012 John Meacham <[email protected]> * make 'div' and 'mod' round to -Infinity properly
Mon Feb 20 17:16:55 PST 2012 John Meacham <[email protected]> * introduce dedicated array allocation routine. clean up jgc garbage collector
New patches: [make 'div' and 'mod' round to -Infinity properly John Meacham <[email protected]>**20120220094634 Ignore-this: c46b383b9a2a6a63ff44e30a8a63f376 ] hunk ./lib/jhc/Jhc/Class/Real.hs 32 n `rem` d = r where (q,r) = quotRem n d n `div` d = q where (q,r) = divMod n d n `mod` d = r where (q,r) = divMod n d - divMod n d = if signum r == - signum d then (q-1, r+d) else qr + divMod n d = n `seq` d `seq` if signum r == - signum d then (q-1, r+d) else qr where qr@(q,r) = quotRem n d quotRem n d = (n `quot` d, n `rem` d) toInteger x = toInteger (toInt x) hunk ./lib/jhc/Jhc/Int.hs 4 {-# OPTIONS_JHC -fno-prelude -fffi #-} -- just a few basic operations on integers to jumpstart things -module Jhc.Int(Int(),Int_(),increment,decrement,plus,minus,times,divide,modulus,zero,one,boxInt,unboxInt) where +module Jhc.Int(Int(),Int_(),increment,decrement,plus,minus,times,quotient,remainder,zero,one,boxInt,unboxInt) where import Jhc.Type.Word(Int(),Int_()) hunk ./lib/jhc/Jhc/Int.hs 8 -foreign import primitive increment :: Int -> Int -foreign import primitive decrement :: Int -> Int +foreign import primitive increment :: Int -> Int +foreign import primitive decrement :: Int -> Int foreign import primitive "Add" plus :: Int -> Int -> Int foreign import primitive "Sub" minus :: Int -> Int -> Int foreign import primitive "Mul" times :: Int -> Int -> Int hunk ./lib/jhc/Jhc/Int.hs 13 -foreign import primitive "Div" divide :: Int -> Int -> Int -foreign import primitive "Mod" modulus :: Int -> Int -> Int -foreign import primitive zero :: Int -foreign import primitive one :: Int +foreign import primitive "Quot" quotient :: Int -> Int -> Int +foreign import primitive "Rem" remainder :: Int -> Int -> Int +foreign import primitive zero :: Int +foreign import primitive one :: Int foreign import primitive "box" boxInt :: Int_ -> Int foreign import primitive "unbox" unboxInt :: Int -> Int_ hunk ./lib/jhc/Jhc/Num.m4 36 m4_define(MkIntegralPrim,{{ instance Integral $1 where - div = div$1 +-- div = div$1 quot = quot$1 hunk ./lib/jhc/Jhc/Num.m4 38 - mod = mod$1 +-- mod = mod$1 rem = rem$1 toInt = toInt$1 toInteger = toInteger$1 hunk ./lib/jhc/Jhc/Num.m4 45 foreign import primitive "I2I" toInt$1 :: $1 -> Int foreign import primitive "I2I" toInteger$1 :: $1 -> Integer -foreign import primitive "Div" div$1 :: $1 -> $1 -> $1 +--foreign import primitive "Div" div$1 :: $1 -> $1 -> $1 foreign import primitive "Quot" quot$1 :: $1 -> $1 -> $1 hunk ./lib/jhc/Jhc/Num.m4 47 -foreign import primitive "Mod" mod$1 :: $1 -> $1 -> $1 +--foreign import primitive "Mod" mod$1 :: $1 -> $1 -> $1 foreign import primitive "Rem" rem$1 :: $1 -> $1 -> $1 }}) hunk ./src/C/FromGrin2.hs 716 | otherwise = return $ err ("prim: " ++ show (p,vs)) signedOps = [ - (Op.Div,"/"), -- TODO round to -Infinity - (Op.Mod,"%"), -- TODO round to -Infinity +-- (Op.Div,"/"), -- TODO round to -Infinity +-- (Op.Mod,"%"), -- TODO round to -Infinity (Op.Quot,"/"), (Op.Rem,"%"), (Op.Shra,">>"), [introduce dedicated array allocation routine. clean up jgc garbage collector John Meacham <[email protected]>**20120221011655 Ignore-this: b8e153205aeaf94af76a97b0ee9aa895 ] hunk ./rts/rts/constants.h 6 /* these constants are shared between jhc-prim and the rts. */ // Normal memory block. -#define SLAB_FLAG_NONE 0 +#define SLAB_FLAG_NONE 0 // Each element has a finalizer-list as its second word. hunk ./rts/rts/constants.h 9 -#define SLAB_FLAG_FINALIZER 1 +#define SLAB_FLAG_FINALIZER 1 // In addition to whatever other finalization is done, 'free' should be called // on the first word of each entry. hunk ./rts/rts/constants.h 13 -#define SLAB_FLAG_FREE 2 +#define SLAB_FLAG_FREE 2 // Finalizers should be delayed until entire slab is freed up and individually // freed members need not be kept track of. hunk ./rts/rts/constants.h 17 -#define SLAB_FLAG_DELAY 4 +#define SLAB_FLAG_DELAY 4 + +// A global finalizer exists for this slab +#define SLAB_GLOBAL_FINALIZER 8 + +// slab is a monolith, should be 'free'd when done with and not returned to +// cache. +#define SLAB_MONOLITH 16 + +// virtual flags are never set in a cache but are used internally to keep track +// of things. + +// virtual flag to indicate location is a value +#define SLAB_VIRTUAL_VALUE 256 + +// virtual flag to indicate location has a special intererpretation. +#define SLAB_VIRTUAL_SPECIAL 512 + +// virtual flag to indication location is a constant. +#define SLAB_VIRTUAL_CONSTANT 1024 #endif hunk ./rts/rts/gc.h 15 void jhc_alloc_init(void); void jhc_alloc_fini(void); -void jhc_alloc_print_stats(void); #include "rts/gc_none.h" #include "rts/gc_jgc.h" hunk ./rts/rts/gc_jgc.c 14 unsigned block_used; unsigned block_threshold; SLIST_HEAD(,s_cache) caches; + SLIST_HEAD(,s_block) monolithic_blocks; SLIST_HEAD(,s_megablock) megablocks; }; hunk ./rts/rts/gc_jgc.c 46 struct s_block_info pi; unsigned short num_entries; struct s_arena *arena; + void (*init_fn)(void *); + void (*fini_fn)(void *); +#if _JHC_PROFILE + unsigned allocations; +#endif }; gc_t saved_gc; hunk ./rts/rts/gc_jgc.c 55 struct s_arena *arena; -static unsigned number_gcs; // number of garbage collections -static unsigned number_allocs; // number of allocations since last garbage collection +static unsigned number_gcs; // number of garbage collections +static unsigned number_allocs; // number of allocations since last garbage collection static gc_t gc_stack_base; hunk ./rts/rts/gc_jgc.c 59 -#define gc_frame0(gc,n,...) void *ptrs[n] = { __VA_ARGS__ }; for(int i = 0; i < n; i++) gc[i] = (sptr_t)ptrs[i]; gc_t sgc = gc; gc_t gc = sgc + n; -#define gc_frame1(gc,p1) gc[0] = (sptr_t)p1; gc_t sgc = gc; gc_t gc = sgc + 1; -#define gc_frame2(gc,p1,p2) gc[0] = (sptr_t)p1; gc[1] = (sptr_t)p2; gc_t sgc = gc; gc_t gc = sgc + 2; #define TO_GCPTR(x) (entry_t *)(FROM_SPTR(x)) static void gc_perform_gc(gc_t gc); hunk ./rts/rts/gc_jgc.c 225 profile_pop(&gc_gc_time); } -void jhc_alloc_print_stats(void) { } +// 7 to share caches with the first 7 tuples +#define GC_STATIC_ARRAY_NUM 256 + +static struct s_cache *static_array_caches[GC_STATIC_ARRAY_NUM]; void jhc_alloc_init(void) { hunk ./rts/rts/gc_jgc.c 244 nh_end = nh_stuff[i]; } } + for (int i = 0; i < GC_STATIC_ARRAY_NUM; i++) { + find_cache(&static_array_caches[i], arena, i + 1, i + 1); + } } void hunk ./rts/rts/gc_jgc.c 251 jhc_alloc_fini(void) { - if(JHC_STATUS) { + if(_JHC_PROFILE || JHC_STATUS) { fprintf(stderr, "arena: %p\n", arena); fprintf(stderr, " block_used: %i\n", arena->block_used); fprintf(stderr, " block_threshold: %i\n", arena->block_threshold); hunk ./rts/rts/gc_jgc.c 276 return (void *)e; } +// Allocate an array of count garbage collectable locations in the garbage collected heap +void * +gc_array_alloc(gc_t gc, unsigned count) +{ + if (!count) + return NULL; + if (count <= GC_STATIC_ARRAY_NUM) + return (wptr_t)s_alloc(gc,static_array_caches[count - 1]); + //if (count < GC_MAX_BLOCK_ENTRIES) + return s_alloc(gc, find_cache(NULL, arena, count, count)); + abort(); +} + /* This finds a bit that isn't set, sets it, then returns its index. It * assumes that a bit is available to be found, otherwise it goes into an * infinite loop. */ hunk ./rts/rts/gc_jgc.c 370 static void s_cleanup_blocks(struct s_arena *arena) { + struct s_block *pg = SLIST_FIRST(&arena->monolithic_blocks); + SLIST_INIT(&arena->monolithic_blocks); + while (pg) { + if(BIT_IS_SET(pg->used, 0)) { + SLIST_INSERT_HEAD(&arena->monolithic_blocks, pg, link); + pg = SLIST_NEXT(pg,link); + } + else { + void *ptr = pg; + pg = SLIST_NEXT(pg,link); + free(ptr); + } + } struct s_cache *sc = SLIST_FIRST(&arena->caches); for(;sc;sc = SLIST_NEXT(sc,next)) { hunk ./rts/rts/gc_jgc.c 385 - // 'best' keeps track of the block with the fewest free spots // and percolates it to the front, effectively a single pass // of a bubblesort to help combat fragmentation. It does hunk ./rts/rts/gc_jgc.c 395 struct s_block *best = NULL; int free_best = 4096; - struct s_block *pg = SLIST_FIRST(&sc->blocks); + pg = SLIST_FIRST(&sc->blocks); struct s_block *fpg = SLIST_FIRST(&sc->full_blocks); SLIST_INIT(&sc->blocks); SLIST_INIT(&sc->full_blocks); hunk ./rts/rts/gc_jgc.c 406 while(pg) { struct s_block *npg = SLIST_NEXT(pg,link); if(__predict_false(pg->num_free == 0)) { + // Add full blockes to the cache's full block list. SLIST_INSERT_HEAD(&sc->full_blocks,pg,link); } else if(__predict_true(pg->num_free == sc->num_entries)) { hunk ./rts/rts/gc_jgc.c 409 + // Return completely free block to arena free block list. arena->block_used--; hunk ./rts/rts/gc_jgc.c 411 - VALGRIND_MAKE_MEM_NOACCESS((char *)pg + sizeof(struct s_block), BLOCK_SIZE - sizeof(struct s_block)); + VALGRIND_MAKE_MEM_NOACCESS((char *)pg + sizeof(struct s_block), + BLOCK_SIZE - sizeof(struct s_block)); SLIST_INSERT_HEAD(&arena->free_blocks,pg,link); } else { if(!best) { hunk ./rts/rts/gc_jgc.c 454 void * A_STD s_alloc(gc_t gc, struct s_cache *sc) { +#if _JHC_PROFILE + sc->allocations++; +#endif struct s_block *pg = SLIST_FIRST(&sc->blocks); if(__predict_false(!pg)) { pg = get_free_block(gc, sc->arena); hunk ./rts/rts/gc_jgc.c 463 VALGRIND_MAKE_MEM_NOACCESS(pg, BLOCK_SIZE); VALGRIND_MAKE_MEM_DEFINED(pg, sizeof(struct s_block)); if(sc->num_entries != pg->num_free) - VALGRIND_MAKE_MEM_UNDEFINED((char *)pg->used,BITARRAY_SIZE_IN_BYTES(sc->num_entries)); + VALGRIND_MAKE_MEM_UNDEFINED((char *)pg->used, + BITARRAY_SIZE_IN_BYTES(sc->num_entries)); else hunk ./rts/rts/gc_jgc.c 466 - VALGRIND_MAKE_MEM_DEFINED((char *)pg->used,BITARRAY_SIZE_IN_BYTES(sc->num_entries)); + VALGRIND_MAKE_MEM_DEFINED((char *)pg->used, + BITARRAY_SIZE_IN_BYTES(sc->num_entries)); assert(pg); pg->pi = sc->pi; pg->next_free = 0; hunk ./rts/rts/gc_jgc.c 499 new_cache(struct s_arena *arena, unsigned short size, unsigned short num_ptrs) { struct s_cache *sc = malloc(sizeof(*sc)); + memset(sc,0,sizeof(*sc)); sc->arena = arena; sc->pi.size = size; sc->pi.num_ptrs = num_ptrs; hunk ./rts/rts/gc_jgc.c 506 sc->pi.flags = 0; size_t excess = BLOCK_SIZE - sizeof(struct s_block); sc->num_entries = (8*excess) / (8*sizeof(uintptr_t)*size + 1) - 1; - //sc->num_entries = (8*excess) / (8*size*sizeof(uintptr_t) + 1); - sc->pi.color = (sizeof(struct s_block) + BITARRAY_SIZE_IN_BYTES(sc->num_entries) + sizeof(uintptr_t) - 1) / sizeof(uintptr_t); + sc->pi.color = (sizeof(struct s_block) + BITARRAY_SIZE_IN_BYTES(sc->num_entries) + + sizeof(uintptr_t) - 1) / sizeof(uintptr_t); SLIST_INIT(&sc->blocks); SLIST_INIT(&sc->full_blocks); SLIST_INSERT_HEAD(&arena->caches,sc,next); hunk ./rts/rts/gc_jgc.c 511 - //print_cache(sc); return sc; } hunk ./rts/rts/gc_jgc.c 531 } } -// set a used bit. returns true if the -// tagged node should be scanned by the GC. -// this happens when the used bit was not previously set -// and the node contains internal pointers. +// Set a used bit. returns true if the tagged node should be scanned by the GC. +// this happens when the used bit was not previously set and the node contains +// internal pointers. static bool s_set_used_bit(void *val) hunk ./rts/rts/gc_jgc.c 550 } struct s_cache * -find_cache(struct s_cache **rsc, struct s_arena *arena, unsigned short size, unsigned short num_ptrs) +find_cache(struct s_cache **rsc, struct s_arena *arena, + unsigned short size, unsigned short num_ptrs) { if(__predict_true(rsc && *rsc)) return *rsc; hunk ./rts/rts/gc_jgc.c 573 SLIST_INIT(&arena->caches); SLIST_INIT(&arena->free_blocks); SLIST_INIT(&arena->megablocks); + SLIST_INIT(&arena->monolithic_blocks); arena->block_used = 0; arena->block_threshold = 8; arena->current_megablock = NULL; hunk ./rts/rts/gc_jgc.c 582 void print_cache(struct s_cache *sc) { - fprintf(stderr, "num_entries: %i\n",(int)sc->num_entries); -// printf(" entries: %i words\n",(int)(sc->num_entries*sc->pi.size)); - fprintf(stderr, " header: %lu bytes\n", sizeof(struct s_block) + BITARRAY_SIZE_IN_BYTES(sc->num_entries)); - fprintf(stderr, " size: %i words\n",(int)sc->pi.size); -// printf(" color: %i words\n",(int)sc->pi.color); - fprintf(stderr, " nptrs: %i words\n",(int)sc->pi.num_ptrs); -// printf(" end: %i bytes\n",(int)(sc->pi.color+ sc->num_entries*sc->pi.size)*sizeof(uintptr_t)); + fprintf(stderr, "num_entries: %i with %lu bytes of header\n", + (int)sc->num_entries, sizeof(struct s_block) + + BITARRAY_SIZE_IN_BYTES(sc->num_entries)); + fprintf(stderr, " size: %i words %i ptrs\n", + (int)sc->pi.size,(int)sc->pi.num_ptrs); +#if _JHC_PROFILE + fprintf(stderr, " allocations: %lu\n", (unsigned long)sc->allocations); +#endif + if(SLIST_EMPTY(&sc->blocks) && SLIST_EMPTY(&sc->full_blocks)) + return; + fprintf(stderr, " blocks:\n"); fprintf(stderr, "%20s %9s %9s %s\n", "block", "num_free", "next_free", "status"); struct s_block *pg; hunk ./rts/rts/gc_jgc.c 595 - SLIST_FOREACH(pg,&sc->blocks,link) { - fprintf(stderr, "%20p %9i %9i %c\n", pg, pg->num_free, pg->next_free, 'P'); - } - fprintf(stderr, " full_blocks:\n"); - SLIST_FOREACH(pg,&sc->full_blocks,link) { - fprintf(stderr, "%20p %9i %9i %c\n", pg, pg->num_free, pg->next_free, 'F'); - } + SLIST_FOREACH(pg,&sc->blocks,link) + fprintf(stderr, "%20p %9i %9i %c\n", pg, pg->num_free, pg->next_free, 'P'); + SLIST_FOREACH(pg,&sc->full_blocks,link) + fprintf(stderr, "%20p %9i %9i %c\n", pg, pg->num_free, pg->next_free, 'F'); } #endif hunk ./rts/rts/gc_jgc.h 14 #define BLOCK_SIZE (1UL << 12) #define MEGABLOCK_SIZE (1UL << 20) -#define S_BLOCK(val) ((struct s_block *)((uintptr_t)(val) & ~ (BLOCK_SIZE - 1))) +#define S_BLOCK(val) ((struct s_block *)((uintptr_t)(val) & ~(BLOCK_SIZE - 1))) #define GC_BASE sizeof(void *) #define TO_BLOCKS(x) ((x) <= GC_BASE ? 1 : (((x) - 1)/GC_BASE) + 1) hunk ./rts/rts/gc_jgc.h 30 unsigned short size, unsigned short num_ptrs); void *(gc_alloc)(gc_t gc,struct s_cache **sc, unsigned count, unsigned nptrs); void gc_add_root(gc_t gc, void * root); +void *gc_array_alloc(gc_t gc, unsigned count); #define gc_frame0(gc,n,...) void *ptrs[n] = { __VA_ARGS__ }; \ for(int i = 0; i < n; i++) gc[i] = (sptr_t)ptrs[i]; \ hunk ./rts/rts/gc_jgc.h 35 gc_t sgc = gc; gc_t gc = sgc + n; +#define gc_frame1(gc,p1) gc[0] = (sptr_t)p1; gc_t sgc = gc; gc_t gc = sgc + 1; +#define gc_frame2(gc,p1,p2) gc[0] = (sptr_t)p1; gc[1] = (sptr_t)p2; \ + gc_t sgc = gc; gc_t gc = sgc + 2; struct StablePtr { LIST_ENTRY(StablePtr) link; hunk ./rts/rts/gc_none.c 14 void jhc_alloc_init(void) { GC_INIT(); } void jhc_alloc_fini(void) { } -void jhc_alloc_print_stats(void) { } #elif _JHC_GC == _JHC_GC_NONE hunk ./rts/rts/gc_none.c 26 static unsigned mem_chunks,mem_offset; void jhc_alloc_init(void) {} -void jhc_alloc_fini(void) {} void hunk ./rts/rts/gc_none.c 28 -jhc_alloc_print_stats(void) { - fprintf(stderr, "Memory Allocated: %u bytes\n", (JHC_MEM_CHUNK_SIZE*(mem_chunks)) + mem_offset); - print_alloc_size_stats(); +jhc_alloc_fini(void) { + if(_JHC_PROFILE) { + fprintf(stderr, "Memory Allocated: %u bytes\n", (JHC_MEM_CHUNK_SIZE*(mem_chunks)) + mem_offset); + print_alloc_size_stats(); + } } static void hunk ./rts/rts/profile.c 80 fprintf(stderr, "Command: %s\n", jhc_command); fprintf(stderr, "Complie: %s\n", jhc_c_compile); fprintf(stderr, "Version: %s\n\n", jhc_version); - jhc_alloc_print_stats(); #if HAVE_TIMES struct tms tm; times(&tm); hunk ./rts/rts/profile.c 92 fprintf(stderr, "-----------------\n"); } -#if _JHC_PROFILE +#if _JHC_PROFILE && _JHC_GC != _JHC_GC_JGC #define BUCKETS 7 static unsigned alloced[BUCKETS]; hunk ./src/C/FromGrin2.hs 609 convertExp Alloc { expValue = v, expCount = c, expRegion = r } | r == region_heap, TyINode == getType v = do v' <- convertVal v c' <- convertVal c - (malloc,tmp) <- jhc_malloc_ptrs (operator "*" (sizeof sptr_t) c') =:: ptrType sptr_t + (malloc,tmp) <- jhc_malloc_ptrs c' =:: ptrType sptr_t fill <- case v of ValUnknown _ -> return mempty _ -> do hunk ./src/C/FromGrin2.hs 931 jhc_malloc _ 0 sz = functionCall (name "jhc_malloc_atomic") [sz] jhc_malloc _ _ sz = functionCall (name "jhc_malloc") [sz] -jhc_malloc_ptrs sz | fopts FO.Jgc = functionCall (name "gc_alloc") [v_gc,nullPtr,tbsize sz, tbsize sz] -jhc_malloc_ptrs sz = functionCall (name "jhc_malloc") [sz] +jhc_malloc_ptrs sz | fopts FO.Jgc = functionCall (name "gc_array_alloc") [v_gc, sz] +jhc_malloc_ptrs sz = functionCall (name "jhc_malloc") [sizeof sptr_t *# sz] f_assert e = functionCall (name "assert") [e] f_FROM_SPTR e = functionCall (name "FROM_SPTR") [e] hunk ./src/C/Generate.hs 6 Structure(..), (=*), (&), + (*#), + (+#), ToExpression(..), ToStatement(..), eq, hunk ./src/C/Generate.hs 685 infixl 1 & + (&) :: (ToStatement a,ToStatement b) => a -> b -> Statement x & y = toStatement x `mappend` toStatement y hunk ./src/C/Generate.hs 688 + +x *# y = operator "*" (toExpression x) (toExpression y) +x +# y = operator "+" (toExpression x) (toExpression y) Context: [add prototype for gc_alloc John Meacham <[email protected]>**20120220050616 Ignore-this: 444b34148332459dc0e3d32b7c55d3e0 ] [fix deriving rules for read/show when it comes to labels John Meacham <[email protected]>**20120220044322 Ignore-this: 20c9c89ae066716fe3ec8eb4d37c6034 ] [disabled buggy unused transformation in type analysis pass John Meacham <[email protected]>**20120220031442 Ignore-this: 8ad84739daff7f4faff0ba251898ea1a ] [move debugging routines to rts/profile.c John Meacham <[email protected]>**20120217052015 Ignore-this: d2e087faf6e3408dc135fd905d85244b ] [fix rts unit tests John Meacham <[email protected]>**20120217035045 Ignore-this: 460d7eadde056908b668ea27d5a69aa5 ] [export gc_alloc John Meacham <[email protected]>**20120217002235 Ignore-this: dcb70b3ad303f0343147b4e1d6d413b9 ] [Makes the class deriving mechanism more robust: [email protected]**20120216214017 Ignore-this: 6d93691849d255c310b2af7098572ea8 - the names of the classes to be derived may be given qualified. - the functions from the Prelude internally used need not be in scope and won't clash with other bindings. ] [Moved Jhc.List.drop to module Jhc.Basics (since it is used in instance deriving) [email protected]**20120214222939 Ignore-this: f95d4818bad6d79d8fc7566ee0912714 ] [The typechecker now verifies that the main function has a type that can be unified with IO a. This is required by the Haskell 98 Report. [email protected]**20120211050446 Ignore-this: 8a1d8ca36929c0de0fb4357538ea6c5b Failing to do so allows both to accept invalid programs like: > main :: [()] > main = return () and to reject valid programs like: > main = return () ] [Improves the error message shown when a monomorphic pattern has a polymorphic type that cannot be defaulted. [email protected]**20120211045931 Ignore-this: efd70b7535eb0444148aabdbe96ed0b9 The previous error message seemed more like an internal error ("withDefaults.ambiguity: ...") ] [fix for building rts in different modes, profile,debug,windows John Meacham <[email protected]>**20120216201402 Ignore-this: 39b08c82b7239beaeaa6e77a3b986cd4 ] [move rest of rts into seperate c files rather than including it directly. John Meacham <[email protected]>**20120216090215 Ignore-this: d0bf719a38e306f78e182a5c0107573d ] [add pragmaExp to the lexer/parser John Meacham <[email protected]>**20120216044837 Ignore-this: 77393cb5bdd28fba526d57d26ac099b8 ] [update documentation with new extensions John Meacham <[email protected]>**20120214172359 Ignore-this: 2f412f29f20127ce3f97f200674ed8b6 ] [fixes for android John Meacham <[email protected]>**20120213150333 Ignore-this: cf6df59b212e3402ec21507410485270 ] [make += work with '-m' command line options John Meacham <[email protected]>**20120213102300 Ignore-this: 36cb4039cd34ba73d2cc973b7c00798b ] [move jhc_rts_alloc to gc_none John Meacham <[email protected]>**20120213100906 Ignore-this: 1c2e9028d72127acd5a448971266f627 ] [added rts/rts_support, cleaned up rts code. John Meacham <[email protected]>**20120213070644 Ignore-this: 79533860331fbd02057748e3d1b81666 ] [make 'Requires' a simple set, include the calling convention with the requirements. John Meacham <[email protected]>**20120212053838 Ignore-this: b7fa6f8ece79c96073d8638a876456de ] [move slub.c and jhc_jgc.* to rts directory John Meacham <[email protected]>**20120212040246 Ignore-this: a40354544b8908732c733bf8a38e7e68 ] [add unit tests for stableptr John Meacham <[email protected]>**20120212031148 Ignore-this: 17b41baeec806fb53ca2c10c6489097 ] [reorganize rts/ directory, add README for it John Meacham <[email protected]>**20120212022718 Ignore-this: c8a9f067696233958757830b62a7264b ] [add rts/test directory John Meacham <[email protected]>**20120212004706 Ignore-this: 1e6d0cb4ba809a1d6089d04704d5a60f ] [allow being explicit in export/import lists by specifying 'kind', 'class', 'type', or 'data'. add PTS rule to allow proper typing of Complex_ John Meacham <[email protected]>**20120211052157 Ignore-this: 12155286186022f896d3474a2bb5d23a ] [fix Options.hs makefile dependency John Meacham <[email protected]>**20120211024909 Ignore-this: a0742d7ce4eba41314741b6ca2d6498d ] [added user defined kind extension John Meacham <[email protected]>**20120211042248 Ignore-this: ded329985c5c81aa8c4612f7aa19559b ] [Add missing src/Options.hs to jhc tarball Sergei Trofimovich <[email protected]>**20120209065334 Ignore-this: dfc50115ee26986ab2d303a462cd29b9 ] [added mingw32-gcc to MINGW search Sergei Trofimovich <[email protected]>**20110414073938 Ignore-this: 87fa46f0e4532663a9d92930c9c38152 ] [add c-- types for complex and vector values John Meacham <[email protected]>**20120210051026 Ignore-this: 4a1e4c8cec01f73b75913622c22fa55 ] [add documentation for the multi-return ccall extension, clean up code. John Meacham <[email protected]>**20120209201351 Ignore-this: 47504b653ee9f71bde40e91959238292 ] [add extension to allow multiple return values from c functions John Meacham <[email protected]>**20120209142228 Ignore-this: 51e4a3f9ca80ff2eae7f21376f0a0992 ] [fix obscure error message for invalid instance reported by roman John Meacham <[email protected]>**20120209114221 Ignore-this: 98d60e20cb63caaebbe1269887160b9f ] [remove APrim type, use Prim directly, clean up corresponding cruft. John Meacham <[email protected]>**20120209104920 Ignore-this: 8a3fbeea72e7f52809a3468df2b8b228 ] [turn ExtType into a real abstract type John Meacham <[email protected]>**20120209100704 Ignore-this: c802a07fee0f2461cca19aa28f99ff61 ] [add 'capi' foreign function call type, simplify type of E.FromHs monad, check for more FFI related errors John Meacham <[email protected]>**20120209091611 Ignore-this: 1945b5336e6001d6da6cd63a77bd1efd ] [add md5lazyIO, check for bad paths in createTempFile John Meacham <[email protected]>**20120209091527 Ignore-this: f9e5f0dafc9615d5c5c50cb49829c5a5 ] [add foreign types, interpret Ptr when creating external C types John Meacham <[email protected]>**20120209090647 Ignore-this: c49bea3938e2edabda9d7528cfb1121a ] [Add some more exotic primitive ops, ffs,clz,ctz,byteswap,popcount,parity. John Meacham <[email protected]>**20120209070848 Ignore-this: b61b1c08db35ccad33f24536b99913df ] [jhc.spec fixes John Meacham <[email protected]>**20120209015329 Ignore-this: 64488edc34893a734f81b1c01c0b1ff4 ] [TAG 0.8.0 John Meacham <[email protected]>**20120208020026 Ignore-this: 2d0d963331a43650879ae72d81ff62e8 ] Patch bundle hash: bcc3ff73b1f05919f173424d2f8cd0e409a7df05
_______________________________________________ jhc mailing list [email protected] http://www.haskell.org/mailman/listinfo/jhc
