1 /* src/vm/method.cpp - method functions
3 Copyright (C) 1996-2011
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.hpp"
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.hpp"
47 #include "vm/loader.hpp"
48 #include "vm/method.hpp"
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)
66 /* global variables ***********************************************************/
68 methodinfo *method_java_lang_reflect_Method_invoke;
71 #if defined(__cplusplus)
76 /* method_init *****************************************************************
78 Initialize method subsystem.
80 *******************************************************************************/
82 void method_init(void)
84 #if defined(ENABLE_JAVASE)
87 if (class_java_lang_reflect_Method == NULL)
88 vm_abort("method_init: class_java_lang_reflect_Method is NULL");
90 /* Cache java.lang.reflect.Method.invoke() */
92 method_java_lang_reflect_Method_invoke =
93 class_findmethod(class_java_lang_reflect_Method, utf_invoke, NULL);
95 if (method_java_lang_reflect_Method_invoke == NULL)
96 vm_abort("method_init: Could not resolve method java.lang.reflect.Method.invoke().");
101 /* method_load *****************************************************************
103 Loads a method from the class file and fills an existing methodinfo
111 attribute_info attributes[attribute_count];
115 u2 attribute_name_index;
117 u1 info[attribute_length];
120 LineNumberTable_attribute {
121 u2 attribute_name_index;
123 u2 line_number_table_length;
127 } line_number_table[line_number_table_length];
130 LocalVariableTable_attribute {
131 u2 attribute_name_index;
133 u2 local_variable_table_length;
140 } local_variable_table[local_variable_table_length];
143 *******************************************************************************/
145 bool method_load(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
154 u2 attribute_name_index;
156 u2 code_attributes_count;
157 u2 code_attribute_name_index;
158 utf *code_attribute_name;
164 m->mutex = new Mutex();
166 #if defined(ENABLE_STATISTICS)
171 /* all fields of m have been zeroed in load_class_from_classbuffer */
175 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
180 m->flags = suck_u2(cb);
184 name_index = suck_u2(cb);
186 if (!(u = (utf*) class_getconstant(c, name_index, CONSTANT_Utf8)))
193 descriptor_index = suck_u2(cb);
195 if (!(u = (utf*) class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
200 if (!descriptor_pool_add(descpool, u, &argcount))
203 #ifdef ENABLE_VERIFIER
205 if (!is_valid_name_utf(m->name)) {
206 exceptions_throw_classformaterror(c, "Method with invalid name");
210 if (m->name->text[0] == '<' &&
211 m->name != utf_init && m->name != utf_clinit) {
212 exceptions_throw_classformaterror(c, "Method with invalid special name");
216 #endif /* ENABLE_VERIFIER */
218 /* Ignore flags for class initializer according to section 4.6
219 of "The Java Virtual Machine Specification, 2nd Edition" (see PR125). */
221 if (m->name == utf_clinit) {
222 m->flags &= ACC_STRICT;
223 m->flags |= ACC_STATIC;
226 if (!(m->flags & ACC_STATIC))
227 argcount++; /* count the 'this' argument */
229 #ifdef ENABLE_VERIFIER
231 if (argcount > 255) {
232 exceptions_throw_classformaterror(c, "Too many arguments in signature");
236 /* check flag consistency */
237 if (m->name != utf_clinit) {
238 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
240 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
241 exceptions_throw_classformaterror(c,
242 "Illegal method modifiers: 0x%X",
247 if (m->flags & ACC_ABSTRACT) {
248 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
249 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
250 exceptions_throw_classformaterror(c,
251 "Illegal method modifiers: 0x%X",
257 if (c->flags & ACC_INTERFACE) {
258 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
259 exceptions_throw_classformaterror(c,
260 "Illegal method modifiers: 0x%X",
266 if (m->name == utf_init) {
267 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
268 ACC_NATIVE | ACC_ABSTRACT)) {
269 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
275 #endif /* ENABLE_VERIFIER */
277 /* mark the method as monomorphic until further notice */
279 m->flags |= ACC_METHOD_MONOMORPHIC;
281 /* non-abstract methods have an implementation in this class */
283 if (!(m->flags & ACC_ABSTRACT))
284 m->flags |= ACC_METHOD_IMPLEMENTED;
286 if (!suck_check_classbuffer_size(cb, 2))
289 /* attributes count */
291 attributes_count = suck_u2(cb);
293 for (i = 0; i < attributes_count; i++) {
294 if (!suck_check_classbuffer_size(cb, 2))
297 /* attribute name index */
299 attribute_name_index = suck_u2(cb);
302 (utf*) class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
304 if (attribute_name == NULL)
307 if (attribute_name == utf_Code) {
310 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
311 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
316 exceptions_throw_classformaterror(c, "Multiple Code attributes");
320 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
324 m->maxstack = suck_u2(cb);
325 m->maxlocals = suck_u2(cb);
327 if (m->maxlocals < argcount) {
328 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
332 if (!suck_check_classbuffer_size(cb, 4))
335 m->jcodelength = suck_u4(cb);
337 if (m->jcodelength == 0) {
338 exceptions_throw_classformaterror(c, "Code of a method has length 0");
342 if (m->jcodelength > 65535) {
343 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
347 if (!suck_check_classbuffer_size(cb, m->jcodelength))
350 m->jcode = MNEW(u1, m->jcodelength);
351 suck_nbytes(m->jcode, cb, m->jcodelength);
353 if (!suck_check_classbuffer_size(cb, 2))
356 m->rawexceptiontablelength = suck_u2(cb);
357 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
360 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
362 #if defined(ENABLE_STATISTICS)
364 count_vmcode_len += m->jcodelength + 18;
366 m->rawexceptiontablelength * sizeof(raw_exception_entry);
370 for (j = 0; j < m->rawexceptiontablelength; j++) {
372 m->rawexceptiontable[j].startpc = suck_u2(cb);
373 m->rawexceptiontable[j].endpc = suck_u2(cb);
374 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
379 m->rawexceptiontable[j].catchtype.any = NULL;
382 /* the classref is created later */
383 if (!(m->rawexceptiontable[j].catchtype.any =
384 (utf *) class_getconstant(c, idx, CONSTANT_Class)))
389 if (!suck_check_classbuffer_size(cb, 2))
392 /* code attributes count */
394 code_attributes_count = suck_u2(cb);
396 for (k = 0; k < code_attributes_count; k++) {
397 if (!suck_check_classbuffer_size(cb, 2))
400 /* code attribute name index */
402 code_attribute_name_index = suck_u2(cb);
404 code_attribute_name =
405 (utf*) class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8);
407 if (code_attribute_name == NULL)
410 /* check which code attribute */
412 if (code_attribute_name == utf_LineNumberTable) {
413 /* LineNumberTable */
415 if (!suck_check_classbuffer_size(cb, 4 + 2))
418 /* attribute length */
422 /* line number table length */
424 m->linenumbercount = suck_u2(cb);
426 if (!suck_check_classbuffer_size(cb,
427 (2 + 2) * m->linenumbercount))
430 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
432 #if defined(ENABLE_STATISTICS)
434 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
437 for (l = 0; l < m->linenumbercount; l++) {
438 m->linenumbers[l].start_pc = suck_u2(cb);
439 m->linenumbers[l].line_number = suck_u2(cb);
442 #if defined(ENABLE_JAVASE)
443 else if (code_attribute_name == utf_StackMapTable) {
446 if (!stackmap_load_attribute_stackmaptable(cb, m))
449 # if defined(ENABLE_JVMTI)
450 else if (code_attribute_name == utf_LocalVariableTable) {
451 /* LocalVariableTable */
453 if (m->localvars != NULL) {
454 exceptions_throw_classformaterror(c, "Multiple LocalVariableTable attributes");
458 if (!suck_check_classbuffer_size(cb, 4 + 2))
464 m->localvarcount = suck_u2(cb);
466 if (!suck_check_classbuffer_size(cb, 10 * m->localvarcount))
469 m->localvars = MNEW(localvarinfo, m->localvarcount);
471 for (l = 0; l < m->localvarcount; l++) {
472 m->localvars[l].start_pc = suck_u2(cb);
473 m->localvars[l].length = suck_u2(cb);
475 uint16_t name_index = suck_u2(cb);
476 if (!(m->localvars[l].name = (utf*) class_getconstant(c, name_index, CONSTANT_Utf8)))
479 uint16_t descriptor_index = suck_u2(cb);
480 if (!(m->localvars[l].descriptor = (utf*) class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
483 m->localvars[l].index = suck_u2(cb);
485 // XXX Check if index is in range.
486 // XXX Check if index already taken.
489 # endif /* defined(ENABLE_JVMTI) */
490 #endif /* defined(ENABLE_JAVASE) */
492 /* unknown code attribute */
494 if (!loader_skip_attribute_body(cb))
499 else if (attribute_name == utf_Exceptions) {
502 if (m->thrownexceptions != NULL) {
503 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
507 if (!suck_check_classbuffer_size(cb, 4 + 2))
510 /* attribute length */
514 m->thrownexceptionscount = suck_u2(cb);
516 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
519 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
521 for (j = 0; j < m->thrownexceptionscount; j++) {
522 /* the classref is created later */
523 if (!((m->thrownexceptions)[j].any =
524 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
528 #if defined(ENABLE_JAVASE)
529 else if (attribute_name == utf_Signature) {
532 if (!loader_load_attribute_signature(cb, &(m->signature)))
536 # if defined(ENABLE_ANNOTATIONS)
537 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
538 /* RuntimeVisibleAnnotations */
539 if (!annotation_load_method_attribute_runtimevisibleannotations(cb, m))
542 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
543 /* RuntimeInvisibleAnnotations */
544 if (!annotation_load_method_attribute_runtimeinvisibleannotations(cb, m))
547 else if (attribute_name == utf_RuntimeVisibleParameterAnnotations) {
548 /* RuntimeVisibleParameterAnnotations */
549 if (!annotation_load_method_attribute_runtimevisibleparameterannotations(cb, m))
552 else if (attribute_name == utf_RuntimeInvisibleParameterAnnotations) {
553 /* RuntimeInvisibleParameterAnnotations */
554 if (!annotation_load_method_attribute_runtimeinvisibleparameterannotations(cb, m))
557 else if (attribute_name == utf_AnnotationDefault) {
558 /* AnnotationDefault */
559 if (!annotation_load_method_attribute_annotationdefault(cb, m))
565 /* unknown attribute */
567 if (!loader_skip_attribute_body(cb))
572 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
573 exceptions_throw_classformaterror(c, "Missing Code attribute");
577 #if defined(ENABLE_REPLACEMENT)
578 /* initialize the hit countdown field */
580 m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
583 /* everything was ok */
589 /* method_free *****************************************************************
591 Frees all memory that was allocated for this method.
593 *******************************************************************************/
595 void method_free(methodinfo *m)
601 MFREE(m->jcode, u1, m->jcodelength);
603 if (m->rawexceptiontable)
604 MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
606 code_free_code_of_method(m);
608 if (m->stubroutine) {
609 if (m->flags & ACC_NATIVE) {
610 NativeStub::remove(m->stubroutine);
613 CompilerStub::remove(m->stubroutine);
618 delete m->breakpoints;
622 /* method_canoverwrite *********************************************************
624 Check if m and old are identical with respect to type and
625 name. This means that old can be overwritten with m.
627 *******************************************************************************/
629 bool method_canoverwrite(methodinfo *m, methodinfo *old)
631 if (m->name != old->name)
634 if (m->descriptor != old->descriptor)
637 if (m->flags & ACC_STATIC)
644 /* method_new_builtin **********************************************************
646 Creates a minimal methodinfo structure for builtins. This comes handy
647 when dealing with builtin stubs or stacktraces.
649 *******************************************************************************/
651 methodinfo *method_new_builtin(builtintable_entry *bte)
655 /* allocate the methodinfo structure */
659 /* initialize methodinfo structure */
661 MZERO(m, methodinfo, 1);
663 m->mutex = new Mutex();
664 m->flags = ACC_METHOD_BUILTIN;
665 m->parseddesc = bte->md;
667 m->descriptor = bte->descriptor;
669 /* return the newly created methodinfo */
675 /* method_vftbl_lookup *********************************************************
677 Does a method lookup in the passed virtual function table. This
678 function does exactly the same thing as JIT, but additionally
679 relies on the fact, that the methodinfo pointer is at the first
680 data segment slot (even for compiler stubs).
682 *******************************************************************************/
684 methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
688 methodinfo *resm; /* pointer to new resolved method */
690 /* If the method is not an instance method, just return it. */
692 if (m->flags & ACC_STATIC)
697 /* Get the method from the virtual function table. Is this an
700 if (m->clazz->flags & ACC_INTERFACE) {
701 pmptr = vftbl->interfacetable[-(m->clazz->index)];
702 mptr = pmptr[(m - m->clazz->methods)];
705 mptr = vftbl->table[m->vftblindex];
708 /* and now get the codeinfo pointer from the first data segment slot */
710 resm = code_get_methodinfo_for_pv(mptr);
716 /* method_get_parametercount **************************************************
718 Use the descriptor of a method to determine the number of parameters
719 of the method. The this pointer of non-static methods is not counted.
722 m........the method of which the parameters should be counted
727 *******************************************************************************/
729 int32_t method_get_parametercount(methodinfo *m)
731 methoddesc *md; /* method descriptor of m */
732 int32_t paramcount = 0; /* the parameter count of m */
736 /* is the descriptor fully parsed? */
738 if (md->params == NULL)
739 descriptor_params_from_paramtypes(md, m->flags);
741 paramcount = md->paramcount;
743 /* skip `this' pointer */
745 if (!(m->flags & ACC_STATIC)) {
753 /* method_get_parametertypearray ***********************************************
755 Use the descriptor of a method to generate a java.lang.Class array
756 which contains the classes of the parametertypes of the method.
758 This function is called by java.lang.reflect.{Constructor,Method}.
760 *******************************************************************************/
762 java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m)
765 typedesc* paramtypes;
772 /* is the descriptor fully parsed? */
774 if (m->parseddesc->params == NULL)
775 descriptor_params_from_paramtypes(md, m->flags);
777 paramtypes = md->paramtypes;
778 paramcount = md->paramcount;
780 /* skip `this' pointer */
782 if (!(m->flags & ACC_STATIC)) {
787 /* create class-array */
789 ClassArray ca(paramcount);
796 for (i = 0; i < paramcount; i++) {
797 if (!resolve_class_from_typedesc(¶mtypes[i], true, false, &c))
800 ca.set_element(i, c);
803 return ca.get_handle();
807 /* method_get_exceptionarray ***************************************************
809 Get the exceptions which can be thrown by a method.
811 *******************************************************************************/
813 java_handle_objectarray_t *method_get_exceptionarray(methodinfo *m)
818 /* create class-array */
820 ClassArray ca(m->thrownexceptionscount);
825 /* iterate over all exceptions and store the class in the array */
827 for (i = 0; i < m->thrownexceptionscount; i++) {
828 c = resolve_classref_or_classinfo_eager(m->thrownexceptions[i], true);
833 ca.set_element(i, c);
836 return ca.get_handle();
840 /* method_returntype_get *******************************************************
842 Get the return type of the method.
844 *******************************************************************************/
846 classinfo *method_returntype_get(methodinfo *m)
851 td = &(m->parseddesc->returntype);
853 if (!resolve_class_from_typedesc(td, true, false, &c))
860 /* method_count_implementations ************************************************
862 Count the implementations of a method in a class cone (a class and all its
866 m................the method to count
867 c................class at which to start the counting (this class and
868 all its subclasses will be searched)
871 *found...........if found != NULL, *found receives the method
872 implementation that was found. This value is only
873 meaningful if the return value is 1.
876 the number of implementations found
878 *******************************************************************************/
880 s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
890 mend = mp + c->methodscount;
892 for (; mp < mend; ++mp) {
893 if (method_canoverwrite(mp, m)) {
901 for (child = c->sub; child != NULL; child = child->nextsub) {
902 count += method_count_implementations(m, child, found);
909 /* method_get_annotations ******************************************************
911 Get a methods' unparsed annotations in a byte array.
914 m........the method of which the annotations should be returned
917 The unparsed annotations in a byte array (or NULL if there aren't any).
919 *******************************************************************************/
921 java_handle_bytearray_t *method_get_annotations(methodinfo *m)
923 #if defined(ENABLE_ANNOTATIONS)
924 classinfo *c; /* methods' declaring class */
925 int slot; /* methods' slot */
926 java_handle_t *method_annotations; /* all methods' unparsed annotations */
927 /* of the declaring class */
930 slot = m - c->methods;
932 LLNI_classinfo_field_get(c, method_annotations, method_annotations);
934 ObjectArray oa((java_handle_objectarray_t*) method_annotations);
936 /* the method_annotations array might be shorter then the method
937 * count if the methods above a certain index have no annotations.
939 if (method_annotations != NULL && oa.get_length() > slot) {
940 return (java_handle_bytearray_t*) oa.get_element(slot);
950 /* method_get_parameterannotations ********************************************
952 Get a methods' unparsed parameter annotations in an array of byte
956 m........the method of which the parameter annotations should be
960 The unparsed parameter annotations in a byte array (or NULL if
963 *******************************************************************************/
965 java_handle_bytearray_t *method_get_parameterannotations(methodinfo *m)
967 #if defined(ENABLE_ANNOTATIONS)
968 classinfo *c; /* methods' declaring class */
969 int slot; /* methods' slot */
970 java_handle_t *method_parameterannotations; /* all methods' unparsed */
971 /* parameter annotations of */
972 /* the declaring class */
975 slot = m - c->methods;
977 LLNI_classinfo_field_get(
978 c, method_parameterannotations, method_parameterannotations);
980 ObjectArray oa((java_handle_objectarray_t*) method_parameterannotations);
982 /* the method_annotations array might be shorter then the method
983 * count if the methods above a certain index have no annotations.
985 if (method_parameterannotations != NULL && oa.get_length() > slot) {
986 return (java_handle_bytearray_t*) oa.get_element(slot);
996 /* method_get_annotationdefault ***********************************************
998 Get a methods' unparsed annotation default value in a byte array.
1001 m........the method of which the annotation default value should be
1005 The unparsed annotation default value in a byte array (or NULL if
1008 *******************************************************************************/
1010 java_handle_bytearray_t *method_get_annotationdefault(methodinfo *m)
1012 #if defined(ENABLE_ANNOTATIONS)
1013 classinfo *c; /* methods' declaring class */
1014 int slot; /* methods' slot */
1015 java_handle_t *method_annotationdefaults; /* all methods' unparsed */
1016 /* annotation default values of */
1017 /* the declaring class */
1020 slot = m - c->methods;
1022 LLNI_classinfo_field_get(
1023 c, method_annotationdefaults, method_annotationdefaults);
1025 ObjectArray oa((java_handle_objectarray_t*) method_annotationdefaults);
1027 /* the method_annotations array might be shorter then the method
1028 * count if the methods above a certain index have no annotations.
1030 if (method_annotationdefaults != NULL && oa.get_length() > slot) {
1031 return (java_handle_bytearray_t*) oa.get_element(slot);
1041 /* method_add_to_worklist ******************************************************
1043 Add the method to the given worklist. If the method already occurs in
1044 the worklist, the worklist remains unchanged.
1046 *******************************************************************************/
1048 static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
1050 method_worklist *wi;
1052 for (wi = *wl; wi != NULL; wi = wi->next)
1056 wi = NEW(method_worklist);
1064 /* method_add_assumption_monomorphic *******************************************
1066 Record the assumption that the method is monomorphic.
1069 m.................the method
1070 caller............the caller making the assumption
1072 *******************************************************************************/
1074 void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
1076 method_assumption *as;
1078 /* XXX LOCKING FOR THIS FUNCTION? */
1080 /* check if we already have registered this assumption */
1082 for (as = m->assumptions; as != NULL; as = as->next) {
1083 if (as->context == caller)
1087 /* register the assumption */
1089 as = NEW(method_assumption);
1090 as->next = m->assumptions;
1091 as->context = caller;
1093 m->assumptions = as;
1096 /* method_break_assumption_monomorphic *****************************************
1098 Break the assumption that this method is monomorphic. All callers that
1099 have registered this assumption are added to the worklist.
1102 m.................the method
1103 wl................worklist where to add invalidated callers
1105 *******************************************************************************/
1107 void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
1109 method_assumption *as;
1111 /* XXX LOCKING FOR THIS FUNCTION? */
1113 for (as = m->assumptions; as != NULL; as = as->next) {
1115 printf("ASSUMPTION BROKEN (monomorphism): ");
1118 method_println(as->context);
1121 method_add_to_worklist(as->context, wl);
1123 #if defined(ENABLE_TLH) && 0
1125 method_assumption *as2;
1126 as2 = m->assumptions;
1127 m->assumptions = NULL;
1128 method_break_assumption_monomorphic(as->context, wl);
1130 assert(m->assumptions == NULL);
1131 m->assumptions = as2;*/
1137 /* method_printflags ***********************************************************
1139 Prints the flags of a method to stdout like.
1141 *******************************************************************************/
1143 #if !defined(NDEBUG)
1144 void method_printflags(methodinfo *m)
1151 if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
1152 if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
1153 if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
1154 if (m->flags & ACC_STATIC) printf(" STATIC");
1155 if (m->flags & ACC_FINAL) printf(" FINAL");
1156 if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1157 if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
1158 if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
1159 if (m->flags & ACC_NATIVE) printf(" NATIVE");
1160 if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
1161 if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
1162 if (m->flags & ACC_METHOD_BUILTIN) printf(" (builtin)");
1163 if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
1164 if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
1166 #endif /* !defined(NDEBUG) */
1169 /* method_print ****************************************************************
1171 Prints a method to stdout like:
1173 java.lang.Object.<init>()V
1175 *******************************************************************************/
1177 #if !defined(NDEBUG)
1178 void method_print(methodinfo *m)
1185 if (m->clazz != NULL)
1186 utf_display_printable_ascii_classname(m->clazz->name);
1190 utf_display_printable_ascii(m->name);
1191 utf_display_printable_ascii(m->descriptor);
1193 method_printflags(m);
1195 #endif /* !defined(NDEBUG) */
1198 /* method_println **************************************************************
1200 Prints a method plus new line to stdout like:
1202 java.lang.Object.<init>()V
1204 *******************************************************************************/
1206 #if !defined(NDEBUG)
1207 void method_println(methodinfo *m)
1209 if (opt_debugcolor) printf("\033[31m"); /* red */
1211 if (opt_debugcolor) printf("\033[m");
1214 #endif /* !defined(NDEBUG) */
1217 /* method_methodref_print ******************************************************
1219 Prints a method reference to stdout.
1221 *******************************************************************************/
1223 #if !defined(NDEBUG)
1224 void method_methodref_print(constant_FMIref *mr)
1227 printf("(constant_FMIref *)NULL");
1231 if (IS_FMIREF_RESOLVED(mr)) {
1232 printf("<method> ");
1233 method_print(mr->p.method);
1236 printf("<methodref> ");
1237 utf_display_printable_ascii_classname(mr->p.classref->name);
1239 utf_display_printable_ascii(mr->name);
1240 utf_display_printable_ascii(mr->descriptor);
1243 #endif /* !defined(NDEBUG) */
1246 /* method_methodref_println ****************************************************
1248 Prints a method reference to stdout, followed by a newline.
1250 *******************************************************************************/
1252 #if !defined(NDEBUG)
1253 void method_methodref_println(constant_FMIref *mr)
1255 method_methodref_print(mr);
1258 #endif /* !defined(NDEBUG) */
1260 #if defined(__cplusplus)
1265 * These are local overrides for various environment variables in Emacs.
1266 * Please do not remove this and leave it at the end of the file, where
1267 * Emacs will automagically detect them.
1268 * ---------------------------------------------------------------------
1271 * indent-tabs-mode: t
1275 * vim:noexpandtab:sw=4:ts=4: