LCOV - code coverage report
Current view: top level - vm/jit - trace.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 142 0.0 %
Date: 2015-06-10 18:10:59 Functions: 0 5 0.0 %

          Line data    Source code
       1             : /* src/vm/jit/trace.cpp - Functions for tracing from java code.
       2             : 
       3             :    Copyright (C) 1996-2013
       4             :    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
       5             : 
       6             :    This file is part of CACAO.
       7             : 
       8             :    This program is free software; you can redistribute it and/or
       9             :    modify it under the terms of the GNU General Public License as
      10             :    published by the Free Software Foundation; either version 2, or (at
      11             :    your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful, but
      14             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :    General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program; if not, write to the Free Software
      20             :    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
      21             :    02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : #include "vm/jit/trace.hpp"
      26             : #include <cstdio>
      27             : #include "config.h"                     // for ENABLE_DEBUG_FILTER, etc
      28             : #include "md-abi.hpp"
      29             : #include "native/llni.hpp"
      30             : #include "threads/thread.hpp"           // for threadobject
      31             : #include "toolbox/logging.hpp"
      32             : #include "toolbox/buffer.hpp"           // for Buffer
      33             : #include "vm/array.hpp"
      34             : #include "vm/class.hpp"                 // for classinfo
      35             : #include "vm/descriptor.hpp"            // for methoddesc, typedesc
      36             : #include "vm/global.hpp"                // for imm_union, java_object_t, etc
      37             : #include "vm/globals.hpp"               // for class_java_lang_Class, etc
      38             : #include "vm/hook.hpp"                  // for method_enter, method_exit
      39             : #include "vm/javaobjects.hpp"           // for java_lang_Throwable, etc
      40             : #include "vm/jit/argument.hpp"          // for argument_jitarray_load, etc
      41             : #include "vm/jit/code.hpp"              // for codeinfo
      42             : #include "vm/jit/codegen-common.hpp"
      43             : #include "vm/jit/show.hpp"
      44             : #include "vm/method.hpp"                // for methodinfo, etc
      45             : #include "vm/options.hpp"               // for opt_TraceBuiltinCalls, etc
      46             : #include "vm/string.hpp"                // for JavaString
      47             : #include "vm/types.hpp"                 // for s4
      48             : #include "vm/utf8.hpp"                  // for Utf8String
      49             : #include "vm/vftbl.hpp"                 // for vftbl_t
      50             : 
      51             : #if !defined(NDEBUG)
      52             : 
      53             : /* trace_java_call_print_argument **********************************************
      54             : 
      55             :    XXX: Document me!
      56             : 
      57             : *******************************************************************************/
      58             : 
      59           0 : static void trace_java_call_print_argument(Buffer<>& logtext, methodinfo *m, typedesc *paramtype, imm_union imu)
      60             : {
      61             :         java_object_t *o;
      62             :         classinfo     *c;
      63           0 :         Utf8String     u;
      64             : 
      65           0 :         switch (paramtype->type) {
      66             :         case TYPE_INT:
      67           0 :                 logtext.write_dec(imu.i).write(" (").write_hex(imu.i).write(')');
      68           0 :                 break;
      69             :         case TYPE_LNG:
      70           0 :                 logtext.write_dec(imu.l).write(" (").write_hex(imu.l).write(')');
      71           0 :                 break;
      72             :         case TYPE_FLT:
      73           0 :                 logtext.write_dec(imu.f).write(" (").write_hex(imu.f).write(')');
      74           0 :                 break;
      75             :         case TYPE_DBL:
      76           0 :                 logtext.write_dec(imu.d).write(" (").write_hex(imu.d).write(')');
      77           0 :                 break;
      78             : 
      79             :         case TYPE_ADR:
      80           0 :                 logtext.write_ptr(imu.a);
      81             : 
      82             :                 /* Workaround for sun.misc.Unsafe methods.  In the future
      83             :                    (exact GC) we should check if the address is on the GC
      84             :                    heap. */
      85             : 
      86           0 :                 if ((m->clazz       != NULL) &&
      87             :                         (m->clazz->name == Utf8String::from_utf8("sun/misc/Unsafe")))
      88           0 :                         break;
      89             : 
      90             :                 /* Cast to java.lang.Object. */
      91             : 
      92           0 :                 o = (java_handle_t*) (uintptr_t) imu.l;
      93             : 
      94             :                 /* Check return argument for java.lang.Class or
      95             :                    java.lang.String. */
      96             : 
      97           0 :                 if (o != NULL) {
      98           0 :                         if (o->vftbl->clazz == class_java_lang_String) {
      99             :                                 /* convert java.lang.String object to utf8 string and strcat it to the logtext */
     100             : 
     101             :                                 logtext.write(" (String = \"")
     102             :                                        .write(o)
     103           0 :                                        .write("\")");
     104             :                         }
     105             :                         else {
     106           0 :                                 if (o->vftbl->clazz == class_java_lang_Class) {
     107             :                                         /* if the object returned is a java.lang.Class
     108             :                                            cast it to classinfo structure and get the name
     109             :                                            of the class */
     110             : 
     111           0 :                                         c = (classinfo *) o;
     112             : 
     113           0 :                                         u = c->name;
     114             :                                 }
     115             :                                 else {
     116             :                                         /* if the object returned is not a java.lang.String or
     117             :                                            a java.lang.Class just print the name of the class */
     118             : 
     119           0 :                                         u = o->vftbl->clazz->name;
     120             :                                 }
     121             : 
     122             :                                 /* strcat to the logtext */
     123             : 
     124             :                                 logtext.write(" (Class = \"")
     125             :                                        .write_slash_to_dot(u)
     126           0 :                                        .write("\")");
     127             :                         }
     128             :                 }
     129             :                 default:
     130           0 :                         assert(false);
     131             :                         break;
     132             :         }
     133           0 : }
     134             : 
     135             : /* trace_java_call_enter ******************************************************
     136             :  
     137             :    Traces an entry into a java method.
     138             : 
     139             :    arg_regs: Array containing all argument registers as int64_t values in
     140             :    the same order as listed in m->methoddesc. The array is usually allocated
     141             :    on the stack and used for restoring the argument registers later.
     142             : 
     143             :    stack: Pointer to first on stack argument in the same format passed to 
     144             :    asm_vm_call_method.
     145             : 
     146             : *******************************************************************************/
     147             : 
     148           0 : void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
     149             : {
     150             :         methoddesc *md;
     151             :         imm_union   arg;
     152             :         s4          i;
     153             : 
     154             :         /* We can only trace "slow" builtin functions (those with a stub)
     155             :          * here, because the argument passing of "fast" ones happens via
     156             :          * the native ABI and does not fit these functions. */
     157             : 
     158           0 :         if (method_is_builtin(m)) {
     159           0 :                 if (!opt_TraceBuiltinCalls)
     160           0 :                         return;
     161             :         }
     162             :         else {
     163           0 :                 if (!opt_TraceJavaCalls)
     164           0 :                         return;
     165             : #if defined(ENABLE_DEBUG_FILTER)
     166           0 :                 if (!show_filters_test_verbosecall_enter(m))
     167           0 :                         return;
     168             : #endif
     169             :         }
     170             : 
     171             :         // Hook point on entry into Java method.
     172           0 :         Hook::method_enter(m);
     173             : 
     174           0 :         md = m->parseddesc;
     175             : 
     176             :         // Create new dump memory area.
     177             : //      DumpMemoryArea dma;
     178             : 
     179           0 :         Buffer<> logtext(128);
     180             : 
     181           0 :         TRACEJAVACALLCOUNT++;
     182             : 
     183           0 :         logtext.writef("%10d ", TRACEJAVACALLCOUNT);
     184           0 :         logtext.writef("-%d-", TRACEJAVACALLINDENT);
     185             : 
     186           0 :         for (i = 0; i < TRACEJAVACALLINDENT; i++)
     187           0 :                 logtext.write("\t");
     188             : 
     189           0 :         logtext.write("called: ");
     190             : 
     191           0 :         if (m->clazz != NULL)
     192           0 :                 logtext.write_slash_to_dot(m->clazz->name);
     193             :         else
     194           0 :                 logtext.write("NULL");
     195           0 :         logtext.write(".");
     196           0 :         logtext.write(m->name);
     197           0 :         logtext.write(m->descriptor);
     198             : 
     199           0 :         if (m->flags & ACC_PUBLIC)         logtext.write(" PUBLIC");
     200           0 :         if (m->flags & ACC_PRIVATE)        logtext.write(" PRIVATE");
     201           0 :         if (m->flags & ACC_PROTECTED)      logtext.write(" PROTECTED");
     202           0 :         if (m->flags & ACC_STATIC)         logtext.write(" STATIC");
     203           0 :         if (m->flags & ACC_FINAL)          logtext.write(" FINAL");
     204           0 :         if (m->flags & ACC_SYNCHRONIZED)   logtext.write(" SYNCHRONIZED");
     205           0 :         if (m->flags & ACC_VOLATILE)       logtext.write(" VOLATILE");
     206           0 :         if (m->flags & ACC_TRANSIENT)      logtext.write(" TRANSIENT");
     207           0 :         if (m->flags & ACC_NATIVE)         logtext.write(" NATIVE");
     208           0 :         if (m->flags & ACC_INTERFACE)      logtext.write(" INTERFACE");
     209           0 :         if (m->flags & ACC_ABSTRACT)       logtext.write(" ABSTRACT");
     210             : 
     211           0 :         logtext.write("(");
     212             : 
     213           0 :         for (i = 0; i < md->paramcount; ++i) {
     214           0 :                 arg = argument_jitarray_load(md, i, arg_regs, stack);
     215           0 :                 trace_java_call_print_argument(logtext, m, &md->paramtypes[i], arg);
     216             :                 
     217           0 :                 if (i != (md->paramcount - 1)) {
     218           0 :                         logtext.write(", ");
     219             :                 }
     220             :         }
     221             : 
     222           0 :         logtext.write(")");
     223             : 
     224           0 :         log_text(logtext.c_str());
     225             : 
     226           0 :         TRACEJAVACALLINDENT++;
     227             : }
     228             : 
     229             : /* trace_java_call_exit ********************************************************
     230             : 
     231             :    Traces an exit form a java method.
     232             : 
     233             :    return_regs: Array of size 1 containing return register.
     234             :    The array is usually allocated on the stack and used for restoring the
     235             :    registers later.
     236             : 
     237             : *******************************************************************************/
     238             : 
     239           0 : void trace_java_call_exit(methodinfo *m, uint64_t *return_regs)
     240             : {
     241             :         methoddesc *md;
     242             :         s4          i;
     243             :         imm_union   val;
     244             : 
     245             :         /* We can only trace "slow" builtin functions (those with a stub)
     246             :          * here, because the argument passing of "fast" ones happens via
     247             :          * the native ABI and does not fit these functions. */
     248             : 
     249           0 :         if (method_is_builtin(m)) {
     250           0 :                 if (!opt_TraceBuiltinCalls)
     251           0 :                         return;
     252             :         }
     253             :         else {
     254           0 :                 if (!opt_TraceJavaCalls)
     255           0 :                         return;
     256             : #if defined(ENABLE_DEBUG_FILTER)
     257           0 :                 if (!show_filters_test_verbosecall_exit(m))
     258           0 :                         return;
     259             : #endif
     260             :         }
     261             : 
     262             :         // Hook point upon exit from Java method.
     263           0 :         Hook::method_exit(m);
     264             : 
     265           0 :         md = m->parseddesc;
     266             : 
     267             :         /* outdent the log message */
     268             : 
     269           0 :         if (TRACEJAVACALLINDENT)
     270           0 :                 TRACEJAVACALLINDENT--;
     271             :         else
     272           0 :                 log_text("trace_java_call_exit: WARNING: unmatched unindent");
     273             : 
     274             :         // Create new dump memory area.
     275             : //      DumpMemoryArea dma;
     276             : 
     277           0 :         Buffer<> logtext(128);
     278             : 
     279             :         /* generate the message */
     280             : 
     281           0 :         logtext.write("           ");
     282           0 :         logtext.writef("-%d-", TRACEJAVACALLINDENT);
     283             : 
     284           0 :         for (i = 0; i < TRACEJAVACALLINDENT; i++)
     285           0 :                 logtext.write("\t");
     286             : 
     287           0 :         logtext.write("finished: ");
     288           0 :         if (m->clazz != NULL)
     289           0 :                 logtext.write_slash_to_dot(m->clazz->name);
     290             :         else
     291           0 :                 logtext.write("NULL");
     292           0 :         logtext.write(".");
     293           0 :         logtext.write(m->name);
     294           0 :         logtext.write(m->descriptor);
     295             : 
     296           0 :         if (!IS_VOID_TYPE(md->returntype.type)) {
     297           0 :                 logtext.write("->");
     298           0 :                 val = argument_jitreturn_load(md, return_regs);
     299             : 
     300           0 :                 trace_java_call_print_argument(logtext, m, &md->returntype, val);
     301             :         }
     302             : 
     303           0 :         log_text(logtext.c_str());
     304             : }
     305             : 
     306             : 
     307             : /* trace_exception *************************************************************
     308             : 
     309             :    Traces an exception which is handled by exceptions_handle_exception.
     310             : 
     311             : *******************************************************************************/
     312             : 
     313           0 : void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
     314             : {
     315             :         codeinfo *code;
     316             : 
     317             :         // Create new dump memory area.
     318             : //      DumpMemoryArea dma;
     319             : 
     320           0 :         Buffer<> logtext(128);
     321             : 
     322           0 :         if (xptr) {
     323           0 :                 logtext.write("Exception ");
     324           0 :                 logtext.write_slash_to_dot(xptr->vftbl->clazz->name);
     325             : 
     326             :         } else {
     327           0 :                 logtext.write("Some Throwable");
     328             :         }
     329             : 
     330           0 :         logtext.write(" thrown in ");
     331             : 
     332           0 :         if (m) {
     333           0 :                 logtext.write_slash_to_dot(m->clazz->name);
     334           0 :                 logtext.write(".");
     335           0 :                 logtext.write(m->name);
     336           0 :                 logtext.write(m->descriptor);
     337             : 
     338           0 :                 if (m->flags & ACC_SYNCHRONIZED)
     339           0 :                         logtext.write("(SYNC");
     340             :                 else
     341           0 :                         logtext.write("(NOSYNC");
     342             : 
     343           0 :                 if (m->flags & ACC_NATIVE) {
     344           0 :                         logtext.write(",NATIVE");
     345             : 
     346           0 :                         code = m->code;
     347             : 
     348             :                         logtext.write(")(").write_ptr(code->entrypoint)
     349           0 :                                .write(") at position ").write_ptr(pos);
     350             :                 } else {
     351             : 
     352             :                         /* XXX preliminary: This should get the actual codeinfo */
     353             :                         /* in which the exception happened.                     */
     354           0 :                         code = m->code;
     355             :                         
     356             :                         logtext.write(")(").write_ptr(code->entrypoint)
     357           0 :                                .write(") at position ").write_ptr(pos);
     358             : 
     359           0 :                         if (m->clazz->sourcefile == NULL)
     360           0 :                                 logtext.write("<NO CLASSFILE INFORMATION>");
     361             :                         else
     362           0 :                                 logtext.write(m->clazz->sourcefile);
     363             : 
     364           0 :                         logtext.writef(":%d)", 0);
     365             :                 }
     366             : 
     367             :         } else
     368           0 :                 logtext.write("call_java_method");
     369             : 
     370           0 :         log_text(logtext.c_str());
     371           0 : }
     372             : 
     373             : 
     374             : /* trace_exception_builtin *****************************************************
     375             : 
     376             :    Traces an exception which is thrown by builtin_throw_exception.
     377             : 
     378             : *******************************************************************************/
     379             : 
     380           0 : void trace_exception_builtin(java_handle_t* h)
     381             : {
     382           0 :         java_lang_Throwable jlt(h);
     383             : 
     384             :         // Get detail message.
     385           0 :         java_handle_t* s = NULL;
     386             : 
     387           0 :         if (jlt.get_handle() != NULL)
     388           0 :                 s = jlt.get_detailMessage();
     389             : 
     390           0 :         java_lang_String jls(s);
     391             : 
     392             :         // Create new dump memory area.
     393             : //      DumpMemoryArea dma;
     394             : 
     395           0 :         Buffer<> logtext(128);
     396             : 
     397           0 :         logtext.write("Builtin exception thrown: ");
     398             : 
     399           0 :         if (jlt.get_handle()) {
     400           0 :                 logtext.write_slash_to_dot(jlt.get_vftbl()->clazz->name);
     401             : 
     402           0 :                 if (s) {
     403           0 :                         logtext.write(": ");
     404           0 :                         logtext.write(JavaString(jls.get_handle()));
     405             :                 }
     406             : 
     407             :         } else {
     408           0 :                 logtext.write("(nil)");
     409             :         }
     410             : 
     411           0 :         log_text(logtext.c_str());
     412           0 : }
     413             : 
     414             : #endif /* !defined(NDEBUG) */
     415             : 
     416             : 
     417             : /*
     418             :  * These are local overrides for various environment variables in Emacs.
     419             :  * Please do not remove this and leave it at the end of the file, where
     420             :  * Emacs will automagically detect them.
     421             :  * ---------------------------------------------------------------------
     422             :  * Local variables:
     423             :  * mode: c++
     424             :  * indent-tabs-mode: t
     425             :  * c-basic-offset: 4
     426             :  * tab-width: 4
     427             :  * End:
     428             :  * vim:noexpandtab:sw=4:ts=4:
     429             :  */

Generated by: LCOV version 1.11