1 /* src/vm/jit/stacktrace.c - machine independent stacktrace system
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
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., 51 Franklin Street, Fifth Floor, Boston, MA
36 #include "mm/gc-common.h"
37 #include "mm/memory.h"
39 #include "vm/jit/stacktrace.h"
41 #include "vm/global.h" /* required here for native includes */
42 #include "native/jni.h"
43 #include "native/llni.h"
44 #include "native/include/java_lang_Throwable.h"
46 #if defined(WITH_CLASSPATH_GNU)
47 # include "native/include/java_lang_VMThrowable.h"
50 #if defined(ENABLE_THREADS)
51 # include "threads/native/threads.h"
53 # include "threads/none/threads.h"
56 #include "toolbox/logging.h"
58 #include "vm/builtin.h"
59 #include "vm/cycles-stats.h"
60 #include "vm/exceptions.h"
61 #include "vm/stringlocal.h"
64 #include "vm/jit/asmpart.h"
65 #include "vm/jit/codegen-common.h"
66 #include "vm/jit/methodheader.h"
68 #include "vmcore/class.h"
69 #include "vmcore/loader.h"
70 #include "vmcore/options.h"
73 /* global variables ***********************************************************/
74 #if !defined(ENABLE_THREADS)
75 stackframeinfo *_no_threads_stackframeinfo = NULL;
78 CYCLES_STATS_DECLARE(stacktrace_overhead ,100,1)
79 CYCLES_STATS_DECLARE(stacktrace_fillInStackTrace,40,5000)
80 CYCLES_STATS_DECLARE(stacktrace_getClassContext ,40,5000)
81 CYCLES_STATS_DECLARE(stacktrace_getCurrentClass ,40,5000)
82 CYCLES_STATS_DECLARE(stacktrace_getStack ,40,10000)
85 /* stacktrace_create_stackframeinfo ********************************************
87 Creates an stackframe info structure for inline code in the
90 *******************************************************************************/
92 #if defined(ENABLE_INTRP)
93 void stacktrace_create_stackframeinfo(stackframeinfo *sfi, u1 *pv, u1 *sp,
96 stackframeinfo **psfi;
100 /* get current stackframe info pointer */
102 psfi = &STACKFRAMEINFO;
104 /* if we don't have pv handy */
107 #if defined(ENABLE_INTRP)
109 pv = codegen_get_pv_from_pc(ra);
113 #if defined(ENABLE_JIT)
114 pv = md_codegen_get_pv_from_pc(ra);
119 /* get codeinfo pointer from data segment */
121 code = *((codeinfo **) (pv + CodeinfoPointer));
123 /* For asm_vm_call_method the codeinfo pointer is NULL. */
125 m = (code == NULL) ? NULL : code->m;
127 /* fill new stackframe info structure */
135 /* xpc is the same as ra, but is required in stacktrace_create */
139 /* store new stackframe info pointer */
143 #endif /* defined(ENABLE_INTRP) */
146 /* stacktrace_create_extern_stackframeinfo *************************************
148 Creates an stackframe info structure for an extern exception
149 (hardware or assembler).
151 *******************************************************************************/
153 void stacktrace_create_extern_stackframeinfo(stackframeinfo *sfi, u1 *pv,
154 u1 *sp, u1 *ra, u1 *xpc)
156 stackframeinfo **psfi;
157 #if !defined(__I386__) && !defined(__X86_64__) && !defined(__S390__) && !defined(__M68K__)
160 #if defined(ENABLE_JIT)
164 /* get current stackframe info pointer */
166 psfi = &STACKFRAMEINFO;
168 /* sometimes we don't have pv handy (e.g. in asmpart.S:
169 L_asm_call_jit_compiler_exception or in the interpreter). */
172 #if defined(ENABLE_INTRP)
174 pv = codegen_get_pv_from_pc(ra);
178 #if defined(ENABLE_JIT)
179 # if defined(__SPARC_64__)
180 pv = md_get_pv_from_stackframe(sp);
182 pv = md_codegen_get_pv_from_pc(ra);
188 #if defined(ENABLE_JIT)
189 # if defined(ENABLE_INTRP)
190 /* When using the interpreter, we pass RA to the function. */
194 # if defined(__I386__) || defined(__X86_64__) || defined(__S390__) || defined(__M68K__)
195 /* On i386 and x86_64 we always have to get the return address
197 /* m68k has return address on stack always */
198 /* On S390 we use REG_RA as REG_ITMP3, so we have always to get
199 the RA from stack. */
201 framesize = *((u4 *) (pv + FrameSize));
203 ra = md_stacktrace_get_returnaddress(sp, framesize);
205 /* If the method is a non-leaf function, we need to get the return
206 address from the stack. For leaf functions the return address
207 is set correctly. This makes the assembler and the signal
208 handler code simpler. */
210 isleafmethod = *((s4 *) (pv + IsLeaf));
213 framesize = *((u4 *) (pv + FrameSize));
215 ra = md_stacktrace_get_returnaddress(sp, framesize);
218 # if defined(ENABLE_INTRP)
221 #endif /* defined(ENABLE_JIT) */
223 /* fill new stackframe info structure */
232 /* store new stackframe info pointer */
236 /* set the native world flag for the current thread */
237 /* ATTENTION: This flag tells the GC how to treat this thread in case of
238 a collection. Set this flag _after_ a valid stackframe info was set. */
240 THREAD_NATIVEWORLD_ENTER;
244 /* stacktrace_create_native_stackframeinfo *************************************
246 Creates a stackframe info structure for a native stub.
248 *******************************************************************************/
250 void stacktrace_create_native_stackframeinfo(stackframeinfo *sfi, u1 *pv,
253 stackframeinfo **psfi;
257 /* get codeinfo pointer from data segment */
259 code = *((codeinfo **) (pv + CodeinfoPointer));
261 /* For asm_vm_call_method the codeinfo pointer is NULL. */
263 m = (code == NULL) ? NULL : code->m;
265 /* get current stackframe info pointer */
267 psfi = &STACKFRAMEINFO;
269 /* fill new stackframe info structure */
278 /* store new stackframe info pointer */
282 /* set the native world flag for the current thread */
283 /* ATTENTION: This flag tells the GC how to treat this thread in case of
284 a collection. Set this flag _after_ a valid stackframe info was set. */
286 THREAD_NATIVEWORLD_ENTER;
290 /* stacktrace_remove_stackframeinfo ********************************************
292 Remove the topmost stackframeinfo in the current thread.
294 *******************************************************************************/
296 void stacktrace_remove_stackframeinfo(stackframeinfo *sfi)
298 stackframeinfo **psfi;
300 /* clear the native world flag for the current thread */
301 /* ATTENTION: Clear this flag _before_ removing the stackframe info */
303 THREAD_NATIVEWORLD_EXIT;
305 /* get current stackframe info pointer */
307 psfi = &STACKFRAMEINFO;
309 /* restore the old pointer */
315 /* stacktrace_add_entry ********************************************************
317 Adds a new entry to the stacktrace buffer.
319 *******************************************************************************/
321 static stacktracebuffer *stacktrace_add_entry(stacktracebuffer *stb,
322 methodinfo *m, u2 line)
324 stacktrace_entry *ste;
328 /* check if we already reached the buffer capacity */
330 if (stb->used >= stb->capacity) {
331 /* calculate size of stacktracebuffer */
333 stb_size_old = sizeof(stacktracebuffer) +
334 sizeof(stacktrace_entry) * stb->capacity -
335 sizeof(stacktrace_entry) * STACKTRACE_CAPACITY_DEFAULT;
337 stb_size_new = stb_size_old +
338 sizeof(stacktrace_entry) * STACKTRACE_CAPACITY_INCREMENT;
340 /* reallocate new memory */
342 stb = DMREALLOC(stb, u1, stb_size_old, stb_size_new);
344 /* set new buffer capacity */
346 stb->capacity = stb->capacity + STACKTRACE_CAPACITY_INCREMENT;
349 /* insert the current entry */
351 ste = &(stb->entries[stb->used]);
354 ste->linenumber = line;
356 /* increase entries used count */
364 /* stacktrace_add_method *******************************************************
366 Add stacktrace entries[1] for the given method to the stacktrace buffer.
369 stb.........stacktracebuffer to fill
370 m...........method for which entries should be created
371 pv..........pv of method
372 pc..........position of program counter within the method's code
375 stacktracebuffer after possible reallocation.
377 [1] In case of inlined methods there may be more than one stacktrace
378 entry for a codegen-level method. (see doc/inlining_stacktrace.txt)
380 *******************************************************************************/
382 static stacktracebuffer *stacktrace_add_method(stacktracebuffer *stb,
383 methodinfo *m, u1 *pv, u1 *pc)
385 codeinfo *code; /* compiled realization of method */
388 /* find the realization of the method the pc is in */
390 code = *((codeinfo **) (pv + CodeinfoPointer));
392 /* search the line number table */
394 linenumber = dseg_get_linenumber_from_pc(&m, pv, pc);
396 /* now add a new entry to the staktrace */
398 stb = stacktrace_add_entry(stb, m, linenumber);
404 /* stacktrace_create ***********************************************************
406 Generates a stacktrace from the thread passed into a
407 stacktracebuffer. The stacktracebuffer is allocated on the
410 NOTE: The first element in the stackframe chain must always be a
411 native stackframeinfo (e.g. VMThrowable.fillInStackTrace() is
415 pointer to the stacktracebuffer, or
416 NULL if there is no stacktrace available for the
419 *******************************************************************************/
421 stacktracebuffer *stacktrace_create(stackframeinfo *sfi)
423 stacktracebuffer *stb;
432 /* prevent compiler warnings */
438 /* create a stacktracebuffer in dump memory */
440 stb = DNEW(stacktracebuffer);
442 stb->capacity = STACKTRACE_CAPACITY_DEFAULT;
446 if (opt_DebugStackTrace) {
447 printf("\n\n---> stacktrace creation start (fillInStackTrace):\n");
452 /* Loop while we have a method pointer (asm_calljavafunction has
453 NULL) or there is a stackframeinfo in the chain. */
457 while ((m != NULL) || (sfi != NULL)) {
458 /* m == NULL should only happen for the first time and inline
459 stackframe infos, like from the exception stubs or the
463 /* for native stub stackframe infos, pv is always NULL */
465 if (sfi->pv == NULL) {
466 /* get methodinfo, sp and ra from the current stackframe info */
469 sp = sfi->sp; /* sp of parent Java function */
472 if (m && !(m->flags & ACC_METHOD_BUILTIN))
473 stb = stacktrace_add_entry(stb, m, 0);
476 if (opt_DebugStackTrace) {
477 printf("ra=%p sp=%p, ", ra, sp);
479 printf(": native stub\n");
483 /* This is an native stub stackframe info, so we can
484 get the parent pv from the return address
487 #if defined(ENABLE_INTRP)
489 pv = codegen_get_pv_from_pc(ra);
493 #if defined(ENABLE_JIT)
494 pv = md_codegen_get_pv_from_pc(ra);
498 /* get methodinfo pointer from parent data segment */
500 code = *((codeinfo **) (pv + CodeinfoPointer));
502 /* For asm_vm_call_method the codeinfo pointer is
505 m = (code == NULL) ? NULL : code->m;
508 /* Inline stackframe infos are special: they have a
509 xpc of the actual exception position and the return
510 address saved since an inline stackframe info can
511 also be in a leaf method (no return address saved
512 on stack!!!). ATTENTION: This one is also for
513 hardware exceptions!!! */
515 /* get methodinfo, sp and ra from the current stackframe info */
517 m = sfi->method; /* m == NULL */
518 pv = sfi->pv; /* pv of parent Java function */
519 sp = sfi->sp; /* sp of parent Java function */
520 ra = sfi->ra; /* ra of parent Java function */
521 xpc = sfi->xpc; /* actual exception position */
524 if (opt_DebugStackTrace) {
525 printf("ra=%p sp=%p, ", ra, sp);
526 printf("NULL: extern stackframe\n");
531 /* get methodinfo from current Java method */
533 code = *((codeinfo **) (pv + CodeinfoPointer));
535 /* For asm_vm_call_method the codeinfo pointer is
538 m = (code == NULL) ? NULL : code->m;
540 /* if m == NULL, this is a asm_calljavafunction call */
544 if (opt_DebugStackTrace) {
545 printf("ra=%p sp=%p, ", ra, sp);
547 printf(": extern stackframe parent");
552 #if defined(ENABLE_INTRP)
556 /* add the method to the stacktrace */
558 stb = stacktrace_add_method(stb, m, pv, (u1 *) ((ptrint) xpc));
560 /* get the current stack frame size */
562 framesize = *((u4 *) (pv + FrameSize));
565 if (opt_DebugStackTrace) {
566 printf(", framesize=%d\n", framesize);
571 /* Set stack pointer to stackframe of parent Java
572 function of the current Java function. */
574 #if defined(__I386__) || defined (__X86_64__) || defined (__M68K__)
575 sp += framesize + SIZEOF_VOID_P;
576 #elif defined(__SPARC_64__)
577 sp = md_get_framepointer(sp);
582 /* get data segment and methodinfo pointer from
585 #if defined(ENABLE_JIT)
586 pv = md_codegen_get_pv_from_pc(ra);
589 code = *((codeinfo **) (pv + CodeinfoPointer));
591 /* For asm_vm_call_method the codeinfo pointer is
594 m = (code == NULL) ? NULL : code->m;
596 #if defined(ENABLE_INTRP)
602 if (opt_DebugStackTrace) {
603 printf("ra=%p sp=%p, ", ra, sp);
604 printf("asm_calljavafunction\n");
611 /* get previous stackframeinfo in the chain */
617 if (opt_DebugStackTrace) {
618 printf("ra=%p sp=%p, ", ra, sp);
625 /* JIT method found, add it to the stacktrace (we subtract
626 1 from the return address since it points the the
627 instruction after call). */
629 stb = stacktrace_add_method(stb, m, pv, (u1 *) ((ptrint) ra) - 1);
631 /* get the current stack frame size */
633 framesize = *((u4 *) (pv + FrameSize));
636 if (opt_DebugStackTrace) {
637 printf(", framesize=%d\n", framesize);
642 /* get return address of current stack frame */
644 #if defined(ENABLE_JIT)
645 # if defined(ENABLE_INTRP)
647 ra = intrp_md_stacktrace_get_returnaddress(sp, framesize);
650 ra = md_stacktrace_get_returnaddress(sp, framesize);
652 ra = intrp_md_stacktrace_get_returnaddress(sp, framesize);
655 /* get data segment and methodinfo pointer from parent method */
657 #if defined(ENABLE_INTRP)
659 pv = codegen_get_pv_from_pc(ra);
663 #if defined(ENABLE_JIT)
664 # if defined(__SPARC_64__)
665 sp = md_get_framepointer(sp);
666 pv = md_get_pv_from_stackframe(sp);
668 pv = md_codegen_get_pv_from_pc(ra);
673 code = *((codeinfo **) (pv + CodeinfoPointer));
675 /* For asm_vm_call_method the codeinfo pointer is NULL. */
677 m = (code == NULL) ? NULL : code->m;
681 #if defined(ENABLE_INTRP)
683 sp = *(u1 **) (sp - framesize);
687 #if defined(__I386__) || defined (__X86_64__) || defined (__M68K__)
688 sp += framesize + SIZEOF_VOID_P;
689 #elif defined(__SPARC_64__)
690 /* already has the new sp */
699 if (opt_DebugStackTrace) {
700 printf("---> stacktrace creation finished.\n\n");
705 /* return the stacktracebuffer */
714 /* stacktrace_fillInStackTrace *************************************************
716 Generate a stacktrace from the current thread for
717 java.lang.VMThrowable.fillInStackTrace.
719 *******************************************************************************/
721 stacktracecontainer *stacktrace_fillInStackTrace(void)
723 stacktracebuffer *stb;
724 stacktracecontainer *gcstc;
727 CYCLES_STATS_DECLARE_AND_START_WITH_OVERHEAD
729 /* mark start of dump memory area */
731 dumpsize = dump_size();
733 /* create a stacktrace from the current thread */
735 stb = stacktrace_create(STACKFRAMEINFO);
740 /* allocate memory from the GC heap and copy the stacktrace buffer */
741 /* ATTENTION: use stacktracecontainer for this and make it look like
744 gcstc_size = sizeof(stacktracebuffer) +
745 sizeof(stacktrace_entry) * stb->used -
746 sizeof(stacktrace_entry) * STACKTRACE_CAPACITY_DEFAULT;
747 gcstc = (stacktracecontainer *) builtin_newarray_byte(gcstc_size);
752 MCOPY(&(gcstc->stb), stb, u1, gcstc_size);
754 /* release dump memory */
756 dump_release(dumpsize);
758 CYCLES_STATS_END_WITH_OVERHEAD(stacktrace_fillInStackTrace,
763 dump_release(dumpsize);
765 CYCLES_STATS_END_WITH_OVERHEAD(stacktrace_fillInStackTrace,
772 /* stacktrace_getClassContext **************************************************
774 Creates a Class context array.
777 the array of java.lang.Class objects, or
778 NULL if an exception has been thrown
780 *******************************************************************************/
782 java_handle_objectarray_t *stacktrace_getClassContext(void)
784 stacktracebuffer *stb;
785 stacktrace_entry *ste;
786 java_handle_objectarray_t *oa;
790 CYCLES_STATS_DECLARE_AND_START
792 /* mark start of dump memory area */
794 dumpsize = dump_size();
796 /* create a stacktrace for the current thread */
798 stb = stacktrace_create(STACKFRAMEINFO);
803 /* calculate the size of the Class array */
805 for (i = 0, oalength = 0; i < stb->used; i++)
806 if (stb->entries[i].method != NULL)
809 /* The first entry corresponds to the method whose implementation */
810 /* calls stacktrace_getClassContext. We remove that entry. */
812 ste = &(stb->entries[0]);
816 /* allocate the Class array */
818 oa = builtin_anewarray(oalength, class_java_lang_Class);
822 /* fill the Class array from the stacktracebuffer */
824 for(i = 0; i < oalength; i++, ste++) {
825 if (ste->method == NULL) {
830 LLNI_array_direct(oa, i) = (java_object_t *) ste->method->class;
833 /* release dump memory */
835 dump_release(dumpsize);
837 CYCLES_STATS_END(stacktrace_getClassContext)
842 dump_release(dumpsize);
844 CYCLES_STATS_END(stacktrace_getClassContext)
850 /* stacktrace_getCurrentClass **************************************************
852 Find the current class by walking the stack trace.
854 Quote from the JNI documentation:
856 In the Java 2 Platform, FindClass locates the class loader
857 associated with the current native method. If the native code
858 belongs to a system class, no class loader will be
859 involved. Otherwise, the proper class loader will be invoked to
860 load and link the named class. When FindClass is called through the
861 Invocation Interface, there is no current native method or its
862 associated class loader. In that case, the result of
863 ClassLoader.getBaseClassLoader is used."
865 *******************************************************************************/
867 #if defined(ENABLE_JAVASE)
868 classinfo *stacktrace_getCurrentClass(void)
870 stacktracebuffer *stb;
871 stacktrace_entry *ste;
875 CYCLES_STATS_DECLARE_AND_START
877 /* mark start of dump memory area */
879 dumpsize = dump_size();
881 /* create a stacktrace for the current thread */
883 stb = stacktrace_create(STACKFRAMEINFO);
886 goto return_NULL; /* XXX exception: how to distinguish from normal NULL return? */
888 /* iterate over all stacktrace entries and find the first suitable
891 for (i = 0, ste = &(stb->entries[0]); i < stb->used; i++, ste++) {
897 if (m->class == class_java_security_PrivilegedAction)
900 if (m->class != NULL) {
901 dump_release(dumpsize);
903 CYCLES_STATS_END(stacktrace_getCurrentClass)
909 /* no Java method found on the stack */
912 dump_release(dumpsize);
914 CYCLES_STATS_END(stacktrace_getCurrentClass)
918 #endif /* ENABLE_JAVASE */
921 /* stacktrace_getStack *********************************************************
923 Create a 2-dimensional array for java.security.VMAccessControler.
927 NULL if an exception has been thrown
929 *******************************************************************************/
931 #if defined(ENABLE_JAVASE)
932 java_handle_objectarray_t *stacktrace_getStack(void)
934 stacktracebuffer *stb;
935 stacktrace_entry *ste;
936 java_handle_objectarray_t *oa;
937 java_handle_objectarray_t *classes;
938 java_handle_objectarray_t *methodnames;
940 java_handle_t *string;
943 CYCLES_STATS_DECLARE_AND_START
945 /* mark start of dump memory area */
947 dumpsize = dump_size();
949 /* create a stacktrace for the current thread */
951 stb = stacktrace_create(STACKFRAMEINFO);
956 /* get the first stacktrace entry */
958 ste = &(stb->entries[0]);
960 /* allocate all required arrays */
962 oa = builtin_anewarray(2, arrayclass_java_lang_Object);
967 classes = builtin_anewarray(stb->used, class_java_lang_Class);
972 methodnames = builtin_anewarray(stb->used, class_java_lang_String);
974 if (methodnames == NULL)
977 /* set up the 2-dimensional array */
979 LLNI_objectarray_element_set(oa, 0, classes);
980 LLNI_objectarray_element_set(oa, 1, methodnames);
982 /* iterate over all stacktrace entries */
984 for (i = 0, ste = &(stb->entries[0]); i < stb->used; i++, ste++) {
985 c = ste->method->class;
987 LLNI_array_direct(classes, i) = (java_object_t *) c;
989 string = javastring_new(ste->method->name);
994 LLNI_objectarray_element_set(methodnames, i, string);
997 /* return the 2-dimensional array */
999 dump_release(dumpsize);
1001 CYCLES_STATS_END(stacktrace_getStack)
1006 dump_release(dumpsize);
1008 CYCLES_STATS_END(stacktrace_getStack)
1012 #endif /* ENABLE_JAVASE */
1015 /* stacktrace_print_trace_from_buffer ******************************************
1017 Print the stacktrace of a given stacktracebuffer with CACAO intern
1018 methods (no Java help). This method is used by
1019 stacktrace_dump_trace and builtin_trace_exception.
1021 *******************************************************************************/
1023 void stacktrace_print_trace_from_buffer(stacktracebuffer *stb)
1025 stacktrace_entry *ste;
1029 ste = &(stb->entries[0]);
1031 for (i = 0; i < stb->used; i++, ste++) {
1035 utf_display_printable_ascii_classname(m->class->name);
1037 utf_display_printable_ascii(m->name);
1038 utf_display_printable_ascii(m->descriptor);
1040 if (m->flags & ACC_NATIVE) {
1041 puts("(Native Method)");
1045 utf_display_printable_ascii(m->class->sourcefile);
1046 printf(":%d)\n", (u4) ste->linenumber);
1050 /* just to be sure */
1056 /* stacktrace_print_trace ******************************************************
1058 Print the stacktrace of a given exception. More or less a wrapper
1059 to stacktrace_print_trace_from_buffer.
1061 *******************************************************************************/
1063 void stacktrace_print_trace(java_handle_t *xptr)
1065 java_lang_Throwable *t;
1066 #if defined(WITH_CLASSPATH_GNU)
1067 java_lang_VMThrowable *vmt;
1069 stacktracecontainer *stc;
1070 stacktracebuffer *stb;
1072 t = (java_lang_Throwable *) xptr;
1077 /* now print the stacktrace */
1079 #if defined(WITH_CLASSPATH_GNU)
1080 LLNI_field_get_ref(t, vmState, vmt);
1081 stc = (stacktracecontainer *) LLNI_field_direct(vmt, vmData);
1082 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
1083 stc = (stacktracecontainer *) t->backtrace;
1085 # error unknown classpath configuration
1090 stacktrace_print_trace_from_buffer(stb);
1094 #if defined(ENABLE_CYCLES_STATS)
1095 void stacktrace_print_cycles_stats(FILE *file)
1097 CYCLES_STATS_PRINT_OVERHEAD(stacktrace_overhead,file);
1098 CYCLES_STATS_PRINT(stacktrace_fillInStackTrace,file);
1099 CYCLES_STATS_PRINT(stacktrace_getClassContext ,file);
1100 CYCLES_STATS_PRINT(stacktrace_getCurrentClass ,file);
1101 CYCLES_STATS_PRINT(stacktrace_getStack ,file);
1107 * These are local overrides for various environment variables in Emacs.
1108 * Please do not remove this and leave it at the end of the file, where
1109 * Emacs will automagically detect them.
1110 * ---------------------------------------------------------------------
1113 * indent-tabs-mode: t
1117 * vim:noexpandtab:sw=4:ts=4: