# HG changeset patch # User Mike Pavone # Date 1282706537 14400 # Node ID 43cc42df26cc46c7c360dda89e6431e3f0e8efda # Parent 7428aa5d6ade684219b05d9b49a761aefda52ec1 Various compiler improvements diff -r 7428aa5d6ade -r 43cc42df26cc array.rhope --- a/array.rhope Wed Aug 11 03:13:28 2010 -0400 +++ b/array.rhope Tue Aug 24 23:22:17 2010 -0400 @@ -20,6 +20,7 @@ { _internal_array_copyout[array(Array), index(Int32,Naked), dest(Any Type,Boxed,Mutable):dest] _internal_array_copyin[array(Array,Boxed,Mutable), index(Int32,Naked), val:array] + _internal_array_copychunk[source(Array), sindex(Int32,Naked), dest(Array,Boxed,Mutable), dindex(Int32,Naked), len(Int32,Naked):dest] _internal_array_getboxed[array(Boxed Array), index(Int32,Naked):out] _internal_array_setboxed[array(Boxed Array,Boxed,Mutable), index(Int32,Naked), val:array] _internal_array_allocboxed[size(Int32,Naked):out(Boxed Array)] diff -r 7428aa5d6ade -r 43cc42df26cc cbackend.rhope --- a/cbackend.rhope Wed Aug 11 03:13:28 2010 -0400 +++ b/cbackend.rhope Tue Aug 24 23:22:17 2010 -0400 @@ -1181,6 +1181,11 @@ out <- [text]Append[ [["object * _const_"]Append[Escape Rhope Name[name]]]Append[";\n"] ] } +_Consts C Release[text,value,name:out] +{ + out <- [text]Append[ [["\trelease_ref(_const_"]Append[Escape Rhope Name[name]]]Append[");\n"] ] +} + _List Literal El[text,val,index,type reg:out] { out <- [[[[text @@ -1467,8 +1472,9 @@ #include \"blueprint.h\" #include \"array.h\" #include \"worker.h\" -#include \"bool.h\"\n\n" - out <- [[[[[[[[[[[[[[[headers +#include \"bool.h\" +#include \n\n" + out <- [[[[[[[[[[[[[[[[[headers ]Append[[program]Dispatch[all methods]] ]Append[[[program]Type Registry >>]Type Defs] ]Append[Fold["_Consts C Program", @@ -1476,8 +1482,17 @@ constants]] ]Append[Fold[["_Text C Program"]Set Input[2, [program]Type Registry >>], "", Filter[[program]Functions >>, "Not Native"]]] ]Append["\n +#ifdef ENABLE_PROFILING +uint64_t profile_counts[END]; +uint64_t profile_totals[END]; +uint64_t profile_selftotals[END]; +#endif + int32_t rhope(uint32_t func, object ** params, uint16_t numparams, uint16_t callspace) { +#ifdef ENABLE_PROFILING + struct timeval time; +#endif uint16_t resume,idx, vcparam_offset, last_vcparam; context * ct; calldata * cdata, *temp_cdata, *my_cdata; @@ -1587,7 +1602,20 @@ inout[1] = make_String(argv[idx]); rhope(FUNC_Append, inout, 2, 2); } - numret = rhope(FUNC_Main, inout, 1, 1); + numret = rhope(FUNC_Main, inout, 1, 1);"] + ]Append[Fold["_Consts C Release", "", constants]] + ]Append[ + " + print_mem_info(manager); + print_live_object_types(manager); + +#ifdef ENABLE_PROFILING + for (idx = 0; idx < END; ++idx) + { + if(profile_counts[idx]) + printf(\"Func: %d\tCount: %llu\tTime: %llu\tAvg: %f\tSelf: %llu\tAvg: %f\n\", idx, profile_counts[idx], profile_totals[idx], ((double)profile_totals[idx])/((double)profile_counts[idx]), profile_selftotals[idx], ((double)profile_selftotals[idx])/((double)profile_counts[idx])); + } +#endif if (!numret) return 0; if (numret < 0) diff -r 7428aa5d6ade -r 43cc42df26cc ctobin --- a/ctobin Wed Aug 11 03:13:28 2010 -0400 +++ b/ctobin Tue Aug 24 23:22:17 2010 -0400 @@ -18,6 +18,7 @@ CC="gcc" fi +echo "$CC -o $bin $2 $1.c blueprint.c context.c fixed_alloc.c object.c" $CC -o $bin $2 "$1.c" blueprint.c context.c fixed_alloc.c object.c cd .. diff -r 7428aa5d6ade -r 43cc42df26cc genasm.rhope --- a/genasm.rhope Wed Aug 11 03:13:28 2010 -0400 +++ b/genasm.rhope Tue Aug 24 23:22:17 2010 -0400 @@ -1,5 +1,3 @@ -//Import extendlib.rhope -Import backendutils.rhope Blueprint Registers { @@ -317,20 +315,6 @@ out <- [pointer]Target Size >> } -Blueprint X86 Instruction -{ - Name - Op1 - Op2 - Width - Extra Offset -} - -X86 Instruction[name, op1, op2, width:out] -{ - out <- [[[[[Build["X86 Instruction"]]Name << [name]]Op1 << [op1]]Op2 <<[op2]]Width <<[width]]Extra Offset <<[0] -} - CAppend[left,right:out] { If[[right] = [""]] @@ -341,589 +325,3 @@ } } -Inst ASM@X86 Instruction[inst,func:out] -{ - If[[[inst]Width >>] = [4]] - { - regs <- ("eax","ecx","edx","ebx","esi","edi","esp") - }{ - If[[[inst]Width >>] = [2]] - { - regs <- ("ax","cx","dx","bx","si","di") - }{ - regs <- ("al","cl","dl","bl","si","di") - } - } - out <- [[[inst]Name >> - ]Append[ [" "]CAppend[[[inst]Op1>>]Op ASM[func, regs, [inst]Extra Offset >>]] ] - ]Append[ [", "]CAppend[[[inst]Op2>>]Op ASM[func, regs, [inst]Extra Offset >>]] ] -} - -Blueprint X86 Function -{ - Name - Registers - Variables - Scratch - Need Save - Free Stack Locations - Stack Size - Param Size - Temp Stack - Convention - Instructions -} - -X86 Function[name,params,convention:out] -{ - [[[[[[[[[Build["X86 Function"] - ]Name << [name] - ]Registers << [Registers[("eax","ecx","edx","ebx","esi","edi"), (0,1,2,3,4,5), (0,1,2,3,4,5), (3,4,5), 4]] - ]Variables <<[New@Dictionary[]] - ]Need Save <<[()] - ]Free Stack Locations <<[()] - ]Stack Size <<[0] - ]Instructions <<[()] - ]Convention <<[convention] - ]Alloc Params[params, convention] - { - out <- [~]Param Size <<[ [~]Stack Size >> ] - } -} - -Pointer Size@X86 Function[func:out] -{ - out <- 4 -} - -Param Helper@X86 Function[func, param:out] -{ - ,loc <- [func]Allocate Stack[4] - { - out <- [~]Variables << [ [[~]Variables >>]Set[param, loc] ] - } -} - -Alloc Params@X86 Function[func,params,convention:out] -{ - If[[convention] = ["fastcall"]] - { - [params]Index[0] - { - next func <- [[func]Registers <<[ [[func]Registers >>]Available? <<[ [[[func]Registers >>]Available? >>]Set[1, No] ]] - ]Variables <<[ [[func]Variables >>]Set[~, Register[1,4]] ] - [params]Index[1] - { - next func2 <- [[next func]Registers <<[ [[next func]Registers >>]Available? <<[ [[[next func]Registers >>]Available? >>]Set[2, No] ]] - ]Variables <<[ [[next func]Variables >>]Set[~, Register[2,4]] ] - [params]Index[2] - { - out <- _Fold[params, 2, next func2, "Param Helper"] - }{ - out <- Val[next func2] - } - }{ - out <- Val[next func] - } - }{ - out <- func - } - }{ - out <- Fold["Param Helper", func, params] - } -} - -Add Instruction@X86 Function[func, inst:out] -{ - out <- [func]Instructions << [ [[func]Instructions >>]Append[ [inst]Extra Offset <<[[func]Temp Stack >>] ] ] -} - -Allocate Stack@X86 Function[func,size:func out,out] -{ - out <- Stack Location[[func]Stack Size >>, size] - func out <- [func]Stack Size <<[ [[func]Stack Size >>]+[size] ] -} - -Allocate Var@X86 Function[func,name,size,type:out func,out] -{ - out func, out <- Processor Allocate[func,name,size,type] -} - -Resolve@X86 Function[func,op:out,out func] -{ - If[[Type Of[op]] = ["String"]] - { - out <- [[func]Variables >>]Index[op] - }{ - out <- op - } -} - -Allocate Scratch@X86 Function[func,size:out func,scratch] -{ - out func,scratch <- Processor Reg[func,"data"] {} {} - { - //FIXME: need to use a reg that's not involved in the current op - //FIXME: Also, might need two scratch regs and both might be in use - ,stack inc <- [func]Save Reg[0] - { - out func <- [~]Scratch << [ [[~]Scratch >>]Set[0, Yes] ] - } - } -} - -Free Scratch@X86 Function[func,scratch:out func] -{ - [[func]Scratch >>]Index[scratch] - { - [func]Restore Reg[scratch] - { - out func <- [~]Scratch << [ [[~]Scratch >>]Remove[scratch] ] - } - }{ - out func <- Processor Free Reg[func, scratch] - } - If[[scratch]Index[1]] - { - - }{ - - } -} - -Classify Op@X86 Function[func,op:class] -{ - If[[op]In Memory?] - { - If[[Type Of[op]] = ["Pointer"]] - { - If[[[[op]Base >>]In Memory?] Or [[[op]Offset >>]In Memory?]] - { - class <- "u" - }{ - class <- "m" - } - }{ - class <- "m" - } - }{ - class <- "r" - } -} - -RegMem2Op@X86 Function[func,dest,notdest,op,size:out] -{ - out <- [func]Add Instruction[X86 Instruction[op, dest, notdest, size]] -} - -MemPointer2Op@X86 Function[func,dest,notdest,op,size:out] -{ - ,scratch <- [func]Allocate Scratch[size] - { - out <- [[[~]Fetch[notdest,scratch] - ]Add Instruction[X86 Instruction[op, dest, scratch, size]] - ]Free Scratch[scratch] - } -} - -//Make sure to map this to both r, (m or r) -> m and r, (m or r) -> r -RegMemToNotPointer@X86 Function[func,source1,source2,dest,op,size:out] -{ - out <- [[func]Move[source2,dest] - ]Add Instruction[X86 Instruction[op, dest, source1, size]] -} - -RegMemToPointer@X86 Function[func,source1,source2,dest,op,size:out] -{ - ,scratch <- [func]Allocate Scratch[size] - { - spointer <- Pointer[scratch, None[], size] - out <- [[[[~]Calculate Address[dest, scratch] - ]Move[source2, spointer] - ]Add Instruction[X86 Instruction[op, spointer, source1, size]] - ]Free Scratch[scratch] - } -} - -RegPointerToMem@X86 Function[func,source1,source2,dest,op,size:out] -{ - ,scratch <- [func]Allocate Scratch[size] - { - spointer <- Pointer[scratch, None[], size] - out <- [[[[~]Calculate Address[source2, scratch] - ]Move[spointer, dest] - ]Add Instruction[X86 Instruction[op, dest, source1, size]] - ]Free Scratch[scratch] - } -} - -RegPointerReg2Op@X86 Function[func,dest,notdest,op,size:out] -{ - ,scratch <- [func]Allocate Scratch[size] - { - spointer <- Pointer[scratch, None[], size] - out <- [[[~]Calculate Address[notdest, scratch] - ]Add Instruction[X86 Instruction[op, dest, spointer, size]] - ]Free Scratch[scratch] - } -} - -RegPointerPointer2Op@X86 Function[func,dest,notdest,op,size:out] -{ - ,scratch <- [func]Allocate Scratch[size] - { - spointer <- Pointer[scratch, None[], size] - out <- [[[~]Calculate Address[dest, scratch] - ]Add Instruction[X86 Instruction[op, spointer, notdest, size]] - ]Free Scratch[scratch] - } -} - -RegPointerToPointer@X86 Function[func,source1,source2,dest,op,size:out] -{ - ,scratch <- [func]Allocate Scratch[size] - { - spointer <- Pointer[scratch, None[], size] - ,scratch2 <- [~]Allocate Scratch[size] - { - spointer2 <- Pointer[scratch2, None[], size] - out <- [[[[[[~]Calculate Address[source2, scratch] - ]Calculate Address[dest, scratch2] - ]Move[spointer2, spointer] - ]Add Instruction[X86 Instruction[op, spointer2, source1, size]] - ]Free Scratch[scratch2] - ]Free Scratch[scratch] - } - } -} - -//If source1, source2 and dest are all pointers with register offsets, allocating a scratch register could -//become a problem unless I let ebp be used as a scratch register. Should be doable as long as thread local -//variables properly report ebp as a used register. Alternatively, one register could be reserved for scratch -//usage -MemPointerToMem@X86 Function[func,source1,source2,dest,op,size:out] -{ - ,scratch <- [func]Allocate Scratch[size] - { - out <- [[[[~]Fetch[source2, scratch] - ]Add Instruction[X86 Instruction[op, scratch, source1, size]] - ]Move[scratch, dest] - ]Free Scratch[scratch] - } -} - -MemPointerToPointer@X86 Function[func,source1,source2,dest,op,size:out] -{ - ,scratch <- [func]Allocate Scratch[size] - { - ,scratch2 <- [~]Allocate Scratch[size] - { - spointer2 <- Pointer[scratch2, None[], size] - out <- [[[[[[~]Fetch[source2, scratch] - ]Add Instruction[X86 Instruction[op, scratch, source1, size]] - ]Calculate Address[dest, scratch2] - ]Move[scratch, spointer2] - ]Free Scratch[scratch2] - ]Free Scratch[scratch] - } - } -} - -//This does almost the same thing as RegMemToNotPointer, depending on how I do the pattern matching I could maybe combine them -PointerMemToReg@X86 Function[func,source1,source2,dest,op,size:out] -{ - out <- [[func]Fetch[source1,dest] - ]Add Instruction[X86 Instruction[op, dest, source2, size]] -} - -PointerPointer2Op@X86 Function[func,dest,notdest,op,size:out] -{ - ,scratch <- [func]Allocate Scratch[size] - { - spointer <- Pointer[scratch, None[], size] - ,scratch2 <- [~]Allocate Scratch[size] - { - out <- [[[[[[[~]Calculate Address[dest, scratch] - ]Fetch[notdest, scratch2] - ]Add Instruction[X86 Instruction[op, scratch, scratch2, size]] - ]Calculate Address[dest, scratch2] - ]Move[scratch, spointer2] - ]Free Scratch[scratch2] - ]Free Scratch[scratch] - } - } -} - -PointerPointerToPointer@X86 Function[func,source1,source2,dest,op,size:out] -{ - ,scratch <- [func]Allocate Scratch[size] - { - ,scratch2 <- [~]Allocate Scratch[size] - { - spointer2 <- Pointer[scratch2, None[], size] - out <- [[[[[[[~]Fetch[source1, scratch] - ]Calculate Address[source2, scratch2] - ]Add Instruction[X86 Instruction[op, scratch, spointer2, size]] - ]Calculate Address[dest, scratch2] - ]Move[scratch, spointer2] - ]Free Scratch[scratch2] - ]Free Scratch[scratch] - } - } -} - -PointerPointerToMem@X86 Function[func,source1,souce2,dest,op,size:out] -{ - ,scratch <- [func]Allocate Scratch[size] - { - spointer <- Pointer[scratch, None[], size] - out <- [[[[[~]Calculate Address[source1, scratch] - ]Move[dest, spointer] - ]Fetch[source2, scratch] - ]Add Instruction[X86 Instruction[op, dest, scratch, size]] - ]Free Scratch[scratch] - } -} - -PointerPointerToReg@X86 Function[func,source1,souce2,dest,op,size:out] -{ - ,scratch <- [func]Allocate Scratch[size] - { - spointer <- Pointer[scratch, None[], size] - out <- [[[[~]Fetch[source1, dest] - ]Calculate Address[source2, scratch] - ]Add Instruction[X86 Instruction[op, dest, scratch, size]] - ]Free Scratch[scratch] - } -} - -2Op Associative@X86 Function[func,psource1,psource2,pdest,name:out func] -{ - source1 <- [func]Resolve[psource1] - source2 <- [func]Resolve[psource2] - dest <- [func]Resolve[pdest] - dest class <- [func]Classify Op[dest] - width <- Min[Min[Min[[source1]Size,[source2]Size], [dest]Size], 4] - swapper <- (1,0) - sources <- [[()]Append[source1]Append[source2] - [sources]Find[dest] - { - source <- [swapper]Index[~] - source class <- [func]Classify Op[source] - If[[dest class] = ["u"]] - { - If[[source class] = ["r"]] - { - out func <- [func]RegPointerPointer2Op[dest,source,name,width] - }{ - out func <- [func]PointerPointer2Op[dest,source,name,width] - } - }{ - If[[dest class] = ["r"]] - { - If[[source class] = ["u"]] - { - out func <- [func]RegPointerReg2Op[dest,source,name,width] - }{ - out func <- [func]RegMem2Op[dest,source,name,width] - } - }{ - If[[source class] = ["r"]] - { - out func <- [func]RegMem2Op[dest,source,name,width] - }{ - out func <- [func]MemPointer2Op[dest,source,name,width] - } - } - } - }{ - sclasses <- Map[sources, ["Classify Op"]Set Input[0, func]] - first <- [sources]Index[found index] - other index <- [swapper]Index[found index] - other <- [sources]Index[other index] - other class <- [sclasses]Index[other index] - found index <- [sclasses]Find["r"] - { - If[[other class] = ["u"]] - { - If[[dest class] = ["m"]] - { - out func <- [func]RegPointerToMem[first,other,dest,name,width] - }{ - If[[dest class] = ["u"]] - { - out func <- [func]RegPointerToPointer[first,other,dest,name,width] - }{ - out func <- [func]PointerMemToReg[other,first,dest,name,width] - } - } - }{ - If[[dest class] = ["u"]] - { - out func <- [func]RegMemToPointer[first,other,dest,name,width] - }{ - out func <- [func]RegMemToNotPointer[first,other,dest,name,width] - } - } - }{ - found index <- [sclasses]Find["m"] - { - If[[dest class] = ["r"]] - { - out func <- [func]PointerMemToReg[other,first,dest,name,width] - }{ - If[[dest class] = ["m"]] - { - out func <- [func]MemPointerToMem[first,other,dest,name,width] - }{ - out func <- [func]MemPointerToPointer[first,other,dest,name,width] - } - } - }{ - If[[dest class] = ["r"]] - { - out func <- [func]PointerPointerToReg[first,other,dest,name,width] - }{ - If[[dest class] = ["m"]] - { - out func <- [func]PointerPointerToMem[first,other,dest,name,width] - }{ - out func <- [func]PointerPointerToPointer[first,other,dest,name,width] - } - } - } - } - } -} - -2Op@X86 Function[func,psource1,psource2,pdest,name:out func] -{ - source1 <- [func]Resolve[psource1] - source2 <- [func]Resolve[psource2] - dest <- [func]Resolve[pdest] - width <- Min[Min[Min[[source1]Size,[source2]Size], [dest]Size], 4] - If[[source1] = [dest]] - { - If[[[source1]In Memory?] And [[source2]In Memory?]] - { - ,scratch, stack inc <- [func]Allocate Scratch[width] - { - out func <- [[[~]Add Instruction[X86 Instruction["mov", [scratch]Index[0], source2, width, stack inc]] - ]Add Instruction[X86 Instruction[name, source1, [scratch]Index[0], width, stack inc]] - ]Free Scratch[scratch] - } - }{ - out func <- [func]Add Instruction[X86 Instruction[name, dest, source2, width, 0]] - } - }{ - If[[dest]In Memory?] - { - If[[source2]In Memory?] - { - ,scratch, stack inc <- [func]Allocate Scratch[width] - { - out func <- [[[[~]Add Instruction[X86 Instruction["mov", [scratch]Index[0], source1, width, stack inc]] - ]Add Instruction[X86 Instruction[name, [scratch]Index[0], source2, width, stack inc]] - ]Add Instruction[X86 Instruction["mov", dest, [scratch]Index[0], width, stack inc]] - ]Free Scratch[scratch] - } - }{ - out func <- [[func]Move[source1,dest] - ]Add Instruction[X86 Instruction[name, dest, source2, width, 0]] - } - }{ - out func <- [[func]Move[source1,dest] - ]Add Instruction[X86 Instruction[name, dest, source2, width, 0]] - } - } -} - -Add@X86 Function[func,source1,source2,dest:out func] -{ - out func <- [func]2Op Associative[source1,source2,dest,"add"] -} - -Sub@X86 Function[func,source1,source2,dest:out func] -{ - out func <- [func]2Op[source1,source2,dest,"sub"] -} - -Move@X86 Function[func,psource,pdest:out func] -{ - source <- [func]Resolve[psource] - dest <- [func]Resolve[pdest] - out func <- [func]Add Instruction[X86 Instruction["mov", dest, source, 4]] -} - -Instruction ASM[current,instruction,func:out] -{ - out <- [[[current]Append["\t"]]Append[ [instruction]Inst ASM[func] ]]Append["\n"] -} - -Save Reg@X86 Function[func,reg:out] -{ - out <- [[func]Add Instruction[X86 Instruction["push", Register[reg, 4], None[], 4]] - ]Temp Stack << [ [[func]Temp Stack >>]+[4] ] -} - -Prolog Save@X86 Function[func,junk,reg:out] -{ - out <- [[func]Add Instruction[X86 Instruction["push", Register[reg, 4], None[], 4]] - ]Stack Size << [ [[func]Stack Size >>]+[4] ] -} - -Restore Reg@X86 Function[func,reg:out] -{ - out <- [[func]Add Instruction[X86 Instruction["pop", Register[reg, 4], None[], 4]] - ]Temp Stack << [ [[func]Temp Stack >>]-[4] ] -} - -Epilogue Restore@X86 Function[func,junk,reg:out] -{ - out <- [func]Add Instruction[X86 Instruction["pop", Register[reg, 4], None[], 4]] -} - -Finalize@X86 Function[func:out] -{ - alloc stack <- [[func]Stack Size >>] - [[func]Param Size >>] - - oldstream <- [func]Instructions >> - - If[[alloc stack] > [0]] - { - start <- [()]Append[X86 Instruction["sub", Register[6, 4],Immediate[alloc stack], Register[6, 4], 4], func] - }{ - start <- () - } - - If[[[func]Convention >>] = ["cdecl"]] - { - If[ [alloc stack] > [0] ] - { - retparam <- Immediate[alloc stack] - }{ - retparam <- None[] - } - }{ - retparam <- Immediate[[func]Stack Size >>] - } - - [[func]Need Save >>]First - { - prolog <- Fold["Prolog Save", [func]Instructions << [start], [func]Need Save >>] - out <- [Reverse Fold["Epilogue Restore", body, [func]Need Save >>]]Add Instruction[X86 Instruction["ret", retparam, None[], 4]] - }{ - prolog <- [func]Instructions <<[start] - out <- [body]Add Instruction[X86 Instruction["ret", retparam, None[], 4]] - } - - body <- Fold["Add Instruction", prolog, oldstream] -} - -Text@X86 Function[func:out] -{ - name line <- [Escape Rhope Name[[func]Name >>] - ]Append[":\n"] - - out <- Fold[["Instruction ASM"]Set Input[2, func], name line, [func]Instructions >>] -} diff -r 7428aa5d6ade -r 43cc42df26cc hello.rhope --- a/hello.rhope Wed Aug 11 03:13:28 2010 -0400 +++ b/hello.rhope Tue Aug 24 23:22:17 2010 -0400 @@ -4,8 +4,8 @@ //All programs in Rhope must have a Main worker //This is where execution of a Rhope program begins -Main[] +Main[:out] { //The Print worker prints a line of text to the terminal - Print["Hello Rhope Programming!"] -} \ No newline at end of file + out <- Print["Hello Rhope Programming!"] +} diff -r 7428aa5d6ade -r 43cc42df26cc nworker.rhope --- a/nworker.rhope Wed Aug 11 03:13:28 2010 -0400 +++ b/nworker.rhope Tue Aug 24 23:22:17 2010 -0400 @@ -492,9 +492,27 @@ out,node index <- [worker]Add Typed Input[name,number,Type Instance["Any Type"]] } +Add Anon Input@NWorker[worker,number:out] +{ + If[[number]>[Length[[worker]Inputs >>]]] + { + prepped <- [worker]Add Anon Input[[number]-[1]] + }{ + prepped <- Val[worker] + } + out <- out <- [[prepped]Inputs <<[[[prepped]Inputs >>]Set[number,[" unnamed"]Append[number]]] + ]Input Types <<[[[prepped]Input Types >>]Set[number,Type Instance["Any Type"]]] +} + Add Typed Input@NWorker[worker,name,number,type:out,node index] { - ,node index <- [worker]Add Node["input",number,0,1] + If[[number]>[Length[[worker]Inputs >>]]] + { + prepped <- [worker]Add Anon Input[[number]-[1]] + }{ + prepped <- Val[worker] + } + ,node index <- [prepped]Add Node["input",number,0,1] { out <- [[~]Inputs <<[[[~]Inputs >>]Set[number,name]] ]Input Types <<[[[~]Input Types >>]Set[number,type]] @@ -873,7 +891,7 @@ [conditions]For Backend { stream <- [[withconst]Instruction Stream - ]Move[Constant[constname], [[["__result_"]Append[node index]]Append["_"]]Append[0]] + ]Move[Strip Addref[Constant[constname]], [[["__result_"]Append[node index]]Append["_"]]Append[0]] nfunc <- [withconst]Do If[~, stream] }{ nfunc <- Val[withconst] @@ -943,8 +961,7 @@ Release Var@NWorker[worker,func,name:out] { - //_result_index_ionum - Print[["Release Var@NWorker: "]Append[name]] + //__result_index_ionum parts <- [name]Split["_"] index <- > - dest node <- [[worker]Nodes >>]Index[dest index] - { Print["got dest node"] } - - [[dest node]Conditions >>]For Backend + ,normal <- If[[[dests]Length] = [1]] + { + dest ionum <- [[dests]Index[0]]IO Num >> + If[[[[dests]Index[0]]IO Num >>]=[-1]] { - Print["dest has conditions"] - out <- [func]Do If[AndCond[NotCond[~], name], [[func]Instruction Stream]Release[name]] - { Print["got output"] } + normal <- Yes }{ - Print["No conditions on dest, no release needed"] - out <- func + dest index <- [[dests]Index[0]]Index >> + dest node <- [[worker]Nodes >>]Index[dest index] + + [[dest node]Conditions >>]For Backend + { + out <- [func]Do If[AndCond[NotCond[~], name], [[func]Instruction Stream]Release[name]] + }{ + out <- func + } } - }{ - Print["Multiple (or zero) dests, definitely release"] + } + + Val[normal] + { do if <- If[[[node]Outputs >>] > [1]] {} { do if <- [[node]Conditions >>]Empty? {} @@ -1079,6 +1098,27 @@ } } +Release Raw Inputs[func,input type,index,inputs,outputs:out] +{ + If[[[input type]Variant >>] = ["Raw Pointer"]] + { + name <- [inputs]Index[index] + If[[input type]Mutable? >>] + { + [outputs]Find[[inputs]Index[index]] + { + out <- func + }{ + out <- [func]Release[name] + } + }{ + out <- [func]Release[name] + } + }{ + out <- func + } +} + FParams[input:out] { iname <- [input]Index[0] @@ -1161,8 +1201,9 @@ Fold[["FInputs"]Set Input[3, [worker]Inputs >>], rfunc, [worker]Input Types >>] { [~]Call Foreign[name, [worker]Convention >>, Map[Zip[[worker]Inputs >>, [worker]Input Types >>], "FParams"], rparam] + { Fold[[["Release Raw Inputs"]Set Input[3, [worker]Inputs >>]]Set Input[4, [worker]Outputs >>], ~, [worker]Input Types >>] { Fold[[[["Save Foreign Result"]Set Input[3, [worker]Output Types >>]]Set Input[4, [worker]Inputs >>]]Set Input[5, [worker]Input Types >>], ~, [worker]Outputs >>] - { out <- [program]Store Function[~] }}} + { out <- [program]Store Function[~] }}}} } Compile Worker@NWorker[worker,program,name:out] diff -r 7428aa5d6ade -r 43cc42df26cc runtime/array.c --- a/runtime/array.c Wed Aug 11 03:13:28 2010 -0400 +++ b/runtime/array.c Tue Aug 24 23:22:17 2010 -0400 @@ -18,6 +18,23 @@ release_ref(val); } +void _internal_array_copychunk(object * src, int32_t srcidx, object * dest, int32_t destidx, int32_t len) +{ + int32_t idx; + object * cur; + t_Array *sarr,*darr; + sarr = (t_Array *)src; + darr = (t_Array *)dest; + memcpy((char *)(darr+1) + darr->payload.Eltype->bp->size * destidx, (char *)(sarr+1) + sarr->payload.Eltype->bp->size * srcidx, len*sarr->payload.Eltype->bp->size); + cur = (object *)((char *)(darr+1) + darr->payload.Eltype->bp->size * destidx - sizeof(object)); + for (idx = 0; idx < len; ++idx) + { + darr->payload.Eltype->bp->copy(cur); + cur++; + } + release_ref(src); +} + object * _internal_array_getboxed(object * array, int32_t index) { object * ret; diff -r 7428aa5d6ade -r 43cc42df26cc runtime/array.h --- a/runtime/array.h Wed Aug 11 03:13:28 2010 -0400 +++ b/runtime/array.h Tue Aug 24 23:22:17 2010 -0400 @@ -7,6 +7,7 @@ void _internal_array_copyout(object * array, int32_t index, object * dest); void _internal_array_copyin(object * array, int32_t index, object * val); +void _internal_array_copychunk(object * src, int32_t srcidx, object * dest, int32_t destidx, int32_t len); object * _internal_array_getboxed(object * array, int32_t index); void _internal_array_setboxed(object *, int32_t index, object * val); object *_internal_array_allocboxed(int32_t size); diff -r 7428aa5d6ade -r 43cc42df26cc runtime/blueprint.c --- a/runtime/blueprint.c Wed Aug 11 03:13:28 2010 -0400 +++ b/runtime/blueprint.c Tue Aug 24 23:22:17 2010 -0400 @@ -21,6 +21,8 @@ { t_Blueprint * l = (t_Blueprint *)left; t_Blueprint * r = (t_Blueprint *)right; + release_ref(left); + release_ref(right); return l->bp == r->bp; } diff -r 7428aa5d6ade -r 43cc42df26cc runtime/fixed_alloc.c --- a/runtime/fixed_alloc.c Wed Aug 11 03:13:28 2010 -0400 +++ b/runtime/fixed_alloc.c Tue Aug 24 23:22:17 2010 -0400 @@ -1,4 +1,5 @@ #include "fixed_alloc.h" +#include "object.h" #include #include #include @@ -24,8 +25,9 @@ { int i,count,freeobjs; mem_block * cur; - printf("Free blocks: %d\n", manager->freecount); - printf("Full Blocks: %d\n", manager->fullcount); + //printf("Free blocks: %d\n", manager->freecount); + if (manager->fullcount) + printf("Full Blocks: %d\n", manager->fullcount); for (i = 0; i < (MAX_SIZE-MIN_SIZE)/STRIDE; i++) { count = 0; @@ -37,11 +39,47 @@ freeobjs += ((int)cur->numfree); cur = cur->next; } - printf("Bucket %d(size: %d) has %d blocks in use with %d total free slots\n", i, i*STRIDE+MIN_SIZE,count, freeobjs); + if (freeobjs) + printf("Bucket %d(size: %d) has %d blocks in use with %d free slots out of %d\n", i, i*STRIDE+MIN_SIZE,count, freeobjs, max_free[i]*count); } fflush(stdout); } +void print_live_object_types(mem_manager * manager) +{ + object * obj; + mem_block * cur; + int32_t i,j,bitslots,bit,*counts = malloc(sizeof(int32_t)*max_registered_type); + memset(counts, 0, sizeof(int32_t)*max_registered_type); + for (i = 0; i < (MAX_SIZE-MIN_SIZE)/STRIDE; i++) + { + cur = manager->inuse[i]; + while(cur) + { + bitslots = max_free[i]/8; + if(max_free[i]&7) + ++bitslots; + for(j = 0; j < bitslots; ++j) + if(cur->bitmap[j] != 0xFF) + { + for (bit = 0; bit < 8; ++bit) + { + if (!(cur->bitmap[j] & (1 << bit))) + { + obj = (object *)(((char *)cur)+BLOCK_SIZE-(((j*8+bit)+1)*(i*STRIDE+MIN_SIZE))); + counts[obj->bprint->type_id]++; + } + } + } + cur = cur->next; + } + } + for (i = 0; i < max_registered_type; ++i) + if(counts[i]) + printf("%d live objects of type %d\n", counts[i], i); + fflush(stdout); +} + void * falloc(size_t size, mem_manager * manager) { uint16_t i,bit; diff -r 7428aa5d6ade -r 43cc42df26cc runtime/fixed_alloc.h --- a/runtime/fixed_alloc.h Wed Aug 11 03:13:28 2010 -0400 +++ b/runtime/fixed_alloc.h Tue Aug 24 23:22:17 2010 -0400 @@ -44,5 +44,6 @@ void * falloc(size_t size, mem_manager * manager); void ffree(void * ptr, size_t size, mem_manager * manager); void print_mem_info(mem_manager * manager); +void print_live_object_types(mem_manager * manager); #endif //FIXED_ALLOC_H_ diff -r 7428aa5d6ade -r 43cc42df26cc runtime/func.h --- a/runtime/func.h Wed Aug 11 03:13:28 2010 -0400 +++ b/runtime/func.h Tue Aug 24 23:22:17 2010 -0400 @@ -33,12 +33,58 @@ #define MethodName(name,type) f_ ## name ## AT_ ## type +#ifdef ENABLE_PROFILING + +#define START_PROFILE \ + gettimeofday(&time, NULL);\ + cdata->accum = cdata->self_accum = 0;\ + cdata->self_start = cdata->start = ((uint64_t)time.tv_sec) * 1000000ULL + ((uint64_t)time.tv_usec); + +#define PAUSE_SELF \ + gettimeofday(&time, NULL);\ + my_cdata->self_accum += ((uint64_t)time.tv_sec) * 1000000ULL + ((uint64_t)time.tv_usec) - my_cdata->self_start; + +#define AND_TOTAL \ + my_cdata->accum += ((uint64_t)time.tv_sec) * 1000000ULL + ((uint64_t)time.tv_usec) - my_cdata->start; + +#define RESUME_SELF \ + gettimeofday(&time, NULL);\ + my_cdata->self_start = ((uint64_t)time.tv_sec) * 1000000ULL + ((uint64_t)time.tv_usec); + +#define AND_RESUME_TOTAL my_cdata->start = my_cdata->self_start; + +#define EndFunc(name) \ + free_stack(ct, lv_ ## name);\ + func = cdata->func;\ + gettimeofday(&time, NULL);\ + profile_counts[FUNC_ ## name]++;\ + profile_totals[FUNC_ ## name] += ((uint64_t)time.tv_sec) * 1000000ULL + ((uint64_t)time.tv_usec) - cdata->start + cdata->accum;\ + profile_selftotals[FUNC_ ## name] += ((uint64_t)time.tv_sec) * 1000000ULL + ((uint64_t)time.tv_usec) - cdata->self_start + cdata->self_accum; + +#else + +#define START_PROFILE +#define PAUSE_SELF +#define RESUME_SELF +#define AND_TOTAL +#define AND_RESUME_TOTAL + +#define EndFunc(name) \ + free_stack(ct, lv_ ## name);\ + func = cdata->func; + + +#endif + +#define EndFuncNoLocals \ + func = cdata->func; #define Func(name,numparams) \ f_ ## name:\ for(idx = numparams; idx < cdata->num_params; ++idx)\ release_ref(cdata->params[idx]); cdata->num_params = numparams;\ sf_ ## name:\ + START_PROFILE\ lv_ ## name = alloc_stack(ct, sizeof(lt_ ## name));\ my_cdata = cdata; @@ -50,32 +96,6 @@ sf_ ## name:\ my_cdata = cdata; -#define EndFunc(name) \ - free_stack(ct, lv_ ## name);\ - func = cdata->func; - -#define EndFuncNoLocals \ - func = cdata->func; - -#define Method(name) \ -f_ ## name:\ -sf_ ## name:\ - switch(get_blueprint(cdata->params[0])->type_id)\ - { - -#define EndMethod(name) \ - default:\ - printf("Type %d does not implement method %s\n", get_blueprint(cdata->params[0])->type_id, #name);\ - cdata = alloc_cdata(ct, cdata, 0);\ - cdata->func = FUNC_ ## name;\ - goto _exception;\ - } - - -#define MethodDispatch(type_id,name,type_name) \ - case type_id:\ - goto m_ ## name ## AT_ ## type_name; - #define MethodImpl(name,type_name,mytype_id,numparams) \ f_ ## name ## AT_ ## type_name:\ sf_ ## name ## AT_ ## type_name:\ @@ -91,6 +111,7 @@ exit(1);\ }\ m_ ## name ## AT_ ## type_name:\ + START_PROFILE\ for(idx = numparams; idx < cdata->num_params; ++idx)\ release_ref(cdata->params[idx]); cdata->num_params = numparams;\ lv_ ## name ## AT_ ## type_name = alloc_stack(ct, sizeof(lt_ ## name ## AT_ ## type_name));\ @@ -113,6 +134,26 @@ for(idx = numparams; idx < cdata->num_params; ++idx)\ release_ref(cdata->params[idx]); cdata->num_params = numparams;\ my_cdata = cdata; + + +#define Method(name) \ +f_ ## name:\ +sf_ ## name:\ + switch(get_blueprint(cdata->params[0])->type_id)\ + { + +#define EndMethod(name) \ + default:\ + printf("Type %d does not implement method %s\n", get_blueprint(cdata->params[0])->type_id, #name);\ + cdata = alloc_cdata(ct, cdata, 0);\ + cdata->func = FUNC_ ## name;\ + goto _exception;\ + } + + +#define MethodDispatch(type_id,name,type_name) \ + case type_id:\ + goto m_ ## name ## AT_ ## type_name; #define NumParams #define CallSpace @@ -175,11 +216,13 @@ cdata->func = RES_ ## resumeto ## _ ## myname;\ cdata->num_params = numparams + ((t_Worker *)tocall)->payload.Count;\ cdata->vars = lv_ ## myname;\ - func = ((t_Worker *)tocall)->payload.Index; + func = ((t_Worker *)tocall)->payload.Index;\ + PAUSE_SELF #define ValCallPostlude(resumeto,myname)\ r ## resumeto ## _ ## myname:\ my_cdata = cdata->lastframe;\ + RESUME_SELF\ lv_ ## myname = cdata->vars; @@ -187,9 +230,21 @@ cdata->func = RES_ ## resumeto ## _ ## myname;\ cdata->num_params = numparams;\ cdata->vars = lv_ ## myname;\ + if(FUNC_ ## tocall == FUNC_ ## myname) {\ + PAUSE_SELF\ + AND_TOTAL\ + } else if (FUNC_ ## tocall != FUNC_PL_ && FUNC_ ## tocall != FUNC_MN_ && FUNC_ ## tocall != FUNC_TM_ && FUNC_ ## tocall != FUNC_DV_ && FUNC_ ## tocall != FUNC_If) {\ + PAUSE_SELF\ + }\ goto sf_ ## tocall;\ r ## resumeto ## _ ## myname:\ my_cdata = cdata->lastframe;\ + if(FUNC_ ## tocall == FUNC_ ## myname) {\ + RESUME_SELF\ + AND_RESUME_TOTAL\ + } else if (FUNC_ ## tocall != FUNC_PL_ && FUNC_ ## tocall != FUNC_MN_ && FUNC_ ## tocall != FUNC_TM_ && FUNC_ ## tocall != FUNC_DV_ && FUNC_ ## tocall != FUNC_If) {\ + RESUME_SELF\ + }\ lv_ ## myname = cdata->vars; diff -r 7428aa5d6ade -r 43cc42df26cc runtime/object.h --- a/runtime/object.h Wed Aug 11 03:13:28 2010 -0400 +++ b/runtime/object.h Tue Aug 24 23:22:17 2010 -0400 @@ -45,10 +45,16 @@ struct calldata { struct calldata *lastframe; void *vars; - uint32_t func; - uint16_t num_params; - uint16_t callspace; - object *params[1]; +#ifdef ENABLE_PROFILING + uint64_t start; + uint64_t accum; + uint64_t self_start; + uint64_t self_accum; +#endif + uint32_t func; + uint16_t num_params; + uint16_t callspace; + object *params[1]; }; #pragma pack(pop) diff -r 7428aa5d6ade -r 43cc42df26cc string.rhope --- a/string.rhope Wed Aug 11 03:13:28 2010 -0400 +++ b/string.rhope Tue Aug 24 23:22:17 2010 -0400 @@ -543,7 +543,7 @@ { If[count] { - out <- [string]_Flatten[[dest]Append[ [[string]Buffer >>]Index[offset] ], [offset]+[1i32], [count]-[1i32]] + out <- [_internal_array_copychunk[[string]Buffer >>, offset, dest, [dest]Length, count]]Length <<[[[dest]Length]+[count]] }{ out <- dest } @@ -561,8 +561,13 @@ Flatten@String Slice[string:out] { - out <- [[Build[String()]]Buffer <<[ [[string]Source >>]_Flatten[Array[], [string]Offset >>, [string]ByteLen >>] ] - ]Length <<[[string]Length >>] + If[[string]ByteLen >>] + { + out <- [[Build[String()]]Buffer <<[ [[string]Source >>]_Flatten[_internal_array_allocnaked[[string]ByteLen >>, UInt8()], [string]Offset >>, [string]ByteLen >>] ] + ]Length <<[[string]Length >>] + }{ + out <- "" + } } Print@String Slice[string:out] @@ -665,12 +670,17 @@ Flatten@String Cat[string:out] { - out <- [[Build[String()] - ]Buffer << [ - [[string]Right >>]_Flatten[ - [[string]Left >>]_Flatten[Array[], 0i32, [[string]Left >>]Byte Length], - 0i32, [[string]Right >>]Byte Length]] - ]Length << [[string]Length >>] + If[[string]ByteLen >>] + { + out <- [[Build[String()] + ]Buffer << [ + [[string]Right >>]_Flatten[ + [[string]Left >>]_Flatten[_internal_array_allocnaked[[string]ByteLen >>, UInt8()], 0i32, [[string]Left >>]Byte Length], + 0i32, [[string]Right >>]Byte Length]] + ]Length << [[string]Length >>] + }{ + out <- "" + } } Print@String Cat[string:out]