From 6b0b7bebf98535365207d8430937ffcf217b37bb Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 5 Oct 2007 17:30:10 -0400 Subject: [PATCH] Simpler callstack layout --- core/cpu/ppc/architecture/architecture.factor | 2 +- core/cpu/ppc/bootstrap.factor | 4 +- core/cpu/x86/architecture/architecture.factor | 3 +- core/cpu/x86/bootstrap.factor | 13 ++-- vm/callstack.c | 61 +++++-------------- vm/callstack.h | 24 ++++++-- vm/cpu-ppc.h | 18 ------ vm/cpu-x86.h | 20 +----- vm/data_gc.c | 3 +- vm/debug.c | 3 +- vm/image.c | 8 +-- vm/os-linux-ppc.h | 2 +- vm/os-macosx-ppc.h | 2 +- 13 files changed, 53 insertions(+), 110 deletions(-) diff --git a/core/cpu/ppc/architecture/architecture.factor b/core/cpu/ppc/architecture/architecture.factor index 9814242cd5..6142b1e49f 100644 --- a/core/cpu/ppc/architecture/architecture.factor +++ b/core/cpu/ppc/architecture/architecture.factor @@ -90,7 +90,7 @@ M: ppc-backend %prologue ( n -- ) 0 MFLR 1 1 pick neg ADDI 11 1 pick xt-save STW - 11 1 factor-area-size neg ADDI + dup 11 LI 11 1 pick next-save STW 0 1 rot lr-save + STW ; diff --git a/core/cpu/ppc/bootstrap.factor b/core/cpu/ppc/bootstrap.factor index e3819dea91..c57a97aed5 100644 --- a/core/cpu/ppc/bootstrap.factor +++ b/core/cpu/ppc/bootstrap.factor @@ -36,8 +36,8 @@ big-endian on 0 MFLR 1 1 stack-frame neg ADDI xt-reg 1 xt-save STW ! save XT - xt-reg 1 factor-area-size neg ADDI - xt-reg 1 next-save STW ! save forward chain pointer + stack-frame xt-reg LI + xt-reg 1 next-save STW ! save frame size temp-reg 1 array-save STW ! save array 0 1 lr-save stack-frame + STW ! save return address ] { } make jit-prolog set diff --git a/core/cpu/x86/architecture/architecture.factor b/core/cpu/x86/architecture/architecture.factor index 328f96b5a9..0309df052b 100644 --- a/core/cpu/x86/architecture/architecture.factor +++ b/core/cpu/x86/architecture/architecture.factor @@ -50,8 +50,7 @@ M: x86-backend %save-xt ( -- ) : factor-area-size 4 cells ; M: x86-backend %prologue ( n -- ) - xt-reg PUSH - xt-reg stack-reg pick factor-area-size + neg [+] LEA + dup cell + PUSH xt-reg PUSH stack-reg swap 2 cells - SUB ; diff --git a/core/cpu/x86/bootstrap.factor b/core/cpu/x86/bootstrap.factor index 67156d8300..a8c1b9a8f2 100644 --- a/core/cpu/x86/bootstrap.factor +++ b/core/cpu/x86/bootstrap.factor @@ -10,15 +10,16 @@ big-endian off : scan-save stack-reg 3 bootstrap-cells [+] ; +: stack-frame-size 8 bootstrap-cells ; + [ arg0 arg0 quot-array@ [+] MOV ! load array scan-reg arg0 scan@ [+] LEA ! initialize scan pointer ] { } make jit-setup set - -[ + +[ + stack-frame-size PUSH ! save stack frame size xt-reg PUSH ! save XT - xt-reg stack-reg next-frame@ [+] LEA ! compute forward chain pointer - xt-reg PUSH ! save forward chain pointer arg0 PUSH ! save array stack-reg 4 bootstrap-cells SUB ! reserve space for scan-save ] { } make jit-prolog set @@ -31,7 +32,7 @@ big-endian off arg0 scan-reg [] MOV ! load literal ds-reg [] arg0 MOV ! store literal on datastack ] { } make jit-push-literal set - + [ advance-scan ds-reg bootstrap-cell ADD ! increment datastack pointer @@ -94,7 +95,7 @@ big-endian off ] { } make jit-dispatch set [ - stack-reg 7 bootstrap-cells ADD ! unwind stack frame + stack-reg stack-frame-size bootstrap-cell - ADD ! unwind stack frame ] { } make jit-epilog set [ 0 RET ] { } make jit-return set diff --git a/vm/callstack.c b/vm/callstack.c index ae1fef0cad..4ac2457dea 100644 --- a/vm/callstack.c +++ b/vm/callstack.c @@ -8,15 +8,13 @@ F_FASTCALL void save_callstack_bottom(F_STACK_FRAME *callstack_bottom) stack_chain->callstack_bottom = callstack_bottom; } -void iterate_callstack(CELL top, CELL bottom, CELL base, CALLSTACK_ITER iterator) +void iterate_callstack(CELL top, CELL bottom, CALLSTACK_ITER iterator) { - CELL delta = (bottom - base); - F_STACK_FRAME *frame = (F_STACK_FRAME *)bottom - 1; while((CELL)frame >= top) { - F_STACK_FRAME *next = REBASE_FRAME_SUCCESSOR(frame,delta); + F_STACK_FRAME *next = frame_successor(frame); iterator(frame); frame = next; } @@ -26,9 +24,8 @@ void iterate_callstack_object(F_CALLSTACK *stack, CALLSTACK_ITER iterator) { CELL top = (CELL)(stack + 1); CELL bottom = top + untag_fixnum_fast(stack->length); - CELL base = stack->bottom; - iterate_callstack(top,bottom,base,iterator); + iterate_callstack(top,bottom,iterator); } F_CALLSTACK *allot_callstack(CELL size) @@ -51,9 +48,9 @@ F_STACK_FRAME *capture_start(void) { F_STACK_FRAME *frame = stack_chain->callstack_bottom - 1; while(frame >= stack_chain->callstack_top - && FRAME_SUCCESSOR(frame) >= stack_chain->callstack_top) + && frame_successor(frame) >= stack_chain->callstack_top) { - frame = FRAME_SUCCESSOR(frame); + frame = frame_successor(frame); } return frame + 1; } @@ -73,31 +70,10 @@ DEFINE_PRIMITIVE(callstack) dpush(tag_object(callstack)); } -/* If a callstack object was captured at a different base stack height than -we have now, we have to patch up the back-chain pointers. */ -static F_FIXNUM delta; - -void adjust_stack_frame(F_STACK_FRAME *frame) -{ - FRAME_SUCCESSOR(frame) = REBASE_FRAME_SUCCESSOR(frame,delta); -} - -void adjust_callstack(F_CALLSTACK *stack, CELL bottom) -{ - delta = (bottom - stack->bottom); - iterate_callstack_object(stack,adjust_stack_frame); - stack->bottom = bottom; -} - DEFINE_PRIMITIVE(set_callstack) { F_CALLSTACK *stack = untag_callstack(dpop()); - CELL bottom = (CELL)stack_chain->callstack_bottom; - - if(stack->bottom != bottom) - adjust_callstack(stack,bottom); - set_callstack(stack_chain->callstack_bottom, FIRST_STACK_FRAME(stack), untag_fixnum_fast(stack->length), @@ -112,7 +88,8 @@ static CELL frame_count; static CELL frame_index; static F_ARRAY *array; -void count_stack_frame(F_STACK_FRAME *frame) { +void count_stack_frame(F_STACK_FRAME *frame) +{ frame_count += 2; } @@ -132,6 +109,11 @@ CELL frame_executing(F_STACK_FRAME *frame) return get(literal_start); } +F_STACK_FRAME *frame_successor(F_STACK_FRAME *frame) +{ + return (F_STACK_FRAME *)((CELL)frame - frame->size); +} + CELL frame_scan(F_STACK_FRAME *frame) { if(frame_type(frame) == QUOTATION_TYPE) @@ -157,10 +139,7 @@ DEFINE_PRIMITIVE(callstack_to_array) array = allot_array_internal(ARRAY_TYPE,frame_count); UNREGISTER_UNTAGGED(stack); - /* frame_count is equal to the total length now */ - frame_index = 0; - iterate_callstack_object(stack,stack_frame_to_array); dpush(tag_object(array)); @@ -170,14 +149,12 @@ F_STACK_FRAME *innermost_stack_frame(F_CALLSTACK *callstack) { CELL top = (CELL)(callstack + 1); CELL bottom = top + untag_fixnum_fast(callstack->length); - CELL base = callstack->bottom; - CELL delta = (bottom - base); F_STACK_FRAME *frame = (F_STACK_FRAME *)bottom - 1; while(frame >= (F_STACK_FRAME *)top - && REBASE_FRAME_SUCCESSOR(frame,delta) >= (F_STACK_FRAME *)top) - frame = REBASE_FRAME_SUCCESSOR(frame,delta); + && frame_successor(frame) >= (F_STACK_FRAME *)top) + frame = frame_successor(frame); return frame; } @@ -220,18 +197,12 @@ DEFINE_PRIMITIVE(set_innermost_stack_frame_quot) type_check(QUOTATION_TYPE,frame_executing(inner)); CELL scan = inner->scan - inner->array; - - CELL top = (CELL)(callstack + 1); - CELL bottom = top + untag_fixnum_fast(callstack->length); - CELL base = callstack->bottom; - CELL delta = (bottom - base); - - CELL offset = FRAME_RETURN_ADDRESS(inner,delta) - inner->xt; + CELL offset = FRAME_RETURN_ADDRESS(inner) - inner->xt; inner->array = quot->array; inner->scan = quot->array + scan; inner->xt = quot->xt; - FRAME_RETURN_ADDRESS(inner,delta) = quot->xt + offset; + FRAME_RETURN_ADDRESS(inner) = quot->xt + offset; } diff --git a/vm/callstack.h b/vm/callstack.h index fdff137604..6bbebfcd34 100644 --- a/vm/callstack.h +++ b/vm/callstack.h @@ -1,14 +1,30 @@ +typedef struct _F_STACK_FRAME +{ + /* In compiled quotation frames, position within the array. + In compiled word frames, unused. */ + CELL scan; + + /* In compiled quotation frames, the quot->array slot. + In compiled word frames, unused. */ + CELL array; + + /* In all compiled frames, the XT on entry. */ + XT xt; + + /* Pointer to the next stack frame; frames are chained from + the bottom on up */ + struct _F_STACK_FRAME *next; +} F_STACK_FRAME; + F_FASTCALL void save_callstack_bottom(F_STACK_FRAME *callstack_bottom); #define FIRST_STACK_FRAME(stack) (F_STACK_FRAME *)((stack) + 1) -#define FRAME_SUCCESSOR(frame) (frame)->next -#define REBASE_FRAME_SUCCESSOR(frame,delta) (F_STACK_FRAME *)((CELL)FRAME_SUCCESSOR(frame) + delta) - typedef void (*CALLSTACK_ITER)(F_STACK_FRAME *frame); -void iterate_callstack(CELL top, CELL bottom, CELL base, CALLSTACK_ITER iterator); +void iterate_callstack(CELL top, CELL bottom, CALLSTACK_ITER iterator); void iterate_callstack_object(F_CALLSTACK *stack, CALLSTACK_ITER iterator); +F_STACK_FRAME *frame_successor(F_STACK_FRAME *frame); CELL frame_executing(F_STACK_FRAME *frame); CELL frame_type(F_STACK_FRAME *frame); diff --git a/vm/cpu-ppc.h b/vm/cpu-ppc.h index ee651f70fb..88bbde5661 100644 --- a/vm/cpu-ppc.h +++ b/vm/cpu-ppc.h @@ -1,21 +1,3 @@ -typedef struct _F_STACK_FRAME -{ - /* In compiled quotation frames, the quot->array slot. - In compiled word frames, unused. */ - CELL array; - - /* In compiled quotation frames, position within the array. - In compiled word frames, unused. */ - CELL scan; - - /* In all compiled frames, the XT on entry. */ - XT xt; - - /* Pointer to the next stack frame; frames are chained from - the bottom on up */ - struct _F_STACK_FRAME *next; -} F_STACK_FRAME; - #define FACTOR_CPU_STRING "ppc" #define F_FASTCALL diff --git a/vm/cpu-x86.h b/vm/cpu-x86.h index cedf861a63..7983c139af 100644 --- a/vm/cpu-x86.h +++ b/vm/cpu-x86.h @@ -1,22 +1,4 @@ -typedef struct _F_STACK_FRAME -{ - /* In compiled quotation frames, position within the array. - In compiled word frames, unused. */ - CELL scan; - - /* In compiled quotation frames, the quot->array slot. - In compiled word frames, unused. */ - CELL array; - - /* Pointer to the next stack frame; frames are chained from - the bottom on up */ - struct _F_STACK_FRAME *next; - - /* In all compiled frames, the XT on entry. */ - XT xt; -} F_STACK_FRAME; - -#define FRAME_RETURN_ADDRESS(frame,delta) *(XT *)(REBASE_FRAME_SUCCESSOR(frame,delta) + 1) +#define FRAME_RETURN_ADDRESS(frame) *(XT *)(frame_successor(frame) + 1) INLINE void flush_icache(CELL start, CELL len) {} diff --git a/vm/data_gc.c b/vm/data_gc.c index a94dcadf81..24d75cf20c 100644 --- a/vm/data_gc.c +++ b/vm/data_gc.c @@ -395,8 +395,7 @@ void collect_callstack(F_CONTEXT *stacks) { CELL top = (CELL)stacks->callstack_top; CELL bottom = (CELL)stacks->callstack_bottom; - CELL base = bottom; - iterate_callstack(top,bottom,base,collect_stack_frame); + iterate_callstack(top,bottom,collect_stack_frame); } /* Copy roots over at the start of GC, namely various constants, stacks, diff --git a/vm/debug.c b/vm/debug.c index 57d195e2ba..07c67422c7 100644 --- a/vm/debug.c +++ b/vm/debug.c @@ -108,8 +108,7 @@ void print_callstack(void) { CELL bottom = (CELL)stack_chain->callstack_bottom; CELL top = (CELL)stack_chain->callstack_top; - CELL base = bottom; - iterate_callstack(top,bottom,base,print_stack_frame); + iterate_callstack(top,bottom,print_stack_frame); } void dump_cell(CELL cell) diff --git a/vm/image.c b/vm/image.c index 9fb13930a9..e5c4b45861 100644 --- a/vm/image.c +++ b/vm/image.c @@ -173,8 +173,6 @@ void fixup_alien(F_ALIEN *d) d->expired = T; } -F_FIXNUM delta; - void fixup_stack_frame(F_STACK_FRAME *frame) { code_fixup(&frame->xt); @@ -186,15 +184,11 @@ void fixup_stack_frame(F_STACK_FRAME *frame) frame->scan = scan + frame->array; } - code_fixup(&FRAME_RETURN_ADDRESS(frame,delta)); + code_fixup(&FRAME_RETURN_ADDRESS(frame)); } void fixup_callstack_object(F_CALLSTACK *stack) { - CELL top = (CELL)(stack + 1); - CELL bottom = top + untag_fixnum_fast(stack->length); - delta = (bottom - stack->bottom); - iterate_callstack_object(stack,fixup_stack_frame); } diff --git a/vm/os-linux-ppc.h b/vm/os-linux-ppc.h index ba047d22b1..86f0509e38 100644 --- a/vm/os-linux-ppc.h +++ b/vm/os-linux-ppc.h @@ -1,4 +1,4 @@ -#define FRAME_RETURN_ADDRESS(frame,delta) *((XT *)(REBASE_FRAME_SUCCESSOR(frame,delta) + 1) + 1) +#define FRAME_RETURN_ADDRESS(frame) *((XT *)(frame_successor(frame) + 1) + 1) #define UAP_PROGRAM_COUNTER(ucontext) \ (((ucontext_t *)(ucontext))->uc_mcontext.uc_regs->gregs[PT_NIP]) diff --git a/vm/os-macosx-ppc.h b/vm/os-macosx-ppc.h index 5eaee9c327..f3a5de88c2 100644 --- a/vm/os-macosx-ppc.h +++ b/vm/os-macosx-ppc.h @@ -1,4 +1,4 @@ -#define FRAME_RETURN_ADDRESS(frame,delta) *((XT *)(REBASE_FRAME_SUCCESSOR(frame,delta) + 1) + 2) +#define FRAME_RETURN_ADDRESS(frame) *((XT *)(frame_successor(frame) + 1) + 2) #define MACH_EXC_STATE_TYPE ppc_exception_state_t #define MACH_EXC_STATE_FLAVOR PPC_EXCEPTION_STATE