/home/travis/build/MoarVM/MoarVM/src/core/frame.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* Frame flags; provide some HLLs can alias. */ |
2 | | #define MVM_FRAME_FLAG_STATE_INIT 1 << 0 |
3 | | #define MVM_FRAME_FLAG_EXIT_HAND_RUN 1 << 1 |
4 | | #define MVM_FRAME_FLAG_HLL_1 1 << 3 |
5 | | #define MVM_FRAME_FLAG_HLL_2 1 << 4 |
6 | | #define MVM_FRAME_FLAG_HLL_3 1 << 5 |
7 | | #define MVM_FRAME_FLAG_HLL_4 1 << 6 |
8 | | |
9 | | /* Lexical hash entry for ->lexical_names on a frame. */ |
10 | | struct MVMLexicalRegistry { |
11 | | /* key string */ |
12 | | MVMString *key; |
13 | | |
14 | | /* index of the lexical entry. */ |
15 | | MVMuint32 value; |
16 | | |
17 | | /* the uthash hash handle inline struct. */ |
18 | | UT_hash_handle hash_handle; |
19 | | }; |
20 | | |
21 | | /* Entry in the linked list of continuation tags for the frame. */ |
22 | | struct MVMContinuationTag { |
23 | | /* The tag itself. */ |
24 | | MVMObject *tag; |
25 | | |
26 | | /* The active exception handler at the point the tag was taken. */ |
27 | | MVMActiveHandler *active_handlers; |
28 | | |
29 | | /* The next continuation tag entry. */ |
30 | | MVMContinuationTag *next; |
31 | | }; |
32 | | |
33 | | /* Function pointer type of special return handler. These are used to allow |
34 | | * return to be intercepted in some way, for things that need to do multiple |
35 | | * calls into the runloop in some C-managed process. Essentially, instead of |
36 | | * nested runloops, you just re-work the C code in question into CPS. */ |
37 | | typedef void (* MVMSpecialReturn)(MVMThreadContext *tc, void *data); |
38 | | |
39 | | /* Function pointer for marking the special return handler data. */ |
40 | | typedef void (* MVMSpecialReturnDataMark)(MVMThreadContext *tc, MVMFrame *frame, |
41 | | MVMGCWorklist *worklist); |
42 | | |
43 | | /* This represents an call frame, aka invocation record. It may exist either on |
44 | | * the heap, in which case its header will have the MVM_CF_FRAME flag set, or |
45 | | * in on a thread-local stack, in which case the collectable header will be |
46 | | * fully zeroed. */ |
47 | | struct MVMFrame { |
48 | | /* Commonalities that all collectable entities have. */ |
49 | | MVMCollectable header; |
50 | | |
51 | | /* The environment for this frame, which lives beyond its execution. |
52 | | * Has space for, for instance, lexicals. */ |
53 | | MVMRegister *env; |
54 | | |
55 | | /* The temporary work space for this frame. After a call is over, this |
56 | | * can be freed up. Must be NULLed out when this happens. */ |
57 | | MVMRegister *work; |
58 | | |
59 | | /* The args buffer. Actually a pointer into an area inside of *work, to |
60 | | * decrease number of allocations. */ |
61 | | MVMRegister *args; |
62 | | |
63 | | /* Callsite that indicates how the current args buffer is being used, if |
64 | | * it is. */ |
65 | | MVMCallsite *cur_args_callsite; |
66 | | |
67 | | /* The outer frame, thus forming the static chain. */ |
68 | | MVMFrame *outer; |
69 | | |
70 | | /* The caller frame, thus forming the dynamic chain. */ |
71 | | MVMFrame *caller; |
72 | | |
73 | | /* The static frame information. Holds all we statically know about |
74 | | * this kind of frame, including information needed to GC-trace it. */ |
75 | | MVMStaticFrame *static_info; |
76 | | |
77 | | /* The code ref object for this frame. */ |
78 | | MVMObject *code_ref; |
79 | | |
80 | | /* Parameters received by this frame. */ |
81 | | MVMArgProcContext params; |
82 | | |
83 | | /* Effective set of spesh slots, if any. */ |
84 | | MVMCollectable **effective_spesh_slots; |
85 | | |
86 | | /* The spesh candidate information, if we're in one. */ |
87 | | MVMSpeshCandidate *spesh_cand; |
88 | | |
89 | | /* Address of the next op to execute if we return to this frame. */ |
90 | | MVMuint8 *return_address; |
91 | | |
92 | | /* The register we should store the return value in, if any. */ |
93 | | MVMRegister *return_value; |
94 | | |
95 | | /* The type of return value that is expected. */ |
96 | | MVMReturnType return_type; |
97 | | |
98 | | /* Assorted frame flags. */ |
99 | | MVMuint8 flags; |
100 | | |
101 | | /* The allocated work/env sizes. */ |
102 | | MVMuint16 allocd_work; |
103 | | MVMuint16 allocd_env; |
104 | | |
105 | | /* The current spesh correlation ID, if we're interpreting code and |
106 | | * recording logs. Zero if interpreting unspecialized and not recording. |
107 | | * Junk if running specialized code. */ |
108 | | MVMint32 spesh_correlation_id; |
109 | | |
110 | | /* A sequence number to indicate our place in the call stack */ |
111 | | MVMint32 sequence_nr; |
112 | | |
113 | | /* The 'entry label' is a sort of indirect return address for the JIT */ |
114 | | void * jit_entry_label; |
115 | | |
116 | | /* Extra data that some frames need, allocated on demand. If allocated, |
117 | | * lives for the dynamic scope of the frame. */ |
118 | | MVMFrameExtra *extra; |
119 | | }; |
120 | | |
121 | | /* Extra data that a handful of call frames optionally need. It is needed |
122 | | * only while the frame is in dynamic scope; after that it can go away. */ |
123 | | struct MVMFrameExtra { |
124 | | /* If we want to invoke a special handler upon a return to this |
125 | | * frame, this function pointer is set. */ |
126 | | MVMSpecialReturn special_return; |
127 | | |
128 | | /* If we want to invoke a special handler upon unwinding past a |
129 | | * frame, this function pointer is set. */ |
130 | | MVMSpecialReturn special_unwind; |
131 | | |
132 | | /* Data slot for the special return handler function. */ |
133 | | void *special_return_data; |
134 | | |
135 | | /* Flag for if special_return_data need to be GC marked. */ |
136 | | MVMSpecialReturnDataMark mark_special_return_data; |
137 | | |
138 | | /* Linked list of any continuation tags we have. */ |
139 | | MVMContinuationTag *continuation_tags; |
140 | | |
141 | | /* If we were invoked with a call capture, that call capture, so we can |
142 | | * keep its callsite alive. */ |
143 | | MVMObject *invoked_call_capture; |
144 | | |
145 | | /* Cache for dynlex lookup; if the name is non-null, the cache is valid |
146 | | * and the register can be accessed directly to find the contextual. */ |
147 | | MVMString *dynlex_cache_name; |
148 | | MVMRegister *dynlex_cache_reg; |
149 | | MVMuint16 dynlex_cache_type; |
150 | | }; |
151 | | |
152 | | /* How do we invoke this thing? Specifies either an attribute to look at for |
153 | | * an invokable thing, a method to call, and maybe a multi-dispatch cache to |
154 | | * look in first for an answer. */ |
155 | | struct MVMInvocationSpec { |
156 | | /* Offsets for fast access; placed first as they are what will be most |
157 | | * often needed. */ |
158 | | size_t code_ref_offset; |
159 | | size_t md_cache_offset; |
160 | | size_t md_valid_offset; |
161 | | |
162 | | /* Function that handles invocation, if any. */ |
163 | | MVMObject *invocation_handler; |
164 | | |
165 | | /* Class handle, name and hint for attribute holding code to invoke. */ |
166 | | MVMObject *class_handle; |
167 | | MVMString *attr_name; |
168 | | MVMint64 hint; |
169 | | |
170 | | /* Multi-dispatch info class handle, and name/hint of attribute that |
171 | | * holds the cache itself and a flag to check if it's allowed to |
172 | | * consider the cache. */ |
173 | | MVMObject *md_class_handle; |
174 | | MVMString *md_cache_attr_name; |
175 | | MVMint64 md_cache_hint; |
176 | | MVMint64 md_valid_hint; |
177 | | MVMString *md_valid_attr_name; |
178 | | }; |
179 | | |
180 | | /* Checks if a frame is allocated on a call stack or on the heap. If it is on |
181 | | * the call stack, then it will have zeroed flags (since heap-allocated frames |
182 | | * always have the "I'm a heap frame" bit set). */ |
183 | 0 | MVM_STATIC_INLINE MVMuint32 MVM_FRAME_IS_ON_CALLSTACK(MVMThreadContext *tc, MVMFrame *frame) { |
184 | 0 | return frame->header.flags == 0; |
185 | 0 | } |
186 | | |
187 | | /* Forces a frame to the callstack if needed. Done as a static inline to make |
188 | | * the quite common case where nothing is needed cheaper. */ |
189 | | MVM_PUBLIC MVMFrame * MVM_frame_move_to_heap(MVMThreadContext *tc, MVMFrame *frame); |
190 | 0 | MVM_STATIC_INLINE MVMFrame * MVM_frame_force_to_heap(MVMThreadContext *tc, MVMFrame *frame) { |
191 | 0 | return MVM_FRAME_IS_ON_CALLSTACK(tc, frame) |
192 | 0 | ? MVM_frame_move_to_heap(tc, frame) |
193 | 0 | : frame; |
194 | 0 | } |
195 | | |
196 | | MVMFrame * MVM_frame_debugserver_move_to_heap(MVMThreadContext *tc, MVMThreadContext *owner, MVMFrame *frame); |
197 | | |
198 | | MVMRegister * MVM_frame_initial_work(MVMThreadContext *tc, MVMuint16 *local_types, |
199 | | MVMuint16 num_locals); |
200 | | void MVM_frame_invoke_code(MVMThreadContext *tc, MVMCode *code, |
201 | | MVMCallsite *callsite, MVMint32 spesh_cand); |
202 | | void MVM_frame_invoke(MVMThreadContext *tc, MVMStaticFrame *static_frame, |
203 | | MVMCallsite *callsite, MVMRegister *args, |
204 | | MVMFrame *outer, MVMObject *code_ref, MVMint32 spesh_cand); |
205 | | MVMFrame * MVM_frame_create_context_only(MVMThreadContext *tc, MVMStaticFrame *static_frame, |
206 | | MVMObject *code_ref); |
207 | | MVMFrame * MVM_frame_create_for_deopt(MVMThreadContext *tc, MVMStaticFrame *static_frame, |
208 | | MVMCode *code_ref); |
209 | | MVM_PUBLIC MVMuint64 MVM_frame_try_return(MVMThreadContext *tc); |
210 | | MVM_PUBLIC MVMuint64 MVM_frame_try_return_no_exit_handlers(MVMThreadContext *tc); |
211 | | void MVM_frame_unwind_to(MVMThreadContext *tc, MVMFrame *frame, MVMuint8 *abs_addr, |
212 | | MVMuint32 rel_addr, MVMObject *return_value, void *jit_return_label); |
213 | | MVM_PUBLIC void MVM_frame_destroy(MVMThreadContext *tc, MVMFrame *frame); |
214 | | MVM_PUBLIC MVMObject * MVM_frame_get_code_object(MVMThreadContext *tc, MVMCode *code); |
215 | | MVM_PUBLIC void MVM_frame_capturelex(MVMThreadContext *tc, MVMObject *code); |
216 | | MVM_PUBLIC void MVM_frame_capture_inner(MVMThreadContext *tc, MVMObject *code); |
217 | | MVM_PUBLIC MVMObject * MVM_frame_takeclosure(MVMThreadContext *tc, MVMObject *code); |
218 | | MVM_PUBLIC MVMObject * MVM_frame_vivify_lexical(MVMThreadContext *tc, MVMFrame *f, MVMuint16 idx); |
219 | | MVM_PUBLIC MVMRegister * MVM_frame_find_lexical_by_name(MVMThreadContext *tc, MVMString *name, MVMuint16 type); |
220 | | MVM_PUBLIC void MVM_frame_bind_lexical_by_name(MVMThreadContext *tc, MVMString *name, MVMuint16 type, MVMRegister *value); |
221 | | MVMObject * MVM_frame_find_lexical_by_name_outer(MVMThreadContext *tc, MVMString *name); |
222 | | MVM_PUBLIC MVMRegister * MVM_frame_find_lexical_by_name_rel(MVMThreadContext *tc, MVMString *name, MVMFrame *cur_frame); |
223 | | MVM_PUBLIC MVMRegister * MVM_frame_find_lexical_by_name_rel_caller(MVMThreadContext *tc, MVMString *name, MVMFrame *cur_caller_frame); |
224 | | MVMRegister * MVM_frame_find_contextual_by_name(MVMThreadContext *tc, MVMString *name, MVMuint16 *type, MVMFrame *cur_frame, MVMint32 vivify, MVMFrame **found_frame); |
225 | | MVMObject * MVM_frame_getdynlex(MVMThreadContext *tc, MVMString *name, MVMFrame *cur_frame); |
226 | | void MVM_frame_binddynlex(MVMThreadContext *tc, MVMString *name, MVMObject *value, MVMFrame *cur_frame); |
227 | | MVMRegister * MVM_frame_lexical(MVMThreadContext *tc, MVMFrame *f, MVMString *name); |
228 | | MVM_PUBLIC MVMRegister * MVM_frame_try_get_lexical(MVMThreadContext *tc, MVMFrame *f, MVMString *name, MVMuint16 type); |
229 | | MVMuint16 MVM_frame_lexical_primspec(MVMThreadContext *tc, MVMFrame *f, MVMString *name); |
230 | | MVM_PUBLIC MVMObject * MVM_frame_find_invokee(MVMThreadContext *tc, MVMObject *code, MVMCallsite **tweak_cs); |
231 | | MVMObject * MVM_frame_find_invokee_multi_ok(MVMThreadContext *tc, MVMObject *code, MVMCallsite **tweak_cs, MVMRegister *args, MVMuint16 *was_multi); |
232 | | MVMObject * MVM_frame_resolve_invokee_spesh(MVMThreadContext *tc, MVMObject *invokee); |
233 | | MVM_PUBLIC MVMObject * MVM_frame_context_wrapper(MVMThreadContext *tc, MVMFrame *f); |
234 | | MVMFrameExtra * MVM_frame_extra(MVMThreadContext *tc, MVMFrame *f); |
235 | | MVM_PUBLIC void MVM_frame_special_return(MVMThreadContext *tc, MVMFrame *f, |
236 | | MVMSpecialReturn special_return, MVMSpecialReturn special_unwind, |
237 | | void *special_return_data, MVMSpecialReturnDataMark mark_special_return_data); |
238 | | MVM_PUBLIC void MVM_frame_clear_special_return(MVMThreadContext *tc, MVMFrame *f); |