* src/threads/thread.c: Moved to .cpp.
[cacao.git] / src / vm / jit / codegen-common.c
1 /* src/vm/jit/codegen-common.c - architecture independent code generator stuff
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    All functions assume the following code area / data area layout:
24
25    +-----------+
26    |           |
27    | code area | code area grows to higher addresses
28    |           |
29    +-----------+ <-- start of procedure
30    |           |
31    | data area | data area grows to lower addresses
32    |           |
33    +-----------+
34
35    The functions first write into a temporary code/data area allocated by
36    "codegen_init". "codegen_finish" copies the code and data area into permanent
37    memory. All functions writing values into the data area return the offset
38    relative the begin of the code area (start of procedure).    
39
40 */
41
42
43 #include "config.h"
44
45 #include <assert.h>
46 #include <string.h>
47
48 #include "vm/types.h"
49
50 #include "codegen.h"
51 #include "md.h"
52 #include "md-abi.h"
53
54 #include "mm/memory.h"
55
56 #include "toolbox/avl.h"
57 #include "toolbox/list.h"
58 #include "toolbox/logging.h"
59
60 #include "native/jni.h"
61 #include "native/llni.h"
62 #include "native/localref.h"
63 #include "native/native.h"
64
65 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
66 # include "native/include/java_lang_Object.h"
67 # include "native/include/java_lang_String.h"           /* required by j.l.CL */
68 # include "native/include/java_nio_ByteBuffer.h"        /* required by j.l.CL */
69 # include "native/include/java_lang_ClassLoader.h"
70 #endif
71
72 #if defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
73 # include "native/include/java_lang_String.h"
74 #endif
75
76 #include "native/include/java_lang_Class.h"
77
78 #include "threads/thread.hpp"
79
80 #include "vm/builtin.h"
81 #include "vm/exceptions.h"
82 #include "vm/stringlocal.h"
83
84 #include "vm/jit/abi.h"
85 #include "vm/jit/asmpart.h"
86 #include "vm/jit/code.h"
87 #include "vm/jit/codegen-common.h"
88
89 #if defined(ENABLE_DISASSEMBLER)
90 # include "vm/jit/disass.h"
91 #endif
92
93 #include "vm/jit/dseg.h"
94 #include "vm/jit/emit-common.h"
95 #include "vm/jit/jit.h"
96 #include "vm/jit/linenumbertable.h"
97 #include "vm/jit/methodheader.h"
98 #include "vm/jit/methodtree.h"
99 #include "vm/jit/patcher-common.h"
100 #include "vm/jit/replace.h"
101 #if defined(ENABLE_SSA)
102 # include "vm/jit/optimizing/lsra.h"
103 # include "vm/jit/optimizing/ssa.h"
104 #endif
105 #include "vm/jit/stacktrace.hpp"
106 #include "vm/jit/trace.hpp"
107
108 #if defined(ENABLE_INTRP)
109 #include "vm/jit/intrp/intrp.h"
110 #endif
111
112 #include "vmcore/method.h"
113 #include "vmcore/options.h"
114
115 # include "vmcore/statistics.h"
116
117 #if defined(ENABLE_VMLOG)
118 #include <vmlog_cacao.h>
119 #endif
120
121 #include "show.h"
122
123
124 /* codegen_init ****************************************************************
125
126    TODO
127
128 *******************************************************************************/
129
130 void codegen_init(void)
131 {
132 }
133
134
135 /* codegen_setup ***************************************************************
136
137    Allocates and initialises code area, data area and references.
138
139 *******************************************************************************/
140
141 void codegen_setup(jitdata *jd)
142 {
143         methodinfo  *m;
144         codegendata *cd;
145
146         /* get required compiler data */
147
148         m  = jd->m;
149         cd = jd->cd;
150
151         /* initialize members */
152
153         cd->flags        = 0;
154
155         cd->mcodebase    = DMNEW(u1, MCODEINITSIZE);
156         cd->mcodeend     = cd->mcodebase + MCODEINITSIZE;
157         cd->mcodesize    = MCODEINITSIZE;
158
159         /* initialize mcode variables */
160
161         cd->mcodeptr     = cd->mcodebase;
162         cd->lastmcodeptr = cd->mcodebase;
163
164 #if defined(ENABLE_INTRP)
165         /* native dynamic superinstructions variables */
166
167         if (opt_intrp) {
168                 cd->ncodebase = DMNEW(u1, NCODEINITSIZE);
169                 cd->ncodesize = NCODEINITSIZE;
170
171                 /* initialize ncode variables */
172         
173                 cd->ncodeptr = cd->ncodebase;
174
175                 cd->lastinstwithoutdispatch = ~0; /* no inst without dispatch */
176                 cd->superstarts = NULL;
177         }
178 #endif
179
180         cd->dseg           = NULL;
181         cd->dseglen        = 0;
182
183         cd->jumpreferences = NULL;
184
185 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
186         cd->datareferences = NULL;
187 #endif
188
189         cd->brancheslabel  = list_create_dump(OFFSET(branch_label_ref_t, linkage));
190         cd->linenumbers    = list_create_dump(OFFSET(linenumbertable_list_entry_t, linkage));
191 }
192
193
194 /* codegen_reset ***************************************************************
195
196    Resets the codegen data structure so we can recompile the method.
197
198 *******************************************************************************/
199
200 static void codegen_reset(jitdata *jd)
201 {
202         codeinfo    *code;
203         codegendata *cd;
204         basicblock  *bptr;
205
206         /* get required compiler data */
207
208         code = jd->code;
209         cd   = jd->cd;
210
211         /* reset error flag */
212
213         cd->flags          &= ~CODEGENDATA_FLAG_ERROR;
214
215         /* reset some members, we reuse the code memory already allocated
216            as this should have almost the correct size */
217
218         cd->mcodeptr        = cd->mcodebase;
219         cd->lastmcodeptr    = cd->mcodebase;
220
221         cd->dseg            = NULL;
222         cd->dseglen         = 0;
223
224         cd->jumpreferences  = NULL;
225
226 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
227         cd->datareferences  = NULL;
228 #endif
229
230         cd->brancheslabel   = list_create_dump(OFFSET(branch_label_ref_t, linkage));
231         cd->linenumbers     = list_create_dump(OFFSET(linenumbertable_list_entry_t, linkage));
232         
233         /* We need to clear the mpc and the branch references from all
234            basic blocks as they will definitely change. */
235
236         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
237                 bptr->mpc        = -1;
238                 bptr->branchrefs = NULL;
239         }
240
241         /* We need to clear all the patcher references from the codeinfo
242            since they all will be regenerated */
243
244         patcher_list_reset(code);
245
246 #if defined(ENABLE_REPLACEMENT)
247         code->rplpoints     = NULL;
248         code->rplpointcount = 0;
249         code->regalloc      = NULL;
250         code->regalloccount = 0;
251         code->globalcount   = 0;
252 #endif
253 }
254
255
256 /* codegen_generate ************************************************************
257
258    Generates the code for the currently compiled method.
259
260 *******************************************************************************/
261
262 bool codegen_generate(jitdata *jd)
263 {
264         codegendata *cd;
265
266         /* get required compiler data */
267
268         cd = jd->cd;
269
270         /* call the machine-dependent code generation function */
271
272         if (!codegen_emit(jd))
273                 return false;
274
275         /* check for an error */
276
277         if (CODEGENDATA_HAS_FLAG_ERROR(cd)) {
278                 /* check for long-branches flag, if it is set we recompile the
279                    method */
280
281 #if !defined(NDEBUG)
282         if (compileverbose)
283             log_message_method("Re-generating code: ", jd->m);
284 #endif
285
286                 /* XXX maybe we should tag long-branches-methods for recompilation */
287
288                 if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
289                         /* we have to reset the codegendata structure first */
290
291                         codegen_reset(jd);
292
293                         /* and restart the compiler run */
294
295                         if (!codegen_emit(jd))
296                                 return false;
297                 }
298                 else {
299                         vm_abort("codegen_generate: unknown error occurred during codegen_emit: flags=%x\n", cd->flags);
300                 }
301
302 #if !defined(NDEBUG)
303         if (compileverbose)
304             log_message_method("Re-generating code done: ", jd->m);
305 #endif
306         }
307
308         /* reallocate the memory and finish the code generation */
309
310         codegen_finish(jd);
311
312         /* everything's ok */
313
314         return true;
315 }
316
317
318 /* codegen_close ***************************************************************
319
320    TODO
321
322 *******************************************************************************/
323
324 void codegen_close(void)
325 {
326         /* TODO: release avl tree on i386 and x86_64 */
327 }
328
329
330 /* codegen_increase ************************************************************
331
332    Doubles code area.
333
334 *******************************************************************************/
335
336 void codegen_increase(codegendata *cd)
337 {
338         u1 *oldmcodebase;
339
340         /* save old mcodebase pointer */
341
342         oldmcodebase = cd->mcodebase;
343
344         /* reallocate to new, doubled memory */
345
346         cd->mcodebase = DMREALLOC(cd->mcodebase,
347                                                           u1,
348                                                           cd->mcodesize,
349                                                           cd->mcodesize * 2);
350         cd->mcodesize *= 2;
351         cd->mcodeend   = cd->mcodebase + cd->mcodesize;
352
353         /* set new mcodeptr */
354
355         cd->mcodeptr = cd->mcodebase + (cd->mcodeptr - oldmcodebase);
356
357 #if defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(__M68K__) || defined(ENABLE_INTRP) \
358  || defined(__SPARC_64__)
359         /* adjust the pointer to the last patcher position */
360
361         if (cd->lastmcodeptr != NULL)
362                 cd->lastmcodeptr = cd->mcodebase + (cd->lastmcodeptr - oldmcodebase);
363 #endif
364 }
365
366
367 /* codegen_ncode_increase ******************************************************
368
369    Doubles code area.
370
371 *******************************************************************************/
372
373 #if defined(ENABLE_INTRP)
374 u1 *codegen_ncode_increase(codegendata *cd, u1 *ncodeptr)
375 {
376         u1 *oldncodebase;
377
378         /* save old ncodebase pointer */
379
380         oldncodebase = cd->ncodebase;
381
382         /* reallocate to new, doubled memory */
383
384         cd->ncodebase = DMREALLOC(cd->ncodebase,
385                                                           u1,
386                                                           cd->ncodesize,
387                                                           cd->ncodesize * 2);
388         cd->ncodesize *= 2;
389
390         /* return the new ncodeptr */
391
392         return (cd->ncodebase + (ncodeptr - oldncodebase));
393 }
394 #endif
395
396
397 /* codegen_add_branch_ref ******************************************************
398
399    Prepends an branch to the list.
400
401 *******************************************************************************/
402
403 void codegen_add_branch_ref(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options)
404 {
405         branchref *br;
406         s4         branchmpc;
407
408         STATISTICS(count_branches_unresolved++);
409
410         /* calculate the mpc of the branch instruction */
411
412         branchmpc = cd->mcodeptr - cd->mcodebase;
413
414         br = DNEW(branchref);
415
416         br->branchmpc = branchmpc;
417         br->condition = condition;
418         br->reg       = reg;
419         br->options   = options;
420         br->next      = target->branchrefs;
421
422         target->branchrefs = br;
423 }
424
425
426 /* codegen_resolve_branchrefs **************************************************
427
428    Resolves and patches the branch references of a given basic block.
429
430 *******************************************************************************/
431
432 void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr)
433 {
434         branchref *br;
435         u1        *mcodeptr;
436
437         /* Save the mcodeptr because in the branch emitting functions
438            we generate code somewhere inside already generated code,
439            but we're still in the actual code generation phase. */
440
441         mcodeptr = cd->mcodeptr;
442
443         /* just to make sure */
444
445         assert(bptr->mpc >= 0);
446
447         for (br = bptr->branchrefs; br != NULL; br = br->next) {
448                 /* temporary set the mcodeptr */
449
450                 cd->mcodeptr = cd->mcodebase + br->branchmpc;
451
452                 /* emit_bccz and emit_branch emit the correct code, even if we
453                    pass condition == BRANCH_UNCONDITIONAL or reg == -1. */
454
455                 emit_bccz(cd, bptr, br->condition, br->reg, br->options);
456         }
457
458         /* restore mcodeptr */
459
460         cd->mcodeptr = mcodeptr;
461 }
462
463
464 /* codegen_branch_label_add ****************************************************
465
466    Append an branch to the label-branch list.
467
468 *******************************************************************************/
469
470 void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
471 {
472         list_t             *l;
473         branch_label_ref_t *br;
474         s4                  mpc;
475
476         /* Get the label list. */
477
478         l = cd->brancheslabel;
479         
480         /* calculate the current mpc */
481
482         mpc = cd->mcodeptr - cd->mcodebase;
483
484         br = DNEW(branch_label_ref_t);
485
486         br->mpc       = mpc;
487         br->label     = label;
488         br->condition = condition;
489         br->reg       = reg;
490         br->options   = options;
491
492         /* Add the branch to the list. */
493
494         list_add_last(l, br);
495 }
496
497
498 /* codegen_set_replacement_point_notrap ****************************************
499
500    Record the position of a non-trappable replacement point.
501
502 *******************************************************************************/
503
504 #if defined(ENABLE_REPLACEMENT)
505 #if !defined(NDEBUG)
506 void codegen_set_replacement_point_notrap(codegendata *cd, s4 type)
507 #else
508 void codegen_set_replacement_point_notrap(codegendata *cd)
509 #endif
510 {
511         assert(cd->replacementpoint);
512         assert(cd->replacementpoint->type == type);
513         assert(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP);
514
515         cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
516
517         cd->replacementpoint++;
518 }
519 #endif /* defined(ENABLE_REPLACEMENT) */
520
521
522 /* codegen_set_replacement_point ***********************************************
523
524    Record the position of a trappable replacement point.
525
526 *******************************************************************************/
527
528 #if defined(ENABLE_REPLACEMENT)
529 #if !defined(NDEBUG)
530 void codegen_set_replacement_point(codegendata *cd, s4 type)
531 #else
532 void codegen_set_replacement_point(codegendata *cd)
533 #endif
534 {
535         assert(cd->replacementpoint);
536         assert(cd->replacementpoint->type == type);
537         assert(!(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP));
538
539         cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
540
541         cd->replacementpoint++;
542
543 #if !defined(NDEBUG)
544         /* XXX actually we should use an own REPLACEMENT_NOPS here! */
545         if (opt_TestReplacement)
546                 PATCHER_NOPS;
547 #endif
548
549         /* XXX assert(cd->lastmcodeptr <= cd->mcodeptr); */
550
551         cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
552 }
553 #endif /* defined(ENABLE_REPLACEMENT) */
554
555
556 /* codegen_finish **************************************************************
557
558    Finishes the code generation. A new memory, large enough for both
559    data and code, is allocated and data and code are copied together
560    to their final layout, unresolved jumps are resolved, ...
561
562 *******************************************************************************/
563
564 void codegen_finish(jitdata *jd)
565 {
566         codeinfo    *code;
567         codegendata *cd;
568         s4           mcodelen;
569 #if defined(ENABLE_INTRP)
570         s4           ncodelen;
571 #endif
572         s4           alignedmcodelen;
573         jumpref     *jr;
574         u1          *epoint;
575         s4           alignedlen;
576
577         /* get required compiler data */
578
579         code = jd->code;
580         cd   = jd->cd;
581
582         /* prevent compiler warning */
583
584 #if defined(ENABLE_INTRP)
585         ncodelen = 0;
586 #endif
587
588         /* calculate the code length */
589
590         mcodelen = (s4) (cd->mcodeptr - cd->mcodebase);
591
592 #if defined(ENABLE_STATISTICS)
593         if (opt_stat) {
594                 count_code_len += mcodelen;
595                 count_data_len += cd->dseglen;
596         }
597 #endif
598
599         alignedmcodelen = MEMORY_ALIGN(mcodelen, MAX_ALIGN);
600
601 #if defined(ENABLE_INTRP)
602         if (opt_intrp)
603                 ncodelen = cd->ncodeptr - cd->ncodebase;
604         else {
605                 ncodelen = 0; /* avoid compiler warning */
606         }
607 #endif
608
609         cd->dseglen = MEMORY_ALIGN(cd->dseglen, MAX_ALIGN);
610         alignedlen = alignedmcodelen + cd->dseglen;
611
612 #if defined(ENABLE_INTRP)
613         if (opt_intrp) {
614                 alignedlen += ncodelen;
615         }
616 #endif
617
618         /* allocate new memory */
619
620         code->mcodelength = mcodelen + cd->dseglen;
621         code->mcode       = CNEW(u1, alignedlen);
622
623         /* set the entrypoint of the method */
624         
625         assert(code->entrypoint == NULL);
626         code->entrypoint = epoint = (code->mcode + cd->dseglen);
627
628         /* fill the data segment (code->entrypoint must already be set!) */
629
630         dseg_finish(jd);
631
632         /* copy code to the new location */
633
634         MCOPY((void *) code->entrypoint, cd->mcodebase, u1, mcodelen);
635
636 #if defined(ENABLE_INTRP)
637         /* relocate native dynamic superinstruction code (if any) */
638
639         if (opt_intrp) {
640                 cd->mcodebase = code->entrypoint;
641
642                 if (ncodelen > 0) {
643                         u1 *ncodebase = code->mcode + cd->dseglen + alignedmcodelen;
644
645                         MCOPY((void *) ncodebase, cd->ncodebase, u1, ncodelen);
646
647                         /* flush the instruction and data caches */
648
649                         md_cacheflush(ncodebase, ncodelen);
650
651                         /* set some cd variables for dynamic_super_rerwite */
652
653                         cd->ncodebase = ncodebase;
654
655                 } else {
656                         cd->ncodebase = NULL;
657                 }
658
659                 dynamic_super_rewrite(cd);
660         }
661 #endif
662
663         /* Create the exception table. */
664
665         exceptiontable_create(jd);
666
667         /* Create the linenumber table. */
668
669         linenumbertable_create(jd);
670
671         /* jump table resolving */
672
673         for (jr = cd->jumpreferences; jr != NULL; jr = jr->next)
674                 *((functionptr *) ((ptrint) epoint + jr->tablepos)) =
675                         (functionptr) ((ptrint) epoint + (ptrint) jr->target->mpc);
676
677         /* patcher resolving */
678
679         patcher_resolve(jd);
680
681 #if defined(ENABLE_REPLACEMENT)
682         /* replacement point resolving */
683         {
684                 int i;
685                 rplpoint *rp;
686
687                 rp = code->rplpoints;
688                 for (i=0; i<code->rplpointcount; ++i, ++rp) {
689                         rp->pc = (u1*) ((ptrint) epoint + (ptrint) rp->pc);
690                 }
691         }
692 #endif /* defined(ENABLE_REPLACEMENT) */
693
694         /* Insert method into methodtree to find the entrypoint. */
695
696         methodtree_insert(code->entrypoint, code->entrypoint + mcodelen);
697
698 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
699         /* resolve data segment references */
700
701         dseg_resolve_datareferences(jd);
702 #endif
703
704         /* flush the instruction and data caches */
705
706         md_cacheflush(code->mcode, code->mcodelength);
707 }
708
709
710 /* codegen_generate_stub_compiler **********************************************
711
712    Wrapper for codegen_emit_stub_compiler.
713
714    Returns:
715        pointer to the compiler stub code.
716
717 *******************************************************************************/
718
719 u1 *codegen_generate_stub_compiler(methodinfo *m)
720 {
721         jitdata     *jd;
722         codegendata *cd;
723         ptrint      *d;                     /* pointer to data memory             */
724         u1          *c;                     /* pointer to code memory             */
725         int32_t      dumpmarker;
726
727         /* mark dump memory */
728
729         DMARKER;
730
731         /* allocate required data structures */
732
733         jd = DNEW(jitdata);
734
735         jd->m     = m;
736         jd->cd    = DNEW(codegendata);
737         jd->flags = 0;
738
739         /* get required compiler data */
740
741         cd = jd->cd;
742
743 #if !defined(JIT_COMPILER_VIA_SIGNAL)
744         /* allocate code memory */
745
746         c = CNEW(u1, 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
747
748         /* set pointers correctly */
749
750         d = (ptrint *) c;
751
752         cd->mcodebase = c;
753
754         c = c + 3 * SIZEOF_VOID_P;
755         cd->mcodeptr = c;
756
757         /* NOTE: The codeinfo pointer is actually a pointer to the
758            methodinfo (this fakes a codeinfo structure). */
759
760         d[0] = (ptrint) asm_call_jit_compiler;
761         d[1] = (ptrint) m;
762         d[2] = (ptrint) &d[1];                                    /* fake code->m */
763
764         /* call the emit function */
765
766         codegen_emit_stub_compiler(jd);
767
768 #if defined(ENABLE_STATISTICS)
769         if (opt_stat)
770                 count_cstub_len += 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE;
771 #endif
772
773         /* flush caches */
774
775         md_cacheflush(cd->mcodebase, 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
776 #else
777         /* Allocate code memory. */
778
779         c = CNEW(uint8_t, 2 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
780
781         /* Set pointers correctly. */
782
783         d = (ptrint *) c;
784
785         cd->mcodebase = c;
786
787         c = c + 2 * SIZEOF_VOID_P;
788         cd->mcodeptr = c;
789
790         /* NOTE: The codeinfo pointer is actually a pointer to the
791            methodinfo (this fakes a codeinfo structure). */
792
793         d[0] = (ptrint) m;
794         d[1] = (ptrint) &d[0];                                    /* fake code->m */
795
796         /* Emit the trap instruction. */
797
798         emit_trap_compiler(cd);
799
800 #if defined(ENABLE_STATISTICS)
801         if (opt_stat)
802                 count_cstub_len += 2 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE;
803 #endif
804
805         /* Flush caches. */
806
807         md_cacheflush(cd->mcodebase, 2 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
808 #endif
809
810         /* release dump memory */
811
812         DRELEASE;
813
814         /* return native stub code */
815
816         return c;
817 }
818
819
820 /* codegen_generate_stub_builtin ***********************************************
821
822    Wrapper for codegen_emit_stub_native.
823
824 *******************************************************************************/
825
826 void codegen_generate_stub_builtin(methodinfo *m, builtintable_entry *bte)
827 {
828         jitdata  *jd;
829         codeinfo *code;
830         int       skipparams;
831         int32_t   dumpmarker;
832
833         /* mark dump memory */
834
835         DMARKER;
836
837         /* Create JIT data structure. */
838
839         jd = jit_jitdata_new(m);
840
841         /* Get required compiler data. */
842
843         code = jd->code;
844
845         /* Stubs are non-leaf methods. */
846
847         code_unflag_leafmethod(code);
848
849         /* setup code generation stuff */
850
851         codegen_setup(jd);
852
853         /* Set the number of native arguments we need to skip. */
854
855         skipparams = 0;
856
857         /* generate the code */
858
859 #if defined(ENABLE_JIT)
860 # if defined(ENABLE_INTRP)
861         if (!opt_intrp) {
862 # endif
863                 assert(bte->fp != NULL);
864                 codegen_emit_stub_native(jd, bte->md, bte->fp, skipparams);
865 # if defined(ENABLE_INTRP)
866         }
867 # endif
868 #endif
869
870         /* reallocate the memory and finish the code generation */
871
872         codegen_finish(jd);
873
874         /* set the stub entry point in the builtin table */
875
876         bte->stub = code->entrypoint;
877
878 #if defined(ENABLE_STATISTICS)
879         if (opt_stat)
880                 size_stub_native += code->mcodelength;
881 #endif
882
883 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
884         /* disassemble native stub */
885
886         if (opt_DisassembleStubs) {
887                 codegen_disassemble_stub(m,
888                                                                  (u1 *) (ptrint) code->entrypoint,
889                                                                  (u1 *) (ptrint) code->entrypoint + (code->mcodelength - jd->cd->dseglen));
890
891                 /* show data segment */
892
893                 if (opt_showddatasegment)
894                         dseg_display(jd);
895         }
896 #endif /* !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) */
897
898         /* release memory */
899
900         DRELEASE;
901 }
902
903
904 /* codegen_generate_stub_native ************************************************
905
906    Wrapper for codegen_emit_stub_native.
907
908    Returns:
909        the codeinfo representing the stub code.
910
911 *******************************************************************************/
912
913 codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f)
914 {
915         jitdata     *jd;
916         codeinfo    *code;
917         methoddesc  *md;
918         methoddesc  *nmd;       
919         int          skipparams;
920         int32_t      dumpmarker;
921
922         /* mark dump memory */
923
924         DMARKER;
925
926         /* Create JIT data structure. */
927
928         jd = jit_jitdata_new(m);
929
930         /* Get required compiler data. */
931
932         code = jd->code;
933
934         /* Stubs are non-leaf methods. */
935
936         code_unflag_leafmethod(code);
937
938         /* set the flags for the current JIT run */
939
940 #if defined(ENABLE_PROFILING)
941         if (opt_prof)
942                 jd->flags |= JITDATA_FLAG_INSTRUMENT;
943 #endif
944
945         if (opt_verbosecall)
946                 jd->flags |= JITDATA_FLAG_VERBOSECALL;
947
948         /* setup code generation stuff */
949
950 #if defined(ENABLE_JIT)
951 # if defined(ENABLE_INTRP)
952         if (!opt_intrp)
953 # endif
954                 reg_setup(jd);
955 #endif
956
957         codegen_setup(jd);
958
959         /* create new method descriptor with additional native parameters */
960
961         md = m->parseddesc;
962
963         /* Set the number of native arguments we need to skip. */
964
965         if (m->flags & ACC_STATIC)
966                 skipparams = 2;
967         else
968                 skipparams = 1;
969         
970         nmd = (methoddesc *) DMNEW(u1, sizeof(methoddesc) - sizeof(typedesc) +
971                                                            md->paramcount * sizeof(typedesc) +
972                                                            skipparams * sizeof(typedesc));
973
974         nmd->paramcount = md->paramcount + skipparams;
975
976         nmd->params = DMNEW(paramdesc, nmd->paramcount);
977
978         nmd->paramtypes[0].type = TYPE_ADR; /* add environment pointer            */
979
980         if (m->flags & ACC_STATIC)
981                 nmd->paramtypes[1].type = TYPE_ADR; /* add class pointer              */
982
983         MCOPY(nmd->paramtypes + skipparams, md->paramtypes, typedesc,
984                   md->paramcount);
985
986 #if defined(ENABLE_JIT)
987 # if defined(ENABLE_INTRP)
988         if (!opt_intrp)
989 # endif
990                 /* pre-allocate the arguments for the native ABI */
991
992                 md_param_alloc_native(nmd);
993 #endif
994
995         /* generate the code */
996
997 #if defined(ENABLE_JIT)
998 # if defined(ENABLE_INTRP)
999         if (opt_intrp)
1000                 intrp_createnativestub(f, jd, nmd);
1001         else
1002 # endif
1003                 codegen_emit_stub_native(jd, nmd, f, skipparams);
1004 #else
1005         intrp_createnativestub(f, jd, nmd);
1006 #endif
1007
1008         /* reallocate the memory and finish the code generation */
1009
1010         codegen_finish(jd);
1011
1012 #if defined(ENABLE_STATISTICS)
1013         /* must be done after codegen_finish() */
1014
1015         if (opt_stat)
1016                 size_stub_native += code->mcodelength;
1017 #endif
1018
1019 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
1020         /* disassemble native stub */
1021
1022         if (opt_DisassembleStubs) {
1023 # if defined(ENABLE_DEBUG_FILTER)
1024                 if (m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
1025 # endif
1026                 {
1027                         codegen_disassemble_stub(m,
1028                                                                          (u1 *) (ptrint) code->entrypoint,
1029                                                                          (u1 *) (ptrint) code->entrypoint + (code->mcodelength - jd->cd->dseglen));
1030
1031                         /* show data segment */
1032
1033                         if (opt_showddatasegment)
1034                                 dseg_display(jd);
1035                 }
1036         }
1037 #endif /* !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) */
1038
1039         /* release memory */
1040
1041         DRELEASE;
1042
1043         /* return native stub code */
1044
1045         return code;
1046 }
1047
1048
1049 /* codegen_disassemble_nativestub **********************************************
1050
1051    Disassembles the generated builtin or native stub.
1052
1053 *******************************************************************************/
1054
1055 #if defined(ENABLE_DISASSEMBLER)
1056 void codegen_disassemble_stub(methodinfo *m, u1 *start, u1 *end)
1057 {
1058         printf("Stub code: ");
1059         if (m->clazz != NULL)
1060                 utf_fprint_printable_ascii_classname(stdout, m->clazz->name);
1061         else
1062                 printf("NULL");
1063         printf(".");
1064         utf_fprint_printable_ascii(stdout, m->name);
1065         utf_fprint_printable_ascii(stdout, m->descriptor);
1066         printf("\nLength: %d\n\n", (s4) (end - start));
1067
1068         DISASSEMBLE(start, end);
1069 }
1070 #endif
1071
1072
1073 /* codegen_start_native_call ***************************************************
1074
1075    Prepares the stuff required for a native (JNI) function call:
1076
1077    - adds a stackframe info structure to the chain, for stacktraces
1078    - prepares the local references table on the stack
1079
1080    The layout of the native stub stackframe should look like this:
1081
1082    +---------------------------+ <- java SP (of parent Java function)
1083    | return address            |
1084    +---------------------------+ <- data SP
1085    |                           |
1086    | stackframe info structure |
1087    |                           |
1088    +---------------------------+
1089    |                           |
1090    | local references table    |
1091    |                           |
1092    +---------------------------+
1093    |                           |
1094    | saved registers (if any)  |
1095    |                           |
1096    +---------------------------+
1097    |                           |
1098    | arguments (if any)        |
1099    |                           |
1100    +---------------------------+ <- current SP (native stub)
1101
1102 *******************************************************************************/
1103
1104 java_handle_t *codegen_start_native_call(u1 *sp, u1 *pv)
1105 {
1106         stackframeinfo_t *sfi;
1107         localref_table   *lrt;
1108         methodinfo       *m;
1109         int32_t           framesize;
1110
1111         uint8_t  *datasp;
1112         uint8_t  *javasp;
1113         uint64_t *arg_regs;
1114         uint64_t *arg_stack;
1115
1116         STATISTICS(count_calls_java_to_native++);
1117
1118         /* Get the methodinfo. */
1119
1120         m = code_get_methodinfo_for_pv(pv);
1121
1122         assert(m);
1123
1124         framesize = *((int32_t *) (pv + FrameSize));
1125
1126         assert(framesize >= sizeof(stackframeinfo_t) + sizeof(localref_table));
1127
1128         /* calculate needed values */
1129
1130 #if defined(__ALPHA__) || defined(__ARM__)
1131         datasp    = sp + framesize - SIZEOF_VOID_P;
1132         javasp    = sp + framesize;
1133         arg_regs  = (uint64_t *) sp;
1134         arg_stack = (uint64_t *) javasp;
1135 #elif defined(__MIPS__)
1136         /* MIPS always uses 8 bytes to store the RA */
1137         datasp    = sp + framesize - 8;
1138         javasp    = sp + framesize;
1139 #elif defined(__S390__)
1140         datasp    = sp + framesize - 8;
1141         javasp    = sp + framesize;
1142         arg_regs  = (uint64_t *) (sp + 96);
1143         arg_stack = (uint64_t *) javasp;
1144 #elif defined(__I386__) || defined(__M68K__) || defined(__X86_64__)
1145         datasp    = sp + framesize;
1146         javasp    = sp + framesize + SIZEOF_VOID_P;
1147         arg_regs  = (uint64_t *) sp;
1148         arg_stack = (uint64_t *) javasp;
1149 #elif defined(__POWERPC__)
1150         datasp    = sp + framesize;
1151         javasp    = sp + framesize;
1152         arg_regs  = (uint64_t *) (sp + LA_SIZE + 4 * SIZEOF_VOID_P);
1153         arg_stack = (uint64_t *) javasp;
1154 #elif defined(__POWERPC64__)
1155         datasp    = sp + framesize;
1156         javasp    = sp + framesize;
1157         arg_regs  = (uint64_t *) (sp + PA_SIZE + LA_SIZE + 4 * SIZEOF_VOID_P);
1158         arg_stack = (uint64_t *) javasp;
1159 #else
1160         /* XXX is was unable to do this port for SPARC64, sorry. (-michi) */
1161         /* XXX maybe we need to pass the RA as argument there */
1162         vm_abort("codegen_start_native_call: unsupported architecture");
1163 #endif
1164
1165         /* get data structures from stack */
1166
1167         sfi = (stackframeinfo_t *) (datasp - sizeof(stackframeinfo_t));
1168         lrt = (localref_table *)   (datasp - sizeof(stackframeinfo_t) - 
1169                                                                 sizeof(localref_table));
1170
1171 #if defined(ENABLE_JNI)
1172         /* add current JNI local references table to this thread */
1173
1174         localref_table_add(lrt);
1175 #endif
1176
1177 #if !defined(NDEBUG)
1178 # if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
1179         /* print the call-trace if necesarry */
1180         /* BEFORE: filling the local reference table */
1181
1182         if (opt_TraceJavaCalls)
1183                 trace_java_call_enter(m, arg_regs, arg_stack);
1184 # endif
1185 #endif
1186
1187 #if defined(ENABLE_HANDLES)
1188         /* place all references into the local reference table */
1189         /* BEFORE: creating stackframeinfo */
1190
1191         localref_native_enter(m, arg_regs, arg_stack);
1192 #endif
1193
1194         /* Add a stackframeinfo for this native method.  We don't have RA
1195            and XPC here.  These are determined in
1196            stacktrace_stackframeinfo_add. */
1197
1198         stacktrace_stackframeinfo_add(sfi, pv, sp, NULL, NULL);
1199
1200         /* Return a wrapped classinfo for static methods. */
1201
1202         if (m->flags & ACC_STATIC)
1203                 return (java_handle_t *) LLNI_classinfo_wrap(m->clazz);
1204         else
1205                 return NULL;
1206 }
1207
1208
1209 /* codegen_finish_native_call **************************************************
1210
1211    Removes the stuff required for a native (JNI) function call.
1212    Additionally it checks for an exceptions and in case, get the
1213    exception object and clear the pointer.
1214
1215 *******************************************************************************/
1216
1217 java_object_t *codegen_finish_native_call(u1 *sp, u1 *pv)
1218 {
1219         stackframeinfo_t *sfi;
1220         java_handle_t    *e;
1221         java_object_t    *o;
1222         codeinfo         *code;
1223         methodinfo       *m;
1224         int32_t           framesize;
1225
1226         uint8_t  *datasp;
1227         uint64_t *ret_regs;
1228
1229         /* get information from method header */
1230
1231         code = code_get_codeinfo_for_pv(pv);
1232
1233         framesize = *((int32_t *) (pv + FrameSize));
1234
1235         assert(code);
1236
1237         /* get the methodinfo */
1238
1239         m = code->m;
1240         assert(m);
1241
1242         /* calculate needed values */
1243
1244 #if defined(__ALPHA__) || defined(__ARM__)
1245         datasp   = sp + framesize - SIZEOF_VOID_P;
1246         ret_regs = (uint64_t *) sp;
1247 #elif defined(__MIPS__)
1248         /* MIPS always uses 8 bytes to store the RA */
1249         datasp   = sp + framesize - 8;
1250 #elif defined(__S390__)
1251         datasp   = sp + framesize - 8;
1252         ret_regs = (uint64_t *) (sp + 96);
1253 #elif defined(__I386__)
1254         datasp   = sp + framesize;
1255         ret_regs = (uint64_t *) (sp + 2 * SIZEOF_VOID_P);
1256 #elif defined(__M68K__)
1257         datasp   = sp + framesize;
1258         ret_regs = (uint64_t *) (sp + 2 * 8);
1259 #elif defined(__X86_64__)
1260         datasp   = sp + framesize;
1261         ret_regs = (uint64_t *) sp;
1262 #elif defined(__POWERPC__)
1263         datasp   = sp + framesize;
1264         ret_regs = (uint64_t *) (sp + LA_SIZE + 2 * SIZEOF_VOID_P);
1265 #elif defined(__POWERPC64__)
1266         datasp   = sp + framesize;
1267         ret_regs = (uint64_t *) (sp + PA_SIZE + LA_SIZE + 2 * SIZEOF_VOID_P);
1268 #else
1269         vm_abort("codegen_finish_native_call: unsupported architecture");
1270 #endif
1271
1272         /* get data structures from stack */
1273
1274         sfi = (stackframeinfo_t *) (datasp - sizeof(stackframeinfo_t));
1275
1276         /* Remove current stackframeinfo from chain. */
1277
1278         stacktrace_stackframeinfo_remove(sfi);
1279
1280 #if defined(ENABLE_HANDLES)
1281         /* unwrap the return value from the local reference table */
1282         /* AFTER: removing the stackframeinfo */
1283         /* BEFORE: releasing the local reference table */
1284
1285         localref_native_exit(m, ret_regs);
1286 #endif
1287
1288         /* get and unwrap the exception */
1289         /* AFTER: removing the stackframe info */
1290         /* BEFORE: releasing the local reference table */
1291
1292         e = exceptions_get_and_clear_exception();
1293         o = LLNI_UNWRAP(e);
1294
1295 #if defined(ENABLE_JNI)
1296         /* release JNI local references table for this thread */
1297
1298         localref_frame_pop_all();
1299         localref_table_remove();
1300 #endif
1301
1302 #if !defined(NDEBUG)
1303 # if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
1304         /* print the call-trace if necesarry */
1305         /* AFTER: unwrapping the return value */
1306
1307         if (opt_TraceJavaCalls)
1308                 trace_java_call_exit(m, ret_regs);
1309 # endif
1310 #endif
1311
1312         return o;
1313 }
1314
1315
1316 /* removecompilerstub **********************************************************
1317
1318    Deletes a compilerstub from memory (simply by freeing it).
1319
1320 *******************************************************************************/
1321
1322 void removecompilerstub(u1 *stub)
1323 {
1324         /* pass size 1 to keep the intern function happy */
1325
1326         CFREE((void *) stub, 1);
1327 }
1328
1329
1330 /* removenativestub ************************************************************
1331
1332    Removes a previously created native-stub from memory.
1333     
1334 *******************************************************************************/
1335
1336 void removenativestub(u1 *stub)
1337 {
1338         /* pass size 1 to keep the intern function happy */
1339
1340         CFREE((void *) stub, 1);
1341 }
1342
1343
1344 /* codegen_reg_of_var **********************************************************
1345
1346    This function determines a register, to which the result of an
1347    operation should go, when it is ultimatively intended to store the
1348    result in pseudoregister v.  If v is assigned to an actual
1349    register, this register will be returned.  Otherwise (when v is
1350    spilled) this function returns tempregnum.  If not already done,
1351    regoff and flags are set in the stack location.
1352        
1353 *******************************************************************************/
1354
1355 s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
1356 {
1357         if (!(v->flags & INMEMORY))
1358                 return v->vv.regoff;
1359
1360         return tempregnum;
1361 }
1362
1363
1364 /* codegen_reg_of_dst **********************************************************
1365
1366    This function determines a register, to which the result of an
1367    operation should go, when it is ultimatively intended to store the
1368    result in iptr->dst.var.  If dst.var is assigned to an actual
1369    register, this register will be returned.  Otherwise (when it is
1370    spilled) this function returns tempregnum.  If not already done,
1371    regoff and flags are set in the stack location.
1372        
1373 *******************************************************************************/
1374
1375 s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
1376 {
1377         return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum);
1378 }
1379
1380
1381 /* codegen_emit_phi_moves ****************************************************
1382
1383    Emits phi moves at the end of the basicblock.
1384
1385 *******************************************************************************/
1386
1387 #if defined(ENABLE_SSA)
1388 void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr)
1389 {
1390         int lt_d,lt_s,i;
1391         lsradata *ls;
1392         codegendata *cd;
1393         varinfo *s, *d;
1394         instruction tmp_i;
1395
1396         cd = jd->cd;
1397         ls = jd->ls;
1398
1399         MCODECHECK(512);
1400
1401         /* Moves from phi functions with highest indices have to be */
1402         /* inserted first, since this is the order as is used for   */
1403         /* conflict resolution */
1404
1405         for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
1406                 lt_d = ls->phi_moves[bptr->nr][i][0];
1407                 lt_s = ls->phi_moves[bptr->nr][i][1];
1408 #if defined(SSA_DEBUG_VERBOSE)
1409                 if (compileverbose)
1410                         printf("BB %3i Move %3i <- %3i ", bptr->nr, lt_d, lt_s);
1411 #endif
1412                 if (lt_s == UNUSED) {
1413 #if defined(SSA_DEBUG_VERBOSE)
1414                 if (compileverbose)
1415                         printf(" ... not processed \n");
1416 #endif
1417                         continue;
1418                 }
1419                         
1420                 d = VAR(ls->lifetime[lt_d].v_index);
1421                 s = VAR(ls->lifetime[lt_s].v_index);
1422                 
1423
1424                 if (d->type == -1) {
1425 #if defined(SSA_DEBUG_VERBOSE)
1426                         if (compileverbose)
1427                                 printf("...returning - phi lifetimes where joined\n");
1428 #endif
1429                         continue;
1430                 }
1431
1432                 if (s->type == -1) {
1433 #if defined(SSA_DEBUG_VERBOSE)
1434                         if (compileverbose)
1435                                 printf("...returning - phi lifetimes where joined\n");
1436 #endif
1437                         continue;
1438                 }
1439
1440                 tmp_i.opc = 0;
1441                 tmp_i.s1.varindex = ls->lifetime[lt_s].v_index;
1442                 tmp_i.dst.varindex = ls->lifetime[lt_d].v_index;
1443                 emit_copy(jd, &tmp_i);
1444
1445 #if defined(SSA_DEBUG_VERBOSE)
1446                 if (compileverbose) {
1447                         if (IS_INMEMORY(d->flags) && IS_INMEMORY(s->flags)) {
1448                                 /* mem -> mem */
1449                                 printf("M%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1450                         }
1451                         else if (IS_INMEMORY(s->flags)) {
1452                                 /* mem -> reg */
1453                                 printf("R%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1454                         }
1455                         else if (IS_INMEMORY(d->flags)) {
1456                                 /* reg -> mem */
1457                                 printf("M%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1458                         }
1459                         else {
1460                                 /* reg -> reg */
1461                                 printf("R%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1462                         }
1463                         printf("\n");
1464                 }
1465 #endif /* defined(SSA_DEBUG_VERBOSE) */
1466         }
1467 }
1468 #endif /* defined(ENABLE_SSA) */
1469
1470
1471 /* REMOVEME When we have exception handling in C. */
1472
1473 void *md_asm_codegen_get_pv_from_pc(void *ra)
1474 {
1475         return md_codegen_get_pv_from_pc(ra);
1476 }
1477
1478
1479 /*
1480  * These are local overrides for various environment variables in Emacs.
1481  * Please do not remove this and leave it at the end of the file, where
1482  * Emacs will automagically detect them.
1483  * ---------------------------------------------------------------------
1484  * Local variables:
1485  * mode: c
1486  * indent-tabs-mode: t
1487  * c-basic-offset: 4
1488  * tab-width: 4
1489  * End:
1490  * vim:noexpandtab:sw=4:ts=4:
1491  */