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 descriptor_params_from_paramtypes(md, m->flags);
740 paramcount = md->paramcount;
742 /* skip `this' pointer */
744 if (!(m->flags & ACC_STATIC)) {
752 /* method_get_parametertypearray ***********************************************
754 Use the descriptor of a method to generate a java.lang.Class array
755 which contains the classes of the parametertypes of the method.
757 This function is called by java.lang.reflect.{Constructor,Method}.
759 *******************************************************************************/
761 java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m)
764 typedesc* paramtypes;
771 /* is the descriptor fully parsed? */
773 descriptor_params_from_paramtypes(md, m->flags);
775 paramtypes = md->paramtypes;
776 paramcount = md->paramcount;
778 /* skip `this' pointer */
780 if (!(m->flags & ACC_STATIC)) {
785 /* create class-array */
787 ClassArray ca(paramcount);
794 for (i = 0; i < paramcount; i++) {
795 if (!resolve_class_from_typedesc(¶mtypes[i], true, false, &c))
798 ca.set_element(i, c);
801 return ca.get_handle();
805 /* method_get_exceptionarray ***************************************************
807 Get the exceptions which can be thrown by a method.
809 *******************************************************************************/
811 java_handle_objectarray_t *method_get_exceptionarray(methodinfo *m)
816 /* create class-array */
818 ClassArray ca(m->thrownexceptionscount);
823 /* iterate over all exceptions and store the class in the array */
825 for (i = 0; i < m->thrownexceptionscount; i++) {
826 c = resolve_classref_or_classinfo_eager(m->thrownexceptions[i], true);
831 ca.set_element(i, c);
834 return ca.get_handle();
838 /* method_returntype_get *******************************************************
840 Get the return type of the method.
842 *******************************************************************************/
844 classinfo *method_returntype_get(methodinfo *m)
849 td = &(m->parseddesc->returntype);
851 if (!resolve_class_from_typedesc(td, true, false, &c))
858 /* method_count_implementations ************************************************
860 Count the implementations of a method in a class cone (a class and all its
864 m................the method to count
865 c................class at which to start the counting (this class and
866 all its subclasses will be searched)
869 *found...........if found != NULL, *found receives the method
870 implementation that was found. This value is only
871 meaningful if the return value is 1.
874 the number of implementations found
876 *******************************************************************************/
878 s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
888 mend = mp + c->methodscount;
890 for (; mp < mend; ++mp) {
891 if (method_canoverwrite(mp, m)) {
899 for (child = c->sub; child != NULL; child = child->nextsub) {
900 count += method_count_implementations(m, child, found);
907 /* method_get_annotations ******************************************************
909 Get a methods' unparsed annotations in a byte array.
912 m........the method of which the annotations should be returned
915 The unparsed annotations in a byte array (or NULL if there aren't any).
917 *******************************************************************************/
919 java_handle_bytearray_t *method_get_annotations(methodinfo *m)
921 #if defined(ENABLE_ANNOTATIONS)
922 classinfo *c; /* methods' declaring class */
923 int slot; /* methods' slot */
924 java_handle_t *method_annotations; /* all methods' unparsed annotations */
925 /* of the declaring class */
928 slot = m - c->methods;
930 LLNI_classinfo_field_get(c, method_annotations, method_annotations);
932 ObjectArray oa((java_handle_objectarray_t*) method_annotations);
934 /* the method_annotations array might be shorter then the method
935 * count if the methods above a certain index have no annotations.
937 if (method_annotations != NULL && oa.get_length() > slot) {
938 return (java_handle_bytearray_t*) oa.get_element(slot);
948 /* method_get_parameterannotations ********************************************
950 Get a methods' unparsed parameter annotations in an array of byte
954 m........the method of which the parameter annotations should be
958 The unparsed parameter annotations in a byte array (or NULL if
961 *******************************************************************************/
963 java_handle_bytearray_t *method_get_parameterannotations(methodinfo *m)
965 #if defined(ENABLE_ANNOTATIONS)
966 classinfo *c; /* methods' declaring class */
967 int slot; /* methods' slot */
968 java_handle_t *method_parameterannotations; /* all methods' unparsed */
969 /* parameter annotations of */
970 /* the declaring class */
973 slot = m - c->methods;
975 LLNI_classinfo_field_get(
976 c, method_parameterannotations, method_parameterannotations);
978 ObjectArray oa((java_handle_objectarray_t*) method_parameterannotations);
980 /* the method_annotations array might be shorter then the method
981 * count if the methods above a certain index have no annotations.
983 if (method_parameterannotations != NULL && oa.get_length() > slot) {
984 return (java_handle_bytearray_t*) oa.get_element(slot);
994 /* method_get_annotationdefault ***********************************************
996 Get a methods' unparsed annotation default value in a byte array.
999 m........the method of which the annotation default value should be
1003 The unparsed annotation default value in a byte array (or NULL if
1006 *******************************************************************************/
1008 java_handle_bytearray_t *method_get_annotationdefault(methodinfo *m)
1010 #if defined(ENABLE_ANNOTATIONS)
1011 classinfo *c; /* methods' declaring class */
1012 int slot; /* methods' slot */
1013 java_handle_t *method_annotationdefaults; /* all methods' unparsed */
1014 /* annotation default values of */
1015 /* the declaring class */
1018 slot = m - c->methods;
1020 LLNI_classinfo_field_get(
1021 c, method_annotationdefaults, method_annotationdefaults);
1023 ObjectArray oa((java_handle_objectarray_t*) method_annotationdefaults);
1025 /* the method_annotations array might be shorter then the method
1026 * count if the methods above a certain index have no annotations.
1028 if (method_annotationdefaults != NULL && oa.get_length() > slot) {
1029 return (java_handle_bytearray_t*) oa.get_element(slot);
1039 /* method_add_to_worklist ******************************************************
1041 Add the method to the given worklist. If the method already occurs in
1042 the worklist, the worklist remains unchanged.
1044 *******************************************************************************/
1046 static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
1048 method_worklist *wi;
1050 for (wi = *wl; wi != NULL; wi = wi->next)
1054 wi = NEW(method_worklist);
1062 /* method_add_assumption_monomorphic *******************************************
1064 Record the assumption that the method is monomorphic.
1067 m.................the method
1068 caller............the caller making the assumption
1070 *******************************************************************************/
1072 void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
1074 method_assumption *as;
1076 /* XXX LOCKING FOR THIS FUNCTION? */
1078 /* check if we already have registered this assumption */
1080 for (as = m->assumptions; as != NULL; as = as->next) {
1081 if (as->context == caller)
1085 /* register the assumption */
1087 as = NEW(method_assumption);
1088 as->next = m->assumptions;
1089 as->context = caller;
1091 m->assumptions = as;
1094 /* method_break_assumption_monomorphic *****************************************
1096 Break the assumption that this method is monomorphic. All callers that
1097 have registered this assumption are added to the worklist.
1100 m.................the method
1101 wl................worklist where to add invalidated callers
1103 *******************************************************************************/
1105 void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
1107 method_assumption *as;
1109 /* XXX LOCKING FOR THIS FUNCTION? */
1111 for (as = m->assumptions; as != NULL; as = as->next) {
1113 printf("ASSUMPTION BROKEN (monomorphism): ");
1116 method_println(as->context);
1119 method_add_to_worklist(as->context, wl);
1121 #if defined(ENABLE_TLH) && 0
1123 method_assumption *as2;
1124 as2 = m->assumptions;
1125 m->assumptions = NULL;
1126 method_break_assumption_monomorphic(as->context, wl);
1128 assert(m->assumptions == NULL);
1129 m->assumptions = as2;*/
1135 /* method_printflags ***********************************************************
1137 Prints the flags of a method to stdout like.
1139 *******************************************************************************/
1141 #if !defined(NDEBUG)
1142 void method_printflags(methodinfo *m)
1149 if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
1150 if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
1151 if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
1152 if (m->flags & ACC_STATIC) printf(" STATIC");
1153 if (m->flags & ACC_FINAL) printf(" FINAL");
1154 if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
1155 if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
1156 if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
1157 if (m->flags & ACC_NATIVE) printf(" NATIVE");
1158 if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
1159 if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
1160 if (m->flags & ACC_METHOD_BUILTIN) printf(" (builtin)");
1161 if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
1162 if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
1164 #endif /* !defined(NDEBUG) */
1167 /* method_print ****************************************************************
1169 Prints a method to stdout like:
1171 java.lang.Object.<init>()V
1173 *******************************************************************************/
1175 #if !defined(NDEBUG)
1176 void method_print(methodinfo *m)
1183 if (m->clazz != NULL)
1184 utf_display_printable_ascii_classname(m->clazz->name);
1188 utf_display_printable_ascii(m->name);
1189 utf_display_printable_ascii(m->descriptor);
1191 method_printflags(m);
1193 #endif /* !defined(NDEBUG) */
1196 /* method_println **************************************************************
1198 Prints a method plus new line to stdout like:
1200 java.lang.Object.<init>()V
1202 *******************************************************************************/
1204 #if !defined(NDEBUG)
1205 void method_println(methodinfo *m)
1207 if (opt_debugcolor) printf("\033[31m"); /* red */
1209 if (opt_debugcolor) printf("\033[m");
1212 #endif /* !defined(NDEBUG) */
1215 /* method_methodref_print ******************************************************
1217 Prints a method reference to stdout.
1219 *******************************************************************************/
1221 #if !defined(NDEBUG)
1222 void method_methodref_print(constant_FMIref *mr)
1225 printf("(constant_FMIref *)NULL");
1229 if (IS_FMIREF_RESOLVED(mr)) {
1230 printf("<method> ");
1231 method_print(mr->p.method);
1234 printf("<methodref> ");
1235 utf_display_printable_ascii_classname(mr->p.classref->name);
1237 utf_display_printable_ascii(mr->name);
1238 utf_display_printable_ascii(mr->descriptor);
1241 #endif /* !defined(NDEBUG) */
1244 /* method_methodref_println ****************************************************
1246 Prints a method reference to stdout, followed by a newline.
1248 *******************************************************************************/
1250 #if !defined(NDEBUG)
1251 void method_methodref_println(constant_FMIref *mr)
1253 method_methodref_print(mr);
1256 #endif /* !defined(NDEBUG) */
1258 #if defined(__cplusplus)
1263 * These are local overrides for various environment variables in Emacs.
1264 * Please do not remove this and leave it at the end of the file, where
1265 * Emacs will automagically detect them.
1266 * ---------------------------------------------------------------------
1269 * indent-tabs-mode: t
1273 * vim:noexpandtab:sw=4:ts=4: