* merged default branch into jitcache-arm-x86 branch
[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 <algorithm>
33 #include <functional>
34
35 #include "codegen.h"                   /* for PATCHER_NOPS */
36 #include "md.h"
37
38 #include "mm/memory.h"
39
40 #include "native/native.hpp"
41
42 #include "toolbox/list.hpp"
43 #include "toolbox/logging.h"           /* XXX remove me! */
44
45 #include "vm/exceptions.hpp"
46 #include "vm/initialize.hpp"
47 #include "vm/options.h"
48 #include "vm/resolve.hpp"
49 #include "vm/vm.hpp"                     /* for vm_abort */
50
51 #include "vm/jit/code.hpp"
52 #include "vm/jit/disass.h"
53 #include "vm/jit/jit.hpp"
54 #include "vm/jit/patcher-common.hpp"
55
56
57 /* patcher_function_list *******************************************************
58
59    This is a list which maps patcher function pointers to the according
60    names of the patcher functions. It is only usefull for debugging
61    purposes.
62
63 *******************************************************************************/
64
65 #if !defined(NDEBUG)
66 typedef struct patcher_function_list_t {
67         functionptr patcher;
68         const char* name;
69 } patcher_function_list_t;
70
71 static patcher_function_list_t patcher_function_list[] = {
72         { PATCHER_initialize_class,              "initialize_class" },
73         { PATCHER_resolve_class,                 "resolve_class" },
74         { PATCHER_resolve_native_function,       "resolve_native_function" },
75         { PATCHER_invokestatic_special,          "invokestatic_special" },
76         { PATCHER_invokevirtual,                 "invokevirtual" },
77         { PATCHER_invokeinterface,               "invokeinterface" },
78         { NULL,                                  "-UNKNOWN PATCHER FUNCTION-" }
79 };
80 #endif
81
82
83 /* patcher_list_create *********************************************************
84
85    Creates an empty patcher list for the given codeinfo.
86
87 *******************************************************************************/
88
89 void patcher_list_create(codeinfo *code)
90 {
91         code->patchers = new List<patchref_t>();
92 }
93
94
95 /* patcher_list_reset **********************************************************
96
97    Resets the patcher list inside a codeinfo. This is usefull when
98    resetting a codeinfo for recompiling.
99
100 *******************************************************************************/
101
102 void patcher_list_reset(codeinfo *code)
103 {
104 #if defined(ENABLE_STATISTICS)
105         if (opt_stat)
106                 size_patchref -= sizeof(patchref_t) * code->patchers->size();
107 #endif
108
109         // Free all elements of the list.
110         code->patchers->clear();
111 }
112
113 /* patcher_list_free ***********************************************************
114
115    Frees the patcher list and all its entries for the given codeinfo.
116
117 *******************************************************************************/
118
119 void patcher_list_free(codeinfo *code)
120 {
121         // Free all elements of the list.
122         patcher_list_reset(code);
123
124         // Free the list itself.
125         delete code->patchers;
126 }
127
128
129 /**
130  * Find an entry inside the patcher list for the given codeinfo by
131  * specifying the program counter of the patcher position.
132  *
133  * NOTE: Caller should hold the patcher list lock or maintain
134  * exclusive access otherwise.
135  *
136  * @param pc Program counter to find.
137  *
138  * @return Pointer to patcher.
139  */
140
141 struct foo : public std::binary_function<patchref_t, void*, bool> {
142         bool operator() (const patchref_t& pr, const void* pc) const
143         {
144                 return (pr.mpc == (uintptr_t) pc);
145         }
146 };
147
148 static patchref_t* patcher_list_find(codeinfo* code, void* pc)
149 {
150         // Search for a patcher with the given PC.
151         List<patchref_t>::iterator it = std::find_if(code->patchers->begin(), code->patchers->end(), std::bind2nd(foo(), pc));
152
153         if (it == code->patchers->end())
154                 return NULL;
155
156         return &(*it);
157 }
158
159
160 /* patcher_add_patch_ref *******************************************************
161
162    Appends a new patcher reference to the list of patching positions.
163
164 *******************************************************************************/
165
166 void patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp)
167 {
168         codegendata *cd;
169         codeinfo    *code;
170         s4           patchmpc;
171
172         cd       = jd->cd;
173         code     = jd->code;
174         patchmpc = cd->mcodeptr - cd->mcodebase;
175
176 #if !defined(NDEBUG)
177         if (patcher_list_find(code, (void*) (intptr_t) patchmpc) != NULL)
178                 vm_abort("patcher_add_patch_ref: different patchers at same position.");
179 #endif
180
181         // Set patcher information (mpc is resolved later).
182         patchref_t pr;
183
184         pr.mpc     = patchmpc;
185         pr.datap   = 0;
186         pr.disp    = disp;
187         pr.patcher = patcher;
188         pr.ref     = ref;
189         pr.mcode   = 0;
190         pr.done    = false;
191
192 #if defined(ENABLE_JITCACHE)
193         pr.attached_ref = NULL;
194 #endif
195
196         // Store patcher in the list (NOTE: structure is copied).
197         code->patchers->push_back(pr);
198
199 #if defined(ENABLE_STATISTICS)
200         if (opt_stat)
201                 size_patchref += sizeof(patchref_t);
202 #endif
203
204 #if defined(ENABLE_JIT) && (defined(__I386__) || defined(__M68K__) || defined(__SPARC_64__) || defined(__X86_64__))
205
206         /* XXX We can remove that when we don't use UD2 anymore on i386
207            and x86_64. */
208
209         /* On some architectures the patcher stub call instruction might
210            be longer than the actual instruction generated.  On this
211            architectures we store the last patcher call position and after
212            the basic block code generation is completed, we check the
213            range and maybe generate some nop's. */
214         /* The nops are generated in codegen_emit in each codegen */
215
216         cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
217 #endif
218 }
219
220
221 /**
222  * Resolve all patchers in the current JIT run.
223  *
224  * @param jd JIT data-structure
225  */
226 void patcher_resolve(jitdata* jd)
227 {
228         // Get required compiler data.
229         codeinfo* code = jd->code;
230
231         for (List<patchref_t>::iterator it = code->patchers->begin(); it != code->patchers->end(); it++) {
232                 patchref_t& pr = *it;
233
234                 pr.mpc   += (intptr_t) code->entrypoint;
235                 pr.datap  = (intptr_t) (pr.disp + code->entrypoint);
236         }
237 }
238
239
240 /**
241  * Check if the patcher is already patched.  This is done by comparing
242  * the machine instruction.
243  *
244  * @param pr Patcher structure.
245  *
246  * @return true if patched, false otherwise.
247  */
248 bool patcher_is_patched(patchref_t* pr)
249 {
250         // Validate the instruction at the patching position is the same
251         // instruction as the patcher structure contains.
252         uint32_t mcode = *((uint32_t*) pr->mpc);
253
254         if (mcode != pr->mcode) {
255                 // The code differs.
256                 return false;
257         }
258
259         return true;
260 }
261
262
263 /**
264  *
265  */
266 bool patcher_is_patched_at(void* pc)
267 {
268         codeinfo* code = code_find_codeinfo_for_pc(pc);
269
270         // Get the patcher for the given PC.
271         patchref_t* pr = patcher_list_find(code, pc);
272
273         if (pr == NULL) {
274                 // The given PC is not a patcher position.
275                 return false;
276         }
277
278         // Validate the instruction.
279         return patcher_is_patched(pr);
280 }
281
282
283 /* patcher_handler *************************************************************
284
285    Handles the request to patch JIT code at the given patching
286    position. This function is normally called by the signal
287    handler.
288
289    NOTE: The patcher list lock is used to maintain exclusive
290    access of the patched position (in fact of the whole code).
291    After patching has suceeded, the patcher reference should be
292    removed from the patcher list to avoid double patching.
293
294 *******************************************************************************/
295
296 #if !defined(NDEBUG)
297 /* XXX this indent is not thread safe! */
298 /* XXX if you want it thread safe, place patcher_depth in threadobject! */
299 static int patcher_depth = 0;
300 #define TRACE_PATCHER_INDENT for (i=0; i<patcher_depth; i++) printf("\t")
301 #endif /* !defined(NDEBUG) */
302
303 java_handle_t *patcher_handler(u1 *pc)
304 {
305         codeinfo      *code;
306         patchref_t    *pr;
307         bool           result;
308         java_handle_t *e;
309 #if !defined(NDEBUG)
310         patcher_function_list_t *l;
311         int                      i;
312 #endif
313
314         /* define the patcher function */
315
316         bool (*patcher_function)(patchref_t *);
317
318         /* search the codeinfo for the given PC */
319
320         code = code_find_codeinfo_for_pc(pc);
321         assert(code);
322
323         // Enter a mutex on the patcher list.
324         code->patchers->lock();
325
326         /* search the patcher information for the given PC */
327
328         pr = patcher_list_find(code, pc);
329
330         if (pr == NULL)
331                 vm_abort("patcher_handler: Unable to find patcher reference.");
332
333         if (pr->done) {
334 #if !defined(NDEBUG)
335                 if (opt_DebugPatcher) {
336                         log_println("patcher_handler: double-patching detected!");
337                 }
338 #endif
339                 code->patchers->unlock();
340                 return NULL;
341         }
342
343 #if !defined(NDEBUG)
344         if (opt_DebugPatcher) {
345                 for (l = patcher_function_list; l->patcher != NULL; l++)
346                         if (l->patcher == pr->patcher)
347                                 break;
348
349                 TRACE_PATCHER_INDENT; printf("patching in "); method_print(code->m); printf(" at %p\n", (void *) pr->mpc);
350                 TRACE_PATCHER_INDENT; printf("\tpatcher function = %s <%p>\n", l->name, (void *) (intptr_t) pr->patcher);
351
352                 TRACE_PATCHER_INDENT;
353                 printf("\tmachine code before = ");
354
355 # if defined(ENABLE_DISASSEMBLER)
356                 disassinstr((u1*) (void*) pr->mpc);
357 # else
358                 printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
359 # endif
360
361                 patcher_depth++;
362                 assert(patcher_depth > 0);
363         }
364 #endif
365
366         /* cast the passed function to a patcher function */
367
368         patcher_function = (bool (*)(patchref_t *)) (ptrint) pr->patcher;
369
370         /* call the proper patcher function */
371
372         result = (patcher_function)(pr);
373
374 #if !defined(NDEBUG)
375         if (opt_DebugPatcher) {
376                 assert(patcher_depth > 0);
377                 patcher_depth--;
378
379                 TRACE_PATCHER_INDENT;
380                 printf("\tmachine code after  = ");
381
382 # if defined(ENABLE_DISASSEMBLER)
383                 disassinstr((u1*) (void*) pr->mpc);
384 # else
385                 printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
386 # endif
387
388                 if (result == false) {
389                         TRACE_PATCHER_INDENT; printf("\tPATCHER EXCEPTION!\n");
390                 }
391         }
392 #endif
393
394 #if defined(ENABLE_JITCACHE)
395         /* Put cached reference into the code and remove it from the patcher */
396         if (pr->attached_ref)
397         {
398                 jitcache_handle_cached_ref(pr->attached_ref, code);
399                 pr->attached_ref = NULL;
400         }
401 #endif
402
403         /* check for return value and exit accordingly */
404
405         if (result == false) {
406                 e = exceptions_get_and_clear_exception();
407
408                 code->patchers->unlock();
409
410                 return e;
411         }
412
413         pr->done = true; /* XXX this is only preliminary to prevent double-patching */
414
415         code->patchers->unlock();
416
417         return NULL;
418 }
419
420
421 /* patcher_initialize_class ****************************************************
422
423    Initalizes a given classinfo pointer.
424    This function does not patch any data.
425
426 *******************************************************************************/
427
428 bool patcher_initialize_class(patchref_t *pr)
429 {
430         classinfo *c;
431
432         /* get stuff from the patcher reference */
433
434         c = (classinfo *) pr->ref;
435
436         /* check if the class is initialized */
437
438         if (!(c->state & CLASS_INITIALIZED))
439                 if (!initialize_class(c))
440                         return false;
441
442         /* patch back original code */
443
444         patcher_patch_code(pr);
445
446         return true;
447 }
448
449
450 /* patcher_resolve_class *******************************************************
451
452    Resolves a given unresolved class reference.
453    This function does not patch any data.
454
455 *******************************************************************************/
456
457 #ifdef ENABLE_VERIFIER
458 bool patcher_resolve_class(patchref_t *pr)
459 {
460         unresolved_class *uc;
461
462         /* get stuff from the patcher reference */
463
464         uc = (unresolved_class *) pr->ref;
465
466         /* resolve the class and check subtype constraints */
467
468         if (!resolve_class_eager_no_access_check(uc))
469                 return false;
470
471         /* patch back original code */
472
473         patcher_patch_code(pr);
474
475         return true;
476 }
477 #endif /* ENABLE_VERIFIER */
478
479
480 /* patcher_resolve_native_function *********************************************
481
482    Resolves the native function for a given methodinfo.
483    This function patches one data segment word.
484
485 *******************************************************************************/
486
487 bool patcher_resolve_native_function(patchref_t *pr)
488 {
489         methodinfo  *m;
490         uint8_t     *datap;
491
492         /* get stuff from the patcher reference */
493
494         m     = (methodinfo *) pr->ref;
495         datap = (uint8_t *)    pr->datap;
496
497         /* resolve native function */
498
499         NativeMethods& nm = VM::get_current()->get_nativemethods();
500         void* f = nm.resolve_method(m);
501
502         if (f == NULL)
503                 return false;
504
505         /* patch native function pointer */
506
507         *((intptr_t*) datap) = (intptr_t) f;
508
509         /* synchronize data cache */
510
511         md_dcacheflush(datap, SIZEOF_VOID_P);
512
513         /* patch back original code */
514
515         patcher_patch_code(pr);
516
517         return true;
518 }
519
520 /** Placeholder functions to calm down linker */
521 #if defined(__I386__)
522 bool patcher_resolve_classref_to_classinfo(patchref_t *pr)
523 {
524         return true;
525 }
526
527 bool patcher_resolve_classref_to_vftbl(patchref_t *pr)
528 {
529         return true;
530 }
531
532 bool patcher_resolve_classref_to_index(patchref_t *pr)
533 {
534         return true;
535 }
536
537 bool patcher_resolve_classref_to_flags(patchref_t *pr)
538 {
539         return true;
540 }
541 #endif
542
543 /*
544  * These are local overrides for various environment variables in Emacs.
545  * Please do not remove this and leave it at the end of the file, where
546  * Emacs will automagically detect them.
547  * ---------------------------------------------------------------------
548  * Local variables:
549  * mode: c++
550  * indent-tabs-mode: t
551  * c-basic-offset: 4
552  * tab-width: 4
553  * End:
554  * vim:noexpandtab:sw=4:ts=4:
555  */
556