]> gitweb.factorcode.org Git - factor.git/blob - vm/callstack.hpp
Put brackets around ipv6 addresses in `inet6 present`
[factor.git] / vm / callstack.hpp
1 namespace factor {
2
3 inline static cell callstack_object_size(cell size) {
4   return sizeof(callstack) + size;
5 }
6
7 // This is a little tricky. The iterator may allocate memory, so we
8 // keep the callstack in a GC root and use relative offsets
9 // Allocates memory
10 template <typename Iterator, typename Fixup>
11 inline void factor_vm::iterate_callstack_object(callstack* stack_,
12                                                 Iterator& iterator,
13                                                 Fixup& fixup) {
14   data_root<callstack> stack(stack_, this);
15   fixnum frame_length = untag_fixnum(stack->length);
16   fixnum frame_offset = 0;
17
18   while (frame_offset < frame_length) {
19     cell frame_top = stack->frame_top_at(frame_offset);
20     cell addr = *(cell*)frame_top;
21     cell fixed_addr = Fixup::translated_code_block_map
22                           ? (cell)fixup.translate_code((code_block*)addr)
23                           : addr;
24     code_block* owner = code->code_block_for_address(fixed_addr);
25
26     cell frame_size = owner->stack_frame_size_for_address(fixed_addr);
27
28     iterator(frame_top, frame_size, owner, fixed_addr);
29     frame_offset += frame_size;
30   }
31   FACTOR_ASSERT(frame_offset == frame_length);
32 }
33
34 // Allocates memory
35 template <typename Iterator>
36 inline void factor_vm::iterate_callstack_object(callstack* stack,
37                                                 Iterator& iterator) {
38   no_fixup none;
39   iterate_callstack_object(stack, iterator, none);
40 }
41
42 // Iterates the callstack from innermost to outermost
43 // callframe. Allocates memory
44 template <typename Iterator, typename Fixup>
45 void factor_vm::iterate_callstack(context* ctx, Iterator& iterator,
46                                   Fixup& fixup) {
47
48   cell top = ctx->callstack_top;
49   cell bottom = ctx->callstack_bottom;
50   // When we are translating the code block maps, all callstacks must
51   // be empty.
52   FACTOR_ASSERT(!Fixup::translated_code_block_map || top == bottom);
53
54   while (top < bottom) {
55     cell addr = *(cell*)top;
56     FACTOR_ASSERT(addr != 0);
57
58     // Only the address is valid, if the code heap has been compacted,
59     // owner might not point to a real code block.
60     code_block* owner = code->code_block_for_address(addr);
61     code_block* fixed_owner = fixup.translate_code(owner);
62
63     cell delta = addr - (cell)owner - sizeof(code_block);
64     cell natural_frame_size = fixed_owner->stack_frame_size();
65     cell size = LEAF_FRAME_SIZE;
66     if (natural_frame_size > 0 && delta > 0)
67       size = natural_frame_size;
68
69     iterator(top, size, owner, addr);
70     top += size;
71   }
72   FACTOR_ASSERT(top == bottom);
73 }
74
75 // Allocates memory
76 template <typename Iterator>
77 inline void factor_vm::iterate_callstack(context* ctx, Iterator& iterator) {
78   no_fixup none;
79   iterate_callstack(ctx, iterator, none);
80 }
81
82 }