- created jitcache-arm-x86 branch
[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.h"                     /* 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 #if defined(ENABLE_JITCACHE)
215         pr->attached_ref = NULL;
216 #endif
217
218         /* Generate NOPs for opt_shownops. */
219
220         if (opt_shownops)
221                 PATCHER_NOPS;
222
223 #if defined(ENABLE_JIT) && (defined(__I386__) || defined(__M68K__) || defined(__SPARC_64__) || defined(__X86_64__))
224
225         /* XXX We can remove that when we don't use UD2 anymore on i386
226            and x86_64. */
227
228         /* On some architectures the patcher stub call instruction might
229            be longer than the actual instruction generated.  On this
230            architectures we store the last patcher call position and after
231            the basic block code generation is completed, we check the
232            range and maybe generate some nop's. */
233         /* The nops are generated in codegen_emit in each codegen */
234
235         cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
236 #endif
237 }
238
239
240 /**
241  * Resolve all patchers in the current JIT run.
242  *
243  * @param jd JIT data-structure
244  */
245 void patcher_resolve(jitdata* jd)
246 {
247         codeinfo*   code;
248         patchref_t* pr;
249
250         /* Get required compiler data. */
251
252         code = jd->code;
253
254         for (pr = list_first(code->patchers); pr != NULL; pr = list_next(code->patchers, pr)) {
255                 pr->mpc   += (intptr_t) code->entrypoint;
256                 pr->datap  = (intptr_t) (pr->disp + code->entrypoint);
257         }
258 }
259
260
261 /* patcher_handler *************************************************************
262
263    Handles the request to patch JIT code at the given patching
264    position. This function is normally called by the signal
265    handler.
266
267    NOTE: The patcher list lock is used to maintain exclusive
268    access of the patched position (in fact of the whole code).
269    After patching has suceeded, the patcher reference should be
270    removed from the patcher list to avoid double patching.
271
272 *******************************************************************************/
273
274 #if !defined(NDEBUG)
275 /* XXX this indent is not thread safe! */
276 /* XXX if you want it thread safe, place patcher_depth in threadobject! */
277 static int patcher_depth = 0;
278 #define TRACE_PATCHER_INDENT for (i=0; i<patcher_depth; i++) printf("\t")
279 #endif /* !defined(NDEBUG) */
280
281 java_handle_t *patcher_handler(u1 *pc)
282 {
283         codeinfo      *code;
284         patchref_t    *pr;
285         bool           result;
286         java_handle_t *e;
287 #if !defined(NDEBUG)
288         patcher_function_list_t *l;
289         int                      i;
290 #endif
291
292         /* define the patcher function */
293
294         bool (*patcher_function)(patchref_t *);
295
296         /* search the codeinfo for the given PC */
297
298         code = code_find_codeinfo_for_pc(pc);
299         assert(code);
300
301         /* enter a monitor on the patcher list */
302
303         LOCK_MONITOR_ENTER(code->patchers);
304
305         /* search the patcher information for the given PC */
306
307         pr = patcher_list_find(code, pc);
308
309         if (pr == NULL)
310                 vm_abort("patcher_handler: Unable to find patcher reference.");
311
312         if (pr->done) {
313 #if !defined(NDEBUG)
314                 if (opt_DebugPatcher) {
315                         log_println("patcher_handler: double-patching detected!");
316                 }
317 #endif
318                 LOCK_MONITOR_EXIT(code->patchers);
319                 return NULL;
320         }
321
322 #if !defined(NDEBUG)
323         if (opt_DebugPatcher) {
324                 for (l = patcher_function_list; l->patcher != NULL; l++)
325                         if (l->patcher == pr->patcher)
326                                 break;
327
328                 TRACE_PATCHER_INDENT; printf("patching in "); method_print(code->m); printf(" at %p\n", (void *) pr->mpc);
329                 TRACE_PATCHER_INDENT; printf("\tpatcher function = %s <%p>\n", l->name, (void *) (intptr_t) pr->patcher);
330
331                 TRACE_PATCHER_INDENT;
332                 printf("\tmachine code before = ");
333
334 # if defined(ENABLE_DISASSEMBLER)
335                 disassinstr((void *) pr->mpc);
336 # else
337                 printf("disassembler disabled\n");
338 # endif
339
340                 patcher_depth++;
341                 assert(patcher_depth > 0);
342         }
343 #endif
344
345         /* cast the passed function to a patcher function */
346
347         patcher_function = (bool (*)(patchref_t *)) (ptrint) pr->patcher;
348
349         /* call the proper patcher function */
350
351         result = (patcher_function)(pr);
352
353 #if !defined(NDEBUG)
354         if (opt_DebugPatcher) {
355                 assert(patcher_depth > 0);
356                 patcher_depth--;
357
358                 TRACE_PATCHER_INDENT;
359                 printf("\tmachine code after  = ");
360
361 # if defined(ENABLE_DISASSEMBLER)
362                 disassinstr((void *) pr->mpc);
363 # else
364                 printf("disassembler disabled\n");
365 # endif
366
367                 if (result == false) {
368                         TRACE_PATCHER_INDENT; printf("\tPATCHER EXCEPTION!\n");
369                 }
370         }
371 #endif
372
373 #if defined(ENABLE_JITCACHE)
374         /* Put cached reference into the code and remove it from the patcher */
375         if (pr->attached_ref)
376         {
377                 jitcache_handle_cached_ref(pr->attached_ref, code);
378                 pr->attached_ref = NULL;
379         }
380 #endif
381
382         /* check for return value and exit accordingly */
383
384         if (result == false) {
385                 e = exceptions_get_and_clear_exception();
386
387                 LOCK_MONITOR_EXIT(code->patchers);
388
389                 return e;
390         }
391
392         pr->done = true; /* XXX this is only preliminary to prevent double-patching */
393
394         LOCK_MONITOR_EXIT(code->patchers);
395
396         return NULL;
397 }
398
399
400 /* patcher_initialize_class ****************************************************
401
402    Initalizes a given classinfo pointer.
403    This function does not patch any data.
404
405 *******************************************************************************/
406
407 bool patcher_initialize_class(patchref_t *pr)
408 {
409         classinfo *c;
410
411         /* get stuff from the patcher reference */
412
413         c = (classinfo *) pr->ref;
414
415         /* check if the class is initialized */
416
417         if (!(c->state & CLASS_INITIALIZED))
418                 if (!initialize_class(c))
419                         return false;
420
421         /* patch back original code */
422
423         patcher_patch_code(pr);
424
425         return true;
426 }
427
428
429 /* patcher_resolve_class *******************************************************
430
431    Resolves a given unresolved class reference.
432    This function does not patch any data.
433
434 *******************************************************************************/
435
436 #ifdef ENABLE_VERIFIER
437 bool patcher_resolve_class(patchref_t *pr)
438 {
439         unresolved_class *uc;
440
441         /* get stuff from the patcher reference */
442
443         uc = (unresolved_class *) pr->ref;
444
445         /* resolve the class and check subtype constraints */
446
447         if (!resolve_class_eager_no_access_check(uc))
448                 return false;
449
450         /* patch back original code */
451
452         patcher_patch_code(pr);
453
454         return true;
455 }
456 #endif /* ENABLE_VERIFIER */
457
458
459 /* patcher_resolve_native_function *********************************************
460
461    Resolves the native function for a given methodinfo.
462    This function patches one data segment word.
463
464 *******************************************************************************/
465
466 bool patcher_resolve_native_function(patchref_t *pr)
467 {
468         methodinfo  *m;
469         uint8_t     *datap;
470         functionptr  f;
471
472         /* get stuff from the patcher reference */
473
474         m     = (methodinfo *) pr->ref;
475         datap = (uint8_t *)    pr->datap;
476
477         /* resolve native function */
478
479         if (!(f = native_method_resolve(m)))
480                 return false;
481
482         /* patch native function pointer */
483
484         *((intptr_t *) datap) = (intptr_t) f;
485
486         /* synchronize data cache */
487
488         md_dcacheflush(datap, SIZEOF_VOID_P);
489
490         /* patch back original code */
491
492         patcher_patch_code(pr);
493
494         return true;
495 }
496
497 /** Placeholder functions to calm down linker */
498 #if defined(__I386__)
499 bool patcher_resolve_classref_to_classinfo(patchref_t *pr)
500 {
501         return true;
502 }
503
504 bool patcher_resolve_classref_to_vftbl(patchref_t *pr)
505 {
506         return true;
507 }
508
509 bool patcher_resolve_classref_to_index(patchref_t *pr)
510 {
511         return true;
512 }
513
514 bool patcher_resolve_classref_to_flags(patchref_t *pr)
515 {
516         return true;
517 }
518 #endif
519
520 /*
521  * These are local overrides for various environment variables in Emacs.
522  * Please do not remove this and leave it at the end of the file, where
523  * Emacs will automagically detect them.
524  * ---------------------------------------------------------------------
525  * Local variables:
526  * mode: c
527  * indent-tabs-mode: t
528  * c-basic-offset: 4
529  * tab-width: 4
530  * End:
531  * vim:noexpandtab:sw=4:ts=4:
532  */
533