1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * This source file is part of SableVM. *
3 * *
4 * See the file "LICENSE" for the copyright information and for *
5 * the terms and conditions for copying, distribution and *
6 * modification of this source file. *
7 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
8
9 /*
10 ----------------------------------------------------------------------
11 m4svm_instruction_head
12 ----------------------------------------------------------------------
13 */
14
15 /* m4svm_comment_define([:m4svm_instruction_head:],
16 * [:m4svm_instruction_1(:]) */
17
18 /*
19 ----------------------------------------------------------------------
20 m4svm_instruction_tail
21 ----------------------------------------------------------------------
22 */
23
24 /* m4svm_comment_define([:m4svm_instruction_tail:],
25 * [:))m4_dnl:]) */
26
27 /*
28 ----------------------------------------------------------------------
29 m4svm_instruction_1
30 ----------------------------------------------------------------------
31 */
32
33 /* m4svm_comment_define([:m4svm_instruction_1:],
34 * [:m4svm_instruction_2$1:]) */
35
36 /*
37 ----------------------------------------------------------------------
38 m4svm_instruction_2
39 ----------------------------------------------------------------------
40 */
41
42 /* m4svm_comment_define([:m4svm_instruction_2:],
43 * [:m4svm_instruction($1, $2, m4_dnl:]) */
44
45 /*
46 ----------------------------------------------------------------------
47 m4svm_instruction
48 ----------------------------------------------------------------------
49 */
50
51 /* m4_ifdef([:m4svm_inlined_threaded:],
52 [:m4_define([:m4svm_instruction:],
53 [:m4svm_instruction_inlined_threaded([:$1:], [:$2:],[:$3:]):]):])
54 m4_ifdef([:m4svm_direct_threaded:],
55 [:m4_define([:m4svm_instruction:],
56 [:m4svm_instruction_direct_threaded([:$1:], [:$2:], [:$3:]):]):])
57 m4_ifdef([:m4svm_switch_threaded:],
58 [:m4_define([:m4svm_instruction:],
59 [:m4svm_instruction_switch_threaded([:$1:], [:$2:], [:$3:]):]):]) */
60
61 /*
62 ----------------------------------------------------------------------
63 m4svm_is_two_modes_fast
64 ----------------------------------------------------------------------
65 */
66
67 /*
68 m4_define(m4svm_is_two_modes_fast,
69 [:m4_ifelse(m4_index(m4svm_two_modes_fast_$1(),[:m4svm:]),
70 0,,m4svm_two_modes_fast_$1()):])
71 */
72
73 /*
74 ----------------------------------------------------------------------
75 m4svm_mark_start_and_skip
76 ----------------------------------------------------------------------
77 */
78
79 /*
80 NOTE: We expect the compiler to be:
81 * EITHER that smart to check comparison of two CONSTANT values at
82 compile time and generate code accordingly
83 * OR that dumb so that it didn't overoptimize this conditional
84 making whole thing non-inlinable
85 */
86
87 /* m4svm_comment_define([:m4svm_mark_start_and_skip_normal:],
88 * [:m4_ifdef([:m4svm_inlined_threaded:],
89 * [:m4_ifelse(m4svm_is_two_modes_fast($1),,,
90 * [:
91 * { /[::]* skip preparation address A *[::]/
92 * if (SVM_INLINEABLE_$1 != SVM_INTRP_FLAG_INLINEABLE) pc++;
93 * }
94 * :]):],
95 * [:m4_ifelse(m4svm_is_two_modes_fast($1),,,
96 * [:
97 * pc++; /[::]* skip preparation address B *[::]/
98 * :]):]):])
99 */
100
101 /*
102 NOTE: Version below is for compilation in special mode to allow
103 testing of inlinablility of bytecodes and is only applicable
104 when you configure for inlined engine. Define
105 m4svm_inlinability_testing_mode to turn it on.
106 */
107
108 /* m4svm_comment_define([:m4svm_mark_start_and_skip_testing:],
109 * [:m4_ifdef([:m4svm_inlined_threaded:],
110 * [:m4_ifelse(m4svm_is_two_modes_fast($1),,,
111 * [:
112 * /[::]* extra skip if we're currently in inlinable but not inlined code *[::]/
113 * { pc = no_inlining_increment_pc(env, SVM_INSTRUCTION_$1, pc); }
114 * :]):],
115 * [:
116 * pc++; /[::]* skip preparation address C *[::]/
117 * :]):])
118 */
119
120 /* m4svm_comment_define([:m4svm_mark_start_and_skip:],
121 * [:m4svm_mark_start_and_skip_1(:]) */
122
123 /* m4svm_comment_define([:m4svm_mark_start_and_skip_1:],
124 * [:m4svm_mark_start_and_skip_2$1:]) */
125
126 /* m4svm_comment_define([:m4svm_mark_start_and_skip_2:],
127 * [:m4svm_mark_start_and_skip_3([:$1:]) m4_dnl:]) */
128
129 /*
130 m4_ifdef([:m4svm_inlinability_testing_mode:],
131 [:m4_define([:m4svm_mark_start_and_skip_3:],
132 [:[:m4svm_mark_start_and_skip_testing($1):]:]):],
133 [:m4_define([:m4svm_mark_start_and_skip_3:],
134 [:[:m4svm_mark_start_and_skip_normal($1):]:]):])
135
136 m4_define([:m4svm_end_start_and_skip:],[:) m4_dnl:])
137 */
138
139 /*
140 ----------------------------------------------------------------------
141 m4svm_(dont_)expect_sigsegv
142 ----------------------------------------------------------------------
143 */
144
145 /* m4svm_comment_define([:m4svm_expect_sigsegv:],[:m4_[::]dnl:]) */
146 /* m4svm_comment_define([:m4svm_dont_expect_sigsegv:],[:m4_[::]dnl:]) */
147
148 /* m4_ifdef([:m4svm_inlinability_testing_mode:],[:
149 * m4svm_comment_define([:m4svm_expect_sigsegv:],
150 * [:[:{ env->inlinability_testing.sigsegv_expected = JNI_TRUE; } {
151 * :] m4_[::]dnl:]):]) */
152
153 /* m4_ifdef([:m4svm_inlinability_testing_mode:],[:
154 * m4svm_comment_define([:m4svm_dont_expect_sigsegv:],
155 * [:[:} { env->inlinability_testing.sigsegv_expected = JNI_FALSE; }
156 * :] m4_[::]dnl:]):]) */
157
158 /*
159 ----------------------------------------------------------------------
160 m4svm_instruction_inlined_threaded
161 ----------------------------------------------------------------------
162 */
163
164 void
dummy()165 dummy ()
166 {
167 switch (dummy)
168 {
169 m4svm_define_begin v = ":], [:m4svm_instruction_inlined_threaded:])";
170
171 /*
172 -----------------------------------m4_dnl
173 -----------------------------------
174 $1
175 -----------------------------------m4_dnl
176 -----------------------------------
177 */
178
179 case SVM_INSTRUCTION_$1:
180 {
181 env->vm->instructions[instr].param_count = $2;
182
183 /* implementation address */
184 env->vm->instructions[instr].code.implementation = &&START_$1;
185 env->vm->instructions[instr].inlined_code.implementation =
186 &&INLINED_START_$1;
187
188 /* code size */
189 env->vm->instructions[instr].inlined_size =
190 ((char *) &&END_$1) - ((char *) &&INLINED_START_$1);
191
192 /* can the implementation be relocated? */
193 env->vm->instructions[instr].flag = SVM_INLINEABLE_$1;
194
195 #if !defined(NDEBUG) || defined(_SABLEVM_INLINABILITY_TESTING)
196 strcpy (env->vm->instructions[instr].name, "$1");
197 #endif
198 break;
199
200 START_$1:
201 {
202 #ifndef NDEBUG
203
204 if (env->vm->verbose_instructions == JNI_TRUE)
205 {
206 _svmf_printf (env, stderr,
207 "T%d: [verbose instructions: executing @%p $1]\n",
208 env->thread.id, (void *) (pc - 1));
209 }
210
211 #endif
212 }
213 INLINED_START_$1:
214 m4svm_mark_start_and_skip ($1);
215 m4svm_end_start_and_skip ();
216
217 {
218
219 _svmm_verbose_instructions_inlined (env, pc, "$1");
220
221 /* instruction body */
222 $3 m4_dnl;
223
224 }
225
226 END_$1:
227 {
228 /* dispatch */
229 goto *((pc++)->implementation);
230 }
231 }
232 m4svm_define_end = ":])";
233 }
234 }
235
236 /*
237 ----------------------------------------------------------------------
238 m4svm_instruction_direct_threaded
239 ----------------------------------------------------------------------
240 */
241
242 void
dummy()243 dummy ()
244 {
245 switch (dummy)
246 {
247 m4svm_define_begin v = ":], [:m4svm_instruction_direct_threaded:])";
248
249 /*
250 -----------------------------------m4_dnl
251 -----------------------------------
252 $1
253 -----------------------------------m4_dnl
254 -----------------------------------
255 */
256
257 case SVM_INSTRUCTION_$1:
258 {
259 env->vm->instructions[instr].param_count = $2;
260
261 /* implementation address */
262 env->vm->instructions[instr].code.implementation = &&START_$1;
263
264 #ifndef NDEBUG
265 strcpy (env->vm->instructions[instr].name, "$1");
266 #endif
267 break;
268
269 START_$1:
270 #ifndef NDEBUG
271
272 if (env->vm->verbose_instructions == JNI_TRUE)
273 {
274 _svmf_printf (env, stderr,
275 "T%d: [verbose instructions: executing @%p $1]\n",
276 env->thread.id, (void *) (pc - 1));
277 }
278
279 #endif
280
281 m4svm_mark_start_and_skip ($1);
282 m4svm_end_start_and_skip ();
283
284 /* instruction body */
285 $3 m4_dnl;
286
287 /* dispatch */
288 goto *((pc++)->implementation);
289 }
290 m4svm_define_end = ":])";
291 }
292 }
293
294 /*
295 ----------------------------------------------------------------------
296 m4svm_instruction_switch_threaded
297 ----------------------------------------------------------------------
298 */
299
300 void
dummy()301 dummy ()
302 {
303 switch (dummy)
304 {
305 m4svm_define_begin v = ":], [:m4svm_instruction_switch_threaded:])";
306
307 /*
308 -----------------------------------m4_dnl
309 -----------------------------------
310 $1
311 -----------------------------------m4_dnl
312 -----------------------------------
313 */
314
315 case SVM_INSTRUCTION_$1:
316 {
317 env->vm->instructions[instr].code.jint = instr;
318 env->vm->instructions[instr].param_count = $2;
319 #ifndef NDEBUG
320 strcpy (env->vm->instructions[instr].name, "$1");
321 #endif
322 break;
323 }
324 m4svm_define_end = ":])";
325 }
326 }
327