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/lock-common.h"
41 #include "vm/builtin.h"
43 #include "vm/exceptions.hpp"
44 #include "vm/global.h"
45 #include "vm/globals.hpp"
46 #include "vm/linker.h"
47 #include "vm/loader.h"
48 #include "vm/method.h"
49 #include "vm/options.h"
50 #include "vm/resolve.h"
55 #include "vm/jit/code.h"
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 LOCK_INIT_OBJECT_LOCK(&(m->header));
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 MFREE(m->jcode, u1, m->jcodelength);
534 if (m->rawexceptiontable)
535 MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
537 code_free_code_of_method(m);
539 if (m->stubroutine) {
540 if (m->flags & ACC_NATIVE) {
541 NativeStub_remove(m->stubroutine);
544 CompilerStub_remove(m->stubroutine);
550 /* method_canoverwrite *********************************************************
552 Check if m and old are identical with respect to type and
553 name. This means that old can be overwritten with m.
555 *******************************************************************************/
557 bool method_canoverwrite(methodinfo *m, methodinfo *old)
559 if (m->name != old->name)
562 if (m->descriptor != old->descriptor)
565 if (m->flags & ACC_STATIC)
572 /* method_new_builtin **********************************************************
574 Creates a minimal methodinfo structure for builtins. This comes handy
575 when dealing with builtin stubs or stacktraces.
577 *******************************************************************************/
579 methodinfo *method_new_builtin(builtintable_entry *bte)
583 /* allocate the methodinfo structure */
587 /* initialize methodinfo structure */
589 MZERO(m, methodinfo, 1);
590 LOCK_INIT_OBJECT_LOCK(&(m->header));
592 m->flags = ACC_METHOD_BUILTIN;
593 m->parseddesc = bte->md;
595 m->descriptor = bte->descriptor;
597 /* return the newly created methodinfo */
603 /* method_vftbl_lookup *********************************************************
605 Does a method lookup in the passed virtual function table. This
606 function does exactly the same thing as JIT, but additionally
607 relies on the fact, that the methodinfo pointer is at the first
608 data segment slot (even for compiler stubs).
610 *******************************************************************************/
612 methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
616 methodinfo *resm; /* pointer to new resolved method */
618 /* If the method is not an instance method, just return it. */
620 if (m->flags & ACC_STATIC)
625 /* Get the method from the virtual function table. Is this an
628 if (m->clazz->flags & ACC_INTERFACE) {
629 pmptr = vftbl->interfacetable[-(m->clazz->index)];
630 mptr = pmptr[(m - m->clazz->methods)];
633 mptr = vftbl->table[m->vftblindex];
636 /* and now get the codeinfo pointer from the first data segment slot */
638 resm = code_get_methodinfo_for_pv(mptr);
644 /* method_get_parametercount **************************************************
646 Use the descriptor of a method to determine the number of parameters
647 of the method. The this pointer of non-static methods is not counted.
650 m........the method of which the parameters should be counted
653 The parameter count or -1 on error.
655 *******************************************************************************/
657 int32_t method_get_parametercount(methodinfo *m)
659 methoddesc *md; /* method descriptor of m */
660 int32_t paramcount = 0; /* the parameter count of m */
664 /* is the descriptor fully parsed? */
666 if (md->params == NULL) {
667 if (!descriptor_params_from_paramtypes(md, m->flags)) {
672 paramcount = md->paramcount;
674 /* skip `this' pointer */
676 if (!(m->flags & ACC_STATIC)) {
684 /* method_get_parametertypearray ***********************************************
686 Use the descriptor of a method to generate a java.lang.Class array
687 which contains the classes of the parametertypes of the method.
689 This function is called by java.lang.reflect.{Constructor,Method}.
691 *******************************************************************************/
693 java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m)
696 typedesc *paramtypes;
698 java_handle_objectarray_t *oa;
704 /* is the descriptor fully parsed? */
706 if (m->parseddesc->params == NULL)
707 if (!descriptor_params_from_paramtypes(md, m->flags))
710 paramtypes = md->paramtypes;
711 paramcount = md->paramcount;
713 /* skip `this' pointer */
715 if (!(m->flags & ACC_STATIC)) {
720 /* create class-array */
722 oa = builtin_anewarray(paramcount, class_java_lang_Class);
729 for (i = 0; i < paramcount; i++) {
730 if (!resolve_class_from_typedesc(¶mtypes[i], true, false, &c))
733 LLNI_array_direct(oa, i) = (java_object_t *) c;
740 /* method_get_exceptionarray ***************************************************
742 Get the exceptions which can be thrown by a method.
744 *******************************************************************************/
746 java_handle_objectarray_t *method_get_exceptionarray(methodinfo *m)
748 java_handle_objectarray_t *oa;
752 /* create class-array */
754 oa = builtin_anewarray(m->thrownexceptionscount, class_java_lang_Class);
759 /* iterate over all exceptions and store the class in the array */
761 for (i = 0; i < m->thrownexceptionscount; i++) {
762 c = resolve_classref_or_classinfo_eager(m->thrownexceptions[i], true);
767 LLNI_array_direct(oa, i) = (java_object_t *) c;
774 /* method_returntype_get *******************************************************
776 Get the return type of the method.
778 *******************************************************************************/
780 classinfo *method_returntype_get(methodinfo *m)
785 td = &(m->parseddesc->returntype);
787 if (!resolve_class_from_typedesc(td, true, false, &c))
794 /* method_count_implementations ************************************************
796 Count the implementations of a method in a class cone (a class and all its
800 m................the method to count
801 c................class at which to start the counting (this class and
802 all its subclasses will be searched)
805 *found...........if found != NULL, *found receives the method
806 implementation that was found. This value is only
807 meaningful if the return value is 1.
810 the number of implementations found
812 *******************************************************************************/
814 s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
824 mend = mp + c->methodscount;
826 for (; mp < mend; ++mp) {
827 if (method_canoverwrite(mp, m)) {
835 for (child = c->sub; child != NULL; child = child->nextsub) {
836 count += method_count_implementations(m, child, found);
843 /* method_get_annotations ******************************************************
845 Get a methods' unparsed annotations in a byte array.
848 m........the method of which the annotations should be returned
851 The unparsed annotations in a byte array (or NULL if there aren't any).
853 *******************************************************************************/
855 java_handle_bytearray_t *method_get_annotations(methodinfo *m)
857 #if defined(ENABLE_ANNOTATIONS)
858 classinfo *c; /* methods' declaring class */
859 int slot; /* methods' slot */
860 java_handle_t *annotations; /* methods' unparsed annotations */
861 java_handle_t *method_annotations; /* all methods' unparsed annotations */
862 /* of the declaring class */
865 slot = m - c->methods;
868 LLNI_classinfo_field_get(c, method_annotations, method_annotations);
870 /* the method_annotations array might be shorter then the method
871 * count if the methods above a certain index have no annotations.
873 if (method_annotations != NULL &&
874 array_length_get(method_annotations) > slot) {
875 annotations = array_objectarray_element_get(
876 (java_handle_objectarray_t*)method_annotations, slot);
879 return (java_handle_bytearray_t*)annotations;
886 /* method_get_parameterannotations ********************************************
888 Get a methods' unparsed parameter annotations in an array of byte
892 m........the method of which the parameter annotations should be
896 The unparsed parameter annotations in a byte array (or NULL if
899 *******************************************************************************/
901 java_handle_bytearray_t *method_get_parameterannotations(methodinfo *m)
903 #if defined(ENABLE_ANNOTATIONS)
904 classinfo *c; /* methods' declaring class */
905 int slot; /* methods' slot */
906 java_handle_t *parameterAnnotations; /* methods' unparsed */
907 /* parameter annotations */
908 java_handle_t *method_parameterannotations; /* all methods' unparsed */
909 /* parameter annotations of */
910 /* the declaring class */
913 slot = m - c->methods;
914 parameterAnnotations = NULL;
916 LLNI_classinfo_field_get(
917 c, method_parameterannotations, method_parameterannotations);
919 /* the method_annotations array might be shorter then the method
920 * count if the methods above a certain index have no annotations.
922 if (method_parameterannotations != NULL &&
923 array_length_get(method_parameterannotations) > slot) {
924 parameterAnnotations = array_objectarray_element_get(
925 (java_handle_objectarray_t*)method_parameterannotations,
929 return (java_handle_bytearray_t*)parameterAnnotations;
936 /* method_get_annotationdefault ***********************************************
938 Get a methods' unparsed annotation default value in a byte array.
941 m........the method of which the annotation default value should be
945 The unparsed annotation default value in a byte array (or NULL if
948 *******************************************************************************/
950 java_handle_bytearray_t *method_get_annotationdefault(methodinfo *m)
952 #if defined(ENABLE_ANNOTATIONS)
953 classinfo *c; /* methods' declaring class */
954 int slot; /* methods' slot */
955 java_handle_t *annotationDefault; /* methods' unparsed */
956 /* annotation default value */
957 java_handle_t *method_annotationdefaults; /* all methods' unparsed */
958 /* annotation default values of */
959 /* the declaring class */
962 slot = m - c->methods;
963 annotationDefault = NULL;
965 LLNI_classinfo_field_get(
966 c, method_annotationdefaults, method_annotationdefaults);
968 /* the method_annotations array might be shorter then the method
969 * count if the methods above a certain index have no annotations.
971 if (method_annotationdefaults != NULL &&
972 array_length_get(method_annotationdefaults) > slot) {
973 annotationDefault = array_objectarray_element_get(
974 (java_handle_objectarray_t*)method_annotationdefaults, slot);
977 return (java_handle_bytearray_t*)annotationDefault;
984 /* method_add_to_worklist ******************************************************
986 Add the method to the given worklist. If the method already occurs in
987 the worklist, the worklist remains unchanged.
989 *******************************************************************************/
991 static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
995 for (wi = *wl; wi != NULL; wi = wi->next)
999 wi = NEW(method_worklist);
1007 /* method_add_assumption_monomorphic *******************************************
1009 Record the assumption that the method is monomorphic.
1012 m.................the method
1013 caller............the caller making the assumption
1015 *******************************************************************************/
1017 void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
1019 method_assumption *as;
1021 /* XXX LOCKING FOR THIS FUNCTION? */
1023 /* check if we already have registered this assumption */
1025 for (as = m->assumptions; as != NULL; as = as->next) {
1026 if (as->context == caller)
1030 /* register the assumption */
1032 as = NEW(method_assumption);
1033 as->next = m->assumptions;
1034 as->context = caller;
1036 m->assumptions = as;
1039 /* method_break_assumption_monomorphic *****************************************
1041 Break the assumption that this method is monomorphic. All callers that
1042 have registered this assumption are added to the worklist.
1045 m.................the method
1046 wl................worklist where to add invalidated callers
1048 *******************************************************************************/
1050 void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
1052 method_assumption *as;
1054 /* XXX LOCKING FOR THIS FUNCTION? */
1056 for (as = m->assumptions; as != NULL; as = as->next) {
1058 printf("ASSUMPTION BROKEN (monomorphism): ");
1061 method_println(as->context);
1064 method_add_to_worklist(as->context, wl);
1066 #if defined(ENABLE_TLH) && 0
1068 method_assumption *as2;
1069 as2 = m->assumptions;
1070 m->assumptions = NULL;
1071 method_break_assumption_monomorphic(as->context, wl);
1073 assert(m->assumptions == NULL);
1074 m->assumptions = as2;*/
1080 /* method_printflags ***********************************************************
1082 Prints the flags of a method to stdout like.
1084 *******************************************************************************/
1086 #if !defined(NDEBUG)
1087 void method_printflags(methodinfo *m)
1094 if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
1095 if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
1096 if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
1097 if (m->flags & ACC_STATIC) printf(" STATIC");
1098 if (m->flags & ACC_FINAL) printf(" FINAL");
1099 if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1100 if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
1101 if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
1102 if (m->flags & ACC_NATIVE) printf(" NATIVE");
1103 if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
1104 if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
1105 if (m->flags & ACC_METHOD_BUILTIN) printf(" (builtin)");
1106 if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
1107 if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
1109 #endif /* !defined(NDEBUG) */
1112 /* method_print ****************************************************************
1114 Prints a method to stdout like:
1116 java.lang.Object.<init>()V
1118 *******************************************************************************/
1120 #if !defined(NDEBUG)
1121 void method_print(methodinfo *m)
1128 if (m->clazz != NULL)
1129 utf_display_printable_ascii_classname(m->clazz->name);
1133 utf_display_printable_ascii(m->name);
1134 utf_display_printable_ascii(m->descriptor);
1136 method_printflags(m);
1138 #endif /* !defined(NDEBUG) */
1141 /* method_println **************************************************************
1143 Prints a method plus new line to stdout like:
1145 java.lang.Object.<init>()V
1147 *******************************************************************************/
1149 #if !defined(NDEBUG)
1150 void method_println(methodinfo *m)
1152 if (opt_debugcolor) printf("\033[31m"); /* red */
1154 if (opt_debugcolor) printf("\033[m");
1157 #endif /* !defined(NDEBUG) */
1160 /* method_methodref_print ******************************************************
1162 Prints a method reference to stdout.
1164 *******************************************************************************/
1166 #if !defined(NDEBUG)
1167 void method_methodref_print(constant_FMIref *mr)
1170 printf("(constant_FMIref *)NULL");
1174 if (IS_FMIREF_RESOLVED(mr)) {
1175 printf("<method> ");
1176 method_print(mr->p.method);
1179 printf("<methodref> ");
1180 utf_display_printable_ascii_classname(mr->p.classref->name);
1182 utf_display_printable_ascii(mr->name);
1183 utf_display_printable_ascii(mr->descriptor);
1186 #endif /* !defined(NDEBUG) */
1189 /* method_methodref_println ****************************************************
1191 Prints a method reference to stdout, followed by a newline.
1193 *******************************************************************************/
1195 #if !defined(NDEBUG)
1196 void method_methodref_println(constant_FMIref *mr)
1198 method_methodref_print(mr);
1201 #endif /* !defined(NDEBUG) */
1205 * These are local overrides for various environment variables in Emacs.
1206 * Please do not remove this and leave it at the end of the file, where
1207 * Emacs will automagically detect them.
1208 * ---------------------------------------------------------------------
1211 * indent-tabs-mode: t
1215 * vim:noexpandtab:sw=4:ts=4: