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