* src/vm/initialize.c: Moved to C++.
[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         // 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 (mcode != pr->mcode) {
251                 // The code differs.
252                 return false;
253         }
254
255         return true;
256 }
257
258
259 /**
260  *
261  */
262 bool patcher_is_patched_at(void* pc)
263 {
264         codeinfo* code = code_find_codeinfo_for_pc(pc);
265
266         // Get the patcher for the given PC.
267         patchref_t* pr = patcher_list_find(code, pc);
268
269         if (pr == NULL) {
270                 // The given PC is not a patcher position.
271                 return false;
272         }
273
274         // Validate the instruction.
275         return patcher_is_patched(pr);
276 }
277
278
279 /* patcher_handler *************************************************************
280
281    Handles the request to patch JIT code at the given patching
282    position. This function is normally called by the signal
283    handler.
284
285    NOTE: The patcher list lock is used to maintain exclusive
286    access of the patched position (in fact of the whole code).
287    After patching has suceeded, the patcher reference should be
288    removed from the patcher list to avoid double patching.
289
290 *******************************************************************************/
291
292 #if !defined(NDEBUG)
293 /* XXX this indent is not thread safe! */
294 /* XXX if you want it thread safe, place patcher_depth in threadobject! */
295 static int patcher_depth = 0;
296 #define TRACE_PATCHER_INDENT for (i=0; i<patcher_depth; i++) printf("\t")
297 #endif /* !defined(NDEBUG) */
298
299 java_handle_t *patcher_handler(u1 *pc)
300 {
301         codeinfo      *code;
302         patchref_t    *pr;
303         bool           result;
304         java_handle_t *e;
305 #if !defined(NDEBUG)
306         patcher_function_list_t *l;
307         int                      i;
308 #endif
309
310         /* define the patcher function */
311
312         bool (*patcher_function)(patchref_t *);
313
314         /* search the codeinfo for the given PC */
315
316         code = code_find_codeinfo_for_pc(pc);
317         assert(code);
318
319         // Enter a mutex on the patcher list.
320         code->patchers->lock();
321
322         /* search the patcher information for the given PC */
323
324         pr = patcher_list_find(code, pc);
325
326         if (pr == NULL)
327                 vm_abort("patcher_handler: Unable to find patcher reference.");
328
329         if (pr->done) {
330 #if !defined(NDEBUG)
331                 if (opt_DebugPatcher) {
332                         log_println("patcher_handler: double-patching detected!");
333                 }
334 #endif
335                 code->patchers->unlock();
336                 return NULL;
337         }
338
339 #if !defined(NDEBUG)
340         if (opt_DebugPatcher) {
341                 for (l = patcher_function_list; l->patcher != NULL; l++)
342                         if (l->patcher == pr->patcher)
343                                 break;
344
345                 TRACE_PATCHER_INDENT; printf("patching in "); method_print(code->m); printf(" at %p\n", (void *) pr->mpc);
346                 TRACE_PATCHER_INDENT; printf("\tpatcher function = %s <%p>\n", l->name, (void *) (intptr_t) pr->patcher);
347
348                 TRACE_PATCHER_INDENT;
349                 printf("\tmachine code before = ");
350
351 # if defined(ENABLE_DISASSEMBLER)
352                 disassinstr((u1*) (void*) pr->mpc);
353 # else
354                 printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
355 # endif
356
357                 patcher_depth++;
358                 assert(patcher_depth > 0);
359         }
360 #endif
361
362         /* cast the passed function to a patcher function */
363
364         patcher_function = (bool (*)(patchref_t *)) (ptrint) pr->patcher;
365
366         /* call the proper patcher function */
367
368         result = (patcher_function)(pr);
369
370 #if !defined(NDEBUG)
371         if (opt_DebugPatcher) {
372                 assert(patcher_depth > 0);
373                 patcher_depth--;
374
375                 TRACE_PATCHER_INDENT;
376                 printf("\tmachine code after  = ");
377
378 # if defined(ENABLE_DISASSEMBLER)
379                 disassinstr((u1*) (void*) pr->mpc);
380 # else
381                 printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
382 # endif
383
384                 if (result == false) {
385                         TRACE_PATCHER_INDENT; printf("\tPATCHER EXCEPTION!\n");
386                 }
387         }
388 #endif
389
390         /* check for return value and exit accordingly */
391
392         if (result == false) {
393                 e = exceptions_get_and_clear_exception();
394
395                 code->patchers->unlock();
396
397                 return e;
398         }
399
400         pr->done = true; /* XXX this is only preliminary to prevent double-patching */
401
402         code->patchers->unlock();
403
404         return NULL;
405 }
406
407
408 /* patcher_initialize_class ****************************************************
409
410    Initalizes a given classinfo pointer.
411    This function does not patch any data.
412
413 *******************************************************************************/
414
415 bool patcher_initialize_class(patchref_t *pr)
416 {
417         classinfo *c;
418
419         /* get stuff from the patcher reference */
420
421         c = (classinfo *) pr->ref;
422
423         /* check if the class is initialized */
424
425         if (!(c->state & CLASS_INITIALIZED))
426                 if (!initialize_class(c))
427                         return false;
428
429         /* patch back original code */
430
431         patcher_patch_code(pr);
432
433         return true;
434 }
435
436
437 /* patcher_resolve_class *******************************************************
438
439    Resolves a given unresolved class reference.
440    This function does not patch any data.
441
442 *******************************************************************************/
443
444 #ifdef ENABLE_VERIFIER
445 bool patcher_resolve_class(patchref_t *pr)
446 {
447         unresolved_class *uc;
448
449         /* get stuff from the patcher reference */
450
451         uc = (unresolved_class *) pr->ref;
452
453         /* resolve the class and check subtype constraints */
454
455         if (!resolve_class_eager_no_access_check(uc))
456                 return false;
457
458         /* patch back original code */
459
460         patcher_patch_code(pr);
461
462         return true;
463 }
464 #endif /* ENABLE_VERIFIER */
465
466
467 /* patcher_resolve_native_function *********************************************
468
469    Resolves the native function for a given methodinfo.
470    This function patches one data segment word.
471
472 *******************************************************************************/
473
474 bool patcher_resolve_native_function(patchref_t *pr)
475 {
476         methodinfo  *m;
477         uint8_t     *datap;
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         NativeMethods& nm = VM::get_current()->get_nativemethods();
487         void* f = nm.resolve_method(m);
488
489         if (f == NULL)
490                 return false;
491
492         /* patch native function pointer */
493
494         *((intptr_t*) datap) = (intptr_t) f;
495
496         /* synchronize data cache */
497
498         md_dcacheflush(datap, SIZEOF_VOID_P);
499
500         /* patch back original code */
501
502         patcher_patch_code(pr);
503
504         return true;
505 }
506
507
508 /*
509  * These are local overrides for various environment variables in Emacs.
510  * Please do not remove this and leave it at the end of the file, where
511  * Emacs will automagically detect them.
512  * ---------------------------------------------------------------------
513  * Local variables:
514  * mode: c++
515  * indent-tabs-mode: t
516  * c-basic-offset: 4
517  * tab-width: 4
518  * End:
519  * vim:noexpandtab:sw=4:ts=4:
520  */
521