/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 | 317 | static MVMCallStackRegion * create_region() { |
6 | 317 | MVMCallStackRegion *region = MVM_malloc(MVM_CALLSTACK_REGION_SIZE); |
7 | 317 | region->prev = region->next = NULL; |
8 | 317 | region->alloc = (char *)region + sizeof(MVMCallStackRegion); |
9 | 317 | region->alloc_limit = (char *)region + MVM_CALLSTACK_REGION_SIZE; |
10 | 317 | return region; |
11 | 317 | } |
12 | | |
13 | | /* Called upon thread creation to set up an initial callstack region for the |
14 | | * thread. */ |
15 | 317 | void MVM_callstack_region_init(MVMThreadContext *tc) { |
16 | 317 | tc->stack_first = tc->stack_current = create_region(); |
17 | 317 | } |
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 | 3.93M | MVMCallStackRegion * MVM_callstack_region_prev(MVMThreadContext *tc) { |
35 | 3.93M | MVMCallStackRegion *prev_region = tc->stack_current->prev; |
36 | 3.93M | if (prev_region) |
37 | 0 | tc->stack_current = prev_region; |
38 | 3.93M | else |
39 | 3.93M | prev_region = tc->stack_current; |
40 | 3.93M | return prev_region; |
41 | 3.93M | } |
42 | | |
43 | | /* Resets a threads's callstack to be empty. Used when its contents has been |
44 | | * promoted to the heap. */ |
45 | 310k | void MVM_callstack_reset(MVMThreadContext *tc) { |
46 | 310k | MVMCallStackRegion *cur_region = tc->stack_current; |
47 | 620k | while (cur_region) { |
48 | 310k | cur_region->alloc = (char *)cur_region + sizeof(MVMCallStackRegion); |
49 | 310k | cur_region = cur_region->prev; |
50 | 310k | } |
51 | 310k | tc->stack_current = tc->stack_first; |
52 | 310k | } |
53 | | |
54 | | /* Called at thread exit to destroy all callstack regions the thread has. */ |
55 | 23 | void MVM_callstack_region_destroy_all(MVMThreadContext *tc) { |
56 | 23 | MVMCallStackRegion *cur = tc->stack_first; |
57 | 46 | while (cur) { |
58 | 23 | MVMCallStackRegion *next = cur->next; |
59 | 23 | MVM_free(cur); |
60 | 23 | cur = next; |
61 | 23 | } |
62 | 23 | tc->stack_first = NULL; |
63 | 23 | } |