1 /* src/vm/jit/stubs.cpp - JIT stubs
3 Copyright (C) 1996-2005, 2006, 2007, 2008
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
31 // Include machine dependent headers.
34 #include "mm/dumpmemory.hpp"
36 #include "vm/method.h"
37 #include "vm/options.h"
39 #include "vm/jit/abi.h"
40 #include "vm/jit/code.hpp"
41 #include "vm/jit/codegen-common.hpp"
42 #include "vm/jit/disass.h"
43 #include "vm/jit/emit-common.hpp"
44 #include "vm/jit/jit.hpp"
45 #include "vm/jit/show.h"
46 #include "vm/jit/stubs.hpp"
50 * Wrapper for codegen_emit_stub_compiler.
52 * @param m Method object.
54 * @return Pointer to the compiler stub code.
56 void* CompilerStub::generate(methodinfo *m)
60 ptrint *d; /* pointer to data memory */
61 u1 *c; /* pointer to code memory */
63 // Create new dump memory area.
66 /* allocate required data structures */
68 jd = (jitdata*) DumpMemory::allocate(sizeof(jitdata));
71 jd->cd = (codegendata*) DumpMemory::allocate(sizeof(codegendata));
74 /* get required compiler data */
78 #if !defined(JIT_COMPILER_VIA_SIGNAL)
79 /* allocate code memory */
81 c = CNEW(u1, 3 * SIZEOF_VOID_P + get_code_size());
83 /* set pointers correctly */
89 c = c + 3 * SIZEOF_VOID_P;
92 /* NOTE: The codeinfo pointer is actually a pointer to the
93 methodinfo (this fakes a codeinfo structure). */
95 d[0] = (ptrint) asm_call_jit_compiler;
97 d[2] = (ptrint) &d[1]; /* fake code->m */
99 /* call the emit function */
101 codegen_emit_stub_compiler(jd);
103 #if defined(ENABLE_STATISTICS)
105 count_cstub_len += 3 * SIZEOF_VOID_P + get_code_size();
110 md_cacheflush(cd->mcodebase, 3 * SIZEOF_VOID_P + get_code_size());
112 /* Allocate code memory. */
114 c = CNEW(uint8_t, 2 * SIZEOF_VOID_P + get_code_size());
116 /* Set pointers correctly. */
122 c = c + 2 * SIZEOF_VOID_P;
125 /* NOTE: The codeinfo pointer is actually a pointer to the
126 methodinfo (this fakes a codeinfo structure). */
129 d[1] = (ptrint) &d[0]; /* fake code->m */
131 /* Emit the trap instruction. */
133 emit_trap_compiler(cd);
135 #if defined(ENABLE_STATISTICS)
137 count_cstub_len += 2 * SIZEOF_VOID_P + get_code_size();
142 md_cacheflush(cd->mcodebase, 2 * SIZEOF_VOID_P + get_code_size());
145 /* return native stub code */
152 * Free a compiler stub from memory.
156 void CompilerStub::remove(void* stub)
158 // Pass size 1 to keep the intern function happy.
163 /* codegen_disassemble_nativestub **********************************************
165 Disassembles the generated builtin or native stub.
167 *******************************************************************************/
169 #if defined(ENABLE_DISASSEMBLER)
170 static void codegen_disassemble_stub(methodinfo *m, u1 *start, u1 *end)
172 printf("Stub code: ");
173 if (m->clazz != NULL)
174 utf_fprint_printable_ascii_classname(stdout, m->clazz->name);
178 utf_fprint_printable_ascii(stdout, m->name);
179 utf_fprint_printable_ascii(stdout, m->descriptor);
180 printf("\nLength: %d\n\n", (s4) (end - start));
182 DISASSEMBLE(start, end);
188 * Wrapper for codegen_emit_stub_native.
190 * @param m Method object.
191 * @param bte Builtin function structure.
193 void BuiltinStub::generate(methodinfo* m, builtintable_entry* bte)
199 // Create new dump memory area.
202 /* Create JIT data structure. */
204 jd = jit_jitdata_new(m);
206 /* Get required compiler data. */
210 /* Stubs are non-leaf methods. */
212 code_unflag_leafmethod(code);
214 /* setup code generation stuff */
218 /* Set the number of native arguments we need to skip. */
222 /* generate the code */
224 #if defined(ENABLE_JIT)
225 # if defined(ENABLE_INTRP)
228 assert(bte->fp != NULL);
229 codegen_emit_stub_native(jd, bte->md, bte->fp, skipparams);
230 # if defined(ENABLE_INTRP)
235 /* reallocate the memory and finish the code generation */
239 /* set the stub entry point in the builtin table */
241 bte->stub = code->entrypoint;
243 #if defined(ENABLE_STATISTICS)
245 size_stub_native += code->mcodelength;
248 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
249 /* disassemble native stub */
251 if (opt_DisassembleStubs) {
252 codegen_disassemble_stub(m,
253 (u1 *) (ptrint) code->entrypoint,
254 (u1 *) (ptrint) code->entrypoint + (code->mcodelength - jd->cd->dseglen));
256 /* show data segment */
258 if (opt_showddatasegment)
261 #endif /* !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) */
266 * Wrapper for codegen_emit_stub_native.
268 * @param m Method object of the native function.
269 * @param f Native function pointer.
271 * @return The codeinfo representing the stub code.
273 codeinfo* NativeStub::generate(methodinfo* m, functionptr f)
281 // Create new dump memory area.
284 /* Create JIT data structure. */
286 jd = jit_jitdata_new(m);
288 /* Get required compiler data. */
292 /* Stubs are non-leaf methods. */
294 code_unflag_leafmethod(code);
296 /* set the flags for the current JIT run */
298 #if defined(ENABLE_PROFILING)
300 jd->flags |= JITDATA_FLAG_INSTRUMENT;
304 jd->flags |= JITDATA_FLAG_VERBOSECALL;
306 /* setup code generation stuff */
308 #if defined(ENABLE_JIT)
309 # if defined(ENABLE_INTRP)
317 /* create new method descriptor with additional native parameters */
321 /* Set the number of native arguments we need to skip. */
323 if (m->flags & ACC_STATIC)
328 nmd = (methoddesc*) DumpMemory::allocate(sizeof(methoddesc) - sizeof(typedesc) +
329 md->paramcount * sizeof(typedesc) +
330 skipparams * sizeof(typedesc));
332 nmd->paramcount = md->paramcount + skipparams;
334 nmd->params = (paramdesc*) DumpMemory::allocate(sizeof(paramdesc) * nmd->paramcount);
336 nmd->paramtypes[0].type = TYPE_ADR; /* add environment pointer */
338 if (m->flags & ACC_STATIC)
339 nmd->paramtypes[1].type = TYPE_ADR; /* add class pointer */
341 MCOPY(nmd->paramtypes + skipparams, md->paramtypes, typedesc,
344 #if defined(ENABLE_JIT)
345 # if defined(ENABLE_INTRP)
348 /* pre-allocate the arguments for the native ABI */
350 md_param_alloc_native(nmd);
353 /* generate the code */
355 #if defined(ENABLE_JIT)
356 # if defined(ENABLE_INTRP)
358 intrp_createnativestub(f, jd, nmd);
361 codegen_emit_stub_native(jd, nmd, f, skipparams);
363 intrp_createnativestub(f, jd, nmd);
366 /* reallocate the memory and finish the code generation */
370 #if defined(ENABLE_STATISTICS)
371 /* must be done after codegen_finish() */
374 size_stub_native += code->mcodelength;
377 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
378 /* disassemble native stub */
380 if (opt_DisassembleStubs) {
381 # if defined(ENABLE_DEBUG_FILTER)
382 if (m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
385 codegen_disassemble_stub(m,
386 (u1 *) (ptrint) code->entrypoint,
387 (u1 *) (ptrint) code->entrypoint + (code->mcodelength - jd->cd->dseglen));
389 /* show data segment */
391 if (opt_showddatasegment)
395 #endif /* !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) */
397 /* return native stub code */
404 * Free a native stub from memory.
406 * @param stub Pointer to stub memory.
408 void NativeStub::remove(void* stub)
410 // Pass size 1 to keep the intern function happy.
415 // Legacy C interface.
418 void* CompilerStub_generate(methodinfo* m) { return CompilerStub::generate(m); }
419 void CompilerStub_remove(void* stub) { CompilerStub::remove(stub); }
421 void BuiltinStub_generate(methodinfo* m, builtintable_entry* bte) { BuiltinStub::generate(m, bte); }
423 void NativeStub_remove(void* stub) { NativeStub::remove(stub); }
428 * These are local overrides for various environment variables in Emacs.
429 * Please do not remove this and leave it at the end of the file, where
430 * Emacs will automagically detect them.
431 * ---------------------------------------------------------------------
434 * indent-tabs-mode: t
438 * vim:noexpandtab:sw=4:ts=4: