1 /* src/vm/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/mutex.hpp"
40 #include "vm/array.hpp"
41 #include "vm/jit/builtin.hpp"
42 #include "vm/class.hpp"
43 #include "vm/exceptions.hpp"
44 #include "vm/global.h"
45 #include "vm/globals.hpp"
46 #include "vm/linker.h"
47 #include "vm/loader.hpp"
48 #include "vm/method.h"
49 #include "vm/options.h"
50 #include "vm/resolve.hpp"
51 #include "vm/suck.hpp"
55 #include "vm/jit/code.hpp"
56 #include "vm/jit/methodheader.h"
57 #include "vm/jit/stubs.hpp"
60 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
61 #define INLINELOG(code) do { if (opt_TraceInlining) { code } } while (0)
63 #define INLINELOG(code)
67 /* global variables ***********************************************************/
69 methodinfo *method_java_lang_reflect_Method_invoke;
72 /* method_init *****************************************************************
74 Initialize method subsystem.
76 *******************************************************************************/
78 void method_init(void)
80 #if defined(ENABLE_JAVASE)
83 if (class_java_lang_reflect_Method == NULL)
84 vm_abort("method_init: class_java_lang_reflect_Method is NULL");
86 /* Cache java.lang.reflect.Method.invoke() */
88 method_java_lang_reflect_Method_invoke =
89 class_findmethod(class_java_lang_reflect_Method, utf_invoke, NULL);
91 if (method_java_lang_reflect_Method_invoke == NULL)
92 vm_abort("method_init: Could not resolve method java.lang.reflect.Method.invoke().");
97 /* method_load *****************************************************************
99 Loads a method from the class file and fills an existing methodinfo
107 attribute_info attributes[attribute_count];
111 u2 attribute_name_index;
113 u1 info[attribute_length];
116 LineNumberTable_attribute {
117 u2 attribute_name_index;
119 u2 line_number_table_length;
123 } line_number_table[line_number_table_length];
126 *******************************************************************************/
128 bool method_load(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
137 u2 attribute_name_index;
139 u2 code_attributes_count;
140 u2 code_attribute_name_index;
141 utf *code_attribute_name;
147 m->mutex = Mutex_new();
149 #if defined(ENABLE_STATISTICS)
154 /* all fields of m have been zeroed in load_class_from_classbuffer */
158 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
163 m->flags = suck_u2(cb);
167 name_index = suck_u2(cb);
169 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
176 descriptor_index = suck_u2(cb);
178 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
183 if (!descriptor_pool_add(descpool, u, &argcount))
186 #ifdef ENABLE_VERIFIER
188 if (!is_valid_name_utf(m->name)) {
189 exceptions_throw_classformaterror(c, "Method with invalid name");
193 if (m->name->text[0] == '<' &&
194 m->name != utf_init && m->name != utf_clinit) {
195 exceptions_throw_classformaterror(c, "Method with invalid special name");
199 #endif /* ENABLE_VERIFIER */
201 if (!(m->flags & ACC_STATIC))
202 argcount++; /* count the 'this' argument */
204 #ifdef ENABLE_VERIFIER
206 if (argcount > 255) {
207 exceptions_throw_classformaterror(c, "Too many arguments in signature");
211 /* check flag consistency */
212 if (m->name != utf_clinit) {
213 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
215 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
216 exceptions_throw_classformaterror(c,
217 "Illegal method modifiers: 0x%X",
222 if (m->flags & ACC_ABSTRACT) {
223 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
224 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
225 exceptions_throw_classformaterror(c,
226 "Illegal method modifiers: 0x%X",
232 if (c->flags & ACC_INTERFACE) {
233 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
234 exceptions_throw_classformaterror(c,
235 "Illegal method modifiers: 0x%X",
241 if (m->name == utf_init) {
242 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
243 ACC_NATIVE | ACC_ABSTRACT)) {
244 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
250 #endif /* ENABLE_VERIFIER */
252 /* mark the method as monomorphic until further notice */
254 m->flags |= ACC_METHOD_MONOMORPHIC;
256 /* non-abstract methods have an implementation in this class */
258 if (!(m->flags & ACC_ABSTRACT))
259 m->flags |= ACC_METHOD_IMPLEMENTED;
261 if (!suck_check_classbuffer_size(cb, 2))
264 /* attributes count */
266 attributes_count = suck_u2(cb);
268 for (i = 0; i < attributes_count; i++) {
269 if (!suck_check_classbuffer_size(cb, 2))
272 /* attribute name index */
274 attribute_name_index = suck_u2(cb);
277 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
279 if (attribute_name == NULL)
282 if (attribute_name == utf_Code) {
285 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
286 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
291 exceptions_throw_classformaterror(c, "Multiple Code attributes");
295 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
299 m->maxstack = suck_u2(cb);
300 m->maxlocals = suck_u2(cb);
302 if (m->maxlocals < argcount) {
303 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
307 if (!suck_check_classbuffer_size(cb, 4))
310 m->jcodelength = suck_u4(cb);
312 if (m->jcodelength == 0) {
313 exceptions_throw_classformaterror(c, "Code of a method has length 0");
317 if (m->jcodelength > 65535) {
318 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
322 if (!suck_check_classbuffer_size(cb, m->jcodelength))
325 m->jcode = MNEW(u1, m->jcodelength);
326 suck_nbytes(m->jcode, cb, m->jcodelength);
328 if (!suck_check_classbuffer_size(cb, 2))
331 m->rawexceptiontablelength = suck_u2(cb);
332 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
335 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
337 #if defined(ENABLE_STATISTICS)
339 count_vmcode_len += m->jcodelength + 18;
341 m->rawexceptiontablelength * sizeof(raw_exception_entry);
345 for (j = 0; j < m->rawexceptiontablelength; j++) {
347 m->rawexceptiontable[j].startpc = suck_u2(cb);
348 m->rawexceptiontable[j].endpc = suck_u2(cb);
349 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
354 m->rawexceptiontable[j].catchtype.any = NULL;
357 /* the classref is created later */
358 if (!(m->rawexceptiontable[j].catchtype.any =
359 (utf *) class_getconstant(c, idx, CONSTANT_Class)))
364 if (!suck_check_classbuffer_size(cb, 2))
367 /* code attributes count */
369 code_attributes_count = suck_u2(cb);
371 for (k = 0; k < code_attributes_count; k++) {
372 if (!suck_check_classbuffer_size(cb, 2))
375 /* code attribute name index */
377 code_attribute_name_index = suck_u2(cb);
379 code_attribute_name =
380 class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8);
382 if (code_attribute_name == NULL)
385 /* check which code attribute */
387 if (code_attribute_name == utf_LineNumberTable) {
388 /* LineNumberTable */
390 if (!suck_check_classbuffer_size(cb, 4 + 2))
393 /* attribute length */
397 /* line number table length */
399 m->linenumbercount = suck_u2(cb);
401 if (!suck_check_classbuffer_size(cb,
402 (2 + 2) * m->linenumbercount))
405 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
407 #if defined(ENABLE_STATISTICS)
409 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
412 for (l = 0; l < m->linenumbercount; l++) {
413 m->linenumbers[l].start_pc = suck_u2(cb);
414 m->linenumbers[l].line_number = suck_u2(cb);
417 #if defined(ENABLE_JAVASE)
418 else if (code_attribute_name == utf_StackMapTable) {
421 if (!stackmap_load_attribute_stackmaptable(cb, m))
426 /* unknown code attribute */
428 if (!loader_skip_attribute_body(cb))
433 else if (attribute_name == utf_Exceptions) {
436 if (m->thrownexceptions != NULL) {
437 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
441 if (!suck_check_classbuffer_size(cb, 4 + 2))
444 /* attribute length */
448 m->thrownexceptionscount = suck_u2(cb);
450 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
453 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
455 for (j = 0; j < m->thrownexceptionscount; j++) {
456 /* the classref is created later */
457 if (!((m->thrownexceptions)[j].any =
458 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
462 #if defined(ENABLE_JAVASE)
463 else if (attribute_name == utf_Signature) {
466 if (!loader_load_attribute_signature(cb, &(m->signature)))
470 #if defined(ENABLE_ANNOTATIONS)
471 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
472 /* RuntimeVisibleAnnotations */
473 if (!annotation_load_method_attribute_runtimevisibleannotations(cb, m))
476 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
477 /* RuntimeInvisibleAnnotations */
478 if (!annotation_load_method_attribute_runtimeinvisibleannotations(cb, m))
481 else if (attribute_name == utf_RuntimeVisibleParameterAnnotations) {
482 /* RuntimeVisibleParameterAnnotations */
483 if (!annotation_load_method_attribute_runtimevisibleparameterannotations(cb, m))
486 else if (attribute_name == utf_RuntimeInvisibleParameterAnnotations) {
487 /* RuntimeInvisibleParameterAnnotations */
488 if (!annotation_load_method_attribute_runtimeinvisibleparameterannotations(cb, m))
491 else if (attribute_name == utf_AnnotationDefault) {
492 /* AnnotationDefault */
493 if (!annotation_load_method_attribute_annotationdefault(cb, m))
499 /* unknown attribute */
501 if (!loader_skip_attribute_body(cb))
506 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
507 exceptions_throw_classformaterror(c, "Missing Code attribute");
511 #if defined(ENABLE_REPLACEMENT)
512 /* initialize the hit countdown field */
514 m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
517 /* everything was ok */
523 /* method_free *****************************************************************
525 Frees all memory that was allocated for this method.
527 *******************************************************************************/
529 void method_free(methodinfo *m)
532 Mutex_delete(m->mutex);
535 MFREE(m->jcode, u1, m->jcodelength);
537 if (m->rawexceptiontable)
538 MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
540 code_free_code_of_method(m);
542 if (m->stubroutine) {
543 if (m->flags & ACC_NATIVE) {
544 NativeStub_remove(m->stubroutine);
547 CompilerStub_remove(m->stubroutine);
553 /* method_canoverwrite *********************************************************
555 Check if m and old are identical with respect to type and
556 name. This means that old can be overwritten with m.
558 *******************************************************************************/
560 bool method_canoverwrite(methodinfo *m, methodinfo *old)
562 if (m->name != old->name)
565 if (m->descriptor != old->descriptor)
568 if (m->flags & ACC_STATIC)
575 /* method_new_builtin **********************************************************
577 Creates a minimal methodinfo structure for builtins. This comes handy
578 when dealing with builtin stubs or stacktraces.
580 *******************************************************************************/
582 methodinfo *method_new_builtin(builtintable_entry *bte)
586 /* allocate the methodinfo structure */
590 /* initialize methodinfo structure */
592 MZERO(m, methodinfo, 1);
594 m->mutex = Mutex_new();
595 m->flags = ACC_METHOD_BUILTIN;
596 m->parseddesc = bte->md;
598 m->descriptor = bte->descriptor;
600 /* return the newly created methodinfo */
606 /* method_vftbl_lookup *********************************************************
608 Does a method lookup in the passed virtual function table. This
609 function does exactly the same thing as JIT, but additionally
610 relies on the fact, that the methodinfo pointer is at the first
611 data segment slot (even for compiler stubs).
613 *******************************************************************************/
615 methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
619 methodinfo *resm; /* pointer to new resolved method */
621 /* If the method is not an instance method, just return it. */
623 if (m->flags & ACC_STATIC)
628 /* Get the method from the virtual function table. Is this an
631 if (m->clazz->flags & ACC_INTERFACE) {
632 pmptr = vftbl->interfacetable[-(m->clazz->index)];
633 mptr = pmptr[(m - m->clazz->methods)];
636 mptr = vftbl->table[m->vftblindex];
639 /* and now get the codeinfo pointer from the first data segment slot */
641 resm = code_get_methodinfo_for_pv(mptr);
647 /* method_get_parametercount **************************************************
649 Use the descriptor of a method to determine the number of parameters
650 of the method. The this pointer of non-static methods is not counted.
653 m........the method of which the parameters should be counted
656 The parameter count or -1 on error.
658 *******************************************************************************/
660 int32_t method_get_parametercount(methodinfo *m)
662 methoddesc *md; /* method descriptor of m */
663 int32_t paramcount = 0; /* the parameter count of m */
667 /* is the descriptor fully parsed? */
669 if (md->params == NULL) {
670 if (!descriptor_params_from_paramtypes(md, m->flags)) {
675 paramcount = md->paramcount;
677 /* skip `this' pointer */
679 if (!(m->flags & ACC_STATIC)) {
687 /* method_get_parametertypearray ***********************************************
689 Use the descriptor of a method to generate a java.lang.Class array
690 which contains the classes of the parametertypes of the method.
692 This function is called by java.lang.reflect.{Constructor,Method}.
694 *******************************************************************************/
696 java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m)
699 typedesc *paramtypes;
701 java_handle_objectarray_t *oa;
707 /* is the descriptor fully parsed? */
709 if (m->parseddesc->params == NULL)
710 if (!descriptor_params_from_paramtypes(md, m->flags))
713 paramtypes = md->paramtypes;
714 paramcount = md->paramcount;
716 /* skip `this' pointer */
718 if (!(m->flags & ACC_STATIC)) {
723 /* create class-array */
725 oa = builtin_anewarray(paramcount, class_java_lang_Class);
732 for (i = 0; i < paramcount; i++) {
733 if (!resolve_class_from_typedesc(¶mtypes[i], true, false, &c))
736 LLNI_array_direct(oa, i) = (java_object_t *) c;
743 /* method_get_exceptionarray ***************************************************
745 Get the exceptions which can be thrown by a method.
747 *******************************************************************************/
749 java_handle_objectarray_t *method_get_exceptionarray(methodinfo *m)
751 java_handle_objectarray_t *oa;
755 /* create class-array */
757 oa = builtin_anewarray(m->thrownexceptionscount, class_java_lang_Class);
762 /* iterate over all exceptions and store the class in the array */
764 for (i = 0; i < m->thrownexceptionscount; i++) {
765 c = resolve_classref_or_classinfo_eager(m->thrownexceptions[i], true);
770 LLNI_array_direct(oa, i) = (java_object_t *) c;
777 /* method_returntype_get *******************************************************
779 Get the return type of the method.
781 *******************************************************************************/
783 classinfo *method_returntype_get(methodinfo *m)
788 td = &(m->parseddesc->returntype);
790 if (!resolve_class_from_typedesc(td, true, false, &c))
797 /* method_count_implementations ************************************************
799 Count the implementations of a method in a class cone (a class and all its
803 m................the method to count
804 c................class at which to start the counting (this class and
805 all its subclasses will be searched)
808 *found...........if found != NULL, *found receives the method
809 implementation that was found. This value is only
810 meaningful if the return value is 1.
813 the number of implementations found
815 *******************************************************************************/
817 s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
827 mend = mp + c->methodscount;
829 for (; mp < mend; ++mp) {
830 if (method_canoverwrite(mp, m)) {
838 for (child = c->sub; child != NULL; child = child->nextsub) {
839 count += method_count_implementations(m, child, found);
846 /* method_get_annotations ******************************************************
848 Get a methods' unparsed annotations in a byte array.
851 m........the method of which the annotations should be returned
854 The unparsed annotations in a byte array (or NULL if there aren't any).
856 *******************************************************************************/
858 java_handle_bytearray_t *method_get_annotations(methodinfo *m)
860 #if defined(ENABLE_ANNOTATIONS)
861 classinfo *c; /* methods' declaring class */
862 int slot; /* methods' slot */
863 java_handle_t *annotations; /* methods' unparsed annotations */
864 java_handle_t *method_annotations; /* all methods' unparsed annotations */
865 /* of the declaring class */
868 slot = m - c->methods;
871 LLNI_classinfo_field_get(c, method_annotations, method_annotations);
873 /* the method_annotations array might be shorter then the method
874 * count if the methods above a certain index have no annotations.
876 if (method_annotations != NULL &&
877 array_length_get(method_annotations) > slot) {
878 annotations = array_objectarray_element_get(
879 (java_handle_objectarray_t*)method_annotations, slot);
882 return (java_handle_bytearray_t*)annotations;
889 /* method_get_parameterannotations ********************************************
891 Get a methods' unparsed parameter annotations in an array of byte
895 m........the method of which the parameter annotations should be
899 The unparsed parameter annotations in a byte array (or NULL if
902 *******************************************************************************/
904 java_handle_bytearray_t *method_get_parameterannotations(methodinfo *m)
906 #if defined(ENABLE_ANNOTATIONS)
907 classinfo *c; /* methods' declaring class */
908 int slot; /* methods' slot */
909 java_handle_t *parameterAnnotations; /* methods' unparsed */
910 /* parameter annotations */
911 java_handle_t *method_parameterannotations; /* all methods' unparsed */
912 /* parameter annotations of */
913 /* the declaring class */
916 slot = m - c->methods;
917 parameterAnnotations = NULL;
919 LLNI_classinfo_field_get(
920 c, method_parameterannotations, method_parameterannotations);
922 /* the method_annotations array might be shorter then the method
923 * count if the methods above a certain index have no annotations.
925 if (method_parameterannotations != NULL &&
926 array_length_get(method_parameterannotations) > slot) {
927 parameterAnnotations = array_objectarray_element_get(
928 (java_handle_objectarray_t*)method_parameterannotations,
932 return (java_handle_bytearray_t*)parameterAnnotations;
939 /* method_get_annotationdefault ***********************************************
941 Get a methods' unparsed annotation default value in a byte array.
944 m........the method of which the annotation default value should be
948 The unparsed annotation default value in a byte array (or NULL if
951 *******************************************************************************/
953 java_handle_bytearray_t *method_get_annotationdefault(methodinfo *m)
955 #if defined(ENABLE_ANNOTATIONS)
956 classinfo *c; /* methods' declaring class */
957 int slot; /* methods' slot */
958 java_handle_t *annotationDefault; /* methods' unparsed */
959 /* annotation default value */
960 java_handle_t *method_annotationdefaults; /* all methods' unparsed */
961 /* annotation default values of */
962 /* the declaring class */
965 slot = m - c->methods;
966 annotationDefault = NULL;
968 LLNI_classinfo_field_get(
969 c, method_annotationdefaults, method_annotationdefaults);
971 /* the method_annotations array might be shorter then the method
972 * count if the methods above a certain index have no annotations.
974 if (method_annotationdefaults != NULL &&
975 array_length_get(method_annotationdefaults) > slot) {
976 annotationDefault = array_objectarray_element_get(
977 (java_handle_objectarray_t*)method_annotationdefaults, slot);
980 return (java_handle_bytearray_t*)annotationDefault;
987 /* method_add_to_worklist ******************************************************
989 Add the method to the given worklist. If the method already occurs in
990 the worklist, the worklist remains unchanged.
992 *******************************************************************************/
994 static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
998 for (wi = *wl; wi != NULL; wi = wi->next)
1002 wi = NEW(method_worklist);
1010 /* method_add_assumption_monomorphic *******************************************
1012 Record the assumption that the method is monomorphic.
1015 m.................the method
1016 caller............the caller making the assumption
1018 *******************************************************************************/
1020 void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
1022 method_assumption *as;
1024 /* XXX LOCKING FOR THIS FUNCTION? */
1026 /* check if we already have registered this assumption */
1028 for (as = m->assumptions; as != NULL; as = as->next) {
1029 if (as->context == caller)
1033 /* register the assumption */
1035 as = NEW(method_assumption);
1036 as->next = m->assumptions;
1037 as->context = caller;
1039 m->assumptions = as;
1042 /* method_break_assumption_monomorphic *****************************************
1044 Break the assumption that this method is monomorphic. All callers that
1045 have registered this assumption are added to the worklist.
1048 m.................the method
1049 wl................worklist where to add invalidated callers
1051 *******************************************************************************/
1053 void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
1055 method_assumption *as;
1057 /* XXX LOCKING FOR THIS FUNCTION? */
1059 for (as = m->assumptions; as != NULL; as = as->next) {
1061 printf("ASSUMPTION BROKEN (monomorphism): ");
1064 method_println(as->context);
1067 method_add_to_worklist(as->context, wl);
1069 #if defined(ENABLE_TLH) && 0
1071 method_assumption *as2;
1072 as2 = m->assumptions;
1073 m->assumptions = NULL;
1074 method_break_assumption_monomorphic(as->context, wl);
1076 assert(m->assumptions == NULL);
1077 m->assumptions = as2;*/
1083 /* method_printflags ***********************************************************
1085 Prints the flags of a method to stdout like.
1087 *******************************************************************************/
1089 #if !defined(NDEBUG)
1090 void method_printflags(methodinfo *m)
1097 if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
1098 if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
1099 if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
1100 if (m->flags & ACC_STATIC) printf(" STATIC");
1101 if (m->flags & ACC_FINAL) printf(" FINAL");
1102 if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1103 if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
1104 if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
1105 if (m->flags & ACC_NATIVE) printf(" NATIVE");
1106 if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
1107 if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
1108 if (m->flags & ACC_METHOD_BUILTIN) printf(" (builtin)");
1109 if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
1110 if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
1112 #endif /* !defined(NDEBUG) */
1115 /* method_print ****************************************************************
1117 Prints a method to stdout like:
1119 java.lang.Object.<init>()V
1121 *******************************************************************************/
1123 #if !defined(NDEBUG)
1124 void method_print(methodinfo *m)
1131 if (m->clazz != NULL)
1132 utf_display_printable_ascii_classname(m->clazz->name);
1136 utf_display_printable_ascii(m->name);
1137 utf_display_printable_ascii(m->descriptor);
1139 method_printflags(m);
1141 #endif /* !defined(NDEBUG) */
1144 /* method_println **************************************************************
1146 Prints a method plus new line to stdout like:
1148 java.lang.Object.<init>()V
1150 *******************************************************************************/
1152 #if !defined(NDEBUG)
1153 void method_println(methodinfo *m)
1155 if (opt_debugcolor) printf("\033[31m"); /* red */
1157 if (opt_debugcolor) printf("\033[m");
1160 #endif /* !defined(NDEBUG) */
1163 /* method_methodref_print ******************************************************
1165 Prints a method reference to stdout.
1167 *******************************************************************************/
1169 #if !defined(NDEBUG)
1170 void method_methodref_print(constant_FMIref *mr)
1173 printf("(constant_FMIref *)NULL");
1177 if (IS_FMIREF_RESOLVED(mr)) {
1178 printf("<method> ");
1179 method_print(mr->p.method);
1182 printf("<methodref> ");
1183 utf_display_printable_ascii_classname(mr->p.classref->name);
1185 utf_display_printable_ascii(mr->name);
1186 utf_display_printable_ascii(mr->descriptor);
1189 #endif /* !defined(NDEBUG) */
1192 /* method_methodref_println ****************************************************
1194 Prints a method reference to stdout, followed by a newline.
1196 *******************************************************************************/
1198 #if !defined(NDEBUG)
1199 void method_methodref_println(constant_FMIref *mr)
1201 method_methodref_print(mr);
1204 #endif /* !defined(NDEBUG) */
1208 * These are local overrides for various environment variables in Emacs.
1209 * Please do not remove this and leave it at the end of the file, where
1210 * Emacs will automagically detect them.
1211 * ---------------------------------------------------------------------
1214 * indent-tabs-mode: t
1218 * vim:noexpandtab:sw=4:ts=4: