* src/vm/jit/parse.cpp,
[cacao.git] / src / vm / jit / inline / inline.c
index 40cb9d49372c24ac50201ff7ecb40c8166b2638a..bb056dbe881ce0fa3401a3ae5a9d7a69e8f2247b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/inline/inline.c - method inlining
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
-   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-   J. Wenninger, Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   Changes:
-
-   $Id: inline.c 7486 2007-03-08 13:50:07Z twisti $
-
 */
 
-#include "config.h"
 
-#include "vm/types.h"
+#include "config.h"
 
 #include <assert.h>
+#include <limits.h>
 #include <stdio.h>
 #include <string.h>
-#include <limits.h>
+
+#include "vm/types.h"
 
 #include "mm/memory.h"
+
+#include "threads/lock.hpp"
+#include "threads/mutex.hpp"
+#include "threads/thread.hpp"
+
 #include "toolbox/logging.h"
-#include "vm/builtin.h"
-#include "vm/global.h"
-#include "vmcore/options.h"
-#include "vmcore/statistics.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/parse.h"
-#include "vm/jit/inline/inline.h"
-#include "vm/jit/loop/loop.h"
 
-#include "vmcore/class.h"
-#include "vm/initialize.h"
-#include "vmcore/method.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/show.h"
+#include "vm/jit/builtin.hpp"
+#include "vm/class.hpp"
+#include "vm/global.h"
+#include "vm/initialize.hpp"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/statistics.h"
 
+#include "vm/jit/jit.hpp"
+#include "vm/jit/parse.hpp"
 #include "vm/jit/reg.h"
+#include "vm/jit/show.hpp"
 #include "vm/jit/stack.h"
 
-#include "vm/jit/verify/typecheck.h"
+#include "vm/jit/inline/inline.h"
+#include "vm/jit/loop/loop.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#endif
+#include "vm/jit/verify/typecheck.h"
 
 
 /* algorithm tuning constants *************************************************/
 
 #if !defined(NDEBUG)
 #define INLINE_VERBOSE
-#define DOLOG(code) do{ if (opt_inline_debug_log) { code; } }while(0)
+#define DOLOG(code)       do{ if (opt_TraceInlining >= 2) { code; } }while(0)
+#define DOLOG_SHORT(code) do{ if (opt_TraceInlining >= 1) { code; } }while(0)
 #else
 #define DOLOG(code)
 #endif
@@ -316,7 +309,7 @@ static bool inline_jit_compile_intern(jitdata *jd)
 
        /* call parse pass */
 
-       DOLOG( log_message_class("Parsing ", m->class) );
+       DOLOG( log_message_class("Parsing ", m->clazz) );
        if (!parse(jd)) {
                return false;
        }
@@ -343,10 +336,9 @@ static bool inline_jit_compile(inline_node *iln)
        m = iln->m;
        assert(m);
 
-#if defined(ENABLE_THREADS)
        /* enter a monitor on the method */
-       lock_monitor_enter((java_objectheader *) m);
-#endif
+
+       Mutex_lock(m->mutex);
 
        /* allocate jitdata structure and fill it */
 
@@ -364,7 +356,6 @@ static bool inline_jit_compile(inline_node *iln)
        /* XXX do a pseudo setup */
        jd->cd = DNEW(codegendata);
        MZERO(jd->cd, codegendata, 1);
-       jd->cd->maxstack = m->maxstack;
        jd->cd->method = m;
        /* XXX uses too much dump memory codegen_setup(jd); */
 
@@ -388,10 +379,9 @@ static bool inline_jit_compile(inline_node *iln)
 
 #endif
 
-#if defined(ENABLE_THREADS)
        /* leave the monitor */
-       lock_monitor_exit((java_objectheader *) m );
-#endif
+
+       Mutex_unlock(m->mutex);
 
        return r;
 }
