* src/vm/vm.c, src/vm/vm.h: Moved to .cpp.
[cacao.git] / src / vm / jit / patcher-common.c
1 /* src/vm/jit/patcher-common.c - architecture independent code patching stuff
2
3    Copyright (C) 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <stdint.h>
30
31 #include "codegen.h"                   /* for PATCHER_NOPS */
32 #include "md.h"
33
34 #include "mm/memory.h"
35
36 #include "native/native.h"
37
38 #include "threads/lock-common.h"
39
40 #include "toolbox/list.h"
41 #include "toolbox/logging.h"           /* XXX remove me! */
42
43 #include "vm/exceptions.h"
44 #include "vm/initialize.h"
45 #include "vm/resolve.h"
46 #include "vm/vm.hpp"                     /* for vm_abort */
47
48 #include "vm/jit/code.h"
49 #include "vm/jit/disass.h"
50 #include "vm/jit/jit.h"
51 #include "vm/jit/patcher-common.h"
52
53 #include "vmcore/options.h"
54
55
56 /* patcher_function_list *******************************************************
57
58    This is a list which maps patcher function pointers to the according
59    names of the patcher functions. It is only usefull for debugging
60    purposes.
61
62 *******************************************************************************/
63
64 #if !defined(NDEBUG)
65 typedef struct patcher_function_list_t {
66         functionptr  patcher;
67         char        *name;
68 } patcher_function_list_t;
69
70 static patcher_function_list_t patcher_function_list[] = {
71         { PATCHER_initialize_class,              "initialize_class" },
72         { PATCHER_resolve_class,                 "resolve_class" },
73         { PATCHER_resolve_native_function,       "resolve_native_function" },
74         { PATCHER_invokestatic_special,          "invokestatic_special" },
75         { PATCHER_invokevirtual,                 "invokevirtual" },
76         { PATCHER_invokeinterface,               "invokeinterface" },
77         { NULL,                                  "-UNKNOWN PATCHER FUNCTION-" }
78 };
79 #endif
80
81
82 /* patcher_list_create *********************************************************
83
84    Creates an empty patcher list for the given codeinfo.
85
86 *******************************************************************************/
87
88 void patcher_list_create(codeinfo *code)
89 {
90         code->patchers = list_create(OFFSET(patchref_t, linkage));
91 }
92
93
94 /* patcher_list_reset **********************************************************
95
96    Resets the patcher list inside a codeinfo. This is usefull when
97    resetting a codeinfo for recompiling.
98
99 *******************************************************************************/
100
101 void patcher_list_reset(codeinfo *code)
102 {
103         patchref_t *pr;
104
105         /* free all elements of the list */
106
107         while((pr = list_first(code->patchers)) != NULL) {
108                 list_remove(code->patchers, pr);
109
110                 FREE(pr, patchref_t);
111
112 #if defined(ENABLE_STATISTICS)
113                 if (opt_stat)
114                         size_patchref -= sizeof(patchref_t);
115 #endif
116         }
117 }
118
119 /* patcher_list_free ***********************************************************
120
121    Frees the patcher list and all its entries for the given codeinfo.
122
123 *******************************************************************************/
124
125 void patcher_list_free(codeinfo *code)
126 {
127         /* free all elements of the list */
128
129         patcher_list_reset(code);
130
131         /* free the list itself */
132
133         FREE(code->patchers, list_t);
134 }
135
136
137 /* patcher_list_find ***********************************************************
138
139    Find an entry inside the patcher list for the given codeinfo
140    by specifying the program counter of the patcher position.
141
142    NOTE: Caller should hold the patcher list lock or maintain
143    exclusive access otherwise.
144
145 *******************************************************************************/
146
147 static patchref_t *patcher_list_find(codeinfo *code, u1 *pc)
148 {
149         patchref_t *pr;
150
151         /* walk through all patcher references for the given codeinfo */
152
153         pr = list_first(code->patchers);
154
155         while (pr) {
156
157 /*#define TRACE_PATCHER_FIND*/
158 #ifdef TRACE_PATCHER_FIND
159                 log_println("patcher_list_find: %p == %p", pr->mpc, pc);
160 #endif
161
162                 if (pr->mpc == (ptrint) pc)
163                         return pr;
164
165                 pr = list_next(code->patchers, pr);
166         }
167
168         return NULL;
169 }
170
171
172 /* patcher_add_patch_ref *******************************************************
173
174    Appends a new patcher reference to the list of patching positions.
175
176 *******************************************************************************/
177
178 void patcher_add_patch_ref(jitdata *jd, functionptr patcher, voidptr ref,
179                            s4 disp)
180 {
181         codegendata *cd;
182         codeinfo    *code;
183         patchref_t  *pr;
184         s4           patchmpc;
185
186         cd       = jd->cd;
187         code     = jd->code;
188         patchmpc = cd->mcodeptr - cd->mcodebase;
189
190 #if !defined(NDEBUG)
191         if (patcher_list_find(code, (u1 *) (intptr_t) patchmpc) != NULL)
192                 vm_abort("patcher_add_patch_ref: different patchers at same position.");
193 #endif
194
195         /* allocate patchref on heap (at least freed together with codeinfo) */
196
197         pr = NEW(patchref_t);
198         list_add_first(code->patchers, pr);
199
200 #if defined(ENABLE_STATISTICS)
201         if (opt_stat)
202                 size_patchref += sizeof(patchref_t);
203 #endif
204
205         /* set patcher information (mpc is resolved later) */
206
207         pr->mpc     = patchmpc;
208         pr->disp    = disp;
209         pr->patcher = patcher;
210         pr->ref     = ref;
211         pr->mcode   = 0;
212         pr->done    = false;
213
214         /* Generate NOPs for opt_shownops. */
215
216         if (opt_shownops)
217                 PATCHER_NOPS;
218
219 #if defined(ENABLE_JIT) && (defined(__I386__) || defined(__M68K__) || defined(__SPARC_64__) || defined(__X86_64__))
220
221         /* XXX We can remove that when we don't use UD2 anymore on i386
222            and x86_64. */
223
224         /* On some architectures the patcher stub call instruction might
225            be longer than the actual instruction generated.  On this
226            architectures we store the last patcher call position and after
227            the basic block code generation is completed, we check the
228            range and maybe generate some nop's. */
229         /* The nops are generated in codegen_emit in each codegen */
230
231         cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
232 #endif
233 }
234
235
236 /**
237  * Resolve all patchers in the current JIT run.
238  *
239  * @param jd JIT data-structure
240  */
241 void patcher_resolve(jitdata* jd)
242 {
243         codeinfo*   code;
244         patchref_t* pr;
245
246         /* Get required compiler data. */
247
248         code = jd->code;
249
250         for (pr = list_first(code->patchers); pr != NULL; pr = list_next(code->patchers, pr)) {
251                 pr->mpc   += (intptr_t) code->entrypoint;
252                 pr->datap  = (intptr_t) (pr->disp + code->entrypoint);
253         }
254 }
255
256
257 /* patcher_handler *************************************************************
258
259    Handles the request to patch JIT code at the given patching
260    position. This function is normally called by the signal
261    handler.
262
263    NOTE: The patcher list lock is used to maintain exclusive
264    access of the patched position (in fact of the whole code).
265    After patching has suceeded, the patcher reference should be
266    removed from the patcher list to avoid double patching.
267
268 *******************************************************************************/
269
270 #if !defined(NDEBUG)
271 /* XXX this indent is not thread safe! */
272 /* XXX if you want it thread safe, place patcher_depth in threadobject! */
273 static int patcher_depth = 0;
274 #define TRACE_PATCHER_INDENT for (i=0; i<patcher_depth; i++) printf("\t")
275 #endif /* !defined(NDEBUG) */
276
277 java_handle_t *patcher_handler(u1 *pc)
278 {
279         codeinfo      *code;
280         patchref_t    *pr;
281         bool           result;
282         java_handle_t *e;
283 #if !defined(NDEBUG)
284         patcher_function_list_t *l;
285         int                      i;
286 #endif
287
288         /* define the patcher function */
289
290         bool (*patcher_function)(patchref_t *);
291
292         /* search the codeinfo for the given PC */
293
294         code = code_find_codeinfo_for_pc(pc);
295         assert(code);
296
297         /* enter a monitor on the patcher list */
298
299         LOCK_MONITOR_ENTER(code->patchers);
300
301         /* search the patcher information for the given PC */
302
303         pr = patcher_list_find(code, pc);
304
305         if (pr == NULL)
306                 vm_abort("patcher_handler: Unable to find patcher reference.");
307
308         if (pr->done) {
309 #if !defined(NDEBUG)
310                 if (opt_DebugPatcher) {
311                         log_println("patcher_handler: double-patching detected!");
312                 }
313 #endif
314                 LOCK_MONITOR_EXIT(code->patchers);
315                 return NULL;
316         }
317
318 #if !defined(NDEBUG)
319         if (opt_DebugPatcher) {
320                 for (l = patcher_function_list; l->patcher != NULL; l++)
321                         if (l->patcher == pr->patcher)
322                                 break;
323
324                 TRACE_PATCHER_INDENT; printf("patching in "); method_print(code->m); printf(" at %p\n", (void *) pr->mpc);
325                 TRACE_PATCHER_INDENT; printf("\tpatcher function = %s <%p>\n", l->name, (void *) (intptr_t) pr->patcher);
326
327                 TRACE_PATCHER_INDENT;
328                 printf("\tmachine code before = ");
329
330 # if defined(ENABLE_DISASSEMBLER)
331                 disassinstr((void *) pr->mpc);
332 # else
333                 printf("disassembler disabled\n");
334 # endif
335
336                 patcher_depth++;
337                 assert(patcher_depth > 0);
338         }
339 #endif
340
341         /* cast the passed function to a patcher function */
342
343         patcher_function = (bool (*)(patchref_t *)) (ptrint) pr->patcher;
344
345         /* call the proper patcher function */
346
347         result = (patcher_function)(pr);
348
349 #if !defined(NDEBUG)
350         if (opt_DebugPatcher) {
351                 assert(patcher_depth > 0);
352                 patcher_depth--;
353
354                 TRACE_PATCHER_INDENT;
355                 printf("\tmachine code after  = ");
356
357 # if defined(ENABLE_DISASSEMBLER)
358                 disassinstr((void *) pr->mpc);
359 # else
360                 printf("disassembler disabled\n");
361 # endif
362
363                 if (result == false) {
364                         TRACE_PATCHER_INDENT; printf("\tPATCHER EXCEPTION!\n");
365                 }
366         }
367 #endif
368
369         /* check for return value and exit accordingly */
370
371         if (result == false) {
372                 e = exceptions_get_and_clear_exception();
373
374                 LOCK_MONITOR_EXIT(code->patchers);
375
376                 return e;
377         }
378
379         pr->done = true; /* XXX this is only preliminary to prevent double-patching */
380
381         LOCK_MONITOR_EXIT(code->patchers);
382
383         return NULL;
384 }
385
386
387 /* patcher_initialize_class ****************************************************
388
389    Initalizes a given classinfo pointer.
390    This function does not patch any data.
391
392 *******************************************************************************/
393
394 bool patcher_initialize_class(patchref_t *pr)
395 {
396         classinfo *c;
397
398         /* get stuff from the patcher reference */
399
400         c = (classinfo *) pr->ref;
401
402         /* check if the class is initialized */
403
404         if (!(c->state & CLASS_INITIALIZED))
405                 if (!initialize_class(c))
406                         return false;
407
408         /* patch back original code */
409
410         patcher_patch_code(pr);
411
412         return true;
413 }
414
415
416 /* patcher_resolve_class *******************************************************
417
418    Resolves a given unresolved class reference.
419    This function does not patch any data.
420
421 *******************************************************************************/
422
423 #ifdef ENABLE_VERIFIER
424 bool patcher_resolve_class(patchref_t *pr)
425 {
426         unresolved_class *uc;
427
428         /* get stuff from the patcher reference */
429
430         uc = (unresolved_class *) pr->ref;
431
432         /* resolve the class and check subtype constraints */
433
434         if (!resolve_class_eager_no_access_check(uc))
435                 return false;
436
437         /* patch back original code */
438
439         patcher_patch_code(pr);
440
441         return true;
442 }
443 #endif /* ENABLE_VERIFIER */
444
445
446 /* patcher_resolve_native_function *********************************************
447
448    Resolves the native function for a given methodinfo.
449    This function patches one data segment word.
450
451 *******************************************************************************/
452
453 bool patcher_resolve_native_function(patchref_t *pr)
454 {
455         methodinfo  *m;
456         uint8_t     *datap;
457         functionptr  f;
458
459         /* get stuff from the patcher reference */
460
461         m     = (methodinfo *) pr->ref;
462         datap = (uint8_t *)    pr->datap;
463
464         /* resolve native function */
465
466         if (!(f = native_method_resolve(m)))
467                 return false;
468
469         /* patch native function pointer */
470
471         *((intptr_t *) datap) = (intptr_t) f;
472
473         /* synchronize data cache */
474
475         md_dcacheflush(datap, SIZEOF_VOID_P);
476
477         /* patch back original code */
478
479         patcher_patch_code(pr);
480
481         return true;
482 }
483
484
485 /*
486  * These are local overrides for various environment variables in Emacs.
487  * Please do not remove this and leave it at the end of the file, where
488  * Emacs will automagically detect them.
489  * ---------------------------------------------------------------------
490  * Local variables:
491  * mode: c
492  * indent-tabs-mode: t
493  * c-basic-offset: 4
494  * tab-width: 4
495  * End:
496  * vim:noexpandtab:sw=4:ts=4:
497  */
498