/home/travis/build/MoarVM/MoarVM/src/spesh/plugin.h
Line | Count | Source |
1 | | /* Data structure that hangs off a static frame's spesh state, holding the |
2 | | * guard tree at each applicable bytecode position. It is allocated using the |
3 | | * FSA, and freed using the safepointing mechanism; this allows, providing a |
4 | | * single read is done before operating, for safe concurrent use. Updated |
5 | | * versions are installed using atomic operations. */ |
6 | | struct MVMSpeshPluginState { |
7 | | /* Array of position states. Held in bytecode index order, which |
8 | | * allows for binary searching. */ |
9 | | MVMSpeshPluginPosition *positions; |
10 | | |
11 | | /* Number of bytecode positions we have state at. */ |
12 | | MVMuint32 num_positions; |
13 | | }; |
14 | | |
15 | | /* Pairing of instruction position with the guard set at that position. */ |
16 | | struct MVMSpeshPluginPosition { |
17 | | MVMSpeshPluginGuardSet *guard_set; |
18 | | MVMuint32 bytecode_position; |
19 | | }; |
20 | | |
21 | | /* The guard set held at a particular position. This is an array of guards |
22 | | * clauses to evaluate, with a count of them to know when we hit the end. |
23 | | * We just append new guard sets to the end. */ |
24 | | struct MVMSpeshPluginGuardSet { |
25 | | MVMSpeshPluginGuard *guards; |
26 | | MVMuint32 num_guards; |
27 | | }; |
28 | | |
29 | | /* The maximum number of guards a spesh plugin can set up. */ |
30 | 117 | #define MVM_SPESH_PLUGIN_GUARD_LIMIT 16 |
31 | | |
32 | | /* Types of guard that we have. */ |
33 | 197k | #define MVM_SPESH_PLUGIN_GUARD_RESULT 0 /* Node indicating a match */ |
34 | 83.3k | #define MVM_SPESH_PLUGIN_GUARD_OBJ 1 /* Literal object match */ |
35 | 762 | #define MVM_SPESH_PLUGIN_GUARD_NOTOBJ 2 /* Literal object non-match */ |
36 | 5.20k | #define MVM_SPESH_PLUGIN_GUARD_TYPE 3 /* Exact type match guard */ |
37 | 5.51k | #define MVM_SPESH_PLUGIN_GUARD_CONC 4 /* Concrete object guard */ |
38 | 5.57k | #define MVM_SPESH_PLUGIN_GUARD_TYPEOBJ 5 /* Type object guard */ |
39 | 1.51k | #define MVM_SPESH_PLUGIN_GUARD_GETATTR 6 /* Gets an attribute for testing */ |
40 | | |
41 | | /* An individual guard. */ |
42 | | struct MVMSpeshPluginGuard { |
43 | | /* What kind of guard is this? */ |
44 | | MVMuint16 kind; |
45 | | |
46 | | /* What arg should we read the value to test from? Up to the number of |
47 | | * callsite positionals will read from the args buffer; beyond that will |
48 | | * read from the buffer of results from a GETATTR guard (those are |
49 | | * appended in the order they happen). */ |
50 | | MVMuint16 test_idx; |
51 | | |
52 | | /* If we fail this, how many nodes should we skip over? */ |
53 | | MVMuint16 skip_on_fail; |
54 | | |
55 | | /* Union used depending on the kind of guard. */ |
56 | | union { |
57 | | /* The result to return; used for RESULT guard. */ |
58 | | MVMObject *result; |
59 | | /* The object literal to test against; used for OBJ guard. */ |
60 | | MVMObject *object; |
61 | | /* The type to test against, used for TYPE guard. */ |
62 | | MVMSTable *type; |
63 | | /* The attribute to load for further testing. */ |
64 | | struct { |
65 | | MVMObject *class_handle; |
66 | | MVMString *name; |
67 | | } attr; |
68 | | } u; |
69 | | }; |
70 | | |
71 | | /* Functions called from the interpreter as spesh plugins are encountered and |
72 | | * guards recorded. */ |
73 | | void MVM_spesh_plugin_register(MVMThreadContext *tc, MVMString *language, |
74 | | MVMString *name, MVMObject *plugin); |
75 | | void MVM_spesh_plugin_resolve(MVMThreadContext *tc, MVMString *name, MVMRegister *result, |
76 | | MVMuint8 *op_addr, MVMuint8 *next_addr, MVMCallsite *callsite); |
77 | | void MVM_spesh_plugin_resolve_spesh(MVMThreadContext *tc, MVMString *name, MVMRegister *result, |
78 | | MVMuint32 bytecode_offset, MVMStaticFrame *sf, MVMuint8 *next_addr, MVMCallsite *callsite); |
79 | | void MVM_spesh_plugin_resolve_jit(MVMThreadContext *tc, MVMString *name, MVMRegister *result, |
80 | | MVMuint32 position, MVMStaticFrame *sf, MVMCallsite *callsite); |
81 | | void MVM_spesh_plugin_addguard_type(MVMThreadContext *tc, MVMObject *guardee, MVMObject *type); |
82 | | void MVM_spesh_plugin_addguard_concrete(MVMThreadContext *tc, MVMObject *guardee); |
83 | | void MVM_spesh_plugin_addguard_typeobj(MVMThreadContext *tc, MVMObject *guardee); |
84 | | void MVM_spesh_plugin_addguard_obj(MVMThreadContext *tc, MVMObject *guardee); |
85 | | void MVM_spesh_plugin_addguard_notobj(MVMThreadContext *tc, MVMObject *guardee, MVMObject *not); |
86 | | MVMObject * MVM_spesh_plugin_addguard_getattr(MVMThreadContext *tc, MVMObject *guardee, |
87 | | MVMObject *class_handle, MVMString *name); |
88 | | |
89 | | /* Rewriting of spesh resolve instructions in the spesh graph. */ |
90 | | void MVM_spesh_plugin_rewrite_resolve(MVMThreadContext *tc, MVMSpeshGraph *g, MVMSpeshBB *bb, |
91 | | MVMSpeshIns *ins, MVMuint32 bytecode_offset, MVMint32 guard_index); |
92 | | |
93 | | /* Functions for dealing with spesh plugin state. */ |
94 | | void MVM_spesh_plugin_guard_list_mark(MVMThreadContext *tc, MVMSpeshPluginGuard *guards, |
95 | | MVMuint32 num_guards, MVMGCWorklist *worklist); |
96 | | void MVM_spesh_plugin_state_mark(MVMThreadContext *tc, MVMSpeshPluginState *ps, MVMGCWorklist *worklist); |
97 | | void MVM_spesh_plugin_state_free(MVMThreadContext *tc, MVMSpeshPluginState *ps); |