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