/* src/vmcore/method.c - method functions
- Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: method.c 8322 2007-08-16 15:54:38Z twisti $
-
*/
#include "threads/lock-common.h"
+#include "vm/array.h"
#include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
#include "vm/global.h"
#include "vm/resolve.h"
+#include "vm/vm.hpp"
+#include "vm/jit/code.h"
#include "vm/jit/methodheader.h"
#include "vm/jit_interface.h"
#include "vmcore/class.h"
+#include "vmcore/globals.hpp"
#include "vmcore/linker.h"
#include "vmcore/loader.h"
#include "vmcore/method.h"
#include "vmcore/options.h"
#include "vmcore/suck.h"
+#include "vmcore/utf8.h"
#if !defined(NDEBUG) && defined(ENABLE_INLINING)
-#define INLINELOG(code) do { if (opt_inline_debug_log) { code } } while (0)
+#define INLINELOG(code) do { if (opt_TraceInlining) { code } } while (0)
#else
#define INLINELOG(code)
#endif
+/* global variables ***********************************************************/
+
+methodinfo *method_java_lang_reflect_Method_invoke;
+
+
+/* method_init *****************************************************************
+
+ Initialize method subsystem.
+
+*******************************************************************************/
+
+void method_init(void)
+{
+#if defined(ENABLE_JAVASE)
+ /* Sanity check. */
+
+ if (class_java_lang_reflect_Method == NULL)
+ vm_abort("method_init: class_java_lang_reflect_Method is NULL");
+
+ /* Cache java.lang.reflect.Method.invoke() */
+
+ method_java_lang_reflect_Method_invoke =
+ class_findmethod(class_java_lang_reflect_Method, utf_invoke, NULL);
+
+ if (method_java_lang_reflect_Method_invoke == NULL)
+ vm_abort("method_init: Could not resolve method java.lang.reflect.Method.invoke().");
+#endif
+}
+
+
/* method_load *****************************************************************
Loads a method from the class file and fills an existing methodinfo
/* get classinfo */
- c = cb->class;
+ c = cb->clazz;
LOCK_INIT_OBJECT_LOCK(&(m->header));
/* all fields of m have been zeroed in load_class_from_classbuffer */
- m->class = c;
+ m->clazz = c;
if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
return false;
}
+/* method_new_builtin **********************************************************
+
+ Creates a minimal methodinfo structure for builtins. This comes handy
+ when dealing with builtin stubs or stacktraces.
+
+*******************************************************************************/
+
+methodinfo *method_new_builtin(builtintable_entry *bte)
+{
+ methodinfo *m;
+
+ /* allocate the methodinfo structure */
+
+ m = NEW(methodinfo);
+
+ /* initialize methodinfo structure */
+
+ MZERO(m, methodinfo, 1);
+ LOCK_INIT_OBJECT_LOCK(&(m->header));
+
+ m->flags = ACC_METHOD_BUILTIN;
+ m->parseddesc = bte->md;
+ m->name = bte->name;
+ m->descriptor = bte->descriptor;
+
+ /* return the newly created methodinfo */
+
+ return m;
+}
+
+
/* method_vftbl_lookup *********************************************************
Does a method lookup in the passed virtual function table. This
/* Get the method from the virtual function table. Is this an
interface method? */
- if (m->class->flags & ACC_INTERFACE) {
- pmptr = vftbl->interfacetable[-(m->class->index)];
- mptr = pmptr[(m - m->class->methods)];
+ if (m->clazz->flags & ACC_INTERFACE) {
+ pmptr = vftbl->interfacetable[-(m->clazz->index)];
+ mptr = pmptr[(m - m->clazz->methods)];
}
else {
mptr = vftbl->table[m->vftblindex];
Use the descriptor of a method to determine the number of parameters
of the method. The this pointer of non-static methods is not counted.
- Returns -1 on error.
+ IN:
+ m........the method of which the parameters should be counted
+
+ RETURN VALUE:
+ The parameter count or -1 on error.
*******************************************************************************/
int32_t method_get_parametercount(methodinfo *m)
{
- methoddesc *md;
- int32_t paramcount = 0;
+ methoddesc *md; /* method descriptor of m */
+ int32_t paramcount = 0; /* the parameter count of m */
md = m->parseddesc;
/* is the descriptor fully parsed? */
- if (m->parseddesc->params == NULL) {
+ if (md->params == NULL) {
if (!descriptor_params_from_paramtypes(md, m->flags)) {
return -1;
}
/* method_get_annotations ******************************************************
- Gets a methods' annotations (or NULL if none).
+ Get a methods' unparsed annotations in a byte array.
+
+ IN:
+ m........the method of which the annotations should be returned
+
+ RETURN VALUE:
+ The unparsed annotations in a byte array (or NULL if there aren't any).
*******************************************************************************/
java_handle_bytearray_t *method_get_annotations(methodinfo *m)
{
#if defined(ENABLE_ANNOTATIONS)
- classinfo *c;
- int slot;
- annotation_bytearray_t *ba;
- java_handle_bytearray_t *annotations;
+ classinfo *c; /* methods' declaring class */
+ int slot; /* methods' slot */
+ java_handle_t *annotations; /* methods' unparsed annotations */
+ java_handle_t *method_annotations; /* all methods' unparsed annotations */
+ /* of the declaring class */
- c = m->class;
+ c = m->clazz;
slot = m - c->methods;
annotations = NULL;
-
- if (c->method_annotations != NULL && c->method_annotations->size > slot) {
- ba = c->method_annotations->data[slot];
-
- if (ba != NULL) {
- annotations = builtin_newarray_byte(ba->size);
-
- if (annotations != NULL) {
- MCOPY(annotations->data, ba->data, uint8_t, ba->size);
- }
- }
+
+ LLNI_classinfo_field_get(c, method_annotations, method_annotations);
+
+ /* the method_annotations array might be shorter then the method
+ * count if the methods above a certain index have no annotations.
+ */
+ if (method_annotations != NULL &&
+ array_length_get(method_annotations) > slot) {
+ annotations = array_objectarray_element_get(
+ (java_handle_objectarray_t*)method_annotations, slot);
}
- return annotations;
+ return (java_handle_bytearray_t*)annotations;
#else
return NULL;
#endif
/* method_get_parameterannotations ********************************************
- Gets a methods' parameter annotations (or NULL if none).
+ Get a methods' unparsed parameter annotations in an array of byte
+ arrays.
+
+ IN:
+ m........the method of which the parameter annotations should be
+ returned
+
+ RETURN VALUE:
+ The unparsed parameter annotations in a byte array (or NULL if
+ there aren't any).
*******************************************************************************/
java_handle_bytearray_t *method_get_parameterannotations(methodinfo *m)
{
#if defined(ENABLE_ANNOTATIONS)
- classinfo *c;
- int slot;
- annotation_bytearray_t *ba;
- java_handle_bytearray_t *parameterAnnotations;
-
- c = m->class;
+ classinfo *c; /* methods' declaring class */
+ int slot; /* methods' slot */
+ java_handle_t *parameterAnnotations; /* methods' unparsed */
+ /* parameter annotations */
+ java_handle_t *method_parameterannotations; /* all methods' unparsed */
+ /* parameter annotations of */
+ /* the declaring class */
+
+ c = m->clazz;
slot = m - c->methods;
parameterAnnotations = NULL;
- if (c->method_parameterannotations != NULL &&
- c->method_parameterannotations->size > slot) {
- ba = c->method_parameterannotations->data[slot];
-
- if (ba != NULL) {
- parameterAnnotations = builtin_newarray_byte(ba->size);
-
- if (parameterAnnotations != NULL) {
- MCOPY(parameterAnnotations->data, ba->data, uint8_t, ba->size);
- }
- }
+ LLNI_classinfo_field_get(
+ c, method_parameterannotations, method_parameterannotations);
+
+ /* the method_annotations array might be shorter then the method
+ * count if the methods above a certain index have no annotations.
+ */
+ if (method_parameterannotations != NULL &&
+ array_length_get(method_parameterannotations) > slot) {
+ parameterAnnotations = array_objectarray_element_get(
+ (java_handle_objectarray_t*)method_parameterannotations,
+ slot);
}
- return parameterAnnotations;
+ return (java_handle_bytearray_t*)parameterAnnotations;
#else
return NULL;
#endif
/* method_get_annotationdefault ***********************************************
- Gets a methods' annotation default value (or NULL if none).
+ Get a methods' unparsed annotation default value in a byte array.
+
+ IN:
+ m........the method of which the annotation default value should be
+ returned
+
+ RETURN VALUE:
+ The unparsed annotation default value in a byte array (or NULL if
+ there isn't one).
*******************************************************************************/
java_handle_bytearray_t *method_get_annotationdefault(methodinfo *m)
{
#if defined(ENABLE_ANNOTATIONS)
- classinfo *c;
- int slot;
- annotation_bytearray_t *ba;
- java_handle_bytearray_t *annotationDefault;
-
- c = m->class;
+ classinfo *c; /* methods' declaring class */
+ int slot; /* methods' slot */
+ java_handle_t *annotationDefault; /* methods' unparsed */
+ /* annotation default value */
+ java_handle_t *method_annotationdefaults; /* all methods' unparsed */
+ /* annotation default values of */
+ /* the declaring class */
+
+ c = m->clazz;
slot = m - c->methods;
annotationDefault = NULL;
- if (c->method_annotationdefaults != NULL &&
- c->method_annotationdefaults->size > slot) {
- ba = c->method_annotationdefaults->data[slot];
-
- if (ba != NULL) {
- annotationDefault = builtin_newarray_byte(ba->size);
-
- if (annotationDefault != NULL) {
- MCOPY(annotationDefault->data, ba->data, uint8_t, ba->size);
- }
- }
+ LLNI_classinfo_field_get(
+ c, method_annotationdefaults, method_annotationdefaults);
+
+ /* the method_annotations array might be shorter then the method
+ * count if the methods above a certain index have no annotations.
+ */
+ if (method_annotationdefaults != NULL &&
+ array_length_get(method_annotationdefaults) > slot) {
+ annotationDefault = array_objectarray_element_get(
+ (java_handle_objectarray_t*)method_annotationdefaults, slot);
}
- return annotationDefault;
+ return (java_handle_bytearray_t*)annotationDefault;
#else
return NULL;
#endif
m->assumptions = as;
}
-
/* method_break_assumption_monomorphic *****************************************
Break the assumption that this method is monomorphic. All callers that
);
method_add_to_worklist(as->context, wl);
+
+#if defined(ENABLE_TLH) && 0
+ /* XXX hack */
+ method_assumption *as2;
+ as2 = m->assumptions;
+ m->assumptions = NULL;
+ method_break_assumption_monomorphic(as->context, wl);
+ /*
+ assert(m->assumptions == NULL);
+ m->assumptions = as2;*/
+#endif
+
}
}
-
/* method_printflags ***********************************************************
Prints the flags of a method to stdout like.
return;
}
- if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
- if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
- if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
- if (m->flags & ACC_STATIC) printf(" STATIC");
- if (m->flags & ACC_FINAL) printf(" FINAL");
- if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
- if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
- if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
- if (m->flags & ACC_NATIVE) printf(" NATIVE");
- if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
- if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
- if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
- if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
+ if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
+ if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
+ if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
+ if (m->flags & ACC_STATIC) printf(" STATIC");
+ if (m->flags & ACC_FINAL) printf(" FINAL");
+ if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
+ if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
+ if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
+ if (m->flags & ACC_NATIVE) printf(" NATIVE");
+ if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
+ if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
+ if (m->flags & ACC_METHOD_BUILTIN) printf(" (builtin)");
+ if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
+ if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
}
#endif /* !defined(NDEBUG) */
return;
}
- utf_display_printable_ascii_classname(m->class->name);
+ if (m->clazz != NULL)
+ utf_display_printable_ascii_classname(m->clazz->name);
+ else
+ printf("NULL");
printf(".");
utf_display_printable_ascii(m->name);
utf_display_printable_ascii(m->descriptor);