1 /* src/vm/method.cpp - 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.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
725 The parameter count or -1 on error.
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 if (!descriptor_params_from_paramtypes(md, m->flags)) {
744 paramcount = md->paramcount;
746 /* skip `this' pointer */
748 if (!(m->flags & ACC_STATIC)) {
756 /* method_get_parametertypearray ***********************************************
758 Use the descriptor of a method to generate a java.lang.Class array
759 which contains the classes of the parametertypes of the method.
761 This function is called by java.lang.reflect.{Constructor,Method}.
763 *******************************************************************************/
765 java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m)
768 typedesc* paramtypes;
775 /* is the descriptor fully parsed? */
777 if (m->parseddesc->params == NULL)
778 if (!descriptor_params_from_paramtypes(md, m->flags))
781 paramtypes = md->paramtypes;
782 paramcount = md->paramcount;
784 /* skip `this' pointer */
786 if (!(m->flags & ACC_STATIC)) {
791 /* create class-array */
793 ClassArray ca(paramcount);
800 for (i = 0; i < paramcount; i++) {
801 if (!resolve_class_from_typedesc(¶mtypes[i], true, false, &c))
804 ca.set_element(i, c);
807 return ca.get_handle();
811 /* method_get_exceptionarray ***************************************************
813 Get the exceptions which can be thrown by a method.
815 *******************************************************************************/
817 java_handle_objectarray_t *method_get_exceptionarray(methodinfo *m)
822 /* create class-array */
824 ClassArray ca(m->thrownexceptionscount);
829 /* iterate over all exceptions and store the class in the array */
831 for (i = 0; i < m->thrownexceptionscount; i++) {
832 c = resolve_classref_or_classinfo_eager(m->thrownexceptions[i], true);
837 ca.set_element(i, c);
840 return ca.get_handle();
844 /* method_returntype_get *******************************************************
846 Get the return type of the method.
848 *******************************************************************************/
850 classinfo *method_returntype_get(methodinfo *m)
855 td = &(m->parseddesc->returntype);
857 if (!resolve_class_from_typedesc(td, true, false, &c))
864 /* method_count_implementations ************************************************
866 Count the implementations of a method in a class cone (a class and all its
870 m................the method to count
871 c................class at which to start the counting (this class and
872 all its subclasses will be searched)
875 *found...........if found != NULL, *found receives the method
876 implementation that was found. This value is only
877 meaningful if the return value is 1.
880 the number of implementations found
882 *******************************************************************************/
884 s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
894 mend = mp + c->methodscount;
896 for (; mp < mend; ++mp) {
897 if (method_canoverwrite(mp, m)) {
905 for (child = c->sub; child != NULL; child = child->nextsub) {
906 count += method_count_implementations(m, child, found);
913 /* method_get_annotations ******************************************************
915 Get a methods' unparsed annotations in a byte array.
918 m........the method of which the annotations should be returned
921 The unparsed annotations in a byte array (or NULL if there aren't any).
923 *******************************************************************************/
925 java_handle_bytearray_t *method_get_annotations(methodinfo *m)
927 #if defined(ENABLE_ANNOTATIONS)
928 classinfo *c; /* methods' declaring class */
929 int slot; /* methods' slot */
930 java_handle_t *method_annotations; /* all methods' unparsed annotations */
931 /* of the declaring class */
934 slot = m - c->methods;
936 LLNI_classinfo_field_get(c, method_annotations, method_annotations);
938 ObjectArray oa((java_handle_objectarray_t*) method_annotations);
940 /* the method_annotations array might be shorter then the method
941 * count if the methods above a certain index have no annotations.
943 if (method_annotations != NULL && oa.get_length() > slot) {
944 return (java_handle_bytearray_t*) oa.get_element(slot);
954 /* method_get_parameterannotations ********************************************
956 Get a methods' unparsed parameter annotations in an array of byte
960 m........the method of which the parameter annotations should be
964 The unparsed parameter annotations in a byte array (or NULL if
967 *******************************************************************************/
969 java_handle_bytearray_t *method_get_parameterannotations(methodinfo *m)
971 #if defined(ENABLE_ANNOTATIONS)
972 classinfo *c; /* methods' declaring class */
973 int slot; /* methods' slot */
974 java_handle_t *method_parameterannotations; /* all methods' unparsed */
975 /* parameter annotations of */
976 /* the declaring class */
979 slot = m - c->methods;
981 LLNI_classinfo_field_get(
982 c, method_parameterannotations, method_parameterannotations);
984 ObjectArray oa((java_handle_objectarray_t*) method_parameterannotations);
986 /* the method_annotations array might be shorter then the method
987 * count if the methods above a certain index have no annotations.
989 if (method_parameterannotations != NULL && oa.get_length() > slot) {
990 return (java_handle_bytearray_t*) oa.get_element(slot);
1000 /* method_get_annotationdefault ***********************************************
1002 Get a methods' unparsed annotation default value in a byte array.
1005 m........the method of which the annotation default value should be
1009 The unparsed annotation default value in a byte array (or NULL if
1012 *******************************************************************************/
1014 java_handle_bytearray_t *method_get_annotationdefault(methodinfo *m)
1016 #if defined(ENABLE_ANNOTATIONS)
1017 classinfo *c; /* methods' declaring class */
1018 int slot; /* methods' slot */
1019 java_handle_t *method_annotationdefaults; /* all methods' unparsed */
1020 /* annotation default values of */
1021 /* the declaring class */
1024 slot = m - c->methods;
1026 LLNI_classinfo_field_get(
1027 c, method_annotationdefaults, method_annotationdefaults);
1029 ObjectArray oa((java_handle_objectarray_t*) method_annotationdefaults);
1031 /* the method_annotations array might be shorter then the method
1032 * count if the methods above a certain index have no annotations.
1034 if (method_annotationdefaults != NULL && oa.get_length() > slot) {
1035 return (java_handle_bytearray_t*) oa.get_element(slot);
1045 /* method_add_to_worklist ******************************************************
1047 Add the method to the given worklist. If the method already occurs in
1048 the worklist, the worklist remains unchanged.
1050 *******************************************************************************/
1052 static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
1054 method_worklist *wi;
1056 for (wi = *wl; wi != NULL; wi = wi->next)
1060 wi = NEW(method_worklist);
1068 /* method_add_assumption_monomorphic *******************************************
1070 Record the assumption that the method is monomorphic.
1073 m.................the method
1074 caller............the caller making the assumption
1076 *******************************************************************************/
1078 void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
1080 method_assumption *as;
1082 /* XXX LOCKING FOR THIS FUNCTION? */
1084 /* check if we already have registered this assumption */
1086 for (as = m->assumptions; as != NULL; as = as->next) {
1087 if (as->context == caller)
1091 /* register the assumption */
1093 as = NEW(method_assumption);
1094 as->next = m->assumptions;
1095 as->context = caller;
1097 m->assumptions = as;
1100 /* method_break_assumption_monomorphic *****************************************
1102 Break the assumption that this method is monomorphic. All callers that
1103 have registered this assumption are added to the worklist.
1106 m.................the method
1107 wl................worklist where to add invalidated callers
1109 *******************************************************************************/
1111 void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
1113 method_assumption *as;
1115 /* XXX LOCKING FOR THIS FUNCTION? */
1117 for (as = m->assumptions; as != NULL; as = as->next) {
1119 printf("ASSUMPTION BROKEN (monomorphism): ");
1122 method_println(as->context);
1125 method_add_to_worklist(as->context, wl);
1127 #if defined(ENABLE_TLH) && 0
1129 method_assumption *as2;
1130 as2 = m->assumptions;
1131 m->assumptions = NULL;
1132 method_break_assumption_monomorphic(as->context, wl);
1134 assert(m->assumptions == NULL);
1135 m->assumptions = as2;*/
1141 /* method_printflags ***********************************************************
1143 Prints the flags of a method to stdout like.
1145 *******************************************************************************/
1147 #if !defined(NDEBUG)
1148 void method_printflags(methodinfo *m)
1155 if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
1156 if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
1157 if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
1158 if (m->flags & ACC_STATIC) printf(" STATIC");
1159 if (m->flags & ACC_FINAL) printf(" FINAL");
1160 if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1161 if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
1162 if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
1163 if (m->flags & ACC_NATIVE) printf(" NATIVE");
1164 if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
1165 if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
1166 if (m->flags & ACC_METHOD_BUILTIN) printf(" (builtin)");
1167 if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
1168 if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
1170 #endif /* !defined(NDEBUG) */
1173 /* method_print ****************************************************************
1175 Prints a method to stdout like:
1177 java.lang.Object.<init>()V
1179 *******************************************************************************/
1181 #if !defined(NDEBUG)
1182 void method_print(methodinfo *m)
1189 if (m->clazz != NULL)
1190 utf_display_printable_ascii_classname(m->clazz->name);
1194 utf_display_printable_ascii(m->name);
1195 utf_display_printable_ascii(m->descriptor);
1197 method_printflags(m);
1199 #endif /* !defined(NDEBUG) */
1202 /* method_println **************************************************************
1204 Prints a method plus new line to stdout like:
1206 java.lang.Object.<init>()V
1208 *******************************************************************************/
1210 #if !defined(NDEBUG)
1211 void method_println(methodinfo *m)
1213 if (opt_debugcolor) printf("\033[31m"); /* red */
1215 if (opt_debugcolor) printf("\033[m");
1218 #endif /* !defined(NDEBUG) */
1221 /* method_methodref_print ******************************************************
1223 Prints a method reference to stdout.
1225 *******************************************************************************/
1227 #if !defined(NDEBUG)
1228 void method_methodref_print(constant_FMIref *mr)
1231 printf("(constant_FMIref *)NULL");
1235 if (IS_FMIREF_RESOLVED(mr)) {
1236 printf("<method> ");
1237 method_print(mr->p.method);
1240 printf("<methodref> ");
1241 utf_display_printable_ascii_classname(mr->p.classref->name);
1243 utf_display_printable_ascii(mr->name);
1244 utf_display_printable_ascii(mr->descriptor);
1247 #endif /* !defined(NDEBUG) */
1250 /* method_methodref_println ****************************************************
1252 Prints a method reference to stdout, followed by a newline.
1254 *******************************************************************************/
1256 #if !defined(NDEBUG)
1257 void method_methodref_println(constant_FMIref *mr)
1259 method_methodref_print(mr);
1262 #endif /* !defined(NDEBUG) */
1264 #if defined(__cplusplus)
1269 * These are local overrides for various environment variables in Emacs.
1270 * Please do not remove this and leave it at the end of the file, where
1271 * Emacs will automagically detect them.
1272 * ---------------------------------------------------------------------
1275 * indent-tabs-mode: t
1279 * vim:noexpandtab:sw=4:ts=4: