1 /* src/vm/jit/patcher-common.cpp - architecture independent code patching stuff
3 Copyright (C) 2007, 2008, 2009
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 Copyright (C) 2008 Theobroma Systems Ltd.
7 This file is part of CACAO.
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.
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.
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
35 #include "codegen.h" /* for PATCHER_NOPS */
39 #include "mm/memory.hpp"
41 #include "native/native.hpp"
43 #include "toolbox/list.hpp"
44 #include "toolbox/logging.hpp" /* XXX remove me! */
46 #include "vm/breakpoint.hpp"
47 #include "vm/exceptions.hpp"
48 #include "vm/initialize.hpp"
49 #include "vm/options.h"
51 #include "vm/resolve.hpp"
53 #include "vm/jit/code.hpp"
54 #include "vm/jit/disass.h"
55 #include "vm/jit/jit.hpp"
56 #include "vm/jit/patcher-common.hpp"
59 /* patcher_function_list *******************************************************
61 This is a list which maps patcher function pointers to the according
62 names of the patcher functions. It is only usefull for debugging
65 *******************************************************************************/
68 typedef struct patcher_function_list_t {
71 } patcher_function_list_t;
73 static patcher_function_list_t patcher_function_list[] = {
74 { PATCHER_initialize_class, "initialize_class" },
75 #ifdef ENABLE_VERIFIER
76 { PATCHER_resolve_class, "resolve_class" },
77 #endif /* ENABLE_VERIFIER */
78 { PATCHER_resolve_native_function, "resolve_native_function" },
79 { PATCHER_invokestatic_special, "invokestatic_special" },
80 { PATCHER_invokevirtual, "invokevirtual" },
81 { PATCHER_invokeinterface, "invokeinterface" },
82 { PATCHER_breakpoint, "breakpoint" },
83 { NULL, "-UNKNOWN PATCHER FUNCTION-" }
88 /* patcher_list_create *********************************************************
90 Creates an empty patcher list for the given codeinfo.
92 *******************************************************************************/
94 void patcher_list_create(codeinfo *code)
96 code->patchers = new LockedList<patchref_t>();
100 /* patcher_list_reset **********************************************************
102 Resets the patcher list inside a codeinfo. This is usefull when
103 resetting a codeinfo for recompiling.
105 *******************************************************************************/
107 void patcher_list_reset(codeinfo *code)
109 #if defined(ENABLE_STATISTICS)
111 size_patchref -= sizeof(patchref_t) * code->patchers->size();
114 // Free all elements of the list.
115 code->patchers->clear();
118 /* patcher_list_free ***********************************************************
120 Frees the patcher list and all its entries for the given codeinfo.
122 *******************************************************************************/
124 void patcher_list_free(codeinfo *code)
126 // Free all elements of the list.
127 patcher_list_reset(code);
129 // Free the list itself.
130 delete code->patchers;
135 * Find an entry inside the patcher list for the given codeinfo by
136 * specifying the program counter of the patcher position.
138 * NOTE: Caller should hold the patcher list lock or maintain
139 * exclusive access otherwise.
141 * @param pc Program counter to find.
143 * @return Pointer to patcher.
146 struct foo : public std::binary_function<patchref_t, void*, bool> {
147 bool operator() (const patchref_t& pr, const void* pc) const
149 return (pr.mpc == (uintptr_t) pc);
153 static patchref_t* patcher_list_find(codeinfo* code, void* pc)
155 // Search for a patcher with the given PC.
156 List<patchref_t>::iterator it = std::find_if(code->patchers->begin(), code->patchers->end(), std::bind2nd(foo(), pc));
158 if (it == code->patchers->end())
166 * Show the content of the whole patcher reference list for
167 * debugging purposes.
169 * @param code The codeinfo containing the patcher list.
172 void patcher_list_show(codeinfo *code)
174 for (List<patchref_t>::iterator it = code->patchers->begin(); it != code->patchers->end(); it++) {
175 patchref_t& pr = *it;
177 // Lookup name in patcher function list.
178 patcher_function_list_t* l;
179 for (l = patcher_function_list; l->patcher != NULL; l++)
180 if (l->patcher == pr.patcher)
183 // Display information about patcher.
184 printf("\tpatcher pc:"PRINTF_FORMAT_INTPTR_T, pr.mpc);
185 printf(" datap:"PRINTF_FORMAT_INTPTR_T, pr.datap);
186 printf(" ref:"PRINTF_FORMAT_INTPTR_T, (intptr_t) pr.ref);
187 #if PATCHER_CALL_SIZE == 4
188 printf(" mcode:%08x", (uint32_t) pr.mcode);
189 #elif PATCHER_CALL_SIZE == 2
190 printf(" mcode:%04x", (uint16_t) pr.mcode);
192 # error Unknown PATCHER_CALL_SIZE
194 printf(" type:%s\n", l->name);
196 // Display machine code of patched position.
197 #if 0 && defined(ENABLE_DISASSEMBLER)
198 printf("\t\tcurrent -> ");
199 disassinstr((uint8_t*) pr.mpc);
200 printf("\t\tapplied -> ");
201 disassinstr((uint8_t*) &(pr.mcode));
208 /* patcher_add_patch_ref *******************************************************
210 Appends a new patcher reference to the list of patching positions.
212 *******************************************************************************/
214 void patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp)
216 codegendata *cd = jd->cd;
217 codeinfo *code = jd->code;
219 #if defined(ALIGN_PATCHER_TRAP)
220 emit_patcher_alignment(cd);
223 int32_t patchmpc = cd->mcodeptr - cd->mcodebase;
226 if (patcher_list_find(code, (void*) (intptr_t) patchmpc) != NULL)
227 os::abort("patcher_add_patch_ref: different patchers at same position.");
230 #if defined(USES_PATCHABLE_MEMORY_BARRIER)
234 // Set patcher information (mpc is resolved later).
240 pr.patcher = patcher;
245 // Store patcher in the list (NOTE: structure is copied).
246 code->patchers->push_back(pr);
248 #if defined(ENABLE_STATISTICS)
250 size_patchref += sizeof(patchref_t);
253 #if defined(ENABLE_JIT) && (defined(__I386__) || defined(__M68K__) || defined(__SPARC_64__) || defined(__X86_64__))
255 /* XXX We can remove that when we don't use UD2 anymore on i386
258 /* On some architectures the patcher stub call instruction might
259 be longer than the actual instruction generated. On this
260 architectures we store the last patcher call position and after
261 the basic block code generation is completed, we check the
262 range and maybe generate some nop's. */
263 /* The nops are generated in codegen_emit in each codegen */
265 cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
271 * Resolve all patchers in the current JIT run.
273 * @param jd JIT data-structure
275 void patcher_resolve(jitdata* jd)
277 // Get required compiler data.
278 codeinfo* code = jd->code;
280 for (List<patchref_t>::iterator it = code->patchers->begin(); it != code->patchers->end(); it++) {
281 patchref_t& pr = *it;
283 pr.mpc += (intptr_t) code->entrypoint;
284 pr.datap = (intptr_t) (pr.disp + code->entrypoint);
290 * Check if the patcher is already patched. This is done by comparing
291 * the machine instruction.
293 * @param pr Patcher structure.
295 * @return true if patched, false otherwise.
297 bool patcher_is_patched(patchref_t* pr)
299 // Validate the instruction at the patching position is the same
300 // instruction as the patcher structure contains.
301 uint32_t mcode = *((uint32_t*) pr->mpc);
303 #if PATCHER_CALL_SIZE == 4
304 if (mcode != pr->mcode) {
305 #elif PATCHER_CALL_SIZE == 2
306 if ((uint16_t) mcode != (uint16_t) pr->mcode) {
308 #error Unknown PATCHER_CALL_SIZE
321 bool patcher_is_patched_at(void* pc)
323 codeinfo* code = code_find_codeinfo_for_pc(pc);
325 // Get the patcher for the given PC.
326 patchref_t* pr = patcher_list_find(code, pc);
329 // The given PC is not a patcher position.
333 // Validate the instruction.
334 return patcher_is_patched(pr);
338 /* patcher_handler *************************************************************
340 Handles the request to patch JIT code at the given patching
341 position. This function is normally called by the signal
344 NOTE: The patcher list lock is used to maintain exclusive
345 access of the patched position (in fact of the whole code).
346 After patching has suceeded, the patcher reference should be
347 removed from the patcher list to avoid double patching.
349 *******************************************************************************/
352 /* XXX this indent is not thread safe! */
353 /* XXX if you want it thread safe, place patcher_depth in threadobject! */
354 static int patcher_depth = 0;
355 #define TRACE_PATCHER_INDENT for (i=0; i<patcher_depth; i++) printf("\t")
356 #endif /* !defined(NDEBUG) */
358 java_handle_t *patcher_handler(u1 *pc)
364 patcher_function_list_t *l;
368 /* define the patcher function */
370 bool (*patcher_function)(patchref_t *);
372 /* search the codeinfo for the given PC */
374 code = code_find_codeinfo_for_pc(pc);
377 // Enter a mutex on the patcher list.
378 code->patchers->lock();
380 /* search the patcher information for the given PC */
382 pr = patcher_list_find(code, pc);
385 os::abort("patcher_handler: Unable to find patcher reference.");
389 if (opt_DebugPatcher) {
390 log_println("patcher_handler: double-patching detected!");
393 code->patchers->unlock();
398 if (opt_DebugPatcher) {
399 for (l = patcher_function_list; l->patcher != NULL; l++)
400 if (l->patcher == pr->patcher)
403 TRACE_PATCHER_INDENT; printf("patching in "); method_print(code->m); printf(" at %p\n", (void *) pr->mpc);
404 TRACE_PATCHER_INDENT; printf("\tpatcher function = %s <%p>\n", l->name, (void *) (intptr_t) pr->patcher);
406 TRACE_PATCHER_INDENT;
407 printf("\tmachine code before = ");
409 # if defined(ENABLE_DISASSEMBLER)
410 disassinstr((u1*) (void*) pr->mpc);
412 printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
416 assert(patcher_depth > 0);
420 /* cast the passed function to a patcher function */
422 patcher_function = (bool (*)(patchref_t *)) (ptrint) pr->patcher;
424 /* call the proper patcher function */
426 result = (patcher_function)(pr);
429 if (opt_DebugPatcher) {
430 assert(patcher_depth > 0);
433 TRACE_PATCHER_INDENT;
434 printf("\tmachine code after = ");
436 # if defined(ENABLE_DISASSEMBLER)
437 disassinstr((u1*) (void*) pr->mpc);
439 printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
442 if (result == false) {
443 TRACE_PATCHER_INDENT; printf("\tPATCHER EXCEPTION!\n");
448 // Check for return value and exit accordingly.
449 if (result == false) {
450 // Mangle the pending exception.
451 resolve_handle_pending_exception(true);
453 // Get the exception and return it.
454 java_handle_t* e = exceptions_get_and_clear_exception();
456 code->patchers->unlock();
461 pr->done = true; /* XXX this is only preliminary to prevent double-patching */
463 code->patchers->unlock();
469 /* patcher_initialize_class ****************************************************
471 Initalizes a given classinfo pointer.
472 This function does not patch any data.
474 *******************************************************************************/
476 bool patcher_initialize_class(patchref_t *pr)
480 /* get stuff from the patcher reference */
482 c = (classinfo *) pr->ref;
484 /* check if the class is initialized */
486 if (!(c->state & CLASS_INITIALIZED))
487 if (!initialize_class(c))
490 /* patch back original code */
492 patcher_patch_code(pr);
498 /* patcher_resolve_class *******************************************************
500 Resolves a given unresolved class reference.
501 This function does not patch any data.
503 *******************************************************************************/
505 #ifdef ENABLE_VERIFIER
506 bool patcher_resolve_class(patchref_t *pr)
508 unresolved_class *uc;
510 /* get stuff from the patcher reference */
512 uc = (unresolved_class *) pr->ref;
514 /* resolve the class and check subtype constraints */
516 if (!resolve_class_eager_no_access_check(uc))
519 /* patch back original code */
521 patcher_patch_code(pr);
525 #endif /* ENABLE_VERIFIER */
528 /* patcher_resolve_native_function *********************************************
530 Resolves the native function for a given methodinfo.
531 This function patches one data segment word.
533 *******************************************************************************/
535 bool patcher_resolve_native_function(patchref_t *pr)
540 /* get stuff from the patcher reference */
542 m = (methodinfo *) pr->ref;
543 datap = (uint8_t *) pr->datap;
545 /* resolve native function */
547 NativeMethods& nm = VM::get_current()->get_nativemethods();
548 void* f = nm.resolve_method(m);
553 /* patch native function pointer */
555 *((intptr_t*) datap) = (intptr_t) f;
557 /* synchronize data cache */
559 md_dcacheflush(datap, SIZEOF_VOID_P);
561 /* patch back original code */
563 patcher_patch_code(pr);
570 * Deals with breakpoint instructions (ICMD_BREAKPOINT) compiled
571 * into a JIT method. This patcher might never patch back the
572 * original machine code because breakpoints are kept active.
574 bool patcher_breakpoint(patchref_t *pr)
576 // Get stuff from the patcher reference.
577 Breakpoint* breakp = (Breakpoint*) pr->ref;
579 #if defined(ENABLE_JVMTI)
580 methodinfo* m = breakp->method;
581 int32_t l = breakp->location;
583 log_message_method("JVMTI: Reached breakpoint in method ", m);
584 log_println("JVMTI: Reached breakpoint at location %d", l);
587 // In case the breakpoint wants to be kept active, we simply
588 // fail to "patch" at this point.
589 if (!breakp->is_oneshot)
592 // Patch back original code.
593 patcher_patch_code(pr);
600 * These are local overrides for various environment variables in Emacs.
601 * Please do not remove this and leave it at the end of the file, where
602 * Emacs will automagically detect them.
603 * ---------------------------------------------------------------------
606 * indent-tabs-mode: t
610 * vim:noexpandtab:sw=4:ts=4: