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