@@ -608,8 +598,8 @@ static s4 *create_variable_map(inline_node *callee)
 {
        s4 *varmap;
        s4 i, t;
-       s4 idx;
-       s4 n_idx;
+       s4 varindex;
+       s4 n_javaindex;
        s4 avail;
        varinfo *v;
 
@@ -623,38 +613,38 @@ static s4 *create_variable_map(inline_node *callee)
 
        for (i=0; i<callee->m->maxlocals; ++i) {
                for (t=0; t<5; ++t) {
-                       idx = callee->jd->local_map[5*i + t];
-                       if (idx == UNUSED)
+                       varindex = callee->jd->local_map[5*i + t];
+                       if (varindex == UNUSED)
                                continue;
 
-                       v = &(callee->jd->var[idx]);
+                       v = &(callee->jd->var[varindex]);
                        assert(v->type == t || v->type == TYPE_VOID); /* XXX stack leaves VOID */
                        v->type = t; /* XXX restore if it is TYPE_VOID */
 
                        avail = callee->ctx->resultjd->local_map[5*(callee->localsoffset + i) + t];
 
                        if (avail == UNUSED) {
-                               avail = inline_new_variable_clone(callee->ctx->resultjd, callee->jd, idx);
+                               avail = inline_new_variable_clone(callee->ctx->resultjd, callee->jd, varindex);
                                callee->ctx->resultjd->local_map[5*(callee->localsoffset + i) + t] = avail;
                        }
 
-                       varmap[idx] = avail;
+                       varmap[varindex] = avail;
                }
        }
 
        /* for synchronized instance methods we need an extra local */
 
        if (callee->synchronize && !(callee->m->flags & ACC_STATIC)) {
-               n_idx = callee->localsoffset - 1;
-               assert(n_idx >= 0);
+               n_javaindex = callee->localsoffset - 1;
+               assert(n_javaindex >= 0);
                assert(callee->parent);
-               assert(n_idx == callee->parent->localsoffset + callee->parent->m->maxlocals);
+               assert(n_javaindex == callee->parent->localsoffset + callee->parent->m->maxlocals);
 
-               avail = callee->ctx->resultjd->local_map[5*n_idx + TYPE_ADR];
+               avail = callee->ctx->resultjd->local_map[5*n_javaindex + TYPE_ADR];
 
                if (avail == UNUSED) {
                        avail = inline_new_variable(callee->ctx->resultjd, TYPE_ADR, 0);
-                       callee->ctx->resultjd->local_map[5*n_idx + TYPE_ADR] = avail;
+                       callee->ctx->resultjd->local_map[5*n_javaindex + TYPE_ADR] = avail;
                }
 
                callee->synclocal = avail;
@@ -672,8 +662,6 @@ static s4 *create_variable_map(inline_node *callee)
 #define INLINE_RETURN_REFERENCE(callee)  \
        ( (basicblock *) (ptrint) (0x333 + (callee)->depth) )
 
-#define RETADDRNR_FROM_BLOCK(bptr)  (UNUSED - 1 - (bptr)->nr)
-
 
 static void inline_add_block_reference(inline_node *iln, basicblock **blockp)
 {
@@ -687,6 +675,7 @@ static void inline_add_block_reference(inline_node *iln, basicblock **blockp)
 }
 
 
+#if 0
 static void inline_add_blocknr_reference(inline_node *iln, s4 *nrp)
 {
        inline_target_ref *ref;
@@ -697,6 +686,7 @@ static void inline_add_blocknr_reference(inline_node *iln, s4 *nrp)
        ref->next = iln->refs;
        iln->refs = ref;
 }
+#endif
 
 
 static void inline_block_translation(inline_node *iln, basicblock *o_bptr, basicblock *n_bptr)
@@ -753,8 +743,8 @@ static void inline_resolve_block_refs(inline_target_ref **refs,
        prev = NULL;
        for (ref = *refs; ref != NULL; ref = ref->next) {
                if (ref->isnumber && !returnref) {
-                       if (*(ref->ref.nr) == RETADDRNR_FROM_BLOCK(o_bptr)) {
-                               *(ref->ref.nr) = RETADDRNR_FROM_BLOCK(n_bptr);
+                       if (*(ref->ref.nr) == JAVALOCAL_FROM_RETADDR(o_bptr->nr)) {
+                               *(ref->ref.nr) = JAVALOCAL_FROM_RETADDR(n_bptr->nr);
                                goto remove_ref;
                        }
                }
@@ -1087,7 +1077,7 @@ static void inline_generate_sync_builtin(inline_node *iln,
                syncvar = inline_new_temp_variable(iln->ctx->resultjd, TYPE_ADR);
 
                n_ins = inline_instruction(iln, ICMD_ACONST, o_iptr);
-               n_ins->sx.val.c.cls = callee->m->class;
+               n_ins->sx.val.c.cls = callee->m->clazz;
                n_ins->dst.varindex = syncvar;
                n_ins->flags.bits |= INS_FLAG_CLASS;
        }
@@ -1118,7 +1108,7 @@ static s4 emit_inlining_prolog(inline_node *iln,
        int type;
        instruction *n_ins;
        insinfo_inline *insinfo;
-       s4 argvar;
+       s4 varindex;
 
        assert(iln && callee && o_iptr);
 
@@ -1175,12 +1165,12 @@ static s4 emit_inlining_prolog(inline_node *iln,
 
                /* translate the argument variable */
 
-               argvar = varmap[o_iptr->sx.s23.s2.args[i]];
-               assert(argvar != UNUSED);
+               varindex = varmap[o_iptr->sx.s23.s2.args[i]];
+               assert(varindex != UNUSED);
 
                /* remove preallocation from the argument variable */
 
-               iln->ctx->resultjd->var[argvar].flags &= ~(PREALLOC | INMEMORY);
+               iln->ctx->resultjd->var[varindex].flags &= ~(PREALLOC | INMEMORY);
 
                /* check the instance slot against NULL */
                /* we don't need that for <init> methods, as the verifier  */
@@ -1190,7 +1180,7 @@ static s4 emit_inlining_prolog(inline_node *iln,
                if (!callee->isstatic && i == 0 && calleem->name != utf_init) {
                        assert(type == TYPE_ADR);
                        n_ins = inline_instruction(iln, ICMD_CHECKNULL, o_iptr);
-                       n_ins->s1.varindex = argvar;
+                       n_ins->s1.varindex = varindex;
                        n_ins->dst.varindex = n_ins->s1.varindex;
                }
 
@@ -1209,7 +1199,7 @@ static s4 emit_inlining_prolog(inline_node *iln,
                                n_ins = inline_instruction(iln, ICMD_ISTORE + type, o_iptr);
                                n_ins->sx.s23.s3.javaindex = UNUSED;
                        }
-                       n_ins->s1.varindex = argvar;
+                       n_ins->s1.varindex = varindex;
                        n_ins->dst.varindex = iln->ctx->resultjd->local_map[5*localindex + type];
                        assert(n_ins->dst.varindex != UNUSED);
                }
@@ -1225,7 +1215,7 @@ static s4 emit_inlining_prolog(inline_node *iln,
                        /* this value is not used, pop it */
 
                        n_ins = inline_instruction(iln, ICMD_POP, o_iptr);
-                       n_ins->s1.varindex = argvar;
+                       n_ins->s1.varindex = varindex;
                }
 
                DOLOG( printf("%sprolog: ", iln->indent);
@@ -1966,7 +1956,7 @@ static void inline_write_exception_handlers(inline_node *master, inline_node *il
                n_ins = master->inlined_iinstr_cursor++;
                if (iln->m->flags & ACC_STATIC) {
                        n_ins->opc = ICMD_ACONST;
-                       n_ins->sx.val.c.cls = iln->m->class;
+                       n_ins->sx.val.c.cls = iln->m->clazz;
                        n_ins->flags.bits = INS_FLAG_CLASS;
                }
                else {
@@ -2025,7 +2015,7 @@ static bool inline_transform(inline_node *iln, jitdata *jd)
 #if defined(INLINE_VERIFY_RESULT)
        static int debug_verify_inlined_code = 1;
 #endif
-#if defined(ENABLE_INLINING_DEBUG)
+#if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
        static int debug_counter = 0;
 #endif
 
@@ -2096,7 +2086,6 @@ static bool inline_transform(inline_node *iln, jitdata *jd)
        /* store created code in jitdata */
 
        n_jd->basicblocks = iln->inlined_basicblocks;
-       n_jd->basicblockindex = NULL;
        n_jd->instructioncount = iln->cumul_instructioncount;
        n_jd->instructions = iln->inlined_iinstr;
 
@@ -2153,7 +2142,7 @@ static bool inline_transform(inline_node *iln, jitdata *jd)
                debug_verify_inlined_code = 0;
                DOLOG( printf("VERIFYING INLINED RESULT...\n"); fflush(stdout); );
                if (!typecheck(n_jd)) {
-                       *exceptionptr = NULL;
+                       exceptions_clear_exception();
                        DOLOG( printf("XXX INLINED RESULT DID NOT PASS VERIFIER XXX\n") );
                        return false;
                }
@@ -2167,15 +2156,12 @@ static bool inline_transform(inline_node *iln, jitdata *jd)
        /* we need bigger free memory stacks (XXX these should not be allocated in reg_setup) */
 
        n_jd->rd->freemem = DMNEW(s4, iln->ctx->maxinoutdepth + 1000) /* XXX max vars/block */;
-#if defined(HAS_4BYTE_STACKSLOT)
-       n_jd->rd->freemem_2 = DMNEW(s4, iln->ctx->maxinoutdepth + 1000) /* XXX max vars/block */;
-#endif
 
 #if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
-       if (   (n_jd->instructioncount >= opt_inline_debug_min_size)
-               && (n_jd->instructioncount <= opt_inline_debug_max_size))
+       if (   (n_jd->instructioncount >= opt_InlineMinSize)
+               && (n_jd->instructioncount <= opt_InlineMaxSize))
        {
-          if (debug_counter <= opt_inline_debug_end_counter)
+          if (debug_counter < opt_InlineCount)
 #endif /* defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG) */
           {
                        /* install the inlined result */
@@ -2189,7 +2175,7 @@ static bool inline_transform(inline_node *iln, jitdata *jd)
 #if !defined(NDEBUG)
                        inline_stat_roots++;
 
-                       DOLOG(
+                       DOLOG_SHORT(
                        printf("==== %d.INLINE ==================================================================\n",
                                debug_counter);
                        printf("\ninline tree:\n");
@@ -3036,6 +3022,7 @@ static void inline_gather_statistics(inline_node *iln)
 
 static void inline_post_process(jitdata *jd)
 {
+       codeinfo   *code;
        basicblock *bptr;
        instruction *iptr;
        instruction *iend;
@@ -3045,6 +3032,10 @@ static void inline_post_process(jitdata *jd)
        methoddesc *md;
        builtintable_entry *bte;
 
+       /* Get required compiler data. */
+
+       code = jd->code;
+
        /* reset the SAVEDVAR flag of all variables */
 
        for (i=0; i<jd->vartop; ++i)
@@ -3082,7 +3073,7 @@ static void inline_post_process(jitdata *jd)
                                        POSTPROCESS_SRCOP(s1);
                                case DF_0_TO_0:
                                        if (icmdt->flags & ICMDTABLE_CALLS) {
-                                               jd->isleafmethod = false;
+                                               code_unflag_leafmethod(code);
                                                MARK_ALL_SAVED;
                                        }
                                        break;
@@ -3094,7 +3085,7 @@ static void inline_post_process(jitdata *jd)
                                        POSTPROCESS_SRCOP(s1);
                                case DF_0_TO_1:
                                        if (icmdt->flags & ICMDTABLE_CALLS) {
-                                               jd->isleafmethod = false;
+                                               code_unflag_leafmethod(code);
                                                MARK_ALL_SAVED;
                                        }
                                case DF_COPY:
@@ -3106,7 +3097,7 @@ static void inline_post_process(jitdata *jd)
                                                POSTPROCESS_SRC(iptr->sx.s23.s2.args[i]);
                                        }
                                        if (icmdt->flags & ICMDTABLE_CALLS) {
-                                               jd->isleafmethod = false;
+                                               code_unflag_leafmethod(code);
                                                MARK_ALL_SAVED;
                                        }
                                        POSTPROCESS_DSTOP(dst);
@@ -3115,7 +3106,7 @@ static void inline_post_process(jitdata *jd)
                                case DF_INVOKE:
                                        INSTRUCTION_GET_METHODDESC(iptr, md);
                post_process_call:
-                                       jd->isleafmethod = false;
+                                       code_unflag_leafmethod(code);
                                        for (i=0; i<md->paramcount; ++i) {
                                                POSTPROCESS_SRC(iptr->sx.s23.s2.args[i]);
                                        }