1 /* src/vm/jit/stacktrace.c - machine independet stacktrace system
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Joseph Wenninger
29 Changes: Christian Thalinger
31 $Id: stacktrace.c 3456 2005-10-19 22:06:23Z twisti $
43 #include "native/native.h"
45 #include "vm/global.h" /* required here for native includes */
46 #include "native/include/java_lang_ClassLoader.h"
48 #include "toolbox/logging.h"
49 #include "vm/builtin.h"
51 #include "vm/exceptions.h"
52 #include "vm/loader.h"
53 #include "vm/options.h"
54 #include "vm/stringlocal.h"
55 #include "vm/tables.h"
56 #include "vm/jit/asmpart.h"
57 #include "vm/jit/codegen.inc.h"
58 #include "vm/jit/methodheader.h"
61 /* lineNumberTableEntry *******************************************************/
63 /* Keep the type of line the same as the pointer type, otherwise we run into */
64 /* alignment troubles (like on MIPS64). */
66 typedef struct lineNumberTableEntry {
69 } lineNumberTableEntry;
72 typedef struct lineNumberTableEntryInlineBegin {
73 /* this should have the same layout and size as the lineNumberTableEntry */
76 } lineNumberTableEntryInlineBegin;
79 typedef bool(*CacaoStackTraceCollector)(void **, stackTraceBuffer*);
81 #define BLOCK_INITIALSIZE 40
82 #define BLOCK_SIZEINCREMENT 40
85 /* global variables ***********************************************************/
87 #if defined(USE_THREADS)
88 #define STACKFRAMEINFO (stackframeinfo **) (&THREADINFO->_stackframeinfo)
90 THREADSPECIFIC stackframeinfo *_no_threads_stackframeinfo = NULL;
92 #define STACKFRAMEINFO (&_no_threads_stackframeinfo)
96 /* stacktrace_create_stackframeinfo ********************************************
98 Creates an stackframe info structure for inline code in the
101 *******************************************************************************/
103 #if defined(ENABLE_INTRP)
104 void stacktrace_create_stackframeinfo(stackframeinfo *sfi, u1 *pv,
105 u1 *sp, functionptr ra)
107 stackframeinfo **psfi;
110 /* get current stackframe info pointer */
112 psfi = STACKFRAMEINFO;
114 /* if we don't have pv handy */
117 pv = (u1 *) (ptrint) codegen_findmethod(ra);
119 /* get methodinfo pointer from data segment */
121 m = *((methodinfo **) (pv + MethodPointer));
123 /* fill new stackframe info structure */
131 /* xpc is the same as ra, but is required in fillInStackTrace */
135 /* store new stackframe info pointer */
139 #endif /* defined(ENABLE_INTRP) */
141 /* stacktrace_create_inline_stackframeinfo *************************************
143 Creates an stackframe info structure for an inline exception stub.
145 *******************************************************************************/
147 void stacktrace_create_inline_stackframeinfo(stackframeinfo *sfi, u1 *pv,
148 u1 *sp, functionptr ra,
151 stackframeinfo **psfi;
153 /* get current stackframe info pointer */
155 psfi = STACKFRAMEINFO;
157 #if defined(ENABLE_INTRP)
159 /* if we don't have pv handy */
162 pv = (u1 *) (ptrint) codegen_findmethod(ra);
167 /* fill new stackframe info structure */
176 /* store new stackframe info pointer */
182 /* stacktrace_create_extern_stackframeinfo *************************************
184 Creates an stackframe info structure for an extern exception
185 (hardware or assembler).
187 *******************************************************************************/
189 void stacktrace_create_extern_stackframeinfo(stackframeinfo *sfi, u1 *pv,
190 u1 *sp, functionptr ra,
193 stackframeinfo **psfi;
194 #if !defined(__I386__) && !defined(__X86_64__)
199 /* get current stackframe info pointer */
201 psfi = STACKFRAMEINFO;
203 /* sometimes we don't have pv handy (e.g. in asmpart.S:
204 L_asm_call_jit_compiler_exception or in the interpreter). */
207 pv = (u1 *) (ptrint) codegen_findmethod(ra);
209 #if defined(ENABLE_INTRP)
210 /* When using the interpreter, we pass RA to the function. */
214 # if defined(__I386__) || defined(__X86_64__)
215 /* On i386 and x86_64 we always have to get the return address
218 framesize = *((u4 *) (pv + FrameSize));
220 ra = md_stacktrace_get_returnaddress(sp, framesize);
222 /* If the method is a non-leaf function, we need to get the return
223 address from the stack. For leaf functions the return address
224 is set correctly. This makes the assembler and the signal
225 handler code simpler. */
227 isleafmethod = *((s4 *) (pv + IsLeaf));
230 framesize = *((u4 *) (pv + FrameSize));
232 ra = md_stacktrace_get_returnaddress(sp, framesize);
235 #if defined(ENABLE_INTRP)
239 /* fill new stackframe info structure */
248 /* store new stackframe info pointer */
254 /* stacktrace_create_native_stackframeinfo *************************************
256 Creates a stackframe info structure for a native stub.
258 *******************************************************************************/
260 void stacktrace_create_native_stackframeinfo(stackframeinfo *sfi, u1 *pv,
261 u1 *sp, functionptr ra)
263 stackframeinfo **psfi;
266 /* get methodinfo pointer from data segment */
268 m = *((methodinfo **) (pv + MethodPointer));
270 /* get current stackframe info pointer */
272 psfi = STACKFRAMEINFO;
274 /* fill new stackframe info structure */
283 /* store new stackframe info pointer */
289 /* stacktrace_remove_stackframeinfo ********************************************
293 *******************************************************************************/
295 void stacktrace_remove_stackframeinfo(stackframeinfo *sfi)
297 stackframeinfo **psfi;
299 /* get current stackframe info pointer */
301 psfi = STACKFRAMEINFO;
303 /* restore the old pointer */
309 /* stacktrace_inline_arithmeticexception ***************************************
311 Creates an ArithemticException for inline stub.
313 *******************************************************************************/
315 java_objectheader *stacktrace_inline_arithmeticexception(u1 *pv, u1 *sp,
320 java_objectheader *o;
322 /* create stackframeinfo */
324 stacktrace_create_inline_stackframeinfo(&sfi, pv, sp, ra, xpc);
326 /* create exception */
328 o = new_arithmeticexception();
330 /* remove stackframeinfo */
332 stacktrace_remove_stackframeinfo(&sfi);
338 /* stacktrace_inline_arrayindexoutofboundsexception ****************************
340 Creates an ArrayIndexOutOfBoundsException for inline stub.
342 *******************************************************************************/
344 java_objectheader *stacktrace_inline_arrayindexoutofboundsexception(u1 *pv,
351 java_objectheader *o;
353 /* create stackframeinfo */
355 stacktrace_create_inline_stackframeinfo(&sfi, pv, sp, ra, xpc);
357 /* create exception */
359 o = new_arrayindexoutofboundsexception(index);
361 /* remove stackframeinfo */
363 stacktrace_remove_stackframeinfo(&sfi);
369 /* stacktrace_inline_arraystoreexception ***************************************
371 Creates an ArrayStoreException for inline stub.
373 *******************************************************************************/
375 java_objectheader *stacktrace_inline_arraystoreexception(u1 *pv, u1 *sp,
380 java_objectheader *o;
382 /* create stackframeinfo */
384 stacktrace_create_inline_stackframeinfo(&sfi, pv, sp, ra, xpc);
386 /* create exception */
388 o = new_arraystoreexception();
390 /* remove stackframeinfo */
392 stacktrace_remove_stackframeinfo(&sfi);
398 /* stacktrace_inline_classcastexception ****************************************
400 Creates an ClassCastException for inline stub.
402 *******************************************************************************/
404 java_objectheader *stacktrace_inline_classcastexception(u1 *pv, u1 *sp,
409 java_objectheader *o;
411 /* create stackframeinfo */
413 stacktrace_create_inline_stackframeinfo(&sfi, pv, sp, ra, xpc);
415 /* create exception */
417 o = new_classcastexception();
419 /* remove stackframeinfo */
421 stacktrace_remove_stackframeinfo(&sfi);
427 /* stacktrace_inline_nullpointerexception **************************************
429 Creates an NullPointerException for inline stub.
431 *******************************************************************************/
433 java_objectheader *stacktrace_inline_nullpointerexception(u1 *pv, u1 *sp,
438 java_objectheader *o;
440 /* create stackframeinfo */
442 stacktrace_create_inline_stackframeinfo(&sfi, pv, sp, ra, xpc);
444 /* create exception */
446 o = new_nullpointerexception();
448 /* remove stackframeinfo */
450 stacktrace_remove_stackframeinfo(&sfi);
456 /* stacktrace_hardware_arithmeticexception *************************************
458 Creates an ArithemticException for inline stub.
460 *******************************************************************************/
462 java_objectheader *stacktrace_hardware_arithmeticexception(u1 *pv, u1 *sp,
467 java_objectheader *o;
469 /* create stackframeinfo */
471 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
473 /* create exception */
475 o = new_arithmeticexception();
477 /* remove stackframeinfo */
479 stacktrace_remove_stackframeinfo(&sfi);
485 /* stacktrace_hardware_nullpointerexception ************************************
487 Creates an NullPointerException for the SIGSEGV signal handler.
489 *******************************************************************************/
491 java_objectheader *stacktrace_hardware_nullpointerexception(u1 *pv, u1 *sp,
496 java_objectheader *o;
498 /* create stackframeinfo */
500 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
502 /* create exception */
504 o = new_nullpointerexception();
506 /* remove stackframeinfo */
508 stacktrace_remove_stackframeinfo(&sfi);
514 /* stacktrace_inline_fillInStackTrace ******************************************
516 Fills in the correct stacktrace into an existing exception object
517 (this one is for inline exception stubs).
519 *******************************************************************************/
521 java_objectheader *stacktrace_inline_fillInStackTrace(u1 *pv, u1 *sp,
526 java_objectheader *o;
529 /* create stackframeinfo */
531 stacktrace_create_inline_stackframeinfo(&sfi, pv, sp, ra, xpc);
537 /* clear exception */
539 *exceptionptr = NULL;
541 /* resolve methodinfo pointer from exception object */
543 m = class_resolvemethod(o->vftbl->class,
544 utf_fillInStackTrace,
545 utf_void__java_lang_Throwable);
549 asm_calljavafunction(m, o, NULL, NULL, NULL);
551 /* remove stackframeinfo */
553 stacktrace_remove_stackframeinfo(&sfi);
559 /* addEntry ********************************************************************
563 *******************************************************************************/
565 static void addEntry(stackTraceBuffer *buffer, methodinfo *method, u2 line)
567 if (buffer->size > buffer->full) {
568 stacktraceelement *tmp = &(buffer->start[buffer->full]);
570 tmp->method = method;
571 tmp->linenumber = line;
572 buffer->full = buffer->full + 1;
575 stacktraceelement *newBuffer;
578 (stacktraceelement *) malloc((buffer->size + BLOCK_SIZEINCREMENT) *
579 sizeof(stacktraceelement));
581 if (newBuffer == 0) {
582 log_text("OOM during stacktrace creation");
586 memcpy(newBuffer, buffer->start, buffer->size * sizeof(stacktraceelement));
587 if (buffer->needsFree)
590 buffer->start = newBuffer;
591 buffer->size = buffer->size + BLOCK_SIZEINCREMENT;
592 buffer->needsFree = 1;
594 addEntry(buffer, method, line);
599 /* stacktrace_fillInStackTrace_methodRecursive *********************************
603 *******************************************************************************/
605 static bool stacktrace_fillInStackTrace_methodRecursive(stackTraceBuffer *buffer,
607 lineNumberTableEntry *lntentry,
612 lineNumberTableEntryInlineBegin *lntinline;
615 /* find the line number for the specified pc (going backwards) */
617 for (; lntsize > 0; lntsize--, lntentry--) {
618 /* did we reach the current line? */
620 if (pc >= lntentry->pc) {
621 /* check for special inline entries */
623 switch (lntentry->line) {
625 /* XXX TWISTI we have to think about this inline stuff again */
627 case -1: /* begin of inlined method */
628 lntinline = (lineNumberTableEntryInlineBegin *) (--lntentry);
630 lntsize--; lntsize--;
631 if (stacktrace_fillInStackTrace_methodRecursive(buffer,
637 addEntry(buffer, m, ilStart->lineNrOuter);
643 case -2: /* end of inlined method */
645 *entriesAhead = ahead;
651 addEntry(buffer, m, lntentry->line);
657 /* check if we are before the actual JIT code */
659 if ((ptrint) pc < (ptrint) m->entrypoint) {
660 dolog("Current pc before start of code: %p < %p", pc, m->entrypoint);
664 /* otherwise just add line 0 */
666 addEntry(buffer, m, 0);
672 /* stacktrace_fillInStackTrace_method ******************************************
676 *******************************************************************************/
678 static void stacktrace_fillInStackTrace_method(stackTraceBuffer *buffer,
679 methodinfo *method, u1 *pv,
682 ptrint lntsize; /* size of line number table */
683 u1 *lntstart; /* start of line number table */
684 lineNumberTableEntry *lntentry; /* points to last entry in the table */
686 /* get size of line number table */
688 lntsize = *((ptrint *) (pv + LineNumberTableSize));
689 lntstart = *((u1 **) (pv + LineNumberTableStart));
691 /* subtract the size of the line number entry of the structure, since the */
692 /* line number table start points to the pc */
694 lntentry = (lineNumberTableEntry *) (lntstart - SIZEOF_VOID_P);
697 /* this happens when an exception is thrown in the native stub */
699 addEntry(buffer, method, 0);
702 if (!stacktrace_fillInStackTrace_methodRecursive(buffer,
707 log_text("Trace point not found in suspected method");
714 /* cacao_stacktrace_fillInStackTrace *******************************************
718 *******************************************************************************/
720 static bool cacao_stacktrace_fillInStackTrace(void **target,
721 CacaoStackTraceCollector coll)
723 stacktraceelement primaryBlock[BLOCK_INITIALSIZE*sizeof(stacktraceelement)];
724 stackTraceBuffer buffer;
734 /* prevent compiler warnings */
740 /* In most cases this should be enough -> one malloc less. I don't think */
741 /* temporary data should be allocated with the GC, only the result. */
743 buffer.needsFree = 0;
744 buffer.start = primaryBlock;
745 buffer.size = BLOCK_INITIALSIZE; /* *sizeof(stacktraceelement); */
748 /* the first element in the stackframe chain must always be a native */
749 /* stackframeinfo (VMThrowable.fillInStackTrace is a native function) */
751 sfi = *STACKFRAMEINFO;
758 #define PRINTMETHODS 0
761 printf("\n\nfillInStackTrace start:\n");
764 /* loop while we have a method pointer (asm_calljavafunction has NULL) or */
765 /* there is a stackframeinfo in the chain */
770 /* m == NULL should only happen for the first time and inline */
771 /* stackframe infos, like from the exception stubs or the patcher */
775 /* for native stub stackframe infos, pv is always NULL */
777 if (sfi->pv == NULL) {
778 /* get methodinfo, sp and ra from the current stackframe info */
781 sp = sfi->sp; /* sp of parent Java function */
785 addEntry(&buffer, m, 0);
788 utf_display_classname(m->class->name);
790 utf_display(m->name);
791 utf_display(m->descriptor);
792 printf(": native stub\n");
794 /* this is an native stub stackframe info, so we can get the */
795 /* parent pv from the return address (ICMD_INVOKE*) */
797 pv = (u1 *) (ptrint) codegen_findmethod(ra);
799 /* get methodinfo pointer from parent data segment */
801 m = *((methodinfo **) (pv + MethodPointer));
804 /* Inline stackframe infos are special: they have a xpc of */
805 /* the actual exception position and the return address saved */
806 /* since an inline stackframe info can also be in a leaf */
807 /* method (no return address saved on stack!!!). */
808 /* ATTENTION: This one is also for hardware exceptions!!! */
810 /* get methodinfo, sp and ra from the current stackframe info */
812 m = sfi->method; /* m == NULL */
813 pv = sfi->pv; /* pv of parent Java function */
814 sp = sfi->sp; /* sp of parent Java function */
815 ra = sfi->ra; /* ra of parent Java function */
816 xpc = sfi->xpc; /* actual exception position */
819 printf("NULL: inline stub\n");
822 /* get methodinfo from current Java method */
824 m = *((methodinfo **) (pv + MethodPointer));
826 /* if m == NULL, this is a asm_calljavafunction call */
830 utf_display_classname(m->class->name);
832 utf_display(m->name);
833 utf_display(m->descriptor);
834 printf(": inline stub parent\n");
837 #if defined(ENABLE_INTRP)
841 /* add it to the stacktrace */
843 stacktrace_fillInStackTrace_method(&buffer, m, pv,
844 (u1 *) ((ptrint) xpc));
846 /* get the current stack frame size */
848 framesize = *((u4 *) (pv + FrameSize));
850 /* set stack pointer to stackframe of parent Java */
851 /* function of the current Java function */
853 #if defined(__I386__) || defined (__X86_64__)
854 sp += framesize + SIZEOF_VOID_P;
859 /* get data segment and methodinfo pointer from parent */
862 pv = (u1 *) (ptrint) codegen_findmethod(ra);
863 m = *((methodinfo **) (pv + MethodPointer));
865 #if defined(ENABLE_INTRP)
871 /* get previous stackframeinfo in the chain */
877 utf_display_classname(m->class->name);
879 utf_display(m->name);
880 utf_display(m->descriptor);
884 /* JIT method found, add it to the stacktrace (we subtract 1 from */
885 /* the return address since it points the the instruction after */
888 stacktrace_fillInStackTrace_method(&buffer, m, pv,
889 (u1 *) ((ptrint) ra) - 1);
891 /* get the current stack frame size */
893 framesize = *((u4 *) (pv + FrameSize));
895 /* get return address of current stack frame */
897 ra = md_stacktrace_get_returnaddress(sp, framesize);
899 /* get data segment and methodinfo pointer from parent method */
901 pv = (u1 *) (ptrint) codegen_findmethod(ra);
902 m = *((methodinfo **) (pv + MethodPointer));
906 #if defined(ENABLE_INTRP)
908 sp = *(u1 **)(sp - framesize);
912 #if defined(__I386__) || defined (__X86_64__)
913 sp += framesize + SIZEOF_VOID_P;
922 result = coll(target, &buffer);
924 if (buffer.needsFree)
931 /* stackTraceCollector *********************************************************
935 *******************************************************************************/
937 static bool stackTraceCollector(void **target, stackTraceBuffer *buffer)
939 stackTraceBuffer *dest;
941 dest = *target = heap_allocate(sizeof(stackTraceBuffer) + buffer->full * sizeof(stacktraceelement), true, 0);
946 memcpy(*target, buffer, sizeof(stackTraceBuffer));
947 memcpy(dest + 1, buffer->start, buffer->full * sizeof(stacktraceelement));
950 dest->size = dest->full;
951 dest->start = (stacktraceelement *) (dest + 1);
957 bool cacao_stacktrace_NormalTrace(void **target)
959 return cacao_stacktrace_fillInStackTrace(target, &stackTraceCollector);
964 static bool classContextCollector(void **target, stackTraceBuffer *buffer)
966 java_objectarray *oa;
967 stacktraceelement *current;
968 stacktraceelement *start;
976 for (i = 0; i < size; i++)
977 if (buffer->start[i].method != 0)
980 start = buffer->start;
984 if (targetSize > 0) {
986 (start->method->class == class_java_lang_SecurityManager)) {
992 oa = builtin_anewarray(targetSize, class_java_lang_Class);
997 for(i = 0, current = start; i < targetSize; i++, current++) {
998 if (!current->method) {
1003 use_class_as_object(current->method->class);
1005 oa->data[i] = (java_objectheader *) current->method->class;
1015 java_objectarray *cacao_createClassContextArray(void)
1017 java_objectarray *array = NULL;
1019 if (!cacao_stacktrace_fillInStackTrace((void **) &array,
1020 &classContextCollector))
1027 /* stacktrace_classLoaderCollector *********************************************
1031 *******************************************************************************/
1033 static bool stacktrace_classLoaderCollector(void **target,
1034 stackTraceBuffer *buffer)
1036 stacktraceelement *current;
1037 stacktraceelement *start;
1042 size = buffer->full;
1043 start = &(buffer->start[0]);
1045 for(i = 0, current = start; i < size; i++, current++) {
1046 m = current->method;
1051 if (m->class == class_java_security_PrivilegedAction) {
1056 if (m->class->classloader) {
1057 *target = (java_lang_ClassLoader *) m->class->classloader;
1068 /* cacao_currentClassLoader ****************************************************
1072 *******************************************************************************/
1074 java_objectheader *cacao_currentClassLoader(void)
1076 java_objectheader *header = NULL;
1078 if (!cacao_stacktrace_fillInStackTrace((void**)&header,
1079 &stacktrace_classLoaderCollector))
1086 static bool callingMethodCollector(void **target, stackTraceBuffer *buffer)
1088 *target = buffer->start[1].method;
1094 methodinfo *cacao_callingMethod(void)
1098 if (!cacao_stacktrace_fillInStackTrace((void **) &method,
1099 &callingMethodCollector))
1106 static bool getStackCollector(void **target, stackTraceBuffer *buffer)
1108 java_objectarray *oa;
1109 java_objectarray *classes;
1110 java_objectarray *methodnames;
1111 java_lang_String *str;
1113 stacktraceelement *current;
1116 /* *result = (java_objectarray **) target; */
1118 size = buffer->full;
1120 oa = builtin_anewarray(2, arrayclass_java_lang_Object);
1125 classes = builtin_anewarray(size, class_java_lang_Class);
1130 methodnames = builtin_anewarray(size, class_java_lang_String);
1135 oa->data[0] = (java_objectheader *) classes;
1136 oa->data[1] = (java_objectheader *) methodnames;
1138 for (i = 0, current = &(buffer->start[0]); i < size; i++, current++) {
1139 c = current->method->class;
1141 use_class_as_object(c);
1143 classes->data[i] = (java_objectheader *) c;
1144 str = javastring_new(current->method->name);
1149 methodnames->data[i] = (java_objectheader *) str;
1158 java_objectarray *cacao_getStackForVMAccessController(void)
1160 java_objectarray *result = NULL;
1162 if (!cacao_stacktrace_fillInStackTrace((void **) &result,
1163 &getStackCollector))
1170 /* stacktrace_dump_trace *******************************************************
1172 This method is call from signal_handler_sigusr1 to dump the
1173 stacktrace of the current thread to stdout.
1175 *******************************************************************************/
1177 void stacktrace_dump_trace(void)
1179 stackTraceBuffer *buffer;
1182 /* get thread stackframeinfo */
1184 info = &THREADINFO->_stackframeinfo;
1186 /* fill stackframeinfo structure */
1188 tmp.oldThreadspecificHeadValue = *info;
1189 tmp.addressOfThreadspecificHead = info;
1192 tmp.ra = _mc->gregs[REG_RIP];
1197 /* generate stacktrace */
1199 cacao_stacktrace_NormalTrace((void **) &buffer);
1201 /* print stacktrace */
1204 stacktrace_print_trace(buffer);
1208 /* stacktrace_print_trace ******************************************************
1210 Print the stacktrace of a given stackTraceBuffer with CACAO intern
1211 methods (no Java help). This method is used by
1212 stacktrace_dump_trace and builtin_trace_exception.
1214 *******************************************************************************/
1216 void stacktrace_print_trace(stackTraceBuffer *stb)
1218 stacktraceelement *ste;
1224 for (i = 0; i < stb->size; i++, ste++) {
1228 utf_display_classname(m->class->name);
1230 utf_display(m->name);
1231 utf_display(m->descriptor);
1233 if (m->flags & ACC_NATIVE) {
1234 printf("(Native Method)\n");
1238 utf_display(m->class->sourcefile);
1239 printf(":%d)\n", (u4) ste->linenumber);
1243 /* just to be sure */
1250 * These are local overrides for various environment variables in Emacs.
1251 * Please do not remove this and leave it at the end of the file, where
1252 * Emacs will automagically detect them.
1253 * ---------------------------------------------------------------------
1256 * indent-tabs-mode: t