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