1 /* src/vmcore/method.c - method functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
36 #include "mm/memory.h"
38 #include "native/llni.h"
40 #include "threads/lock-common.h"
43 #include "vm/builtin.h"
44 #include "vm/exceptions.h"
45 #include "vm/global.h"
46 #include "vm/resolve.h"
48 #include "vm/jit/code.h"
49 #include "vm/jit/methodheader.h"
51 #include "vm/jit_interface.h"
53 #include "vmcore/class.h"
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"
61 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
62 #define INLINELOG(code) do { if (opt_TraceInlining) { code } } while (0)
64 #define INLINELOG(code)
68 /* method_load *****************************************************************
70 Loads a method from the class file and fills an existing methodinfo
78 attribute_info attributes[attribute_count];
82 u2 attribute_name_index;
84 u1 info[attribute_length];
87 LineNumberTable_attribute {
88 u2 attribute_name_index;
90 u2 line_number_table_length;
94 } line_number_table[line_number_table_length];
97 *******************************************************************************/
99 bool method_load(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
108 u2 attribute_name_index;
110 u2 code_attributes_count;
111 u2 code_attribute_name_index;
112 utf *code_attribute_name;
118 LOCK_INIT_OBJECT_LOCK(&(m->header));
120 #if defined(ENABLE_STATISTICS)
125 /* all fields of m have been zeroed in load_class_from_classbuffer */
129 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
134 m->flags = suck_u2(cb);
138 name_index = suck_u2(cb);
140 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
147 descriptor_index = suck_u2(cb);
149 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
154 if (!descriptor_pool_add(descpool, u, &argcount))
157 #ifdef ENABLE_VERIFIER
159 if (!is_valid_name_utf(m->name)) {
160 exceptions_throw_classformaterror(c, "Method with invalid name");
164 if (m->name->text[0] == '<' &&
165 m->name != utf_init && m->name != utf_clinit) {
166 exceptions_throw_classformaterror(c, "Method with invalid special name");
170 #endif /* ENABLE_VERIFIER */
172 if (!(m->flags & ACC_STATIC))
173 argcount++; /* count the 'this' argument */
175 #ifdef ENABLE_VERIFIER
177 if (argcount > 255) {
178 exceptions_throw_classformaterror(c, "Too many arguments in signature");
182 /* check flag consistency */
183 if (m->name != utf_clinit) {
184 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
186 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
187 exceptions_throw_classformaterror(c,
188 "Illegal method modifiers: 0x%X",
193 if (m->flags & ACC_ABSTRACT) {
194 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
195 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
196 exceptions_throw_classformaterror(c,
197 "Illegal method modifiers: 0x%X",
203 if (c->flags & ACC_INTERFACE) {
204 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
205 exceptions_throw_classformaterror(c,
206 "Illegal method modifiers: 0x%X",
212 if (m->name == utf_init) {
213 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
214 ACC_NATIVE | ACC_ABSTRACT)) {
215 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
221 #endif /* ENABLE_VERIFIER */
223 /* mark the method as monomorphic until further notice */
225 m->flags |= ACC_METHOD_MONOMORPHIC;
227 /* non-abstract methods have an implementation in this class */
229 if (!(m->flags & ACC_ABSTRACT))
230 m->flags |= ACC_METHOD_IMPLEMENTED;
232 if (!suck_check_classbuffer_size(cb, 2))
235 /* attributes count */
237 attributes_count = suck_u2(cb);
239 for (i = 0; i < attributes_count; i++) {
240 if (!suck_check_classbuffer_size(cb, 2))
243 /* attribute name index */
245 attribute_name_index = suck_u2(cb);
248 class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
250 if (attribute_name == NULL)
253 if (attribute_name == utf_Code) {
256 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
257 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
262 exceptions_throw_classformaterror(c, "Multiple Code attributes");
266 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
270 m->maxstack = suck_u2(cb);
271 m->maxlocals = suck_u2(cb);
273 if (m->maxlocals < argcount) {
274 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
278 if (!suck_check_classbuffer_size(cb, 4))
281 m->jcodelength = suck_u4(cb);
283 if (m->jcodelength == 0) {
284 exceptions_throw_classformaterror(c, "Code of a method has length 0");
288 if (m->jcodelength > 65535) {
289 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
293 if (!suck_check_classbuffer_size(cb, m->jcodelength))
296 m->jcode = MNEW(u1, m->jcodelength);
297 suck_nbytes(m->jcode, cb, m->jcodelength);
299 if (!suck_check_classbuffer_size(cb, 2))
302 m->rawexceptiontablelength = suck_u2(cb);
303 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
306 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
308 #if defined(ENABLE_STATISTICS)
310 count_vmcode_len += m->jcodelength + 18;
312 m->rawexceptiontablelength * sizeof(raw_exception_entry);
316 for (j = 0; j < m->rawexceptiontablelength; j++) {
318 m->rawexceptiontable[j].startpc = suck_u2(cb);
319 m->rawexceptiontable[j].endpc = suck_u2(cb);
320 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
325 m->rawexceptiontable[j].catchtype.any = NULL;
328 /* the classref is created later */
329 if (!(m->rawexceptiontable[j].catchtype.any =
330 (utf *) class_getconstant(c, idx, CONSTANT_Class)))
335 if (!suck_check_classbuffer_size(cb, 2))
338 /* code attributes count */
340 code_attributes_count = suck_u2(cb);
342 for (k = 0; k < code_attributes_count; k++) {
343 if (!suck_check_classbuffer_size(cb, 2))
346 /* code attribute name index */
348 code_attribute_name_index = suck_u2(cb);
350 code_attribute_name =
351 class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8);
353 if (code_attribute_name == NULL)
356 /* check which code attribute */
358 if (code_attribute_name == utf_LineNumberTable) {
359 /* LineNumberTable */
361 if (!suck_check_classbuffer_size(cb, 4 + 2))
364 /* attribute length */
368 /* line number table length */
370 m->linenumbercount = suck_u2(cb);
372 if (!suck_check_classbuffer_size(cb,
373 (2 + 2) * m->linenumbercount))
376 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
378 #if defined(ENABLE_STATISTICS)
380 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
383 for (l = 0; l < m->linenumbercount; l++) {
384 m->linenumbers[l].start_pc = suck_u2(cb);
385 m->linenumbers[l].line_number = suck_u2(cb);
388 #if defined(ENABLE_JAVASE)
389 else if (code_attribute_name == utf_StackMapTable) {
392 if (!stackmap_load_attribute_stackmaptable(cb, m))
397 /* unknown code attribute */
399 if (!loader_skip_attribute_body(cb))
404 else if (attribute_name == utf_Exceptions) {
407 if (m->thrownexceptions != NULL) {
408 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
412 if (!suck_check_classbuffer_size(cb, 4 + 2))
415 /* attribute length */
419 m->thrownexceptionscount = suck_u2(cb);
421 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
424 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
426 for (j = 0; j < m->thrownexceptionscount; j++) {
427 /* the classref is created later */
428 if (!((m->thrownexceptions)[j].any =
429 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
433 #if defined(ENABLE_JAVASE)
434 else if (attribute_name == utf_Signature) {
437 if (!loader_load_attribute_signature(cb, &(m->signature)))
441 #if defined(ENABLE_ANNOTATIONS)
442 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
443 /* RuntimeVisibleAnnotations */
444 if (!annotation_load_method_attribute_runtimevisibleannotations(cb, m))
447 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
448 /* RuntimeInvisibleAnnotations */
449 if (!annotation_load_method_attribute_runtimeinvisibleannotations(cb, m))
452 else if (attribute_name == utf_RuntimeVisibleParameterAnnotations) {
453 /* RuntimeVisibleParameterAnnotations */
454 if (!annotation_load_method_attribute_runtimevisibleparameterannotations(cb, m))
457 else if (attribute_name == utf_RuntimeInvisibleParameterAnnotations) {
458 /* RuntimeInvisibleParameterAnnotations */
459 if (!annotation_load_method_attribute_runtimeinvisibleparameterannotations(cb, m))
462 else if (attribute_name == utf_AnnotationDefault) {
463 /* AnnotationDefault */
464 if (!annotation_load_method_attribute_annotationdefault(cb, m))
470 /* unknown attribute */
472 if (!loader_skip_attribute_body(cb))
477 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
478 exceptions_throw_classformaterror(c, "Missing Code attribute");
482 #if defined(ENABLE_REPLACEMENT)
483 /* initialize the hit countdown field */
485 m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
488 /* everything was ok */
494 /* method_free *****************************************************************
496 Frees all memory that was allocated for this method.
498 *******************************************************************************/
500 void method_free(methodinfo *m)
503 MFREE(m->jcode, u1, m->jcodelength);
505 if (m->rawexceptiontable)
506 MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
508 code_free_code_of_method(m);
510 if (m->stubroutine) {
511 if (m->flags & ACC_NATIVE) {
512 removenativestub(m->stubroutine);
515 removecompilerstub(m->stubroutine);
521 /* method_canoverwrite *********************************************************
523 Check if m and old are identical with respect to type and
524 name. This means that old can be overwritten with m.
526 *******************************************************************************/
528 bool method_canoverwrite(methodinfo *m, methodinfo *old)
530 if (m->name != old->name)
533 if (m->descriptor != old->descriptor)
536 if (m->flags & ACC_STATIC)
543 /* method_new_builtin **********************************************************
545 Creates a minimal methodinfo structure for builtins. This comes handy
546 when dealing with builtin stubs or stacktraces.
548 *******************************************************************************/
550 methodinfo *method_new_builtin(builtintable_entry *bte)
554 /* allocate the methodinfo structure */
558 /* initialize methodinfo structure */
560 MZERO(m, methodinfo, 1);
561 LOCK_INIT_OBJECT_LOCK(&(m->header));
563 m->flags = ACC_METHOD_BUILTIN;
564 m->parseddesc = bte->md;
566 m->descriptor = bte->descriptor;
568 /* return the newly created methodinfo */
574 /* method_vftbl_lookup *********************************************************
576 Does a method lookup in the passed virtual function table. This
577 function does exactly the same thing as JIT, but additionally
578 relies on the fact, that the methodinfo pointer is at the first
579 data segment slot (even for compiler stubs).
581 *******************************************************************************/
583 methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
587 methodinfo *resm; /* pointer to new resolved method */
589 /* If the method is not an instance method, just return it. */
591 if (m->flags & ACC_STATIC)
596 /* Get the method from the virtual function table. Is this an
599 if (m->class->flags & ACC_INTERFACE) {
600 pmptr = vftbl->interfacetable[-(m->class->index)];
601 mptr = pmptr[(m - m->class->methods)];
604 mptr = vftbl->table[m->vftblindex];
607 /* and now get the codeinfo pointer from the first data segment slot */
609 resm = code_get_methodinfo_for_pv(mptr);
615 /* method_get_parametercount **************************************************
617 Use the descriptor of a method to determine the number of parameters
618 of the method. The this pointer of non-static methods is not counted.
621 m........the method of which the parameters should be counted
624 The parameter count or -1 on error.
626 *******************************************************************************/
628 int32_t method_get_parametercount(methodinfo *m)
630 methoddesc *md; /* method descriptor of m */
631 int32_t paramcount = 0; /* the parameter count of m */
635 /* is the descriptor fully parsed? */
637 if (md->params == NULL) {
638 if (!descriptor_params_from_paramtypes(md, m->flags)) {
643 paramcount = md->paramcount;
645 /* skip `this' pointer */
647 if (!(m->flags & ACC_STATIC)) {
655 /* method_get_parametertypearray ***********************************************
657 Use the descriptor of a method to generate a java.lang.Class array
658 which contains the classes of the parametertypes of the method.
660 This function is called by java.lang.reflect.{Constructor,Method}.
662 *******************************************************************************/
664 java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m)
667 typedesc *paramtypes;
669 java_handle_objectarray_t *oa;
675 /* is the descriptor fully parsed? */
677 if (m->parseddesc->params == NULL)
678 if (!descriptor_params_from_paramtypes(md, m->flags))
681 paramtypes = md->paramtypes;
682 paramcount = md->paramcount;
684 /* skip `this' pointer */
686 if (!(m->flags & ACC_STATIC)) {
691 /* create class-array */
693 oa = builtin_anewarray(paramcount, class_java_lang_Class);
700 for (i = 0; i < paramcount; i++) {
701 if (!resolve_class_from_typedesc(¶mtypes[i], true, false, &c))
704 LLNI_array_direct(oa, i) = (java_object_t *) c;
711 /* method_get_exceptionarray ***************************************************
713 Get the exceptions which can be thrown by a method.
715 *******************************************************************************/
717 java_handle_objectarray_t *method_get_exceptionarray(methodinfo *m)
719 java_handle_objectarray_t *oa;
723 /* create class-array */
725 oa = builtin_anewarray(m->thrownexceptionscount, class_java_lang_Class);
730 /* iterate over all exceptions and store the class in the array */
732 for (i = 0; i < m->thrownexceptionscount; i++) {
733 c = resolve_classref_or_classinfo_eager(m->thrownexceptions[i], true);
738 LLNI_array_direct(oa, i) = (java_object_t *) c;
745 /* method_returntype_get *******************************************************
747 Get the return type of the method.
749 *******************************************************************************/
751 classinfo *method_returntype_get(methodinfo *m)
756 td = &(m->parseddesc->returntype);
758 if (!resolve_class_from_typedesc(td, true, false, &c))
765 /* method_count_implementations ************************************************
767 Count the implementations of a method in a class cone (a class and all its
771 m................the method to count
772 c................class at which to start the counting (this class and
773 all its subclasses will be searched)
776 *found...........if found != NULL, *found receives the method
777 implementation that was found. This value is only
778 meaningful if the return value is 1.
781 the number of implementations found
783 *******************************************************************************/
785 s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
795 mend = mp + c->methodscount;
797 for (; mp < mend; ++mp) {
798 if (method_canoverwrite(mp, m)) {
806 for (child = c->sub; child != NULL; child = child->nextsub) {
807 count += method_count_implementations(m, child, found);
814 /* method_get_annotations ******************************************************
816 Get a methods' unparsed annotations in a byte array.
819 m........the method of which the annotations should be returned
822 The unparsed annotations in a byte array (or NULL if there aren't any).
824 *******************************************************************************/
826 java_handle_bytearray_t *method_get_annotations(methodinfo *m)
828 #if defined(ENABLE_ANNOTATIONS)
829 classinfo *c; /* methods' declaring class */
830 int slot; /* methods' slot */
831 java_handle_t *annotations; /* methods' unparsed annotations */
832 java_handle_t *method_annotations; /* all methods' unparsed annotations */
833 /* of the declaring class */
836 slot = m - c->methods;
839 LLNI_classinfo_field_get(c, method_annotations, method_annotations);
841 /* the method_annotations array might be shorter then the method
842 * count if the methods above a certain index have no annotations.
844 if (method_annotations != NULL &&
845 array_length_get(method_annotations) > slot) {
846 annotations = array_objectarray_element_get(
847 (java_handle_objectarray_t*)method_annotations, slot);
850 return (java_handle_bytearray_t*)annotations;
857 /* method_get_parameterannotations ********************************************
859 Get a methods' unparsed parameter annotations in an array of byte
863 m........the method of which the parameter annotations should be
867 The unparsed parameter annotations in a byte array (or NULL if
870 *******************************************************************************/
872 java_handle_bytearray_t *method_get_parameterannotations(methodinfo *m)
874 #if defined(ENABLE_ANNOTATIONS)
875 classinfo *c; /* methods' declaring class */
876 int slot; /* methods' slot */
877 java_handle_t *parameterAnnotations; /* methods' unparsed */
878 /* parameter annotations */
879 java_handle_t *method_parameterannotations; /* all methods' unparsed */
880 /* parameter annotations of */
881 /* the declaring class */
884 slot = m - c->methods;
885 parameterAnnotations = NULL;
887 LLNI_classinfo_field_get(
888 c, method_parameterannotations, method_parameterannotations);
890 /* the method_annotations array might be shorter then the method
891 * count if the methods above a certain index have no annotations.
893 if (method_parameterannotations != NULL &&
894 array_length_get(method_parameterannotations) > slot) {
895 parameterAnnotations = array_objectarray_element_get(
896 (java_handle_objectarray_t*)method_parameterannotations,
900 return (java_handle_bytearray_t*)parameterAnnotations;
907 /* method_get_annotationdefault ***********************************************
909 Get a methods' unparsed annotation default value in a byte array.
912 m........the method of which the annotation default value should be
916 The unparsed annotation default value in a byte array (or NULL if
919 *******************************************************************************/
921 java_handle_bytearray_t *method_get_annotationdefault(methodinfo *m)
923 #if defined(ENABLE_ANNOTATIONS)
924 classinfo *c; /* methods' declaring class */
925 int slot; /* methods' slot */
926 java_handle_t *annotationDefault; /* methods' unparsed */
927 /* annotation default value */
928 java_handle_t *method_annotationdefaults; /* all methods' unparsed */
929 /* annotation default values of */
930 /* the declaring class */
933 slot = m - c->methods;
934 annotationDefault = NULL;
936 LLNI_classinfo_field_get(
937 c, method_annotationdefaults, method_annotationdefaults);
939 /* the method_annotations array might be shorter then the method
940 * count if the methods above a certain index have no annotations.
942 if (method_annotationdefaults != NULL &&
943 array_length_get(method_annotationdefaults) > slot) {
944 annotationDefault = array_objectarray_element_get(
945 (java_handle_objectarray_t*)method_annotationdefaults, slot);
948 return (java_handle_bytearray_t*)annotationDefault;
955 /* method_add_to_worklist ******************************************************
957 Add the method to the given worklist. If the method already occurs in
958 the worklist, the worklist remains unchanged.
960 *******************************************************************************/
962 static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
966 for (wi = *wl; wi != NULL; wi = wi->next)
970 wi = NEW(method_worklist);
978 /* method_add_assumption_monomorphic *******************************************
980 Record the assumption that the method is monomorphic.
983 m.................the method
984 caller............the caller making the assumption
986 *******************************************************************************/
988 void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
990 method_assumption *as;
992 /* XXX LOCKING FOR THIS FUNCTION? */
994 /* check if we already have registered this assumption */
996 for (as = m->assumptions; as != NULL; as = as->next) {
997 if (as->context == caller)
1001 /* register the assumption */
1003 as = NEW(method_assumption);
1004 as->next = m->assumptions;
1005 as->context = caller;
1007 m->assumptions = as;
1011 /* method_break_assumption_monomorphic *****************************************
1013 Break the assumption that this method is monomorphic. All callers that
1014 have registered this assumption are added to the worklist.
1017 m.................the method
1018 wl................worklist where to add invalidated callers
1020 *******************************************************************************/
1022 void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
1024 method_assumption *as;
1026 /* XXX LOCKING FOR THIS FUNCTION? */
1028 for (as = m->assumptions; as != NULL; as = as->next) {
1030 printf("ASSUMPTION BROKEN (monomorphism): ");
1033 method_println(as->context);
1036 method_add_to_worklist(as->context, wl);
1041 /* method_printflags ***********************************************************
1043 Prints the flags of a method to stdout like.
1045 *******************************************************************************/
1047 #if !defined(NDEBUG)
1048 void method_printflags(methodinfo *m)
1055 if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
1056 if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
1057 if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
1058 if (m->flags & ACC_STATIC) printf(" STATIC");
1059 if (m->flags & ACC_FINAL) printf(" FINAL");
1060 if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1061 if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
1062 if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
1063 if (m->flags & ACC_NATIVE) printf(" NATIVE");
1064 if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
1065 if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
1066 if (m->flags & ACC_METHOD_BUILTIN) printf(" (builtin)");
1067 if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
1068 if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
1070 #endif /* !defined(NDEBUG) */
1073 /* method_print ****************************************************************
1075 Prints a method to stdout like:
1077 java.lang.Object.<init>()V
1079 *******************************************************************************/
1081 #if !defined(NDEBUG)
1082 void method_print(methodinfo *m)
1089 if (m->class != NULL)
1090 utf_display_printable_ascii_classname(m->class->name);
1094 utf_display_printable_ascii(m->name);
1095 utf_display_printable_ascii(m->descriptor);
1097 method_printflags(m);
1099 #endif /* !defined(NDEBUG) */
1102 /* method_println **************************************************************
1104 Prints a method plus new line to stdout like:
1106 java.lang.Object.<init>()V
1108 *******************************************************************************/
1110 #if !defined(NDEBUG)
1111 void method_println(methodinfo *m)
1113 if (opt_debugcolor) printf("\033[31m"); /* red */
1115 if (opt_debugcolor) printf("\033[m");
1118 #endif /* !defined(NDEBUG) */
1121 /* method_methodref_print ******************************************************
1123 Prints a method reference to stdout.
1125 *******************************************************************************/
1127 #if !defined(NDEBUG)
1128 void method_methodref_print(constant_FMIref *mr)
1131 printf("(constant_FMIref *)NULL");
1135 if (IS_FMIREF_RESOLVED(mr)) {
1136 printf("<method> ");
1137 method_print(mr->p.method);
1140 printf("<methodref> ");
1141 utf_display_printable_ascii_classname(mr->p.classref->name);
1143 utf_display_printable_ascii(mr->name);
1144 utf_display_printable_ascii(mr->descriptor);
1147 #endif /* !defined(NDEBUG) */
1150 /* method_methodref_println ****************************************************
1152 Prints a method reference to stdout, followed by a newline.
1154 *******************************************************************************/
1156 #if !defined(NDEBUG)
1157 void method_methodref_println(constant_FMIref *mr)
1159 method_methodref_print(mr);
1162 #endif /* !defined(NDEBUG) */
1166 * These are local overrides for various environment variables in Emacs.
1167 * Please do not remove this and leave it at the end of the file, where
1168 * Emacs will automagically detect them.
1169 * ---------------------------------------------------------------------
1172 * indent-tabs-mode: t
1176 * vim:noexpandtab:sw=4:ts=4: