/home/travis/build/MoarVM/MoarVM/src/core/interp.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* A GC sync point is a point where we can check if we're being signalled |
2 | | * to stop to do a GC run. This is placed at points where it is safe to |
3 | | * do such a thing, and hopefully so that it happens often enough; note |
4 | | * that every call down to the allocator is also a sync point, so this |
5 | | * really only means we need to do this enough to make sure tight native |
6 | | * loops trigger it. */ |
7 | | /* Don't use a MVM_load(&tc->gc_status) here for performance, it's okay |
8 | | * if the interrupt is delayed a bit. */ |
9 | | #define GC_SYNC_POINT(tc) \ |
10 | | if (tc->gc_status) { \ |
11 | | MVM_gc_enter_from_interrupt(tc); \ |
12 | | } |
13 | | |
14 | | /* Different views of a register. */ |
15 | | union MVMRegister { |
16 | | MVMObject *o; |
17 | | MVMString *s; |
18 | | MVMint8 i8; |
19 | | MVMuint8 u8; |
20 | | MVMint16 i16; |
21 | | MVMuint16 u16; |
22 | | MVMint32 i32; |
23 | | MVMuint32 u32; |
24 | | MVMint64 i64; |
25 | | MVMuint64 u64; |
26 | | MVMnum32 n32; |
27 | | MVMnum64 n64; |
28 | | }; |
29 | | |
30 | | /* Most operands an operation will have. */ |
31 | | #define MVM_MAX_OPERANDS 8 |
32 | | |
33 | | /* Kind of de-opt mark. */ |
34 | | #define MVM_DEOPT_MARK_ONE 1 |
35 | | #define MVM_DEOPT_MARK_ALL 2 |
36 | | #define MVM_DEOPT_MARK_OSR 4 |
37 | | #define MVM_DEOPT_MARK_ONE_PRE 8 |
38 | | |
39 | | /* Information about an opcode. */ |
40 | | struct MVMOpInfo { |
41 | | MVMuint16 opcode; |
42 | | const char *name; |
43 | | char mark[2]; |
44 | | MVMuint16 num_operands; |
45 | | MVMuint8 pure; |
46 | | MVMuint8 deopt_point; |
47 | | MVMuint8 logged; |
48 | | MVMuint8 no_inline; |
49 | | MVMuint8 jittivity; |
50 | | MVMuint8 uses_hll; |
51 | | MVMuint8 operands[MVM_MAX_OPERANDS]; |
52 | | }; |
53 | | |
54 | | /* Operand read/write/literal flags. */ |
55 | | #define MVM_operand_literal 0 |
56 | | #define MVM_operand_read_reg 1 |
57 | | #define MVM_operand_write_reg 2 |
58 | | #define MVM_operand_read_lex 3 |
59 | | #define MVM_operand_write_lex 4 |
60 | | #define MVM_operand_rw_mask 7 |
61 | | |
62 | | /* Register data types. */ |
63 | | #define MVM_reg_int8 1 |
64 | | #define MVM_reg_int16 2 |
65 | | #define MVM_reg_int32 3 |
66 | | #define MVM_reg_int64 4 |
67 | | #define MVM_reg_num32 5 |
68 | | #define MVM_reg_num64 6 |
69 | | #define MVM_reg_str 7 |
70 | | #define MVM_reg_obj 8 |
71 | | #define MVM_reg_uint8 17 |
72 | | #define MVM_reg_uint16 18 |
73 | | #define MVM_reg_uint32 19 |
74 | | #define MVM_reg_uint64 20 |
75 | | |
76 | | /* Operand data types. */ |
77 | | #define MVM_operand_int8 (MVM_reg_int8 << 3) |
78 | | #define MVM_operand_int16 (MVM_reg_int16 << 3) |
79 | | #define MVM_operand_int32 (MVM_reg_int32 << 3) |
80 | | #define MVM_operand_int64 (MVM_reg_int64 << 3) |
81 | | #define MVM_operand_num32 (MVM_reg_num32 << 3) |
82 | | #define MVM_operand_num64 (MVM_reg_num64 << 3) |
83 | | #define MVM_operand_str (MVM_reg_str << 3) |
84 | | #define MVM_operand_obj (MVM_reg_obj << 3) |
85 | | #define MVM_operand_ins (9 << 3) |
86 | | #define MVM_operand_type_var (10 << 3) |
87 | | #define MVM_operand_coderef (12 << 3) |
88 | | #define MVM_operand_callsite (13 << 3) |
89 | | #define MVM_operand_spesh_slot (16 << 3) |
90 | | #define MVM_operand_uint8 (MVM_reg_uint8 << 3) |
91 | | #define MVM_operand_uint16 (MVM_reg_uint16 << 3) |
92 | | #define MVM_operand_uint32 (MVM_reg_uint32 << 3) |
93 | | #define MVM_operand_uint64 (MVM_reg_uint64 << 3) |
94 | | #define MVM_operand_type_mask (31 << 3) |
95 | | |
96 | | /* Functions. */ |
97 | | void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContext *, void *), void *invoke_data); |
98 | | MVM_PUBLIC void MVM_interp_enable_tracing(); |
99 | | |
100 | 0 | MVM_STATIC_INLINE MVMint64 MVM_BC_get_I64(const MVMuint8 *cur_op, int offset) { |
101 | 0 | const MVMuint8 *const where = cur_op + offset; |
102 | 0 | #ifdef MVM_CAN_UNALIGNED_INT64 |
103 | 0 | return *(MVMint64 *)where; |
104 | 0 | #else |
105 | 0 | MVMint64 temp; |
106 | 0 | memmove(&temp, where, sizeof(MVMint64)); |
107 | 0 | return temp; |
108 | 0 | #endif |
109 | 0 | } |
110 | | |
111 | 0 | MVM_STATIC_INLINE MVMnum64 MVM_BC_get_N64(const MVMuint8 *cur_op, int offset) { |
112 | 0 | const MVMuint8 *const where = cur_op + offset; |
113 | 0 | #ifdef MVM_CAN_UNALIGNED_NUM64 |
114 | 0 | return *(MVMnum64 *)where; |
115 | 0 | #else |
116 | 0 | MVMnum64 temp; |
117 | 0 | memmove(&temp, cur_op + offset, sizeof(MVMnum64)); |
118 | 0 | return temp; |
119 | 0 | #endif |
120 | 0 | } |
121 | | /* For MVM_reg_* types */ |
122 | 0 | static char * MVM_reg_get_debug_name(MVMThreadContext *tc, MVMuint16 type) { |
123 | 0 | switch (type) { |
124 | 0 | case MVM_reg_int8: |
125 | 0 | return "int8"; |
126 | 0 | case MVM_reg_int16: |
127 | 0 | return "int16"; |
128 | 0 | case MVM_reg_int32: |
129 | 0 | return "int32"; |
130 | 0 | case MVM_reg_int64: |
131 | 0 | return "int64"; |
132 | 0 | case MVM_reg_num32: |
133 | 0 | return "num32"; |
134 | 0 | case MVM_reg_num64: |
135 | 0 | return "num64"; |
136 | 0 | case MVM_reg_str: |
137 | 0 | return "str"; |
138 | 0 | case MVM_reg_obj: |
139 | 0 | return "obj"; |
140 | 0 | case MVM_reg_uint8: |
141 | 0 | return "uint8"; |
142 | 0 | case MVM_reg_uint16: |
143 | 0 | return "uint16"; |
144 | 0 | case MVM_reg_uint32: |
145 | 0 | return "uint32"; |
146 | 0 | case MVM_reg_uint64: |
147 | 0 | return "uint64"; |
148 | 0 | default: |
149 | 0 | return "unknown"; |
150 | 0 | } |
151 | 0 | } |