From 89ec3f099a5d4d7bb870dbab1b8253a588996638 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 28 Oct 2010 14:16:34 -0400 Subject: [PATCH] making new GC the default fixing making symbols from non-0-terminated strings changing IntSet to use a proper array --- Make.inc.Linux | 4 ++-- alloc.c | 10 +++++++++- doc/todo | 6 +++++- expr.j | 3 ++- gc.c | 44 ++++++++++++++++++++------------------------ inference.j | 4 ++-- intset.j | 34 +++++++++++++--------------------- io.j | 3 ++- julia.expmap | 2 +- julia.h | 3 ++- lib/bitvector.c | 2 +- multi.j | 5 +++-- task.c | 2 +- 13 files changed, 63 insertions(+), 59 deletions(-) diff --git a/Make.inc.Linux b/Make.inc.Linux index e959f74b208be..176f37be2b438 100644 --- a/Make.inc.Linux +++ b/Make.inc.Linux @@ -1,6 +1,6 @@ CC = gcc CXX = g++ -CFLAGS = +CFLAGS = -std=gnu99 PFX = /usr/local #PFX = /afs/csail.mit.edu/u/b/bezanson @@ -8,7 +8,7 @@ HFILEDIRS = $(PFX)/include LIBDIRS = $(PFX)/lib # BOEHM or MARKSWEEP -JULIAGC = BOEHM +JULIAGC = MARKSWEEP ifeq ($(JULIAGC),BOEHM) GCLIBS = -l:libgc.a diff --git a/alloc.c b/alloc.c index 49f31a823e477..04f5a575abcc3 100644 --- a/alloc.c +++ b/alloc.c @@ -262,7 +262,7 @@ static jl_sym_t **symtab_lookup(jl_sym_t **ptree, const char *str) return ptree; } -DLLEXPORT jl_sym_t *jl_symbol(const char *str) +jl_sym_t *jl_symbol(const char *str) { jl_sym_t **pnode; @@ -272,6 +272,14 @@ DLLEXPORT jl_sym_t *jl_symbol(const char *str) return *pnode; } +DLLEXPORT jl_sym_t *jl_symbol_n(const char *str, int32_t len) +{ + char name[len+1]; + memcpy(name, str, len); + name[len] = '\0'; + return jl_symbol(name); +} + DLLEXPORT jl_sym_t *jl_gensym() { static uint32_t gs_ctr = 0; // TODO: per-thread diff --git a/doc/todo b/doc/todo index 1f6d398d170ea..a9370c1a5942f 100644 --- a/doc/todo +++ b/doc/todo @@ -556,6 +556,10 @@ promote_type: promote_type(Type{T},Type{T}) first ref: ref(Array{Any,1},Int32) before ref(Array{T,1},Int32) convert files for new GC: -*alloc.c codegen.cpp *gf.c *intrinsics.cpp +*alloc.c *codegen.cpp *gf.c *intrinsics.cpp *ast.c *init.c *io.c *task.c *builtins.c *interpreter.c *jltypes.c *repl.c + +startup time, mem0, mem after tests.j, exe size: +marksweep: 7.8s, 58356 43m, 69792 55m, 8285616 +boehm: 7.8s, 50236 35m, 78320 63m, 8376416 diff --git a/expr.j b/expr.j index bd9a81545ae4a..1557913a98683 100644 --- a/expr.j +++ b/expr.j @@ -3,7 +3,8 @@ symbol(s::Latin1String) = symbol(s.data) symbol(s::UTF8String) = symbol(s.data) symbol(a::Array{Uint8,1}) = - ccall(dlsym(JuliaDLHandle,"jl_symbol"), Any, (Ptr{Uint8},), a)::Symbol + ccall(dlsym(JuliaDLHandle,"jl_symbol_n"), Any, + (Ptr{Uint8}, Int32), a, int32(length(a)))::Symbol gensym() = ccall(dlsym(JuliaDLHandle,"jl_gensym"), Any, ())::Symbol (==)(x::Symbol, y::Symbol) = is(x, y) diff --git a/gc.c b/gc.c index c1ed360ef0934..6f30c51395b5f 100644 --- a/gc.c +++ b/gc.c @@ -21,11 +21,11 @@ /* integration steps: * convert idtable to use an Array - - give GC access to relevant C local variables + * give GC access to relevant C local variables - allocate ios objects with malloc, use finalizer */ -#define GC_PAGE_SZ 16384//bytes +#define GC_PAGE_SZ (4096*sizeof(void*))//bytes typedef struct _gcpage_t { struct _gcpage_t *next; @@ -83,46 +83,42 @@ typedef struct _bigval_t { static bigval_t *big_objects = NULL; -#define N_POOLS 16 +#define N_POOLS 19 static pool_t pools[N_POOLS]; static size_t allocd_bytes = 0; static size_t collect_interval = 8192*1024; // size classes: -// <=8, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048 -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +// <=8, 12, 16, 20, 24, 28, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048 +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15, 16, 17, 18 static int szclass(size_t sz) { if (sz <= 8) return 0; + if (sz <= 32) return ((sz+3)>>2) - 2; if (sz <= 128) { - if (sz <= 16) return 1; - if (sz <= 32) { - if (sz <= 24) return 2; - return 3; - } if (sz <= 64) { - if (sz <= 48) return 4; - return 5; + if (sz <= 48) return 7; + return 8; } - if (sz <= 96) return 6; - return 7; + if (sz <= 96) return 9; + return 10; } if (sz <= 512) { if (sz <= 256) { - if (sz <= 192) return 8; - return 9; + if (sz <= 192) return 11; + return 12; } - if (sz <= 384) return 10; - return 11; + if (sz <= 384) return 13; + return 14; } if (sz <= 1024) { - if (sz <= 768) return 12; - return 13; + if (sz <= 768) return 15; + return 16; } - if (sz <= 1536) return 14; - return 15; + if (sz <= 1536) return 17; + return 18; } static void *alloc_big(size_t sz) @@ -489,8 +485,8 @@ void *alloc_permanent(size_t sz) void jl_gc_init() { - int szc[N_POOLS] = { 8, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, - 768, 1024, 1536, 2048 }; + int szc[N_POOLS] = { 8, 12, 16, 20, 24, 28, 32, 48, 64, 96, 128, 192, 256, + 384, 512, 768, 1024, 1536, 2048 }; int i; for(i=0; i < N_POOLS; i++) { pools[i].osize = szc[i]+sizeof(void*); diff --git a/inference.j b/inference.j index 000cacaea7073..c31d3898735b9 100644 --- a/inference.j +++ b/inference.j @@ -642,8 +642,8 @@ function typeinf(linfo::LambdaStaticData, atypes::Tuple, sparams::Tuple, cop) n = length(body) s = { idtable() | i=1:n } - recpts = intset(n+1) # statements that depend recursively on our value - W = intset(n+1) + recpts = IntSet(n+1) # statements that depend recursively on our value + W = IntSet(n+1) # initial set of pc adjoin(W,1) # initial types diff --git a/intset.j b/intset.j index 8f3a44fe7833e..914d9af5dc0e4 100644 --- a/intset.j +++ b/intset.j @@ -1,35 +1,29 @@ struct IntSet - bits::Ptr{Uint32} + bits::Array{Uint32,1} limit::Int32 # todo: should be Int64 + + IntSet() = IntSet(1024) + IntSet(max::Int32) = (lim = (max+31) & -32; + new(zeros(Uint32,lim>>5), lim)) end -intset(max::Int32) = - IntSet(ccall(dlsym(JuliaDLHandle,"bitvector_new"), Ptr{Uint32}, - (Uint64, Int32), - uint64(max), 1), - max) - -intset() = intset(1024) - function adjoin(s::IntSet, n::Int) if n >= s.limit lim = int32(n + div(n,2)) - s.bits = ccall(dlsym(JuliaDLHandle,"bitvector_resize"), Ptr{Uint32}, - (Ptr{Uint32}, Uint64, Uint64, Int32), - s.bits, uint64(s.limit), uint64(lim), 1) + olsz = length(s.bits) + newbits = Array(Uint32,(lim+31)>>5) + newbits[1:olsz] = s.bits + for i=(olsz+1):length(newbits); newbits[i] = 0; end + s.bits = newbits s.limit = lim end - ccall(dlsym(JuliaDLHandle,"bitvector_set"), Void, - (Ptr{Uint32}, Uint64, Int32), - s.bits, uint64(n), 1) + s.bits[n>>5 + 1] |= (1<<(n&31)) s end function remove(s::IntSet, n::Int) if n < s.limit - ccall(dlsym(JuliaDLHandle,"bitvector_set"), Void, - (Ptr{Uint32}, Uint64, Int32), - s.bits, uint64(n), 0) + s.bits[n>>5 + 1] &= ~(1<<(n&31)) end s end @@ -40,9 +34,7 @@ function contains(s::IntSet, n::Int) if n >= s.limit false else - (ccall(dlsym(JuliaDLHandle,"bitvector_get"), Int32, - (Ptr{Uint32}, Uint64), - s.bits, uint64(n)) != 0) + (s.bits[n>>5 + 1] & (1<<(n&31))) != 0 end end diff --git a/io.j b/io.j index aa6b31e44cb9c..55db17a5b3933 100644 --- a/io.j +++ b/io.j @@ -213,8 +213,9 @@ function serialize(s, x) for n = t.names serialize(s, getfield(x, n)) end + else + error("not serializable") end - error("not serializable") end ## deserializing values ## diff --git a/julia.expmap b/julia.expmap index 889cc79b031dc..95d58018c3b59 100644 --- a/julia.expmap +++ b/julia.expmap @@ -22,7 +22,7 @@ jl_new_structt; jl_word_size; jl_enable_inference; - jl_symbol; + jl_symbol_n; jl_matching_methods; jl_is_builtin; jl_is_genericfunc; diff --git a/julia.h b/julia.h index 95d3d38555e95..cc589fe5f39be 100644 --- a/julia.h +++ b/julia.h @@ -451,7 +451,8 @@ jl_tuple_t *jl_alloc_tuple_uninit(size_t n); jl_tuple_t *jl_tuple_append(jl_tuple_t *a, jl_tuple_t *b); jl_tuple_t *jl_flatten_pairs(jl_tuple_t *t); jl_tuple_t *jl_pair(jl_value_t *a, jl_value_t *b); -DLLEXPORT jl_sym_t *jl_symbol(const char *str); +jl_sym_t *jl_symbol(const char *str); +DLLEXPORT jl_sym_t *jl_symbol_n(const char *str, int32_t len); DLLEXPORT jl_sym_t *jl_gensym(); jl_array_t *jl_alloc_array_1d(jl_type_t *atype, size_t nr); DLLEXPORT jl_array_t *jl_cstr_to_array(char *str); diff --git a/lib/bitvector.c b/lib/bitvector.c index 670f163995499..11c3e9fb307bb 100644 --- a/lib/bitvector.c +++ b/lib/bitvector.c @@ -102,7 +102,7 @@ uint32_t bitvector_next(uint32_t *b, uint64_t n0, uint64_t n) uint32_t nw = (n+31)>>5; uint32_t w; - if (i < nw-1) + if (i < nw-1 || (n&31)==0) w = b[i]>>nb; else w = (b[i]&lomask(n&31))>>nb; diff --git a/multi.j b/multi.j index 9421d79e7e093..d3039673074d6 100644 --- a/multi.j +++ b/multi.j @@ -248,9 +248,10 @@ function pmap_s(wpool, fname, lst) fut end +# fv(a)=eig(a)[2][2] # A=randn(800,800);A=A*A'; # wp=WorkPool(3) -# pmap_d(wp, `eig, {A,A,A}) +# pmap_d(wp, `fv, {A,A,A}) # p={Worker(),Worker()} -# pmap_s(p,`eig,{A,A}) +# pmap_s(p,`fv,{A,A}) diff --git a/task.c b/task.c index b7353393801e0..a54a348f17f9a 100644 --- a/task.c +++ b/task.c @@ -1,6 +1,6 @@ /* task.c - lightweight processes (or asymmetric coroutines) + lightweight processes (symmetric coroutines) */ #include #include