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