1 /* src/vmcore/method.c - method functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
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.
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.
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
34 #include "mm/memory.h"
36 #include "native/llni.h"
38 #include "threads/lock-common.h"
41 #include "vm/builtin.h"
42 #include "vm/exceptions.h"
43 #include "vm/global.h"
44 #include "vm/resolve.h"
47 #include "vm/jit/code.h"
48 #include "vm/jit/methodheader.h"
50 #include "vm/jit_interface.h"
52 #include "vmcore/class.h"
53 #include "vmcore/globals.hpp"
54 #include "vmcore/linker.h"
55 #include "vmcore/loader.h"
56 #include "vmcore/method.h"
57 #include "vmcore/options.h"
58 #include "vmcore/suck.h"
59 #include "vmcore/utf8.h"
62 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
63 #define INLINELOG(code) do { if (opt_TraceInlining) { code } } while (0)
65 #define INLINELOG(code)
69 /* global variables ***********************************************************/
71 methodinfo *method_java_lang_reflect_Method_invoke;
74 /* method_init *****************************************************************
76 Initialize method subsystem.
78 *******************************************************************************/
80 void method_init(void)
82 #if defined(ENABLE_JAVASE)
85 if (class_java_lang_reflect_Method == NULL)
86 vm_abort("method_init: class_java_lang_reflect_Method is NULL");
88 /* Cache java.lang.reflect.Method.invoke() */
90 method_java_lang_reflect_Method_invoke =
91 class_findmethod(class_java_lang_reflect_Method, utf_invoke, NULL);
93 if (method_java_lang_reflect_Method_invoke == NULL)
94 vm_abort("method_init: Could not resolve method java.lang.reflect.Method.invoke().");
99 /* method_load *****************************************************************
101 Loads a method from the class file and fills an existing methodinfo
109 attribute_info attributes[attribute_count];
113 u2 attribute_name_index;
115 u1 info[attribute_length];
118 LineNumberTable_attribute {
119 u2 attribute_name_index;
121 u2 line_number_table_length;
125 } line_number_table[line_number_table_length];
128 *******************************************************************************/
130 bool method_load(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
139 u2 attribute_name_index;
141 u2 code_attributes_count;
142 u2 code_attribute_name_index;
143 utf *code_attribute_name;
149 LOCK_INIT_OBJECT_LOCK(&(m->header));
151 #if defined(ENABLE_STATISTICS)
156 /* all fields of m have been zeroed in load_class_from_classbuffer */
160 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
165 m->flags = suck_u2(cb);
169 name_index = suck_u2(cb);
171 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
178 descriptor_index = suck_u2(cb);
180 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
185 if (!descriptor_pool_add(descpool, u, &argcount))
188 #ifdef ENABLE_VERIFIER
190 if (!is_valid_name_utf(m->name)) {
191 exceptions_throw_classformaterror(c, "Method with invalid name");
195 if (m->name->text[0] == '<' &&
196 m->name != utf_init && m->name != utf_clinit) {
197 exceptions_throw_classformaterror(c, "Method with invalid special name");
201 #endif /* ENABLE_VERIFIER */
203 if (!(m->flags & ACC_STATIC))
204 argcount++; /* count the 'this' argument */
206 #ifdef ENABLE_VERIFIER
208 if (argcount > 255) {
209 exceptions_throw_classformaterror(c, "Too many arguments in signature");
213 /* check flag consistency */
214 if (m->name != utf_clinit) {
215 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
217 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
218 exceptions_throw_classformaterror(c,
219 "Illegal method modifiers: 0x%X",
224 if (m->flags & ACC_ABSTRACT) {
225 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
226 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
227 exceptions_throw_classformaterror(c,
228 "Illegal method modifiers: 0x%X",
234 if (c->flags & ACC_INTERFACE) {
235 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
236 exceptions_throw_classformaterror(c,
237 "Illegal method modifiers: 0x%X",
243 if (m->name == utf_init) {
244 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
245 ACC_NATIVE | ACC_ABSTRACT)) {
246 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
252 #endif /* ENABLE_VERIFIER */
254 /* mark the method as monomorphic until further notice */
256 m->flags |= ACC_METHOD_MONOMORPHIC;
258 /* non-abstract methods have an implementation in this class */
260 if (!(m->flags & ACC_ABSTRACT))
261 m->flags |= ACC_METHOD_IMPLEMENTED;
263 if (!suck_check_classbuffer_size(cb, 2))
266 /* attributes count */
268 attributes_count = suck_u2(cb);
270 for (i = 0; i < attributes_count; i++) {
271 if (!suck_check_classbuffer_size(cb, 2))
274 /* attribute name index */
276 attribute_name_index = suck_u2(cb);
279 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
281 if (attribute_name == NULL)
284 if (attribute_name == utf_Code) {
287 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
288 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
293 exceptions_throw_classformaterror(c, "Multiple Code attributes");
297 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
301 m->maxstack = suck_u2(cb);
302 m->maxlocals = suck_u2(cb);
304 if (m->maxlocals < argcount) {
305 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
309 if (!suck_check_classbuffer_size(cb, 4))
312 m->jcodelength = suck_u4(cb);
314 if (m->jcodelength == 0) {
315 exceptions_throw_classformaterror(c, "Code of a method has length 0");
319 if (m->jcodelength > 65535) {
320 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
324 if (!suck_check_classbuffer_size(cb, m->jcodelength))
327 m->jcode = MNEW(u1, m->jcodelength);
328 suck_nbytes(m->jcode, cb, m->jcodelength);
330 if (!suck_check_classbuffer_size(cb, 2))
333 m->rawexceptiontablelength = suck_u2(cb);
334 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
337 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
339 #if defined(ENABLE_STATISTICS)
341 count_vmcode_len += m->jcodelength + 18;
343 m->rawexceptiontablelength * sizeof(raw_exception_entry);
347 for (j = 0; j < m->rawexceptiontablelength; j++) {
349 m->rawexceptiontable[j].startpc = suck_u2(cb);
350 m->rawexceptiontable[j].endpc = suck_u2(cb);
351 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
356 m->rawexceptiontable[j].catchtype.any = NULL;
359 /* the classref is created later */
360 if (!(m->rawexceptiontable[j].catchtype.any =
361 (utf *) class_getconstant(c, idx, CONSTANT_Class)))
366 if (!suck_check_classbuffer_size(cb, 2))
369 /* code attributes count */
371 code_attributes_count = suck_u2(cb);
373 for (k = 0; k < code_attributes_count; k++) {
374 if (!suck_check_classbuffer_size(cb, 2))
377 /* code attribute name index */
379 code_attribute_name_index = suck_u2(cb);
381 code_attribute_name =
382 class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8);
384 if (code_attribute_name == NULL)
387 /* check which code attribute */
389 if (code_attribute_name == utf_LineNumberTable) {
390 /* LineNumberTable */
392 if (!suck_check_classbuffer_size(cb, 4 + 2))
395 /* attribute length */
399 /* line number table length */
401 m->linenumbercount = suck_u2(cb);
403 if (!suck_check_classbuffer_size(cb,
404 (2 + 2) * m->linenumbercount))
407 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
409 #if defined(ENABLE_STATISTICS)
411 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
414 for (l = 0; l < m->linenumbercount; l++) {
415 m->linenumbers[l].start_pc = suck_u2(cb);
416 m->linenumbers[l].line_number = suck_u2(cb);
419 #if defined(ENABLE_JAVASE)
420 else if (code_attribute_name == utf_StackMapTable) {
423 if (!stackmap_load_attribute_stackmaptable(cb, m))
428 /* unknown code attribute */
430 if (!loader_skip_attribute_body(cb))
435 else if (attribute_name == utf_Exceptions) {
438 if (m->thrownexceptions != NULL) {
439 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
443 if (!suck_check_classbuffer_size(cb, 4 + 2))
446 /* attribute length */
450 m->thrownexceptionscount = suck_u2(cb);
452 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
455 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
457 for (j = 0; j < m->thrownexceptionscount; j++) {
458 /* the classref is created later */
459 if (!((m->thrownexceptions)[j].any =
460 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
464 #if defined(ENABLE_JAVASE)
465 else if (attribute_name == utf_Signature) {
468 if (!loader_load_attribute_signature(cb, &(m->signature)))
472 #if defined(ENABLE_ANNOTATIONS)
473 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
474 /* RuntimeVisibleAnnotations */
475 if (!annotation_load_method_attribute_runtimevisibleannotations(cb, m))
478 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
479 /* RuntimeInvisibleAnnotations */
480 if (!annotation_load_method_attribute_runtimeinvisibleannotations(cb, m))
483 else if (attribute_name == utf_RuntimeVisibleParameterAnnotations) {
484 /* RuntimeVisibleParameterAnnotations */
485 if (!annotation_load_method_attribute_runtimevisibleparameterannotations(cb, m))
488 else if (attribute_name == utf_RuntimeInvisibleParameterAnnotations) {
489 /* RuntimeInvisibleParameterAnnotations */
490 if (!annotation_load_method_attribute_runtimeinvisibleparameterannotations(cb, m))
493 else if (attribute_name == utf_AnnotationDefault) {
494 /* AnnotationDefault */
495 if (!annotation_load_method_attribute_annotationdefault(cb, m))
501 /* unknown attribute */
503 if (!loader_skip_attribute_body(cb))
508 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
509 exceptions_throw_classformaterror(c, "Missing Code attribute");
513 #if defined(ENABLE_REPLACEMENT)
514 /* initialize the hit countdown field */
516 m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
519 /* everything was ok */
525 /* method_free *****************************************************************
527 Frees all memory that was allocated for this method.
529 *******************************************************************************/
531 void method_free(methodinfo *m)
534 MFREE(m->jcode, u1, m->jcodelength);
536 if (m->rawexceptiontable)
537 MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
539 code_free_code_of_method(m);
541 if (m->stubroutine) {
542 if (m->flags & ACC_NATIVE) {
543 removenativestub(m->stubroutine);
546 removecompilerstub(m->stubroutine);
552 /* method_canoverwrite *********************************************************
554 Check if m and old are identical with respect to type and
555 name. This means that old can be overwritten with m.
557 *******************************************************************************/
559 bool method_canoverwrite(methodinfo *m, methodinfo *old)
561 if (m->name != old->name)
564 if (m->descriptor != old->descriptor)
567 if (m->flags & ACC_STATIC)
574 /* method_new_builtin **********************************************************
576 Creates a minimal methodinfo structure for builtins. This comes handy
577 when dealing with builtin stubs or stacktraces.
579 *******************************************************************************/
581 methodinfo *method_new_builtin(builtintable_entry *bte)
585 /* allocate the methodinfo structure */
589 /* initialize methodinfo structure */
591 MZERO(m, methodinfo, 1);
592 LOCK_INIT_OBJECT_LOCK(&(m->header));
594 m->flags = ACC_METHOD_BUILTIN;
595 m->parseddesc = bte->md;
597 m->descriptor = bte->descriptor;
599 /* return the newly created methodinfo */
605 /* method_vftbl_lookup *********************************************************
607 Does a method lookup in the passed virtual function table. This
608 function does exactly the same thing as JIT, but additionally
609 relies on the fact, that the methodinfo pointer is at the first
610 data segment slot (even for compiler stubs).
612 *******************************************************************************/
614 methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
618 methodinfo *resm; /* pointer to new resolved method */
620 /* If the method is not an instance method, just return it. */
622 if (m->flags & ACC_STATIC)
627 /* Get the method from the virtual function table. Is this an
630 if (m->clazz->flags & ACC_INTERFACE) {
631 pmptr = vftbl->interfacetable[-(m->clazz->index)];
632 mptr = pmptr[(m - m->clazz->methods)];
635 mptr = vftbl->table[m->vftblindex];
638 /* and now get the codeinfo pointer from the first data segment slot */
640 resm = code_get_methodinfo_for_pv(mptr);
646 /* method_get_parametercount **************************************************
648 Use the descriptor of a method to determine the number of parameters
649 of the method. The this pointer of non-static methods is not counted.
652 m........the method of which the parameters should be counted
655 The parameter count or -1 on error.
657 *******************************************************************************/
659 int32_t method_get_parametercount(methodinfo *m)
661 methoddesc *md; /* method descriptor of m */
662 int32_t paramcount = 0; /* the parameter count of m */
666 /* is the descriptor fully parsed? */
668 if (md->params == NULL) {
669 if (!descriptor_params_from_paramtypes(md, m->flags)) {
674 paramcount = md->paramcount;
676 /* skip `this' pointer */
678 if (!(m->flags & ACC_STATIC)) {
686 /* method_get_parametertypearray ***********************************************
688 Use the descriptor of a method to generate a java.lang.Class array
689 which contains the classes of the parametertypes of the method.
691 This function is called by java.lang.reflect.{Constructor,Method}.
693 *******************************************************************************/
695 java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m)
698 typedesc *paramtypes;
700 java_handle_objectarray_t *oa;
706 /* is the descriptor fully parsed? */
708 if (m->parseddesc->params == NULL)
709 if (!descriptor_params_from_paramtypes(md, m->flags))
712 paramtypes = md->paramtypes;
713 paramcount = md->paramcount;
715 /* skip `this' pointer */
717 if (!(m->flags & ACC_STATIC)) {
722 /* create class-array */
724 oa = builtin_anewarray(paramcount, class_java_lang_Class);
731 for (i = 0; i < paramcount; i++) {
732 if (!resolve_class_from_typedesc(¶mtypes[i], true, false, &c))
735 LLNI_array_direct(oa, i) = (java_object_t *) c;
742 /* method_get_exceptionarray ***************************************************
744 Get the exceptions which can be thrown by a method.
746 *******************************************************************************/
748 java_handle_objectarray_t *method_get_exceptionarray(methodinfo *m)
750 java_handle_objectarray_t *oa;
754 /* create class-array */
756 oa = builtin_anewarray(m->thrownexceptionscount, class_java_lang_Class);
761 /* iterate over all exceptions and store the class in the array */
763 for (i = 0; i < m->thrownexceptionscount; i++) {
764 c = resolve_classref_or_classinfo_eager(m->thrownexceptions[i], true);
769 LLNI_array_direct(oa, i) = (java_object_t *) c;
776 /* method_returntype_get *******************************************************
778 Get the return type of the method.
780 *******************************************************************************/
782 classinfo *method_returntype_get(methodinfo *m)
787 td = &(m->parseddesc->returntype);
789 if (!resolve_class_from_typedesc(td, true, false, &c))
796 /* method_count_implementations ************************************************
798 Count the implementations of a method in a class cone (a class and all its
802 m................the method to count
803 c................class at which to start the counting (this class and
804 all its subclasses will be searched)
807 *found...........if found != NULL, *found receives the method
808 implementation that was found. This value is only
809 meaningful if the return value is 1.
812 the number of implementations found
814 *******************************************************************************/
816 s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
826 mend = mp + c->methodscount;
828 for (; mp < mend; ++mp) {
829 if (method_canoverwrite(mp, m)) {
837 for (child = c->sub; child != NULL; child = child->nextsub) {
838 count += method_count_implementations(m, child, found);
845 /* method_get_annotations ******************************************************
847 Get a methods' unparsed annotations in a byte array.
850 m........the method of which the annotations should be returned
853 The unparsed annotations in a byte array (or NULL if there aren't any).
855 *******************************************************************************/
857 java_handle_bytearray_t *method_get_annotations(methodinfo *m)
859 #if defined(ENABLE_ANNOTATIONS)
860 classinfo *c; /* methods' declaring class */
861 int slot; /* methods' slot */
862 java_handle_t *annotations; /* methods' unparsed annotations */
863 java_handle_t *method_annotations; /* all methods' unparsed annotations */
864 /* of the declaring class */
867 slot = m - c->methods;
870 LLNI_classinfo_field_get(c, method_annotations, method_annotations);
872 /* the method_annotations array might be shorter then the method
873 * count if the methods above a certain index have no annotations.
875 if (method_annotations != NULL &&
876 array_length_get(method_annotations) > slot) {
877 annotations = array_objectarray_element_get(
878 (java_handle_objectarray_t*)method_annotations, slot);
881 return (java_handle_bytearray_t*)annotations;
888 /* method_get_parameterannotations ********************************************
890 Get a methods' unparsed parameter annotations in an array of byte
894 m........the method of which the parameter annotations should be
898 The unparsed parameter annotations in a byte array (or NULL if
901 *******************************************************************************/
903 java_handle_bytearray_t *method_get_parameterannotations(methodinfo *m)
905 #if defined(ENABLE_ANNOTATIONS)
906 classinfo *c; /* methods' declaring class */
907 int slot; /* methods' slot */
908 java_handle_t *parameterAnnotations; /* methods' unparsed */
909 /* parameter annotations */
910 java_handle_t *method_parameterannotations; /* all methods' unparsed */
911 /* parameter annotations of */
912 /* the declaring class */
915 slot = m - c->methods;
916 parameterAnnotations = NULL;
918 LLNI_classinfo_field_get(
919 c, method_parameterannotations, method_parameterannotations);
921 /* the method_annotations array might be shorter then the method
922 * count if the methods above a certain index have no annotations.
924 if (method_parameterannotations != NULL &&
925 array_length_get(method_parameterannotations) > slot) {
926 parameterAnnotations = array_objectarray_element_get(
927 (java_handle_objectarray_t*)method_parameterannotations,
931 return (java_handle_bytearray_t*)parameterAnnotations;
938 /* method_get_annotationdefault ***********************************************
940 Get a methods' unparsed annotation default value in a byte array.
943 m........the method of which the annotation default value should be
947 The unparsed annotation default value in a byte array (or NULL if
950 *******************************************************************************/
952 java_handle_bytearray_t *method_get_annotationdefault(methodinfo *m)
954 #if defined(ENABLE_ANNOTATIONS)
955 classinfo *c; /* methods' declaring class */
956 int slot; /* methods' slot */
957 java_handle_t *annotationDefault; /* methods' unparsed */
958 /* annotation default value */
959 java_handle_t *method_annotationdefaults; /* all methods' unparsed */
960 /* annotation default values of */
961 /* the declaring class */
964 slot = m - c->methods;
965 annotationDefault = NULL;
967 LLNI_classinfo_field_get(
968 c, method_annotationdefaults, method_annotationdefaults);
970 /* the method_annotations array might be shorter then the method
971 * count if the methods above a certain index have no annotations.
973 if (method_annotationdefaults != NULL &&
974 array_length_get(method_annotationdefaults) > slot) {
975 annotationDefault = array_objectarray_element_get(
976 (java_handle_objectarray_t*)method_annotationdefaults, slot);
979 return (java_handle_bytearray_t*)annotationDefault;
986 /* method_add_to_worklist ******************************************************
988 Add the method to the given worklist. If the method already occurs in
989 the worklist, the worklist remains unchanged.
991 *******************************************************************************/
993 static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
997 for (wi = *wl; wi != NULL; wi = wi->next)
1001 wi = NEW(method_worklist);
1009 /* method_add_assumption_monomorphic *******************************************
1011 Record the assumption that the method is monomorphic.
1014 m.................the method
1015 caller............the caller making the assumption
1017 *******************************************************************************/
1019 void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
1021 method_assumption *as;
1023 /* XXX LOCKING FOR THIS FUNCTION? */
1025 /* check if we already have registered this assumption */
1027 for (as = m->assumptions; as != NULL; as = as->next) {
1028 if (as->context == caller)
1032 /* register the assumption */
1034 as = NEW(method_assumption);
1035 as->next = m->assumptions;
1036 as->context = caller;
1038 m->assumptions = as;
1041 /* method_break_assumption_monomorphic *****************************************
1043 Break the assumption that this method is monomorphic. All callers that
1044 have registered this assumption are added to the worklist.
1047 m.................the method
1048 wl................worklist where to add invalidated callers
1050 *******************************************************************************/
1052 void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
1054 method_assumption *as;
1056 /* XXX LOCKING FOR THIS FUNCTION? */
1058 for (as = m->assumptions; as != NULL; as = as->next) {
1060 printf("ASSUMPTION BROKEN (monomorphism): ");
1063 method_println(as->context);
1066 method_add_to_worklist(as->context, wl);
1068 #if defined(ENABLE_TLH) && 0
1070 method_assumption *as2;
1071 as2 = m->assumptions;
1072 m->assumptions = NULL;
1073 method_break_assumption_monomorphic(as->context, wl);
1075 assert(m->assumptions == NULL);
1076 m->assumptions = as2;*/
1082 /* method_printflags ***********************************************************
1084 Prints the flags of a method to stdout like.
1086 *******************************************************************************/
1088 #if !defined(NDEBUG)
1089 void method_printflags(methodinfo *m)
1096 if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
1097 if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
1098 if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
1099 if (m->flags & ACC_STATIC) printf(" STATIC");
1100 if (m->flags & ACC_FINAL) printf(" FINAL");
1101 if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1102 if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
1103 if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
1104 if (m->flags & ACC_NATIVE) printf(" NATIVE");
1105 if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
1106 if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
1107 if (m->flags & ACC_METHOD_BUILTIN) printf(" (builtin)");
1108 if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
1109 if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
1111 #endif /* !defined(NDEBUG) */
1114 /* method_print ****************************************************************
1116 Prints a method to stdout like:
1118 java.lang.Object.<init>()V
1120 *******************************************************************************/
1122 #if !defined(NDEBUG)
1123 void method_print(methodinfo *m)
1130 if (m->clazz != NULL)
1131 utf_display_printable_ascii_classname(m->clazz->name);
1135 utf_display_printable_ascii(m->name);
1136 utf_display_printable_ascii(m->descriptor);
1138 method_printflags(m);
1140 #endif /* !defined(NDEBUG) */
1143 /* method_println **************************************************************
1145 Prints a method plus new line to stdout like:
1147 java.lang.Object.<init>()V
1149 *******************************************************************************/
1151 #if !defined(NDEBUG)
1152 void method_println(methodinfo *m)
1154 if (opt_debugcolor) printf("\033[31m"); /* red */
1156 if (opt_debugcolor) printf("\033[m");
1159 #endif /* !defined(NDEBUG) */
1162 /* method_methodref_print ******************************************************
1164 Prints a method reference to stdout.
1166 *******************************************************************************/
1168 #if !defined(NDEBUG)
1169 void method_methodref_print(constant_FMIref *mr)
1172 printf("(constant_FMIref *)NULL");
1176 if (IS_FMIREF_RESOLVED(mr)) {
1177 printf("<method> ");
1178 method_print(mr->p.method);
1181 printf("<methodref> ");
1182 utf_display_printable_ascii_classname(mr->p.classref->name);
1184 utf_display_printable_ascii(mr->name);
1185 utf_display_printable_ascii(mr->descriptor);
1188 #endif /* !defined(NDEBUG) */
1191 /* method_methodref_println ****************************************************
1193 Prints a method reference to stdout, followed by a newline.
1195 *******************************************************************************/
1197 #if !defined(NDEBUG)
1198 void method_methodref_println(constant_FMIref *mr)
1200 method_methodref_print(mr);
1203 #endif /* !defined(NDEBUG) */
1207 * These are local overrides for various environment variables in Emacs.
1208 * Please do not remove this and leave it at the end of the file, where
1209 * Emacs will automagically detect them.
1210 * ---------------------------------------------------------------------
1213 * indent-tabs-mode: t
1217 * vim:noexpandtab:sw=4:ts=4: