7fc4470f2a21af4ad26e1535250998157f99fe81
[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 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    All functions assume the following code area / data area layout:
26
27    +-----------+
28    |           |
29    | code area | code area grows to higher addresses
30    |           |
31    +-----------+ <-- start of procedure
32    |           |
33    | data area | data area grows to lower addresses
34    |           |
35    +-----------+
36
37    The functions first write into a temporary code/data area allocated by
38    "codegen_init". "codegen_finish" copies the code and data area into permanent
39    memory. All functions writing values into the data area return the offset
40    relative the begin of the code area (start of procedure).    
41
42 */
43
44
45 #include "config.h"
46
47 #include <assert.h>
48 #include <string.h>
49
50 #include "vm/types.h"
51
52 #if defined(ENABLE_JIT)
53 /* this is required PATCHER_CALL_SIZE */
54 # include "codegen.h"
55 #endif
56
57 #include "md-abi.h"
58
59 #include "mm/memory.h"
60
61 #include "toolbox/avl.h"
62 #include "toolbox/list.h"
63 #include "toolbox/logging.h"
64
65 #include "native/jni.h"
66 #include "native/llni.h"
67 #include "native/localref.h"
68 #include "native/native.h"
69
70 #if defined(WITH_CLASSPATH_SUN)
71 # include "native/include/java_lang_Object.h"
72 # include "native/include/java_lang_String.h"
73 # include "native/include/java_nio_ByteBuffer.h"        /* required by j.l.CL */
74 # include "native/include/java_lang_ClassLoader.h"
75 #endif
76
77 #include "native/include/java_lang_Class.h"
78
79 #include "threads/threads-common.h"
80
81 #include "vm/builtin.h"
82 #include "vm/exceptions.h"
83 #include "vm/stringlocal.h"
84
85 #include "vm/jit/abi.h"
86 #include "vm/jit/asmpart.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/md.h"
97 #include "vm/jit/methodheader.h"
98 #include "vm/jit/patcher-common.h"
99 #include "vm/jit/replace.h"
100 #if defined(ENABLE_SSA)
101 # include "vm/jit/optimizing/lsra.h"
102 # include "vm/jit/optimizing/ssa.h"
103 #endif
104 #include "vm/jit/stacktrace.h"
105 #include "vm/jit/trace.h"
106
107 #if defined(ENABLE_INTRP)
108 #include "vm/jit/intrp/intrp.h"
109 #endif
110
111 #include "vmcore/method.h"
112 #include "vmcore/options.h"
113
114 # include "vmcore/statistics.h"
115
116 #if defined(ENABLE_VMLOG)
117 #include <vmlog_cacao.h>
118 #endif
119
120 #include "show.h"
121
122 /* in this tree we store all method addresses *********************************/
123
124 static avl_tree_t *methodtree = NULL;
125 static s4 methodtree_comparator(const void *treenode, const void *node);
126
127
128 /* codegen_init ****************************************************************
129
130    TODO
131
132 *******************************************************************************/
133
134 void codegen_init(void)
135 {
136         /* this tree is global, not method specific */
137
138         if (!methodtree) {
139 #if defined(ENABLE_JIT)
140                 methodtree_element *mte;
141 #endif
142
143                 methodtree = avl_create(&methodtree_comparator);
144
145 #if defined(ENABLE_JIT)
146                 /* insert asm_vm_call_method */
147
148                 mte = NEW(methodtree_element);
149
150                 mte->startpc = (u1 *) (ptrint) asm_vm_call_method;
151                 mte->endpc   = (u1 *) (ptrint) asm_vm_call_method_end;
152
153                 avl_insert(methodtree, mte);
154 #endif /* defined(ENABLE_JIT) */
155
156         }
157
158 }
159
160
161 /* codegen_setup ***************************************************************
162
163    Allocates and initialises code area, data area and references.
164
165 *******************************************************************************/
166
167 void codegen_setup(jitdata *jd)
168 {
169         methodinfo  *m;
170         codegendata *cd;
171
172         /* get required compiler data */
173
174         m  = jd->m;
175         cd = jd->cd;
176
177         /* initialize members */
178
179         cd->flags        = 0;
180
181         cd->mcodebase    = DMNEW(u1, MCODEINITSIZE);
182         cd->mcodeend     = cd->mcodebase + MCODEINITSIZE;
183         cd->mcodesize    = MCODEINITSIZE;
184
185         /* initialize mcode variables */
186
187         cd->mcodeptr     = cd->mcodebase;
188         cd->lastmcodeptr = cd->mcodebase;
189
190 #if defined(ENABLE_INTRP)
191         /* native dynamic superinstructions variables */
192
193         if (opt_intrp) {
194                 cd->ncodebase = DMNEW(u1, NCODEINITSIZE);
195                 cd->ncodesize = NCODEINITSIZE;
196
197                 /* initialize ncode variables */
198         
199                 cd->ncodeptr = cd->ncodebase;
200
201                 cd->lastinstwithoutdispatch = ~0; /* no inst without dispatch */
202                 cd->superstarts = NULL;
203         }
204 #endif
205
206         cd->dseg           = NULL;
207         cd->dseglen        = 0;
208
209         cd->jumpreferences = NULL;
210
211 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
212         cd->datareferences = NULL;
213 #endif
214
215 /*      cd->patchrefs      = list_create_dump(OFFSET(patchref, linkage)); */
216         cd->patchrefs      = NULL;
217         cd->brancheslabel  = list_create_dump(OFFSET(branch_label_ref_t, linkage));
218         cd->listcritical   = list_create_dump(OFFSET(critical_section_ref_t, linkage));
219
220         cd->linenumberreferences = NULL;
221         cd->linenumbertablesizepos = 0;
222         cd->linenumbertablestartpos = 0;
223         cd->linenumbertab = 0;
224 }
225
226
227 /* codegen_reset ***************************************************************
228
229    Resets the codegen data structure so we can recompile the method.
230
231 *******************************************************************************/
232
233 static void codegen_reset(jitdata *jd)
234 {
235         codeinfo    *code;
236         codegendata *cd;
237         basicblock  *bptr;
238
239         /* get required compiler data */
240
241         code = jd->code;
242         cd   = jd->cd;
243
244         /* reset error flag */
245
246         cd->flags          &= ~CODEGENDATA_FLAG_ERROR;
247
248         /* reset some members, we reuse the code memory already allocated
249            as this should have almost the correct size */
250
251         cd->mcodeptr        = cd->mcodebase;
252         cd->lastmcodeptr    = cd->mcodebase;
253
254         cd->dseg            = NULL;
255         cd->dseglen         = 0;
256
257         cd->jumpreferences  = NULL;
258
259 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
260         cd->datareferences  = NULL;
261 #endif
262
263 /*      cd->patchrefs       = list_create_dump(OFFSET(patchref, linkage)); */
264         cd->patchrefs       = NULL;
265         cd->brancheslabel   = list_create_dump(OFFSET(branch_label_ref_t, linkage));
266         cd->listcritical    = list_create_dump(OFFSET(critical_section_ref_t, linkage));
267
268         cd->linenumberreferences    = NULL;
269         cd->linenumbertablesizepos  = 0;
270         cd->linenumbertablestartpos = 0;
271         cd->linenumbertab           = 0;
272         
273         /* We need to clear the mpc and the branch references from all
274            basic blocks as they will definitely change. */
275
276         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
277                 bptr->mpc        = -1;
278                 bptr->branchrefs = NULL;
279         }
280
281         /* We need to clear all the patcher references from the codeinfo
282            since they all will be regenerated */
283
284         patcher_list_reset(code);
285
286 #if defined(ENABLE_REPLACEMENT)
287         code->rplpoints     = NULL;
288         code->rplpointcount = 0;
289         code->regalloc      = NULL;
290         code->regalloccount = 0;
291         code->globalcount   = 0;
292 #endif
293 }
294
295
296 /* codegen_generate ************************************************************
297
298    Generates the code for the currently compiled method.
299
300 *******************************************************************************/
301
302 bool codegen_generate(jitdata *jd)
303 {
304         codegendata *cd;
305
306         /* get required compiler data */
307
308         cd = jd->cd;
309
310         /* call the machine-dependent code generation function */
311
312         if (!codegen_emit(jd))
313                 return false;
314
315         /* check for an error */
316
317         if (CODEGENDATA_HAS_FLAG_ERROR(cd)) {
318                 /* check for long-branches flag, if it is set we recompile the
319                    method */
320
321 #if !defined(NDEBUG)
322         if (compileverbose)
323             log_message_method("Re-generating code: ", jd->m);
324 #endif
325
326                 /* XXX maybe we should tag long-branches-methods for recompilation */
327
328                 if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
329                         /* we have to reset the codegendata structure first */
330
331                         codegen_reset(jd);
332
333                         /* and restart the compiler run */
334
335                         if (!codegen_emit(jd))
336                                 return false;
337                 }
338                 else {
339                         vm_abort("codegen_generate: unknown error occurred during codegen_emit: flags=%x\n", cd->flags);
340                 }
341
342 #if !defined(NDEBUG)
343         if (compileverbose)
344             log_message_method("Re-generating code done: ", jd->m);
345 #endif
346         }
347
348         /* reallocate the memory and finish the code generation */
349
350         codegen_finish(jd);
351
352         /* everything's ok */
353
354         return true;
355 }
356
357
358 /* codegen_close ***************************************************************
359
360    TODO
361
362 *******************************************************************************/
363
364 void codegen_close(void)
365 {
366         /* TODO: release avl tree on i386 and x86_64 */
367 }
368
369
370 /* codegen_increase ************************************************************
371
372    Doubles code area.
373
374 *******************************************************************************/
375
376 void codegen_increase(codegendata *cd)
377 {
378         u1 *oldmcodebase;
379
380         /* save old mcodebase pointer */
381
382         oldmcodebase = cd->mcodebase;
383
384         /* reallocate to new, doubled memory */
385
386         cd->mcodebase = DMREALLOC(cd->mcodebase,
387                                                           u1,
388                                                           cd->mcodesize,
389                                                           cd->mcodesize * 2);
390         cd->mcodesize *= 2;
391         cd->mcodeend   = cd->mcodebase + cd->mcodesize;
392
393         /* set new mcodeptr */
394
395         cd->mcodeptr = cd->mcodebase + (cd->mcodeptr - oldmcodebase);
396
397 #if defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(__M68K__) || defined(ENABLE_INTRP) \
398  || defined(__SPARC_64__)
399         /* adjust the pointer to the last patcher position */
400
401         if (cd->lastmcodeptr != NULL)
402                 cd->lastmcodeptr = cd->mcodebase + (cd->lastmcodeptr - oldmcodebase);
403 #endif
404 }
405
406
407 /* codegen_ncode_increase ******************************************************
408
409    Doubles code area.
410
411 *******************************************************************************/
412
413 #if defined(ENABLE_INTRP)
414 u1 *codegen_ncode_increase(codegendata *cd, u1 *ncodeptr)
415 {
416         u1 *oldncodebase;
417
418         /* save old ncodebase pointer */
419
420         oldncodebase = cd->ncodebase;
421
422         /* reallocate to new, doubled memory */
423
424         cd->ncodebase = DMREALLOC(cd->ncodebase,
425                                                           u1,
426                                                           cd->ncodesize,
427                                                           cd->ncodesize * 2);
428         cd->ncodesize *= 2;
429
430         /* return the new ncodeptr */
431
432         return (cd->ncodebase + (ncodeptr - oldncodebase));
433 }
434 #endif
435
436
437 /* codegen_add_branch_ref ******************************************************
438
439    Prepends an branch to the list.
440
441 *******************************************************************************/
442
443 void codegen_add_branch_ref(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options)
444 {
445         branchref *br;
446         s4         branchmpc;
447
448         STATISTICS(count_branches_unresolved++);
449
450         /* calculate the mpc of the branch instruction */
451
452         branchmpc = cd->mcodeptr - cd->mcodebase;
453
454         br = DNEW(branchref);
455
456         br->branchmpc = branchmpc;
457         br->condition = condition;
458         br->reg       = reg;
459         br->options   = options;
460         br->next      = target->branchrefs;
461
462         target->branchrefs = br;
463 }
464
465
466 /* codegen_resolve_branchrefs **************************************************
467
468    Resolves and patches the branch references of a given basic block.
469
470 *******************************************************************************/
471
472 void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr)
473 {
474         branchref *br;
475         u1        *mcodeptr;
476
477         /* Save the mcodeptr because in the branch emitting functions
478            we generate code somewhere inside already generated code,
479            but we're still in the actual code generation phase. */
480
481         mcodeptr = cd->mcodeptr;
482
483         /* just to make sure */
484
485         assert(bptr->mpc >= 0);
486
487         for (br = bptr->branchrefs; br != NULL; br = br->next) {
488                 /* temporary set the mcodeptr */
489
490                 cd->mcodeptr = cd->mcodebase + br->branchmpc;
491
492                 /* emit_bccz and emit_branch emit the correct code, even if we
493                    pass condition == BRANCH_UNCONDITIONAL or reg == -1. */
494
495                 emit_bccz(cd, bptr, br->condition, br->reg, br->options);
496         }
497
498         /* restore mcodeptr */
499
500         cd->mcodeptr = mcodeptr;
501 }
502
503
504 /* codegen_branch_label_add ****************************************************
505
506    Append an branch to the label-branch list.
507
508 *******************************************************************************/
509
510 void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
511 {
512         list_t             *list;
513         branch_label_ref_t *br;
514         s4                  mpc;
515
516         /* get the label list */
517
518         list = cd->brancheslabel;
519         
520         /* calculate the current mpc */
521
522         mpc = cd->mcodeptr - cd->mcodebase;
523
524         br = DNEW(branch_label_ref_t);
525
526         br->mpc       = mpc;
527         br->label     = label;
528         br->condition = condition;
529         br->reg       = reg;
530         br->options   = options;
531
532         /* add the branch to the list */
533
534         list_add_last_unsynced(list, br);
535 }
536
537
538 /* codegen_add_patch_ref *******************************************************
539
540    Appends a new patcher reference to the list of patching positions.
541
542 *******************************************************************************/
543
544 void codegen_add_patch_ref(codegendata *cd, functionptr patcher, voidptr ref,
545                                                    s4 disp)
546 {
547         patchref *pr;
548         s4        branchmpc;
549
550         branchmpc = cd->mcodeptr - cd->mcodebase;
551
552         pr = DNEW(patchref);
553
554         pr->branchpos = branchmpc;
555         pr->disp      = disp;
556         pr->patcher   = patcher;
557         pr->ref       = ref;
558
559 /*      list_add_first(cd->patchrefs, pr); */
560         pr->next      = cd->patchrefs;
561         cd->patchrefs = pr;
562
563         /* Generate NOPs for opt_shownops. */
564
565         if (opt_shownops)
566                 PATCHER_NOPS;
567
568 #if defined(ENABLE_JIT) && (defined(__I386__) || defined(__M68K__) || defined(__MIPS__) \
569  || defined(__SPARC_64__) || defined(__X86_64__))
570
571         /* On some architectures the patcher stub call instruction might
572            be longer than the actual instruction generated.  On this
573            architectures we store the last patcher call position and after
574            the basic block code generation is completed, we check the
575            range and maybe generate some nop's. */
576         /* The nops are generated in codegen_emit in each codegen */
577
578         cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
579 #endif
580 }
581
582
583 /* codegen_critical_section_new ************************************************
584
585    Allocates a new critical-section reference and adds it to the
586    critical-section list.
587
588 *******************************************************************************/
589
590 #if defined(ENABLE_THREADS)
591 void codegen_critical_section_new(codegendata *cd)
592 {
593         list_t                 *list;
594         critical_section_ref_t *csr;
595         s4                      mpc;
596
597         /* get the critical section list */
598
599         list = cd->listcritical;
600         
601         /* calculate the current mpc */
602
603         mpc = cd->mcodeptr - cd->mcodebase;
604
605         csr = DNEW(critical_section_ref_t);
606
607         /* We only can set restart right now, as start and end are set by
608            the following, corresponding functions. */
609
610         csr->start   = -1;
611         csr->end     = -1;
612         csr->restart = mpc;
613
614         /* add the branch to the list */
615
616         list_add_last_unsynced(list, csr);
617 }
618 #endif
619
620
621 /* codegen_critical_section_start **********************************************
622
623    Set the start-point of the current critical section (which is the
624    last element of the list).
625
626 *******************************************************************************/
627
628 #if defined(ENABLE_THREADS)
629 void codegen_critical_section_start(codegendata *cd)
630 {
631         list_t                 *list;
632         critical_section_ref_t *csr;
633         s4                      mpc;
634
635         /* get the critical section list */
636
637         list = cd->listcritical;
638         
639         /* calculate the current mpc */
640
641         mpc = cd->mcodeptr - cd->mcodebase;
642
643         /* get the current critical section */
644
645         csr = list_last_unsynced(list);
646
647         /* set the start point */
648
649         assert(csr->start == -1);
650
651         csr->start = mpc;
652 }
653 #endif
654
655
656 /* codegen_critical_section_end ************************************************
657
658    Set the end-point of the current critical section (which is the
659    last element of the list).
660
661 *******************************************************************************/
662
663 #if defined(ENABLE_THREADS)
664 void codegen_critical_section_end(codegendata *cd)
665 {
666         list_t                 *list;
667         critical_section_ref_t *csr;
668         s4                      mpc;
669
670         /* get the critical section list */
671
672         list = cd->listcritical;
673         
674         /* calculate the current mpc */
675
676         mpc = cd->mcodeptr - cd->mcodebase;
677
678         /* get the current critical section */
679
680         csr = list_last_unsynced(list);
681
682         /* set the end point */
683
684         assert(csr->end == -1);
685
686         csr->end = mpc;
687 }
688 #endif
689
690
691 /* codegen_critical_section_finish *********************************************
692
693    Finish the critical sections, create the critical section nodes for
694    the AVL tree and insert them into the tree.
695
696 *******************************************************************************/
697
698 #if defined(ENABLE_THREADS)
699 static void codegen_critical_section_finish(jitdata *jd)
700 {
701         codeinfo    *code;
702         codegendata *cd;
703         list_t                  *list;
704         critical_section_ref_t  *csr;
705         critical_section_node_t *csn;
706
707         /* get required compiler data */
708
709         code = jd->code;
710         cd   = jd->cd;
711
712         /* get the critical section list */
713
714         list = cd->listcritical;
715
716         /* iterate over all critical sections */
717
718         for (csr = list_first_unsynced(list); csr != NULL;
719                  csr = list_next_unsynced(list, csr)) {
720                 /* check if all points are set */
721
722                 assert(csr->start   != -1);
723                 assert(csr->end     != -1);
724                 assert(csr->restart != -1);
725
726                 /* allocate tree node */
727
728                 csn = NEW(critical_section_node_t);
729
730                 csn->start   = code->entrypoint + csr->start;
731                 csn->end     = code->entrypoint + csr->end;
732                 csn->restart = code->entrypoint + csr->restart;
733
734                 /* insert into the tree */
735
736                 critical_section_register(csn);
737         }
738 }
739 #endif
740
741
742 /* methodtree_comparator *******************************************************
743
744    Comparator function used for the AVL tree of methods.
745
746    ARGUMENTS:
747       treenode....the node from the tree
748       node........the node to compare to the tree-node
749
750 *******************************************************************************/
751
752 static s4 methodtree_comparator(const void *treenode, const void *node)
753 {
754         methodtree_element *mte;
755         methodtree_element *mtepc;
756
757         mte   = (methodtree_element *) treenode;
758         mtepc = (methodtree_element *) node;
759
760         /* compare both startpc and endpc of pc, even if they have the same value,
761            otherwise the avl_probe sometimes thinks the element is already in the
762            tree */
763
764 #ifdef __S390__
765         /* On S390 addresses are 31 bit. Compare only 31 bits of value.
766          */
767 #       define ADDR_MASK(a) ((a) & 0x7FFFFFFF)
768 #else
769 #       define ADDR_MASK(a) (a)
770 #endif
771
772         if (ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->startpc) &&
773                 ADDR_MASK((long) mtepc->startpc) <= ADDR_MASK((long) mte->endpc) &&
774                 ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->endpc) &&
775                 ADDR_MASK((long) mtepc->endpc) <= ADDR_MASK((long) mte->endpc)) {
776                 return 0;
777
778         } else if (ADDR_MASK((long) mtepc->startpc) < ADDR_MASK((long) mte->startpc)) {
779                 return -1;
780
781         } else {
782                 return 1;
783         }
784
785 #       undef ADDR_MASK
786 }
787
788
789 /* codegen_insertmethod ********************************************************
790
791    Insert the machine code range of a method into the AVL tree of methods.
792
793 *******************************************************************************/
794
795 void codegen_insertmethod(u1 *startpc, u1 *endpc)
796 {
797         methodtree_element *mte;
798
799         /* allocate new method entry */
800
801         mte = NEW(methodtree_element);
802
803         mte->startpc = startpc;
804         mte->endpc   = endpc;
805
806         /* this function does not return an error, but asserts for
807            duplicate entries */
808
809         avl_insert(methodtree, mte);
810 }
811
812
813 /* codegen_get_pv_from_pc ******************************************************
814
815    Find the PV for the given PC by searching in the AVL tree of
816    methods.
817
818 *******************************************************************************/
819
820 u1 *codegen_get_pv_from_pc(u1 *pc)
821 {
822         methodtree_element  mtepc;
823         methodtree_element *mte;
824
825         /* allocation of the search structure on the stack is much faster */
826
827         mtepc.startpc = pc;
828         mtepc.endpc   = pc;
829
830         mte = avl_find(methodtree, &mtepc);
831
832         if (mte == NULL) {
833                 /* No method was found.  Let's dump a stacktrace. */
834
835 #if defined(ENABLE_VMLOG)
836                 vmlog_cacao_signl("SIGSEGV");
837 #endif
838
839                 log_println("We received a SIGSEGV and tried to handle it, but we were");
840                 log_println("unable to find a Java method at:");
841                 log_println("");
842 #if SIZEOF_VOID_P == 8
843                 log_println("PC=0x%016lx", pc);
844 #else
845                 log_println("PC=0x%08x", pc);
846 #endif
847                 log_println("");
848                 assert(0);
849                 log_println("Dumping the current stacktrace:");
850
851 #if defined(ENABLE_THREADS)
852                 /* XXX michi: This should be available even without threads! */
853                 threads_print_stacktrace();
854 #endif
855
856                 vm_abort("Exiting...");
857         }
858
859         return mte->startpc;
860 }
861
862
863 /* codegen_get_pv_from_pc_nocheck **********************************************
864
865    Find the PV for the given PC by searching in the AVL tree of
866    methods.  This method does not check the return value and is used
867    by the profiler.
868
869 *******************************************************************************/
870
871 u1 *codegen_get_pv_from_pc_nocheck(u1 *pc)
872 {
873         methodtree_element  mtepc;
874         methodtree_element *mte;
875
876         /* allocation of the search structure on the stack is much faster */
877
878         mtepc.startpc = pc;
879         mtepc.endpc   = pc;
880
881         mte = avl_find(methodtree, &mtepc);
882
883         if (mte == NULL)
884                 return NULL;
885         else
886                 return mte->startpc;
887 }
888
889
890 /* codegen_set_replacement_point_notrap ****************************************
891
892    Record the position of a non-trappable replacement point.
893
894 *******************************************************************************/
895
896 #if defined(ENABLE_REPLACEMENT)
897 #if !defined(NDEBUG)
898 void codegen_set_replacement_point_notrap(codegendata *cd, s4 type)
899 #else
900 void codegen_set_replacement_point_notrap(codegendata *cd)
901 #endif
902 {
903         assert(cd->replacementpoint);
904         assert(cd->replacementpoint->type == type);
905         assert(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP);
906
907         cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
908
909         cd->replacementpoint++;
910 }
911 #endif /* defined(ENABLE_REPLACEMENT) */
912
913
914 /* codegen_set_replacement_point ***********************************************
915
916    Record the position of a trappable replacement point.
917
918 *******************************************************************************/
919
920 #if defined(ENABLE_REPLACEMENT)
921 #if !defined(NDEBUG)
922 void codegen_set_replacement_point(codegendata *cd, s4 type)
923 #else
924 void codegen_set_replacement_point(codegendata *cd)
925 #endif
926 {
927         assert(cd->replacementpoint);
928         assert(cd->replacementpoint->type == type);
929         assert(!(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP));
930
931         cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
932
933         cd->replacementpoint++;
934
935 #if !defined(NDEBUG)
936         /* XXX actually we should use an own REPLACEMENT_NOPS here! */
937         if (opt_TestReplacement)
938                 PATCHER_NOPS;
939 #endif
940
941         /* XXX assert(cd->lastmcodeptr <= cd->mcodeptr); */
942
943         cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
944 }
945 #endif /* defined(ENABLE_REPLACEMENT) */
946
947
948 /* codegen_finish **************************************************************
949
950    Finishes the code generation. A new memory, large enough for both
951    data and code, is allocated and data and code are copied together
952    to their final layout, unresolved jumps are resolved, ...
953
954 *******************************************************************************/
955
956 void codegen_finish(jitdata *jd)
957 {
958         codeinfo    *code;
959         codegendata *cd;
960         s4           mcodelen;
961 #if defined(ENABLE_INTRP)
962         s4           ncodelen;
963 #endif
964         s4           alignedmcodelen;
965         jumpref     *jr;
966         patchref_t  *pr;
967         u1          *epoint;
968         s4           alignedlen;
969
970         /* get required compiler data */
971
972         code = jd->code;
973         cd   = jd->cd;
974
975         /* prevent compiler warning */
976
977 #if defined(ENABLE_INTRP)
978         ncodelen = 0;
979 #endif
980
981         /* calculate the code length */
982
983         mcodelen = (s4) (cd->mcodeptr - cd->mcodebase);
984
985 #if defined(ENABLE_STATISTICS)
986         if (opt_stat) {
987                 count_code_len += mcodelen;
988                 count_data_len += cd->dseglen;
989         }
990 #endif
991
992         alignedmcodelen = MEMORY_ALIGN(mcodelen, MAX_ALIGN);
993
994 #if defined(ENABLE_INTRP)
995         if (opt_intrp)
996                 ncodelen = cd->ncodeptr - cd->ncodebase;
997         else {
998                 ncodelen = 0; /* avoid compiler warning */
999         }
1000 #endif
1001
1002         cd->dseglen = MEMORY_ALIGN(cd->dseglen, MAX_ALIGN);
1003         alignedlen = alignedmcodelen + cd->dseglen;
1004
1005 #if defined(ENABLE_INTRP)
1006         if (opt_intrp) {
1007                 alignedlen += ncodelen;
1008         }
1009 #endif
1010
1011         /* allocate new memory */
1012
1013         code->mcodelength = mcodelen + cd->dseglen;
1014         code->mcode       = CNEW(u1, alignedlen);
1015
1016         /* set the entrypoint of the method */
1017         
1018         assert(code->entrypoint == NULL);
1019         code->entrypoint = epoint = (code->mcode + cd->dseglen);
1020
1021         /* fill the data segment (code->entrypoint must already be set!) */
1022
1023         dseg_finish(jd);
1024
1025         /* copy code to the new location */
1026
1027         MCOPY((void *) code->entrypoint, cd->mcodebase, u1, mcodelen);
1028
1029 #if defined(ENABLE_INTRP)
1030         /* relocate native dynamic superinstruction code (if any) */
1031
1032         if (opt_intrp) {
1033                 cd->mcodebase = code->entrypoint;
1034
1035                 if (ncodelen > 0) {
1036                         u1 *ncodebase = code->mcode + cd->dseglen + alignedmcodelen;
1037
1038                         MCOPY((void *) ncodebase, cd->ncodebase, u1, ncodelen);
1039
1040                         /* flush the instruction and data caches */
1041
1042                         md_cacheflush(ncodebase, ncodelen);
1043
1044                         /* set some cd variables for dynamic_super_rerwite */
1045
1046                         cd->ncodebase = ncodebase;
1047
1048                 } else {
1049                         cd->ncodebase = NULL;
1050                 }
1051
1052                 dynamic_super_rewrite(cd);
1053         }
1054 #endif
1055
1056         /* jump table resolving */
1057
1058         for (jr = cd->jumpreferences; jr != NULL; jr = jr->next)
1059                 *((functionptr *) ((ptrint) epoint + jr->tablepos)) =
1060                         (functionptr) ((ptrint) epoint + (ptrint) jr->target->mpc);
1061
1062         /* line number table resolving */
1063         {
1064                 linenumberref *lr;
1065                 ptrint lrtlen = 0;
1066                 ptrint target;
1067
1068                 for (lr = cd->linenumberreferences; lr != NULL; lr = lr->next) {
1069                         lrtlen++;
1070                         target = lr->targetmpc;
1071                         /* if the entry contains an mcode pointer (normal case), resolve it */
1072                         /* (see doc/inlining_stacktrace.txt for details)                    */
1073                         if (lr->linenumber >= -2) {
1074                             target += (ptrint) epoint;
1075                         }
1076                         *((functionptr *) ((ptrint) epoint + (ptrint) lr->tablepos)) = 
1077                                 (functionptr) target;
1078                 }
1079                 
1080                 *((functionptr *) ((ptrint) epoint + cd->linenumbertablestartpos)) =
1081                         (functionptr) ((ptrint) epoint + cd->linenumbertab);
1082
1083                 *((ptrint *) ((ptrint) epoint + cd->linenumbertablesizepos)) = lrtlen;
1084         }
1085
1086         /* patcher resolving */
1087
1088         pr = list_first_unsynced(code->patchers);
1089         while (pr) {
1090                 pr->mpc += (ptrint) epoint;
1091                 pr->datap = (ptrint) (pr->disp + epoint);
1092                 pr = list_next_unsynced(code->patchers, pr);
1093         }
1094
1095 #if defined(ENABLE_REPLACEMENT)
1096         /* replacement point resolving */
1097         {
1098                 int i;
1099                 rplpoint *rp;
1100
1101                 rp = code->rplpoints;
1102                 for (i=0; i<code->rplpointcount; ++i, ++rp) {
1103                         rp->pc = (u1*) ((ptrint) epoint + (ptrint) rp->pc);
1104                 }
1105         }
1106 #endif /* defined(ENABLE_REPLACEMENT) */
1107
1108         /* add method into methodtree to find the entrypoint */
1109
1110         codegen_insertmethod(code->entrypoint, code->entrypoint + mcodelen);
1111
1112 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
1113         /* resolve data segment references */
1114
1115         dseg_resolve_datareferences(jd);
1116 #endif
1117
1118 #if defined(ENABLE_THREADS)
1119         /* create cirtical sections */
1120
1121         codegen_critical_section_finish(jd);
1122 #endif
1123
1124         /* flush the instruction and data caches */
1125
1126         md_cacheflush(code->mcode, code->mcodelength);
1127 }
1128
1129
1130 /* codegen_generate_stub_compiler **********************************************
1131
1132    Wrapper for codegen_emit_stub_compiler.
1133
1134    Returns:
1135        pointer to the compiler stub code.
1136
1137 *******************************************************************************/
1138
1139 u1 *codegen_generate_stub_compiler(methodinfo *m)
1140 {
1141         jitdata     *jd;
1142         codegendata *cd;
1143         ptrint      *d;                     /* pointer to data memory             */
1144         u1          *c;                     /* pointer to code memory             */
1145         s4           dumpsize;
1146
1147         /* mark dump memory */
1148
1149         dumpsize = dump_size();
1150
1151         /* allocate required data structures */
1152
1153         jd = DNEW(jitdata);
1154
1155         jd->m     = m;
1156         jd->cd    = DNEW(codegendata);
1157         jd->flags = 0;
1158
1159         /* get required compiler data */
1160
1161         cd = jd->cd;
1162
1163         /* allocate code memory */
1164
1165         c = CNEW(u1, 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
1166
1167         /* set pointers correctly */
1168
1169         d = (ptrint *) c;
1170
1171         cd->mcodebase = c;
1172
1173         c = c + 3 * SIZEOF_VOID_P;
1174         cd->mcodeptr = c;
1175
1176         /* NOTE: The codeinfo pointer is actually a pointer to the
1177            methodinfo (this fakes a codeinfo structure). */
1178
1179         d[0] = (ptrint) asm_call_jit_compiler;
1180         d[1] = (ptrint) m;
1181         d[2] = (ptrint) &d[1];                                    /* fake code->m */
1182
1183         /* call the emit function */
1184
1185         codegen_emit_stub_compiler(jd);
1186
1187 #if defined(ENABLE_STATISTICS)
1188         if (opt_stat)
1189                 count_cstub_len += 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE;
1190 #endif
1191
1192         /* flush caches */
1193
1194         md_cacheflush(cd->mcodebase, 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
1195
1196         /* release dump memory */
1197
1198         dump_release(dumpsize);
1199
1200         /* return native stub code */
1201
1202         return c;
1203 }
1204
1205
1206 /* codegen_generate_stub_builtin ***********************************************
1207
1208    Wrapper for codegen_emit_stub_native.
1209
1210 *******************************************************************************/
1211
1212 void codegen_generate_stub_builtin(methodinfo *m, builtintable_entry *bte)
1213 {
1214         jitdata  *jd;
1215         codeinfo *code;
1216         int       skipparams;
1217         s4        dumpsize;
1218
1219         /* mark dump memory */
1220
1221         dumpsize = dump_size();
1222
1223         jd = DNEW(jitdata);
1224
1225         jd->m     = m;
1226         jd->cd    = DNEW(codegendata);
1227         jd->rd    = NULL;
1228         jd->flags = 0;
1229
1230         /* Allocate codeinfo memory from the heap as we need to keep them. */
1231
1232         jd->code  = code_codeinfo_new(m);
1233
1234         /* get required compiler data */
1235
1236         code = jd->code;
1237
1238         /* setup code generation stuff */
1239
1240         codegen_setup(jd);
1241
1242         /* Set the number of native arguments we need to skip. */
1243
1244         skipparams = 0;
1245
1246         /* generate the code */
1247
1248 #if defined(ENABLE_JIT)
1249 # if defined(ENABLE_INTRP)
1250         if (!opt_intrp) {
1251 # endif
1252                 assert(bte->fp != NULL);
1253                 codegen_emit_stub_native(jd, bte->md, bte->fp, skipparams);
1254 # if defined(ENABLE_INTRP)
1255         }
1256 # endif
1257 #endif
1258
1259         /* reallocate the memory and finish the code generation */
1260
1261         codegen_finish(jd);
1262
1263         /* set the stub entry point in the builtin table */
1264
1265         bte->stub = code->entrypoint;
1266
1267 #if defined(ENABLE_STATISTICS)
1268         if (opt_stat)
1269                 size_stub_native += code->mcodelength;
1270 #endif
1271
1272 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
1273         /* disassemble native stub */
1274
1275         if (opt_DisassembleStubs) {
1276                 codegen_disassemble_stub(m,
1277                                                                  (u1 *) (ptrint) code->entrypoint,
1278                                                                  (u1 *) (ptrint) code->entrypoint + (code->mcodelength - jd->cd->dseglen));
1279
1280                 /* show data segment */
1281
1282                 if (opt_showddatasegment)
1283                         dseg_display(jd);
1284         }
1285 #endif /* !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) */
1286
1287         /* release memory */
1288
1289         dump_release(dumpsize);
1290 }
1291
1292
1293 /* codegen_generate_stub_native ************************************************
1294
1295    Wrapper for codegen_emit_stub_native.
1296
1297    Returns:
1298        the codeinfo representing the stub code.
1299
1300 *******************************************************************************/
1301
1302 codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f)
1303 {
1304         jitdata     *jd;
1305         codeinfo    *code;
1306         s4           dumpsize;
1307         methoddesc  *md;
1308         methoddesc  *nmd;       
1309         int          skipparams;
1310
1311         /* mark dump memory */
1312
1313         dumpsize = dump_size();
1314
1315         jd = DNEW(jitdata);
1316
1317         jd->m     = m;
1318         jd->cd    = DNEW(codegendata);
1319         jd->rd    = DNEW(registerdata);
1320         jd->flags = 0;
1321
1322         /* Allocate codeinfo memory from the heap as we need to keep them. */
1323
1324         jd->code  = code_codeinfo_new(m);
1325
1326         /* get required compiler data */
1327
1328         code = jd->code;
1329
1330         /* set the flags for the current JIT run */
1331
1332 #if defined(ENABLE_PROFILING)
1333         if (opt_prof)
1334                 jd->flags |= JITDATA_FLAG_INSTRUMENT;
1335 #endif
1336
1337         if (opt_verbosecall)
1338                 jd->flags |= JITDATA_FLAG_VERBOSECALL;
1339
1340         /* setup code generation stuff */
1341
1342 #if defined(ENABLE_JIT)
1343 # if defined(ENABLE_INTRP)
1344         if (!opt_intrp)
1345 # endif
1346                 reg_setup(jd);
1347 #endif
1348
1349         codegen_setup(jd);
1350
1351         /* create new method descriptor with additional native parameters */
1352
1353         md = m->parseddesc;
1354
1355         /* Set the number of native arguments we need to skip. */
1356
1357         if (m->flags & ACC_STATIC)
1358                 skipparams = 2;
1359         else
1360                 skipparams = 1;
1361         
1362         nmd = (methoddesc *) DMNEW(u1, sizeof(methoddesc) - sizeof(typedesc) +
1363                                                            md->paramcount * sizeof(typedesc) +
1364                                                            skipparams * sizeof(typedesc));
1365
1366         nmd->paramcount = md->paramcount + skipparams;
1367
1368         nmd->params = DMNEW(paramdesc, nmd->paramcount);
1369
1370         nmd->paramtypes[0].type = TYPE_ADR; /* add environment pointer            */
1371
1372         if (m->flags & ACC_STATIC)
1373                 nmd->paramtypes[1].type = TYPE_ADR; /* add class pointer              */
1374
1375         MCOPY(nmd->paramtypes + skipparams, md->paramtypes, typedesc,
1376                   md->paramcount);
1377
1378 #if defined(ENABLE_JIT)
1379 # if defined(ENABLE_INTRP)
1380         if (!opt_intrp)
1381 # endif
1382                 /* pre-allocate the arguments for the native ABI */
1383
1384                 md_param_alloc_native(nmd);
1385 #endif
1386
1387         /* generate the code */
1388
1389 #if defined(ENABLE_JIT)
1390 # if defined(ENABLE_INTRP)
1391         if (opt_intrp)
1392                 intrp_createnativestub(f, jd, nmd);
1393         else
1394 # endif
1395                 codegen_emit_stub_native(jd, nmd, f, skipparams);
1396 #else
1397         intrp_createnativestub(f, jd, nmd);
1398 #endif
1399
1400         /* reallocate the memory and finish the code generation */
1401
1402         codegen_finish(jd);
1403
1404 #if defined(ENABLE_STATISTICS)
1405         /* must be done after codegen_finish() */
1406
1407         if (opt_stat)
1408                 size_stub_native += code->mcodelength;
1409 #endif
1410
1411 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
1412         /* disassemble native stub */
1413
1414         if (opt_DisassembleStubs) {
1415 # if defined(ENABLE_DEBUG_FILTER)
1416                 if (m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
1417 # endif
1418                 {
1419                         codegen_disassemble_stub(m,
1420                                                                          (u1 *) (ptrint) code->entrypoint,
1421                                                                          (u1 *) (ptrint) code->entrypoint + (code->mcodelength - jd->cd->dseglen));
1422
1423                         /* show data segment */
1424
1425                         if (opt_showddatasegment)
1426                                 dseg_display(jd);
1427                 }
1428         }
1429 #endif /* !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) */
1430
1431         /* release memory */
1432
1433         dump_release(dumpsize);
1434
1435         /* return native stub code */
1436
1437         return code;
1438 }
1439
1440
1441 /* codegen_disassemble_nativestub **********************************************
1442
1443    Disassembles the generated builtin or native stub.
1444
1445 *******************************************************************************/
1446
1447 #if defined(ENABLE_DISASSEMBLER)
1448 void codegen_disassemble_stub(methodinfo *m, u1 *start, u1 *end)
1449 {
1450         printf("Stub code: ");
1451         if (m->class != NULL)
1452                 utf_fprint_printable_ascii_classname(stdout, m->class->name);
1453         else
1454                 printf("NULL");
1455         printf(".");
1456         utf_fprint_printable_ascii(stdout, m->name);
1457         utf_fprint_printable_ascii(stdout, m->descriptor);
1458         printf("\nLength: %d\n\n", (s4) (end - start));
1459
1460         DISASSEMBLE(start, end);
1461 }
1462 #endif
1463
1464
1465 /* codegen_start_native_call ***************************************************
1466
1467    Prepares the stuff required for a native (JNI) function call:
1468
1469    - adds a stackframe info structure to the chain, for stacktraces
1470    - prepares the local references table on the stack
1471
1472    The layout of the native stub stackframe should look like this:
1473
1474    +---------------------------+ <- java SP (of parent Java function)
1475    | return address            |
1476    +---------------------------+ <- data SP
1477    |                           |
1478    | stackframe info structure |
1479    |                           |
1480    +---------------------------+
1481    |                           |
1482    | local references table    |
1483    |                           |
1484    +---------------------------+
1485    |                           |
1486    | saved registers (if any)  |
1487    |                           |
1488    +---------------------------+
1489    |                           |
1490    | arguments (if any)        |
1491    |                           |
1492    +---------------------------+ <- current SP (native stub)
1493
1494 *******************************************************************************/
1495
1496 java_handle_t *codegen_start_native_call(u1 *currentsp, u1 *pv)
1497 {
1498         stackframeinfo *sfi;
1499         localref_table *lrt;
1500         codeinfo       *code;
1501         methodinfo     *m;
1502         int32_t         framesize;
1503
1504         uint8_t  *datasp;
1505         uint8_t  *javasp;
1506         uint8_t  *javara;
1507         uint64_t *arg_regs;
1508         uint64_t *arg_stack;
1509
1510         STATISTICS(count_calls_java_to_native++);
1511
1512         /* get information from method header */
1513
1514         code      = *((codeinfo **) (pv + CodeinfoPointer));
1515         framesize = *((int32_t *)   (pv + FrameSize));
1516         assert(code);
1517         assert(framesize >= sizeof(stackframeinfo) + sizeof(localref_table));
1518
1519         /* get the methodinfo */
1520
1521         m = code->m;
1522         assert(m);
1523
1524         /* calculate needed values */
1525
1526 #if defined(__ALPHA__) || defined(__ARM__)
1527         datasp    = currentsp + framesize - SIZEOF_VOID_P;
1528         javasp    = currentsp + framesize;
1529         javara    = *((uint8_t **) datasp);
1530         arg_regs  = (uint64_t *) currentsp;
1531         arg_stack = (uint64_t *) javasp;
1532 #elif defined(__MIPS__)
1533         /* MIPS always uses 8 bytes to store the RA */
1534         datasp    = currentsp + framesize - 8;
1535         javasp    = currentsp + framesize;
1536         javara    = *((uint8_t **) datasp);
1537 #elif defined(__S390__)
1538         datasp    = currentsp + framesize - 8;
1539         javasp    = currentsp + framesize;
1540         javara    = *((uint8_t **) datasp);
1541         arg_regs  = (uint64_t *) (currentsp + 96);
1542         arg_stack = (uint64_t *) javasp;
1543 #elif defined(__I386__) || defined(__M68K__) || defined(__X86_64__)
1544         datasp    = currentsp + framesize;
1545         javasp    = currentsp + framesize + SIZEOF_VOID_P;
1546         javara    = *((uint8_t **) datasp);
1547         arg_regs  = (uint64_t *) currentsp;
1548         arg_stack = (uint64_t *) javasp;
1549 #elif defined(__POWERPC__)
1550         datasp    = currentsp + framesize;
1551         javasp    = currentsp + framesize;
1552         javara    = *((uint8_t **) (datasp + LA_LR_OFFSET));
1553         arg_regs  = (uint64_t *) (currentsp + LA_SIZE + 4 * SIZEOF_VOID_P);
1554         arg_stack = (uint64_t *) javasp;
1555 #elif defined(__POWERPC64__)
1556         datasp    = currentsp + framesize;
1557         javasp    = currentsp + framesize;
1558         javara    = *((uint8_t **) (datasp + LA_LR_OFFSET));
1559         arg_regs  = (uint64_t *) (currentsp + PA_SIZE + LA_SIZE + 4 * SIZEOF_VOID_P);
1560         arg_stack = (uint64_t *) javasp;
1561 #else
1562         /* XXX is was unable to do this port for SPARC64, sorry. (-michi) */
1563         /* XXX maybe we need to pass the RA as argument there */
1564         vm_abort("codegen_start_native_call: unsupported architecture");
1565 #endif
1566
1567 #if !defined(NDEBUG)
1568 # if defined(__ALPHA__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__X86_64__) || defined(__S390__)
1569         /* print the call-trace if necesarry */
1570
1571         if (opt_TraceJavaCalls)
1572                 trace_java_call_enter(m, arg_regs, arg_stack);
1573 # endif
1574 #endif
1575
1576         /* get data structures from stack */
1577
1578         sfi = (stackframeinfo *) (datasp - sizeof(stackframeinfo));
1579         lrt = (localref_table *) (datasp - sizeof(stackframeinfo) - 
1580                                                           sizeof(localref_table));
1581
1582 #if defined(ENABLE_JNI)
1583         /* add current JNI local references table to this thread */
1584
1585         localref_table_add(lrt);
1586 #endif
1587
1588 #if defined(ENABLE_HANDLES)
1589         /* place all references into the local reference table */
1590
1591         localref_fill(m, arg_regs, arg_stack);
1592 #endif
1593
1594         /* add a stackframeinfo to the chain */
1595
1596         stacktrace_create_native_stackframeinfo(sfi, pv, javasp, javara);
1597
1598         /* return a wrapped classinfo for static native methods */
1599
1600         if (m->flags & ACC_STATIC)
1601                 return LLNI_classinfo_wrap(m->class);
1602         else
1603                 return NULL;
1604 }
1605
1606
1607 /* codegen_finish_native_call **************************************************
1608
1609    Removes the stuff required for a native (JNI) function call.
1610    Additionally it checks for an exceptions and in case, get the
1611    exception object and clear the pointer.
1612
1613 *******************************************************************************/
1614
1615 java_object_t *codegen_finish_native_call(u1 *currentsp, u1 *pv)
1616 {
1617         stackframeinfo *sfi;
1618         java_handle_t  *e;
1619         java_object_t  *o;
1620         codeinfo       *code;
1621         methodinfo     *m;
1622         int32_t         framesize;
1623
1624         uint8_t  *datasp;
1625         uint64_t *ret_regs;
1626
1627         /* get information from method header */
1628
1629         code      = *((codeinfo **) (pv + CodeinfoPointer));
1630         framesize = *((int32_t *)   (pv + FrameSize));
1631         assert(code);
1632
1633         /* get the methodinfo */
1634
1635         m = code->m;
1636         assert(m);
1637
1638         /* calculate needed values */
1639
1640 #if defined(__ALPHA__) || defined(__ARM__)
1641         datasp   = currentsp + framesize - SIZEOF_VOID_P;
1642         ret_regs = (uint64_t *) currentsp;
1643 #elif defined(__MIPS__)
1644         /* MIPS always uses 8 bytes to store the RA */
1645         datasp   = currentsp + framesize - 8;
1646 #elif defined(__S390__)
1647         datasp   = currentsp + framesize - 8;
1648         ret_regs = (uint64_t *) (currentsp + 96);
1649 #elif defined(__I386__)
1650         datasp   = currentsp + framesize;
1651         ret_regs = (uint64_t *) (currentsp + 2 * SIZEOF_VOID_P);
1652 #elif defined(__M68K__) || defined(__X86_64__)
1653         datasp   = currentsp + framesize;
1654         ret_regs = (uint64_t *) currentsp;
1655 #elif defined(__POWERPC__)
1656         datasp   = currentsp + framesize;
1657         ret_regs = (uint64_t *) (currentsp + LA_SIZE + 2 * SIZEOF_VOID_P);
1658 #elif defined(__POWERPC64__)
1659         datasp   = currentsp + framesize;
1660         ret_regs = (uint64_t *) (currentsp + PA_SIZE + LA_SIZE + 2 * SIZEOF_VOID_P);
1661 #else
1662         vm_abort("codegen_finish_native_call: unsupported architecture");
1663 #endif
1664
1665
1666 #if !defined(NDEBUG)
1667 # if defined(__ALPHA__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__X86_64__) || defined(__S390__)
1668         /* print the call-trace if necesarry */
1669
1670         if (opt_TraceJavaCalls)
1671                 trace_java_call_exit(m, ret_regs);
1672 # endif
1673 #endif
1674
1675         /* get data structures from stack */
1676
1677         sfi = (stackframeinfo *) (datasp - sizeof(stackframeinfo));
1678
1679         /* remove current stackframeinfo from chain */
1680
1681         stacktrace_remove_stackframeinfo(sfi);
1682
1683         /* XXX unfill lrt here!!! */
1684
1685         /* get and unwrap the exception */
1686         /* ATTENTION: do the this _after_ the stackframeinfo was
1687        removed but _before_ the localref_table gets removed! */
1688
1689         e = exceptions_get_and_clear_exception();
1690         o = LLNI_UNWRAP(e);
1691
1692 #if defined(ENABLE_JNI)
1693         /* release JNI local references table for this thread */
1694
1695         localref_frame_pop_all();
1696         localref_table_remove();
1697 #endif
1698
1699         return o;
1700 }
1701
1702
1703 /* removecompilerstub **********************************************************
1704
1705    Deletes a compilerstub from memory (simply by freeing it).
1706
1707 *******************************************************************************/
1708
1709 void removecompilerstub(u1 *stub)
1710 {
1711         /* pass size 1 to keep the intern function happy */
1712
1713         CFREE((void *) stub, 1);
1714 }
1715
1716
1717 /* removenativestub ************************************************************
1718
1719    Removes a previously created native-stub from memory.
1720     
1721 *******************************************************************************/
1722
1723 void removenativestub(u1 *stub)
1724 {
1725         /* pass size 1 to keep the intern function happy */
1726
1727         CFREE((void *) stub, 1);
1728 }
1729
1730
1731 /* codegen_reg_of_var **********************************************************
1732
1733    This function determines a register, to which the result of an
1734    operation should go, when it is ultimatively intended to store the
1735    result in pseudoregister v.  If v is assigned to an actual
1736    register, this register will be returned.  Otherwise (when v is
1737    spilled) this function returns tempregnum.  If not already done,
1738    regoff and flags are set in the stack location.
1739        
1740 *******************************************************************************/
1741
1742 s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
1743 {
1744
1745 #if 0
1746         /* Do we have to generate a conditional move?  Yes, then always
1747            return the temporary register.  The real register is identified
1748            during the store. */
1749
1750         if (opcode & ICMD_CONDITION_MASK)
1751                 return tempregnum;
1752 #endif
1753
1754         if (!(v->flags & INMEMORY))
1755                 return v->vv.regoff;
1756
1757         return tempregnum;
1758 }
1759
1760
1761 /* codegen_reg_of_dst **********************************************************
1762
1763    This function determines a register, to which the result of an
1764    operation should go, when it is ultimatively intended to store the
1765    result in iptr->dst.var.  If dst.var is assigned to an actual
1766    register, this register will be returned.  Otherwise (when it is
1767    spilled) this function returns tempregnum.  If not already done,
1768    regoff and flags are set in the stack location.
1769        
1770 *******************************************************************************/
1771
1772 s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
1773 {
1774         return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum);
1775 }
1776
1777
1778 /* codegen_emit_phi_moves ****************************************************
1779
1780    Emits phi moves at the end of the basicblock.
1781
1782 *******************************************************************************/
1783
1784 #if defined(ENABLE_SSA)
1785 void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr)
1786 {
1787         int lt_d,lt_s,i;
1788         lsradata *ls;
1789         codegendata *cd;
1790         varinfo *s, *d;
1791         instruction tmp_i;
1792
1793         cd = jd->cd;
1794         ls = jd->ls;
1795
1796         MCODECHECK(512);
1797
1798         /* Moves from phi functions with highest indices have to be */
1799         /* inserted first, since this is the order as is used for   */
1800         /* conflict resolution */
1801
1802         for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
1803                 lt_d = ls->phi_moves[bptr->nr][i][0];
1804                 lt_s = ls->phi_moves[bptr->nr][i][1];
1805 #if defined(SSA_DEBUG_VERBOSE)
1806                 if (compileverbose)
1807                         printf("BB %3i Move %3i <- %3i ", bptr->nr, lt_d, lt_s);
1808 #endif
1809                 if (lt_s == UNUSED) {
1810 #if defined(SSA_DEBUG_VERBOSE)
1811                 if (compileverbose)
1812                         printf(" ... not processed \n");
1813 #endif
1814                         continue;
1815                 }
1816                         
1817                 d = VAR(ls->lifetime[lt_d].v_index);
1818                 s = VAR(ls->lifetime[lt_s].v_index);
1819                 
1820
1821                 if (d->type == -1) {
1822 #if defined(SSA_DEBUG_VERBOSE)
1823                         if (compileverbose)
1824                                 printf("...returning - phi lifetimes where joined\n");
1825 #endif
1826                         return;
1827                 }
1828
1829                 if (s->type == -1) {
1830 #if defined(SSA_DEBUG_VERBOSE)
1831                         if (compileverbose)
1832                                 printf("...returning - phi lifetimes where joined\n");
1833 #endif
1834                         return;
1835                 }
1836
1837                 tmp_i.opc = 0;
1838                 tmp_i.s1.varindex = ls->lifetime[lt_s].v_index;
1839                 tmp_i.dst.varindex = ls->lifetime[lt_d].v_index;
1840                 emit_copy(jd, &tmp_i);
1841
1842 #if defined(SSA_DEBUG_VERBOSE)
1843                 if (compileverbose) {
1844                         if (IS_INMEMORY(d->flags) && IS_INMEMORY(s->flags)) {
1845                                 /* mem -> mem */
1846                                 printf("M%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1847                         }
1848                         else if (IS_INMEMORY(s->flags)) {
1849                                 /* mem -> reg */
1850                                 printf("R%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1851                         }
1852                         else if (IS_INMEMORY(d->flags)) {
1853                                 /* reg -> mem */
1854                                 printf("M%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1855                         }
1856                         else {
1857                                 /* reg -> reg */
1858                                 printf("R%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1859                         }
1860                         printf("\n");
1861                 }
1862 #endif /* defined(SSA_DEBUG_VERBOSE) */
1863         }
1864 }
1865 #endif /* defined(ENABLE_SSA) */
1866
1867
1868
1869 /*
1870  * These are local overrides for various environment variables in Emacs.
1871  * Please do not remove this and leave it at the end of the file, where
1872  * Emacs will automagically detect them.
1873  * ---------------------------------------------------------------------
1874  * Local variables:
1875  * mode: c
1876  * indent-tabs-mode: t
1877  * c-basic-offset: 4
1878  * tab-width: 4
1879  * End:
1880  * vim:noexpandtab:sw=4:ts=4:
1881  */