4 inline static cell callstack_object_size(cell size)
6 return sizeof(callstack) + size;
9 /* This is a little tricky. The iterator may allocate memory, so we
10 keep the callstack in a GC root and use relative offsets */
11 template<typename Iterator, typename Fixup>
12 void factor_vm::iterate_callstack_object_reversed(callstack *stack_,
13 Iterator &iterator, Fixup &fixup)
15 data_root<callstack> stack(stack_,this);
16 fixnum frame_length = factor::untag_fixnum(stack->length);
17 fixnum frame_offset = 0;
19 while(frame_offset < frame_length)
21 void *frame_top = stack->frame_top_at(frame_offset);
22 void *addr = frame_return_address(frame_top);
24 void *fixed_addr = Fixup::translated_code_block_map
25 ? (void*)fixup.translate_code((code_block*)addr)
27 code_block *owner = code->code_block_for_address((cell)fixed_addr);
28 cell frame_size = owner->stack_frame_size_for_address((cell)fixed_addr);
31 // check our derived owner and frame size against the ones stored in the frame
32 // by the function prolog
33 stack_frame *frame = (stack_frame*)((char*)frame_top + frame_size) - 1;
34 void *fixed_entry_point =
35 (void*)fixup.translate_code((code_block*)frame->entry_point);
36 FACTOR_ASSERT(owner->entry_point() == fixed_entry_point);
37 FACTOR_ASSERT(frame_size == frame->size);
40 iterator(frame_top, frame_size, owner, fixed_addr);
41 frame_offset += frame_size;
45 template<typename Iterator>
46 void factor_vm::iterate_callstack_object(callstack *stack_, Iterator &iterator)
48 data_root<callstack> stack(stack_,this);
49 fixnum frame_offset = factor::untag_fixnum(stack->length) - sizeof(stack_frame);
51 while(frame_offset >= 0)
53 stack_frame *frame = stack->frame_at(frame_offset);
54 frame_offset -= frame->size;
59 template<typename Iterator, typename Fixup>
60 void factor_vm::iterate_callstack_reversed(context *ctx, Iterator &iterator, Fixup &fixup)
62 if (ctx->callstack_top == ctx->callstack_bottom)
65 char *frame_top = (char*)ctx->callstack_top;
67 while (frame_top < (char*)ctx->callstack_bottom)
69 void *addr = frame_return_address((void*)frame_top);
70 FACTOR_ASSERT(addr != 0);
71 void *fixed_addr = Fixup::translated_code_block_map
72 ? (void*)fixup.translate_code((code_block*)addr)
75 code_block *owner = code->code_block_for_address((cell)fixed_addr);
76 code_block *fixed_owner = Fixup::translated_code_block_map
78 : fixup.translate_code(owner);
80 cell frame_size = fixed_owner->stack_frame_size_for_address((cell)fixed_addr);
83 // check our derived owner and frame size against the ones stored in the frame
84 // by the function prolog
85 stack_frame *frame = (stack_frame*)(frame_top + frame_size) - 1;
86 void *fixed_entry_point = Fixup::translated_code_block_map
87 ? (void*)fixup.translate_code((code_block*)frame->entry_point)
89 FACTOR_ASSERT(owner->entry_point() == fixed_entry_point);
90 FACTOR_ASSERT(frame_size == frame->size);
92 void *fixed_addr_for_iter = Fixup::translated_code_block_map
96 iterator(frame_top, frame_size, owner, fixed_addr_for_iter);
97 frame_top += frame_size;
101 template<typename Iterator>
102 void factor_vm::iterate_callstack_reversed(context *ctx, Iterator &iterator)
104 if (ctx->callstack_top == ctx->callstack_bottom)
107 char *frame_top = (char*)ctx->callstack_top;
109 while (frame_top < (char*)ctx->callstack_bottom)
111 void *addr = frame_return_address((void*)frame_top);
112 FACTOR_ASSERT(addr != 0);
114 code_block *owner = code->code_block_for_address((cell)addr);
115 cell frame_size = owner->stack_frame_size_for_address((cell)addr);
118 // check our derived owner and frame size against the ones stored in the frame
119 // by the function prolog
120 stack_frame *frame = (stack_frame*)(frame_top + frame_size) - 1;
121 FACTOR_ASSERT(owner->entry_point() == frame->entry_point);
122 FACTOR_ASSERT(frame_size == frame->size);
125 iterator(frame_top, frame_size, owner, addr);
126 frame_top += frame_size;
130 template<typename Iterator>
131 void factor_vm::iterate_callstack(context *ctx, Iterator &iterator)
133 stack_frame *frame = ctx->callstack_bottom - 1;
135 while(frame >= ctx->callstack_top)
138 frame = frame_successor(frame);