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/linker.h"
54 #include "vmcore/loader.h"
55 #include "vmcore/method.h"
56 #include "vmcore/options.h"
57 #include "vmcore/suck.h"
58 #include "vmcore/utf8.h"
61 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
62 #define INLINELOG(code) do { if (opt_TraceInlining) { code } } while (0)
64 #define INLINELOG(code)
68 /* global variables ***********************************************************/
70 methodinfo *method_java_lang_reflect_Method_invoke;
73 /* method_init *****************************************************************
75 Initialize method subsystem.
77 *******************************************************************************/
79 void method_init(void)
81 #if defined(ENABLE_JAVASE)
84 if (class_java_lang_reflect_Method == NULL)
85 vm_abort("method_init: class_java_lang_reflect_Method is NULL");
87 /* Cache java.lang.reflect.Method.invoke() */
89 method_java_lang_reflect_Method_invoke =
90 class_findmethod(class_java_lang_reflect_Method, utf_invoke, NULL);
92 if (method_java_lang_reflect_Method_invoke == NULL)
93 vm_abort("method_init: Could not resolve method java.lang.reflect.Method.invoke().");
98 /* method_load *****************************************************************
100 Loads a method from the class file and fills an existing methodinfo
108 attribute_info attributes[attribute_count];
112 u2 attribute_name_index;
114 u1 info[attribute_length];
117 LineNumberTable_attribute {
118 u2 attribute_name_index;
120 u2 line_number_table_length;
124 } line_number_table[line_number_table_length];
127 *******************************************************************************/
129 bool method_load(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
138 u2 attribute_name_index;
140 u2 code_attributes_count;
141 u2 code_attribute_name_index;
142 utf *code_attribute_name;
148 LOCK_INIT_OBJECT_LOCK(&(m->header));
150 #if defined(ENABLE_STATISTICS)
155 /* all fields of m have been zeroed in load_class_from_classbuffer */
159 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
164 m->flags = suck_u2(cb);
168 name_index = suck_u2(cb);
170 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
177 descriptor_index = suck_u2(cb);
179 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
184 if (!descriptor_pool_add(descpool, u, &argcount))
187 #ifdef ENABLE_VERIFIER
189 if (!is_valid_name_utf(m->name)) {
190 exceptions_throw_classformaterror(c, "Method with invalid name");
194 if (m->name->text[0] == '<' &&
195 m->name != utf_init && m->name != utf_clinit) {
196 exceptions_throw_classformaterror(c, "Method with invalid special name");
200 #endif /* ENABLE_VERIFIER */
202 if (!(m->flags & ACC_STATIC))
203 argcount++; /* count the 'this' argument */
205 #ifdef ENABLE_VERIFIER
207 if (argcount > 255) {
208 exceptions_throw_classformaterror(c, "Too many arguments in signature");
212 /* check flag consistency */
213 if (m->name != utf_clinit) {
214 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
216 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
217 exceptions_throw_classformaterror(c,
218 "Illegal method modifiers: 0x%X",
223 if (m->flags & ACC_ABSTRACT) {
224 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
225 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
226 exceptions_throw_classformaterror(c,
227 "Illegal method modifiers: 0x%X",
233 if (c->flags & ACC_INTERFACE) {
234 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
235 exceptions_throw_classformaterror(c,
236 "Illegal method modifiers: 0x%X",
242 if (m->name == utf_init) {
243 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
244 ACC_NATIVE | ACC_ABSTRACT)) {
245 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
251 #endif /* ENABLE_VERIFIER */
253 /* mark the method as monomorphic until further notice */
255 m->flags |= ACC_METHOD_MONOMORPHIC;
257 /* non-abstract methods have an implementation in this class */
259 if (!(m->flags & ACC_ABSTRACT))
260 m->flags |= ACC_METHOD_IMPLEMENTED;
262 if (!suck_check_classbuffer_size(cb, 2))
265 /* attributes count */
267 attributes_count = suck_u2(cb);
269 for (i = 0; i < attributes_count; i++) {
270 if (!suck_check_classbuffer_size(cb, 2))
273 /* attribute name index */
275 attribute_name_index = suck_u2(cb);
278 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
280 if (attribute_name == NULL)
283 if (attribute_name == utf_Code) {
286 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
287 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
292 exceptions_throw_classformaterror(c, "Multiple Code attributes");
296 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
300 m->maxstack = suck_u2(cb);
301 m->maxlocals = suck_u2(cb);
303 if (m->maxlocals < argcount) {
304 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
308 if (!suck_check_classbuffer_size(cb, 4))
311 m->jcodelength = suck_u4(cb);
313 if (m->jcodelength == 0) {
314 exceptions_throw_classformaterror(c, "Code of a method has length 0");
318 if (m->jcodelength > 65535) {
319 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
323 if (!suck_check_classbuffer_size(cb, m->jcodelength))
326 m->jcode = MNEW(u1, m->jcodelength);
327 suck_nbytes(m->jcode, cb, m->jcodelength);
329 if (!suck_check_classbuffer_size(cb, 2))
332 m->rawexceptiontablelength = suck_u2(cb);
333 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
336 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
338 #if defined(ENABLE_STATISTICS)
340 count_vmcode_len += m->jcodelength + 18;
342 m->rawexceptiontablelength * sizeof(raw_exception_entry);
346 for (j = 0; j < m->rawexceptiontablelength; j++) {
348 m->rawexceptiontable[j].startpc = suck_u2(cb);
349 m->rawexceptiontable[j].endpc = suck_u2(cb);
350 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
355 m->rawexceptiontable[j].catchtype.any = NULL;
358 /* the classref is created later */
359 if (!(m->rawexceptiontable[j].catchtype.any =
360 (utf *) class_getconstant(c, idx, CONSTANT_Class)))
365 if (!suck_check_classbuffer_size(cb, 2))
368 /* code attributes count */
370 code_attributes_count = suck_u2(cb);
372 for (k = 0; k < code_attributes_count; k++) {
373 if (!suck_check_classbuffer_size(cb, 2))
376 /* code attribute name index */
378 code_attribute_name_index = suck_u2(cb);
380 code_attribute_name =
381 class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8);
383 if (code_attribute_name == NULL)
386 /* check which code attribute */
388 if (code_attribute_name == utf_LineNumberTable) {
389 /* LineNumberTable */
391 if (!suck_check_classbuffer_size(cb, 4 + 2))
394 /* attribute length */
398 /* line number table length */
400 m->linenumbercount = suck_u2(cb);
402 if (!suck_check_classbuffer_size(cb,
403 (2 + 2) * m->linenumbercount))
406 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
408 #if defined(ENABLE_STATISTICS)
410 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
413 for (l = 0; l < m->linenumbercount; l++) {
414 m->linenumbers[l].start_pc = suck_u2(cb);
415 m->linenumbers[l].line_number = suck_u2(cb);
418 #if defined(ENABLE_JAVASE)
419 else if (code_attribute_name == utf_StackMapTable) {
422 if (!stackmap_load_attribute_stackmaptable(cb, m))
427 /* unknown code attribute */
429 if (!loader_skip_attribute_body(cb))
434 else if (attribute_name == utf_Exceptions) {
437 if (m->thrownexceptions != NULL) {
438 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
442 if (!suck_check_classbuffer_size(cb, 4 + 2))
445 /* attribute length */
449 m->thrownexceptionscount = suck_u2(cb);
451 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
454 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
456 for (j = 0; j < m->thrownexceptionscount; j++) {
457 /* the classref is created later */
458 if (!((m->thrownexceptions)[j].any =
459 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
463 #if defined(ENABLE_JAVASE)
464 else if (attribute_name == utf_Signature) {
467 if (!loader_load_attribute_signature(cb, &(m->signature)))
471 #if defined(ENABLE_ANNOTATIONS)
472 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
473 /* RuntimeVisibleAnnotations */
474 if (!annotation_load_method_attribute_runtimevisibleannotations(cb, m))
477 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
478 /* RuntimeInvisibleAnnotations */
479 if (!annotation_load_method_attribute_runtimeinvisibleannotations(cb, m))
482 else if (attribute_name == utf_RuntimeVisibleParameterAnnotations) {
483 /* RuntimeVisibleParameterAnnotations */
484 if (!annotation_load_method_attribute_runtimevisibleparameterannotations(cb, m))
487 else if (attribute_name == utf_RuntimeInvisibleParameterAnnotations) {
488 /* RuntimeInvisibleParameterAnnotations */
489 if (!annotation_load_method_attribute_runtimeinvisibleparameterannotations(cb, m))
492 else if (attribute_name == utf_AnnotationDefault) {
493 /* AnnotationDefault */
494 if (!annotation_load_method_attribute_annotationdefault(cb, m))
500 /* unknown attribute */
502 if (!loader_skip_attribute_body(cb))
507 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
508 exceptions_throw_classformaterror(c, "Missing Code attribute");
512 #if defined(ENABLE_REPLACEMENT)
513 /* initialize the hit countdown field */
515 m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
518 /* everything was ok */
524 /* method_free *****************************************************************
526 Frees all memory that was allocated for this method.
528 *******************************************************************************/
530 void method_free(methodinfo *m)
533 MFREE(m->jcode, u1, m->jcodelength);
535 if (m->rawexceptiontable)
536 MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
538 code_free_code_of_method(m);
540 if (m->stubroutine) {
541 if (m->flags & ACC_NATIVE) {
542 removenativestub(m->stubroutine);
545 removecompilerstub(m->stubroutine);
551 /* method_canoverwrite *********************************************************
553 Check if m and old are identical with respect to type and
554 name. This means that old can be overwritten with m.
556 *******************************************************************************/
558 bool method_canoverwrite(methodinfo *m, methodinfo *old)
560 if (m->name != old->name)
563 if (m->descriptor != old->descriptor)
566 if (m->flags & ACC_STATIC)
573 /* method_new_builtin **********************************************************
575 Creates a minimal methodinfo structure for builtins. This comes handy
576 when dealing with builtin stubs or stacktraces.
578 *******************************************************************************/
580 methodinfo *method_new_builtin(builtintable_entry *bte)
584 /* allocate the methodinfo structure */
588 /* initialize methodinfo structure */
590 MZERO(m, methodinfo, 1);
591 LOCK_INIT_OBJECT_LOCK(&(m->header));
593 m->flags = ACC_METHOD_BUILTIN;
594 m->parseddesc = bte->md;
596 m->descriptor = bte->descriptor;
598 /* return the newly created methodinfo */
604 /* method_vftbl_lookup *********************************************************
606 Does a method lookup in the passed virtual function table. This
607 function does exactly the same thing as JIT, but additionally
608 relies on the fact, that the methodinfo pointer is at the first
609 data segment slot (even for compiler stubs).
611 *******************************************************************************/
613 methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
617 methodinfo *resm; /* pointer to new resolved method */
619 /* If the method is not an instance method, just return it. */
621 if (m->flags & ACC_STATIC)
626 /* Get the method from the virtual function table. Is this an
629 if (m->clazz->flags & ACC_INTERFACE) {
630 pmptr = vftbl->interfacetable[-(m->clazz->index)];
631 mptr = pmptr[(m - m->clazz->methods)];
634 mptr = vftbl->table[m->vftblindex];
637 /* and now get the codeinfo pointer from the first data segment slot */
639 resm = code_get_methodinfo_for_pv(mptr);
645 /* method_get_parametercount **************************************************
647 Use the descriptor of a method to determine the number of parameters
648 of the method. The this pointer of non-static methods is not counted.
651 m........the method of which the parameters should be counted
654 The parameter count or -1 on error.
656 *******************************************************************************/
658 int32_t method_get_parametercount(methodinfo *m)
660 methoddesc *md; /* method descriptor of m */
661 int32_t paramcount = 0; /* the parameter count of m */
665 /* is the descriptor fully parsed? */
667 if (md->params == NULL) {
668 if (!descriptor_params_from_paramtypes(md, m->flags)) {
673 paramcount = md->paramcount;
675 /* skip `this' pointer */
677 if (!(m->flags & ACC_STATIC)) {
685 /* method_get_parametertypearray ***********************************************
687 Use the descriptor of a method to generate a java.lang.Class array
688 which contains the classes of the parametertypes of the method.
690 This function is called by java.lang.reflect.{Constructor,Method}.
692 *******************************************************************************/
694 java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m)
697 typedesc *paramtypes;
699 java_handle_objectarray_t *oa;
705 /* is the descriptor fully parsed? */
707 if (m->parseddesc->params == NULL)
708 if (!descriptor_params_from_paramtypes(md, m->flags))
711 paramtypes = md->paramtypes;
712 paramcount = md->paramcount;
714 /* skip `this' pointer */
716 if (!(m->flags & ACC_STATIC)) {
721 /* create class-array */
723 oa = builtin_anewarray(paramcount, class_java_lang_Class);
730 for (i = 0; i < paramcount; i++) {
731 if (!resolve_class_from_typedesc(¶mtypes[i], true, false, &c))
734 LLNI_array_direct(oa, i) = (java_object_t *) c;
741 /* method_get_exceptionarray ***************************************************
743 Get the exceptions which can be thrown by a method.
745 *******************************************************************************/
747 java_handle_objectarray_t *method_get_exceptionarray(methodinfo *m)
749 java_handle_objectarray_t *oa;
753 /* create class-array */
755 oa = builtin_anewarray(m->thrownexceptionscount, class_java_lang_Class);
760 /* iterate over all exceptions and store the class in the array */
762 for (i = 0; i < m->thrownexceptionscount; i++) {
763 c = resolve_classref_or_classinfo_eager(m->thrownexceptions[i], true);
768 LLNI_array_direct(oa, i) = (java_object_t *) c;
775 /* method_returntype_get *******************************************************
777 Get the return type of the method.
779 *******************************************************************************/
781 classinfo *method_returntype_get(methodinfo *m)
786 td = &(m->parseddesc->returntype);
788 if (!resolve_class_from_typedesc(td, true, false, &c))
795 /* method_count_implementations ************************************************
797 Count the implementations of a method in a class cone (a class and all its
801 m................the method to count
802 c................class at which to start the counting (this class and
803 all its subclasses will be searched)
806 *found...........if found != NULL, *found receives the method
807 implementation that was found. This value is only
808 meaningful if the return value is 1.
811 the number of implementations found
813 *******************************************************************************/
815 s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
825 mend = mp + c->methodscount;
827 for (; mp < mend; ++mp) {
828 if (method_canoverwrite(mp, m)) {
836 for (child = c->sub; child != NULL; child = child->nextsub) {
837 count += method_count_implementations(m, child, found);
844 /* method_get_annotations ******************************************************
846 Get a methods' unparsed annotations in a byte array.
849 m........the method of which the annotations should be returned
852 The unparsed annotations in a byte array (or NULL if there aren't any).
854 *******************************************************************************/
856 java_handle_bytearray_t *method_get_annotations(methodinfo *m)
858 #if defined(ENABLE_ANNOTATIONS)
859 classinfo *c; /* methods' declaring class */
860 int slot; /* methods' slot */
861 java_handle_t *annotations; /* methods' unparsed annotations */
862 java_handle_t *method_annotations; /* all methods' unparsed annotations */
863 /* of the declaring class */
866 slot = m - c->methods;
869 LLNI_classinfo_field_get(c, method_annotations, method_annotations);
871 /* the method_annotations array might be shorter then the method
872 * count if the methods above a certain index have no annotations.
874 if (method_annotations != NULL &&
875 array_length_get(method_annotations) > slot) {
876 annotations = array_objectarray_element_get(
877 (java_handle_objectarray_t*)method_annotations, slot);
880 return (java_handle_bytearray_t*)annotations;
887 /* method_get_parameterannotations ********************************************
889 Get a methods' unparsed parameter annotations in an array of byte
893 m........the method of which the parameter annotations should be
897 The unparsed parameter annotations in a byte array (or NULL if
900 *******************************************************************************/
902 java_handle_bytearray_t *method_get_parameterannotations(methodinfo *m)
904 #if defined(ENABLE_ANNOTATIONS)
905 classinfo *c; /* methods' declaring class */
906 int slot; /* methods' slot */
907 java_handle_t *parameterAnnotations; /* methods' unparsed */
908 /* parameter annotations */
909 java_handle_t *method_parameterannotations; /* all methods' unparsed */
910 /* parameter annotations of */
911 /* the declaring class */
914 slot = m - c->methods;
915 parameterAnnotations = NULL;
917 LLNI_classinfo_field_get(
918 c, method_parameterannotations, method_parameterannotations);
920 /* the method_annotations array might be shorter then the method
921 * count if the methods above a certain index have no annotations.
923 if (method_parameterannotations != NULL &&
924 array_length_get(method_parameterannotations) > slot) {
925 parameterAnnotations = array_objectarray_element_get(
926 (java_handle_objectarray_t*)method_parameterannotations,
930 return (java_handle_bytearray_t*)parameterAnnotations;
937 /* method_get_annotationdefault ***********************************************
939 Get a methods' unparsed annotation default value in a byte array.
942 m........the method of which the annotation default value should be
946 The unparsed annotation default value in a byte array (or NULL if
949 *******************************************************************************/
951 java_handle_bytearray_t *method_get_annotationdefault(methodinfo *m)
953 #if defined(ENABLE_ANNOTATIONS)
954 classinfo *c; /* methods' declaring class */
955 int slot; /* methods' slot */
956 java_handle_t *annotationDefault; /* methods' unparsed */
957 /* annotation default value */
958 java_handle_t *method_annotationdefaults; /* all methods' unparsed */
959 /* annotation default values of */
960 /* the declaring class */
963 slot = m - c->methods;
964 annotationDefault = NULL;
966 LLNI_classinfo_field_get(
967 c, method_annotationdefaults, method_annotationdefaults);
969 /* the method_annotations array might be shorter then the method
970 * count if the methods above a certain index have no annotations.
972 if (method_annotationdefaults != NULL &&
973 array_length_get(method_annotationdefaults) > slot) {
974 annotationDefault = array_objectarray_element_get(
975 (java_handle_objectarray_t*)method_annotationdefaults, slot);
978 return (java_handle_bytearray_t*)annotationDefault;
985 /* method_add_to_worklist ******************************************************
987 Add the method to the given worklist. If the method already occurs in
988 the worklist, the worklist remains unchanged.
990 *******************************************************************************/
992 static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
996 for (wi = *wl; wi != NULL; wi = wi->next)
1000 wi = NEW(method_worklist);
1008 /* method_add_assumption_monomorphic *******************************************
1010 Record the assumption that the method is monomorphic.
1013 m.................the method
1014 caller............the caller making the assumption
1016 *******************************************************************************/
1018 void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
1020 method_assumption *as;
1022 /* XXX LOCKING FOR THIS FUNCTION? */
1024 /* check if we already have registered this assumption */
1026 for (as = m->assumptions; as != NULL; as = as->next) {
1027 if (as->context == caller)
1031 /* register the assumption */
1033 as = NEW(method_assumption);
1034 as->next = m->assumptions;
1035 as->context = caller;
1037 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);
1071 /* method_printflags ***********************************************************
1073 Prints the flags of a method to stdout like.
1075 *******************************************************************************/
1077 #if !defined(NDEBUG)
1078 void method_printflags(methodinfo *m)
1085 if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
1086 if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
1087 if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
1088 if (m->flags & ACC_STATIC) printf(" STATIC");
1089 if (m->flags & ACC_FINAL) printf(" FINAL");
1090 if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1091 if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
1092 if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
1093 if (m->flags & ACC_NATIVE) printf(" NATIVE");
1094 if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
1095 if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
1096 if (m->flags & ACC_METHOD_BUILTIN) printf(" (builtin)");
1097 if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
1098 if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
1100 #endif /* !defined(NDEBUG) */
1103 /* method_print ****************************************************************
1105 Prints a method to stdout like:
1107 java.lang.Object.<init>()V
1109 *******************************************************************************/
1111 #if !defined(NDEBUG)
1112 void method_print(methodinfo *m)
1119 if (m->clazz != NULL)
1120 utf_display_printable_ascii_classname(m->clazz->name);
1124 utf_display_printable_ascii(m->name);
1125 utf_display_printable_ascii(m->descriptor);
1127 method_printflags(m);
1129 #endif /* !defined(NDEBUG) */
1132 /* method_println **************************************************************
1134 Prints a method plus new line to stdout like:
1136 java.lang.Object.<init>()V
1138 *******************************************************************************/
1140 #if !defined(NDEBUG)
1141 void method_println(methodinfo *m)
1143 if (opt_debugcolor) printf("\033[31m"); /* red */
1145 if (opt_debugcolor) printf("\033[m");
1148 #endif /* !defined(NDEBUG) */
1151 /* method_methodref_print ******************************************************
1153 Prints a method reference to stdout.
1155 *******************************************************************************/
1157 #if !defined(NDEBUG)
1158 void method_methodref_print(constant_FMIref *mr)
1161 printf("(constant_FMIref *)NULL");
1165 if (IS_FMIREF_RESOLVED(mr)) {
1166 printf("<method> ");
1167 method_print(mr->p.method);
1170 printf("<methodref> ");
1171 utf_display_printable_ascii_classname(mr->p.classref->name);
1173 utf_display_printable_ascii(mr->name);
1174 utf_display_printable_ascii(mr->descriptor);
1177 #endif /* !defined(NDEBUG) */
1180 /* method_methodref_println ****************************************************
1182 Prints a method reference to stdout, followed by a newline.
1184 *******************************************************************************/
1186 #if !defined(NDEBUG)
1187 void method_methodref_println(constant_FMIref *mr)
1189 method_methodref_print(mr);
1192 #endif /* !defined(NDEBUG) */
1196 * These are local overrides for various environment variables in Emacs.
1197 * Please do not remove this and leave it at the end of the file, where
1198 * Emacs will automagically detect them.
1199 * ---------------------------------------------------------------------
1202 * indent-tabs-mode: t
1206 * vim:noexpandtab:sw=4:ts=4: