/home/travis/build/MoarVM/MoarVM/src/core/callstack.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "moar.h" |
2 | | |
3 | | /* Allocates a new call stack region, not incorporated into the regions double |
4 | | * linked list yet. */ |
5 | 130 | static MVMCallStackRegion * create_region() { |
6 | 130 | MVMCallStackRegion *region = MVM_malloc(MVM_CALLSTACK_REGION_SIZE); |
7 | 130 | region->prev = region->next = NULL; |
8 | 130 | region->alloc = (char *)region + sizeof(MVMCallStackRegion); |
9 | 130 | region->alloc_limit = (char *)region + MVM_CALLSTACK_REGION_SIZE; |
10 | 130 | return region; |
11 | 130 | } |
12 | | |
13 | | /* Called upon thread creation to set up an initial callstack region for the |
14 | | * thread. */ |
15 | 130 | void MVM_callstack_region_init(MVMThreadContext *tc) { |
16 | 130 | tc->stack_first = tc->stack_current = create_region(); |
17 | 130 | } |
18 | | |
19 | | /* Moves the current call stack region we're allocating/freeing in along to |
20 | | * the next one in the region chain, allocating that next one if needed. */ |
21 | 0 | MVMCallStackRegion * MVM_callstack_region_next(MVMThreadContext *tc) { |
22 | 0 | MVMCallStackRegion *next_region = tc->stack_current->next; |
23 | 0 | if (!next_region) { |
24 | 0 | next_region = create_region(); |
25 | 0 | tc->stack_current->next = next_region; |
26 | 0 | next_region->prev = tc->stack_current; |
27 | 0 | } |
28 | 0 | tc->stack_current = next_region; |
29 | 0 | return next_region; |
30 | 0 | } |
31 | | |
32 | | /* Switches to the previous call stack region, if any. Otherwise, stays in |
33 | | * the current region. */ |
34 | 2.55M | MVMCallStackRegion * MVM_callstack_region_prev(MVMThreadContext *tc) { |
35 | 2.55M | MVMCallStackRegion *prev_region = tc->stack_current->prev; |
36 | 2.55M | if (prev_region) |
37 | 0 | tc->stack_current = prev_region; |
38 | 2.55M | else |
39 | 2.55M | prev_region = tc->stack_current; |
40 | 2.55M | return prev_region; |
41 | 2.55M | } |
42 | | |
43 | | /* Resets a threads's callstack to be empty. Used when its contents has been |
44 | | * promoted to the heap. */ |
45 | 347k | void MVM_callstack_reset(MVMThreadContext *tc) { |
46 | 347k | MVMCallStackRegion *cur_region = tc->stack_current; |
47 | 695k | while (cur_region) { |
48 | 347k | cur_region->alloc = (char *)cur_region + sizeof(MVMCallStackRegion); |
49 | 347k | cur_region = cur_region->prev; |
50 | 347k | } |
51 | 347k | tc->stack_current = tc->stack_first; |
52 | 347k | } |
53 | | |
54 | | /* Called at thread exit to destroy all callstack regions the thread has. */ |
55 | 0 | void MVM_callstack_region_destroy_all(MVMThreadContext *tc) { |
56 | 0 | MVMCallStackRegion *cur = tc->stack_first; |
57 | 0 | while (cur) { |
58 | 0 | MVMCallStackRegion *next = cur->next; |
59 | 0 | MVM_free(cur); |
60 | 0 | cur = next; |
61 | 0 | } |
62 | 0 | tc->stack_first = NULL; |
63 | 0 | } |