/* src/vm/builtin.c - functions for unsupported operations
- Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ 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
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Contact: cacao@cacaojvm.org
-
- Authors: Reinhard Grafl
- Andreas Krall
- Mark Probst
-
- Changes: Christian Thalinger
- Edwin Steiner
-
Contains C functions for JavaVM Instructions that cannot be
translated to machine language directly. Consequently, the
generated machine code for these instructions contains function
calls instead of machine instructions, using the C calling
convention.
- $Id: builtin.c 6102 2006-12-02 12:22:06Z twisti $
-
*/
#include <assert.h>
#include <errno.h>
-#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include "mm/gc-common.h"
#include "mm/memory.h"
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/include/java_lang_String.h"
+#include "native/include/java_lang_Throwable.h"
+
+#include "threads/lock-common.h"
#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
+#include "threads/native/threads.h"
+#else
+#include "threads/none/threads.h"
#endif
#include "toolbox/logging.h"
#include "toolbox/util.h"
+
+#include "vm/array.h"
#include "vm/builtin.h"
-#include "vm/class.h"
+#include "vm/cycles-stats.h"
#include "vm/exceptions.h"
#include "vm/global.h"
#include "vm/initialize.h"
-#include "vm/loader.h"
-#include "vm/options.h"
+#include "vm/primitive.h"
#include "vm/stringlocal.h"
+
#include "vm/jit/asmpart.h"
-#include "vm/jit/patcher.h"
-#include "vm/rt-timing.h"
-#include "vm/cycles-stats.h"
+#include "vmcore/class.h"
+#include "vmcore/linker.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/rt-timing.h"
+
+#if defined(ENABLE_VMLOG)
+#include <vmlog_cacao.h>
+#endif
+
+#if defined(ENABLE_DEBUG_FILTER)
+# include "vm/jit/show.h"
+#endif
/* include builtin tables *****************************************************/
descriptor_pool_alloc_parsed_descriptors(descpool);
- /* now parse all descriptors */
+ /* Now parse all descriptors. NOTE: builtin-functions are treated
+ like static methods (no `this' pointer). */
for (bte = builtintable_internal; bte->fp != NULL; bte++) {
- /* parse the descriptor, builtin is always static (no `this' pointer) */
-
- bte->md = descriptor_pool_parse_method_descriptor(descpool,
- bte->descriptor,
- ACC_STATIC, NULL);
+ bte->md =
+ descriptor_pool_parse_method_descriptor(descpool,
+ bte->descriptor,
+ ACC_STATIC | ACC_METHOD_BUILTIN,
+ NULL);
}
for (bte = builtintable_automatic; bte->fp != NULL; bte++) {
- bte->md = descriptor_pool_parse_method_descriptor(descpool,
- bte->descriptor,
- ACC_STATIC, NULL);
+ bte->md =
+ descriptor_pool_parse_method_descriptor(descpool,
+ bte->descriptor,
+ ACC_STATIC | ACC_METHOD_BUILTIN,
+ NULL);
}
for (bte = builtintable_function; bte->fp != NULL; bte++) {
- bte->md = descriptor_pool_parse_method_descriptor(descpool,
- bte->descriptor,
- ACC_STATIC, NULL);
+ bte->md =
+ descriptor_pool_parse_method_descriptor(descpool,
+ bte->descriptor,
+ ACC_STATIC | ACC_METHOD_BUILTIN,
+ NULL);
}
/* release dump area */
*******************************************************************************/
-bool builtintable_replace_function(instruction *iptr)
+#if defined(ENABLE_JIT)
+bool builtintable_replace_function(void *iptr_)
{
constant_FMIref *mr;
builtintable_entry *bte;
+ instruction *iptr;
+
+ iptr = (instruction *) iptr_; /* twisti will kill me ;) */
/* get name and descriptor of the function */
return false;
}
+#endif /* defined(ENABLE_JIT) */
/*****************************************************************************
TYPE CHECKS
*****************************************************************************/
+/* builtin_instanceof **********************************************************
+ Checks if an object is an instance of some given class (or subclass
+ of that class). If class is an interface, checks if the interface
+ is implemented.
-/*************** internal function: builtin_isanysubclass *********************
-
- Checks a subclass relation between two classes. Implemented interfaces
- are interpreted as super classes.
- Return value: 1 ... sub is subclass of super
- 0 ... otherwise
-
-******************************************************************************/
-
-s4 builtin_isanysubclass(classinfo *sub, classinfo *super)
-{
- s4 res;
- castinfo classvalues;
-
- if (sub == super)
- return 1;
-
- if (super->flags & ACC_INTERFACE) {
- res = (sub->vftbl->interfacetablelength > super->index) &&
- (sub->vftbl->interfacetable[-super->index] != NULL);
-
- } else {
- /* java.lang.Object is the only super_class_ of any interface */
- if (sub->flags & ACC_INTERFACE)
- return (super == class_java_lang_Object);
-
- ASM_GETCLASSVALUES_ATOMIC(super->vftbl, sub->vftbl, &classvalues);
-
- res = (u4) (classvalues.sub_baseval - classvalues.super_baseval) <=
- (u4) classvalues.super_diffval;
- }
-
- return res;
-}
-
-
-s4 builtin_isanysubclass_vftbl(vftbl_t *sub, vftbl_t *super)
-{
- s4 res;
- s4 base;
- castinfo classvalues;
-
- if (sub == super)
- return 1;
-
- ASM_GETCLASSVALUES_ATOMIC(super, sub, &classvalues);
-
- if ((base = classvalues.super_baseval) <= 0) {
- /* super is an interface */
- res = (sub->interfacetablelength > -base) &&
- (sub->interfacetable[base] != NULL);
- }
- else {
- /* java.lang.Object is the only super_class_ of any interface */
- if (classvalues.sub_baseval <= 0)
- return classvalues.super_baseval == 1;
-
- res = (u4) (classvalues.sub_baseval - classvalues.super_baseval)
- <= (u4) classvalues.super_diffval;
- }
-
- return res;
-}
-
-
-/****************** function: builtin_instanceof *****************************
-
- Checks if an object is an instance of some given class (or subclass of
- that class). If class is an interface, checks if the interface is
- implemented.
- Return value: 1 ... obj is an instance of class or implements the interface
- 0 ... otherwise or if obj == NULL
+ Return value: 1 ... o is an instance of class or implements the interface
+ 0 ... otherwise or if o == NULL
-*****************************************************************************/
+*******************************************************************************/
-s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
+s4 builtin_instanceof(java_handle_t *o, classinfo *class)
{
- if (!obj)
+ if (o == NULL)
return 0;
- return builtin_isanysubclass(obj->vftbl->class, class);
+ return class_isanysubclass(o->vftbl->class, class);
}
-/**************** function: builtin_checkcast *******************************
+/* builtin_checkcast ***********************************************************
- The same as builtin_instanceof except that 1 is returned when
- obj == NULL
+ The same as builtin_instanceof except that 1 is returned when o ==
+ NULL.
-****************************************************************************/
+*******************************************************************************/
-s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
+s4 builtin_checkcast(java_handle_t *o, classinfo *class)
{
- if (obj == NULL)
+ if (o == NULL)
return 1;
- if (builtin_isanysubclass(obj->vftbl->class, class))
+ if (class_isanysubclass(o->vftbl->class, class))
return 1;
return 0;
(target->elementvftbl->baseval == 1))
return 1;
- return builtin_isanysubclass_vftbl(desc->elementvftbl,
- target->elementvftbl);
+ return class_isanysubclass(desc->elementvftbl->class,
+ target->elementvftbl->class);
}
if (desc->dimension < target->dimension)
/* {desc has higher dimension than target} */
- return builtin_isanysubclass_vftbl(pseudo_class_Arraystub->vftbl,
- target->elementvftbl);
+ return class_isanysubclass(pseudo_class_Arraystub,
+ target->elementvftbl->class);
}
*******************************************************************************/
-s4 builtin_arraycheckcast(java_objectheader *o, classinfo *targetclass)
+s4 builtin_arraycheckcast(java_handle_t *o, classinfo *targetclass)
{
arraydescriptor *desc;
- if (!o)
+ if (o == NULL)
return 1;
- if ((desc = o->vftbl->arraydesc) == NULL)
+ desc = o->vftbl->arraydesc;
+
+ if (desc == NULL)
return 0;
return builtin_descriptorscompatible(desc, targetclass->vftbl->arraydesc);
}
-s4 builtin_arrayinstanceof(java_objectheader *o, classinfo *targetclass)
+s4 builtin_arrayinstanceof(java_handle_t *o, classinfo *targetclass)
{
- if (!o)
+ if (o == NULL)
return 0;
return builtin_arraycheckcast(o, targetclass);
*******************************************************************************/
-void *builtin_throw_exception(java_objectheader *xptr)
+void *builtin_throw_exception(java_handle_t *xptr)
{
#if !defined(NDEBUG)
java_lang_Throwable *t;
+ java_lang_String *s;
char *logtext;
s4 logtextlen;
s4 dumpsize;
if (opt_verbose) {
t = (java_lang_Throwable *) xptr;
+ /* get detail message */
+ if (t)
+ LLNI_field_get_ref(t, detailMessage, s);
+
/* calculate message length */
logtextlen = strlen("Builtin exception thrown: ") + strlen("0");
if (t) {
logtextlen +=
utf_bytes(xptr->vftbl->class->name);
- if (t->detailMessage) {
+ if (s) {
logtextlen += strlen(": ") +
- u2_utflength(t->detailMessage->value->data
- + t->detailMessage->offset,
- t->detailMessage->count);
+ u2_utflength(LLNI_field_direct(s, value)->data
+ + LLNI_field_direct(s, offset),
+ LLNI_field_direct(s,count));
}
}
else {
if (t) {
utf_cat_classname(logtext, xptr->vftbl->class->name);
- if (t->detailMessage) {
+ if (s) {
char *buf;
- buf = javastring_tochar((java_objectheader *) t->detailMessage);
+ buf = javastring_tochar((java_handle_t *) s);
strcat(logtext, ": ");
strcat(logtext, buf);
MFREE(buf, char, strlen(buf) + 1);
/* actually set the exception */
- *exceptionptr = xptr;
+ exceptions_set_exception(xptr);
/* Return a NULL pointer. This is required for vm_call_method to
check for an exception. This is for convenience. */
Checks, if an object can be stored in an array.
Return value: 1 ... possible
- 0 ... otherwise
+ 0 ... otherwise (throws an ArrayStoreException)
*******************************************************************************/
-s4 builtin_canstore(java_objectarray *oa, java_objectheader *o)
+s4 builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
{
arraydescriptor *desc;
arraydescriptor *valuedesc;
vftbl_t *componentvftbl;
vftbl_t *valuevftbl;
- s4 base;
- castinfo classvalues;
+ int32_t baseval;
+ uint32_t diffval;
+ int result;
- if (!o)
+ if (o == NULL)
return 1;
/* The following is guaranteed (by verifier checks):
desc = oa->header.objheader.vftbl->arraydesc;
componentvftbl = desc->componentvftbl;
valuevftbl = o->vftbl;
+ valuedesc = valuevftbl->arraydesc;
if ((desc->dimension - 1) == 0) {
- s4 res;
-
/* {oa is a one-dimensional array} */
/* {oa is an array of references} */
if (valuevftbl == componentvftbl)
return 1;
- ASM_GETCLASSVALUES_ATOMIC(componentvftbl, valuevftbl, &classvalues);
+ LOCK_MONITOR_ENTER(linker_classrenumber_lock);
- if ((base = classvalues.super_baseval) <= 0)
+ baseval = componentvftbl->baseval;
+
+ if (baseval <= 0) {
/* an array of interface references */
- return (valuevftbl->interfacetablelength > -base &&
- valuevftbl->interfacetable[base] != NULL);
-
- res = ((unsigned) (classvalues.sub_baseval - classvalues.super_baseval)
- <= (unsigned) classvalues.super_diffval);
- return res;
- }
+ result = ((valuevftbl->interfacetablelength > -baseval) &&
+ (valuevftbl->interfacetable[baseval] != NULL));
+ }
+ else {
+ diffval = valuevftbl->baseval - componentvftbl->baseval;
+ result = diffval <= (uint32_t) componentvftbl->diffval;
+ }
- /* {oa has dimension > 1} */
- /* {componentvftbl->arraydesc != NULL} */
+ LOCK_MONITOR_EXIT(linker_classrenumber_lock);
+ }
+ else if (valuedesc == NULL) {
+ /* {oa has dimension > 1} */
+ /* {componentvftbl->arraydesc != NULL} */
- /* check if o is an array */
+ /* check if o is an array */
- if ((valuedesc = valuevftbl->arraydesc) == NULL)
return 0;
+ }
+ else {
+ /* {o is an array} */
+
+ result = builtin_descriptorscompatible(valuedesc, componentvftbl->arraydesc);
+ }
+
+ /* if not possible, throw an exception */
- /* {o is an array} */
+ if (result == 0)
+ exceptions_throw_arraystoreexception();
- return builtin_descriptorscompatible(valuedesc, componentvftbl->arraydesc);
+ /* return result */
+
+ return result;
}
/* This is an optimized version where a is guaranteed to be one-dimensional */
-s4 builtin_canstore_onedim (java_objectarray *a, java_objectheader *o)
+s4 builtin_canstore_onedim (java_handle_objectarray_t *a, java_handle_t *o)
{
arraydescriptor *desc;
- vftbl_t *elementvftbl;
- vftbl_t *valuevftbl;
- s4 res;
- int base;
- castinfo classvalues;
+ vftbl_t *elementvftbl;
+ vftbl_t *valuevftbl;
+ int32_t baseval;
+ uint32_t diffval;
+ int result;
- if (!o) return 1;
+ if (o == NULL)
+ return 1;
/* The following is guaranteed (by verifier checks):
*
if (valuevftbl == elementvftbl)
return 1;
- ASM_GETCLASSVALUES_ATOMIC(elementvftbl, valuevftbl, &classvalues);
+ LOCK_MONITOR_ENTER(linker_classrenumber_lock);
+
+ baseval = elementvftbl->baseval;
- if ((base = classvalues.super_baseval) <= 0)
+ if (baseval <= 0) {
/* an array of interface references */
- return (valuevftbl->interfacetablelength > -base &&
- valuevftbl->interfacetable[base] != NULL);
+ result = ((valuevftbl->interfacetablelength > -baseval) &&
+ (valuevftbl->interfacetable[baseval] != NULL));
+ }
+ else {
+ diffval = valuevftbl->baseval - elementvftbl->baseval;
+ result = diffval <= (uint32_t) elementvftbl->diffval;
+ }
- res = (unsigned) (classvalues.sub_baseval - classvalues.super_baseval)
- <= (unsigned) classvalues.super_diffval;
+ LOCK_MONITOR_EXIT(linker_classrenumber_lock);
- return res;
+ return result;
}
/* This is an optimized version where a is guaranteed to be a
* one-dimensional array of a class type */
-s4 builtin_canstore_onedim_class(java_objectarray *a, java_objectheader *o)
+s4 builtin_canstore_onedim_class(java_handle_objectarray_t *a, java_handle_t *o)
{
- vftbl_t *elementvftbl;
- vftbl_t *valuevftbl;
- s4 res;
- castinfo classvalues;
+ vftbl_t *elementvftbl;
+ vftbl_t *valuevftbl;
+ uint32_t diffval;
+ int result;
- if (!o) return 1;
+ if (o == NULL)
+ return 1;
/* The following is guaranteed (by verifier checks):
*
if (valuevftbl == elementvftbl)
return 1;
- ASM_GETCLASSVALUES_ATOMIC(elementvftbl, valuevftbl, &classvalues);
+ LOCK_MONITOR_ENTER(linker_classrenumber_lock);
- res = (unsigned) (classvalues.sub_baseval - classvalues.super_baseval)
- <= (unsigned) classvalues.super_diffval;
+ diffval = valuevftbl->baseval - elementvftbl->baseval;
+ result = diffval <= (uint32_t) elementvftbl->diffval;
- return res;
+ LOCK_MONITOR_EXIT(linker_classrenumber_lock);
+
+ return result;
}
*******************************************************************************/
-java_objectheader *builtin_new(classinfo *c)
+java_handle_t *builtin_new(classinfo *c)
{
- java_objectheader *o;
+ java_object_t *o;
#if defined(ENABLE_RT_TIMING)
struct timespec time_start, time_end;
#endif
/* check if we can instantiate this class */
if (c->flags & ACC_ABSTRACT) {
- *exceptionptr =
- new_exception_utfmessage(string_java_lang_InstantiationError,
- c->name);
+ exceptions_throw_instantiationerror(c);
return NULL;
}
*******************************************************************************/
-java_arrayheader *builtin_newarray(s4 size, classinfo *arrayclass)
+java_handle_t *builtin_newarray(s4 size, classinfo *arrayclass)
{
- arraydescriptor *desc;
- s4 dataoffset;
- s4 componentsize;
- s4 actualsize;
- java_arrayheader *a;
+ arraydescriptor *desc;
+ s4 dataoffset;
+ s4 componentsize;
+ s4 actualsize;
+ java_array_t *a;
#if defined(ENABLE_RT_TIMING)
struct timespec time_start, time_end;
#endif
actualsize = dataoffset + size * componentsize;
- if (((u4) actualsize) < ((u4) size)) { /* overflow */
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
+ /* check for overflow */
+
+ if (((u4) actualsize) < ((u4) size)) {
+ exceptions_throw_outofmemoryerror();
return NULL;
}
a = heap_allocate(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL);
- if (!a)
+ if (a == NULL)
return NULL;
a->objheader.vftbl = arrayclass->vftbl;
lock_init_object_lock(&a->objheader);
#endif
- a->size = size;
+ LLNI_array_size(a) = size;
RT_TIMING_GET_TIME(time_end);
RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_ARRAY);
*******************************************************************************/
-java_objectarray *builtin_anewarray(s4 size, classinfo *componentclass)
+java_handle_objectarray_t *builtin_anewarray(s4 size, classinfo *componentclass)
{
classinfo *arrayclass;
if (!arrayclass)
return NULL;
- return (java_objectarray *) builtin_newarray(size, arrayclass);
+ return (java_handle_objectarray_t *) builtin_newarray(size, arrayclass);
}
*******************************************************************************/
-java_booleanarray *builtin_newarray_boolean(s4 size)
+java_handle_booleanarray_t *builtin_newarray_boolean(s4 size)
{
- return (java_booleanarray *)
+ return (java_handle_booleanarray_t *)
builtin_newarray(size,
primitivetype_table[ARRAYTYPE_BOOLEAN].arrayclass);
}
*******************************************************************************/
-java_bytearray *builtin_newarray_byte(s4 size)
+java_handle_bytearray_t *builtin_newarray_byte(s4 size)
{
- return (java_bytearray *)
+ return (java_handle_bytearray_t *)
builtin_newarray(size, primitivetype_table[ARRAYTYPE_BYTE].arrayclass);
}
*******************************************************************************/
-java_chararray *builtin_newarray_char(s4 size)
+java_handle_chararray_t *builtin_newarray_char(s4 size)
{
- return (java_chararray *)
+ return (java_handle_chararray_t *)
builtin_newarray(size, primitivetype_table[ARRAYTYPE_CHAR].arrayclass);
}
*******************************************************************************/
-java_shortarray *builtin_newarray_short(s4 size)
+java_handle_shortarray_t *builtin_newarray_short(s4 size)
{
- return (java_shortarray *)
+ return (java_handle_shortarray_t *)
builtin_newarray(size, primitivetype_table[ARRAYTYPE_SHORT].arrayclass);
}
*******************************************************************************/
-java_intarray *builtin_newarray_int(s4 size)
+java_handle_intarray_t *builtin_newarray_int(s4 size)
{
- return (java_intarray *)
+ return (java_handle_intarray_t *)
builtin_newarray(size, primitivetype_table[ARRAYTYPE_INT].arrayclass);
}
*******************************************************************************/
-java_longarray *builtin_newarray_long(s4 size)
+java_handle_longarray_t *builtin_newarray_long(s4 size)
{
- return (java_longarray *)
+ return (java_handle_longarray_t *)
builtin_newarray(size, primitivetype_table[ARRAYTYPE_LONG].arrayclass);
}
*******************************************************************************/
-java_floatarray *builtin_newarray_float(s4 size)
+java_handle_floatarray_t *builtin_newarray_float(s4 size)
{
- return (java_floatarray *)
+ return (java_handle_floatarray_t *)
builtin_newarray(size, primitivetype_table[ARRAYTYPE_FLOAT].arrayclass);
}
*******************************************************************************/
-java_doublearray *builtin_newarray_double(s4 size)
+java_handle_doublearray_t *builtin_newarray_double(s4 size)
{
- return (java_doublearray *)
+ return (java_handle_doublearray_t *)
builtin_newarray(size,
primitivetype_table[ARRAYTYPE_DOUBLE].arrayclass);
}
passed in an array of longs.
Arguments:
- n............number of dimensions to create
- arrayvftbl...vftbl of the array class
- dims.........array containing the size of each dimension to create
+ n.............number of dimensions to create
+ arrayclass....the array class
+ dims..........array containing the size of each dimension to create
Return value: pointer to the array or NULL if no memory is
available
******************************************************************************/
-static java_arrayheader *builtin_multianewarray_intern(int n,
- classinfo *arrayclass,
- long *dims)
+static java_handle_t *builtin_multianewarray_intern(int n,
+ classinfo *arrayclass,
+ long *dims)
{
- s4 size;
- java_arrayheader *a;
- classinfo *componentclass;
- s4 i;
+ s4 size;
+ java_handle_t *a;
+ classinfo *componentclass;
+ s4 i;
/* create this dimension */
size = (s4) dims[0];
- a = builtin_newarray(size, arrayclass);
+ a = builtin_newarray(size, arrayclass);
if (!a)
return NULL;
/* create the component arrays */
for (i = 0; i < size; i++) {
- java_arrayheader *ea =
+ java_handle_t *ea =
#if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
/* we save an s4 to a s8 slot, 8-byte aligned */
if (!ea)
return NULL;
- ((java_objectarray *) a)->data[i] = (java_objectheader *) ea;
+ ((java_handle_objectarray_t *) a)->data[i] = (java_object_t *) ea;
}
return a;
******************************************************************************/
-java_arrayheader *builtin_multianewarray(int n, classinfo *arrayclass,
- long *dims)
+java_handle_objectarray_t *builtin_multianewarray(int n, classinfo *arrayclass,
+ long *dims)
{
s4 i;
s4 size;
static s4 methodindent = 0;
static u4 callcount = 0;
-java_objectheader *builtin_trace_exception(java_objectheader *xptr,
- methodinfo *m,
- void *pos,
- s4 indent)
+java_handle_t *builtin_trace_exception(java_handle_t *xptr,
+ methodinfo *m,
+ void *pos,
+ s4 indent)
{
char *logtext;
s4 logtextlen;
s4 dumpsize;
codeinfo *code;
+#if defined(ENABLE_DEBUG_FILTER)
+ if (! show_filters_test_verbosecall_exit(m)) return xptr;
+#endif
+
+#if defined(ENABLE_VMLOG)
+ return xptr;
+#endif
+
if (opt_verbosecall && indent)
+#if defined(__S390__)
+ TRACEJAVACALLINDENT--;
+#else
methodindent--;
+#endif
/* calculate message length */
typedesc *paramtype, s8 value)
{
imm_union imu;
- java_objectheader *o;
- java_lang_String *s;
+ java_handle_t *o;
classinfo *c;
utf *u;
u4 len;
break;
case TYPE_FLT:
+#if defined(__S390__)
+ imu.l = value;
+ /* The below won't work on S390 */
+#else
imu.i = (s4) value;
+#endif
sprintf(logtext + strlen(logtext), "%g (0x%08x)", imu.f, imu.i);
break;
/* cast to java.lang.Object */
- o = (java_objectheader *) (ptrint) value;
+ o = (java_handle_t *) (ptrint) value;
/* check return argument for java.lang.Class or java.lang.String */
/* get java.lang.String object and the length of the
string */
- s = (java_lang_String *) o;
-
- u = javastring_toutf(s, false);
+ u = javastring_toutf(o, false);
len = strlen(" (String = \"") + utf_bytes(u) + strlen("\")");
}
#endif /* !defined(NDEBUG) */
-
-/* builtin_trace_args **********************************************************
+/* builtin_verbosecall_enter ***************************************************
Print method call with arguments for -verbose:call.
#if !defined(NDEBUG)
#ifdef TRACE_ARGS_NUM
-void builtin_trace_args(s8 a0, s8 a1,
-#if TRACE_ARGS_NUM >= 4
- s8 a2, s8 a3,
-#endif /* TRACE_ARGS_NUM >= 4 */
-#if TRACE_ARGS_NUM >= 6
- s8 a4, s8 a5,
-#endif /* TRACE_ARGS_NUM >= 6 */
-#if TRACE_ARGS_NUM == 8
- s8 a6, s8 a7,
-#endif /* TRACE_ARGS_NUM == 8 */
- methodinfo *m)
+void builtin_verbosecall_enter(s8 a0, s8 a1,
+# if TRACE_ARGS_NUM >= 4
+ s8 a2, s8 a3,
+# endif
+# if TRACE_ARGS_NUM >= 6
+ s8 a4, s8 a5,
+# endif
+# if TRACE_ARGS_NUM == 8
+ s8 a6, s8 a7,
+# endif
+ methodinfo *m)
{
methoddesc *md;
char *logtext;
s4 i;
s4 pos;
+#if defined(ENABLE_DEBUG_FILTER)
+ if (! show_filters_test_verbosecall_enter(m)) return;
+#endif
+
+#if defined(ENABLE_VMLOG)
+ vmlog_cacao_enter_method(m);
+ return;
+#endif
+
md = m->parseddesc;
/* calculate message length */
dump_release(dumpsize);
methodindent++;
+
}
#endif
#endif /* !defined(NDEBUG) */
-/* builtin_displaymethodstop ***************************************************
+/* builtin_verbosecall_exit ****************************************************
Print method exit for -verbose:call.
*******************************************************************************/
#if !defined(NDEBUG)
-void builtin_displaymethodstop(methodinfo *m, s8 l, double d, float f)
+void builtin_verbosecall_exit(s8 l, double d, float f, methodinfo *m)
{
methoddesc *md;
char *logtext;
s4 pos;
imm_union val;
+#if defined(ENABLE_DEBUG_FILTER)
+ if (! show_filters_test_verbosecall_exit(m)) return;
+#endif
+
+#if defined(ENABLE_VMLOG)
+ vmlog_cacao_leave_method(m);
+ return;
+#endif
+
md = m->parseddesc;
/* calculate message length */
/* release memory */
dump_release(dumpsize);
+
}
#endif /* !defined(NDEBUG) */
#endif /* !(SUPPORT_LONG && SUPPORT_LONG_MUL) */
-#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
+#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) || defined (DISABLE_GC)
s8 builtin_ldiv(s8 a, s8 b)
{
s8 c;
#endif /* !SUPPORT_FLOAT */
-#if !SUPPORT_FLOAT || defined(ENABLE_INTRP)
+#if !SUPPORT_FLOAT || !SUPPORT_FLOAT_CMP || defined(ENABLE_INTRP)
s4 builtin_fcmpl(float a, float b)
{
- if (isnanf(a)) return -1;
- if (isnanf(b)) return -1;
+ if (isnanf(a))
+ return -1;
+
+ if (isnanf(b))
+ return -1;
+
if (!finitef(a) || !finitef(b)) {
a = finitef(a) ? 0 : copysignf(1.0, a);
b = finitef(b) ? 0 : copysignf(1.0, b);
}
- if (a > b) return 1;
- if (a == b) return 0;
+
+ if (a > b)
+ return 1;
+
+ if (a == b)
+ return 0;
+
return -1;
}
if (a == b) return 0;
return -1;
}
-#endif /* !SUPPORT_FLOAT || defined(ENABLE_INTRP) */
+#endif /* !SUPPORT_FLOAT || !SUPPORT_FLOAT_CMP || defined(ENABLE_INTRP) */
float builtin_frem(float a, float b)
#endif /* !SUPPORT_DOUBLE */
-#if !SUPPORT_DOUBLE || defined(ENABLE_INTRP)
+#if !SUPPORT_DOUBLE || !SUPPORT_DOUBLE_CMP || defined(ENABLE_INTRP)
s4 builtin_dcmpl(double a, double b)
{
- if (isnan(a)) return -1;
- if (isnan(b)) return -1;
+ if (isnan(a))
+ return -1;
+
+ if (isnan(b))
+ return -1;
+
if (!finite(a) || !finite(b)) {
a = finite(a) ? 0 : copysign(1.0, a);
b = finite(b) ? 0 : copysign(1.0, b);
}
- if (a > b) return 1;
- if (a == b) return 0;
+
+ if (a > b)
+ return 1;
+
+ if (a == b)
+ return 0;
+
return -1;
}
s4 builtin_dcmpg(double a, double b)
{
- if (isnan(a)) return 1;
- if (isnan(b)) return 1;
+ if (isnan(a))
+ return 1;
+
+ if (isnan(b))
+ return 1;
+
if (!finite(a) || !finite(b)) {
a = finite(a) ? 0 : copysign(1.0, a);
b = finite(b) ? 0 : copysign(1.0, b);
}
- if (a > b) return 1;
- if (a == b) return 0;
+
+ if (a > b)
+ return 1;
+
+ if (a == b)
+ return 0;
+
return -1;
}
-#endif /* !SUPPORT_DOUBLE || defined(ENABLE_INTRP) */
+#endif /* !SUPPORT_DOUBLE || !SUPPORT_DOUBLE_CMP || defined(ENABLE_INTRP) */
double builtin_drem(double a, double b)
#endif /* !(SUPPORT_FLOAT && SUPPORT_F2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC) */
-#if !(SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_F2L)
+#if !(SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_F2L) || defined(DISABLE_GC)
s8 builtin_f2l(float a)
{
s8 l;
#endif /* !(SUPPORT_DOUBLE && SUPPORT_D2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC) */
-#if !(SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_D2L)
+#if !(SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_D2L) || defined(DISABLE_GC)
s8 builtin_d2l(double a)
{
double d;
*******************************************************************************/
-bool builtin_arraycopy(java_arrayheader *src, s4 srcStart,
- java_arrayheader *dest, s4 destStart, s4 len)
+bool builtin_arraycopy(java_handle_t *src, s4 srcStart,
+ java_handle_t *dest, s4 destStart, s4 len)
{
arraydescriptor *sdesc;
arraydescriptor *ddesc;
return false;
}
- sdesc = src->objheader.vftbl->arraydesc;
- ddesc = dest->objheader.vftbl->arraydesc;
+ sdesc = LLNI_vftbl_direct(src)->arraydesc;
+ ddesc = LLNI_vftbl_direct(dest)->arraydesc;
if (!sdesc || !ddesc || (sdesc->arraytype != ddesc->arraytype)) {
exceptions_throw_arraystoreexception();
/* we try to throw exception with the same message as SUN does */
if ((len < 0) || (srcStart < 0) || (destStart < 0) ||
- (srcStart + len < 0) || (srcStart + len > src->size) ||
- (destStart + len < 0) || (destStart + len > dest->size)) {
+ (srcStart + len < 0) || (srcStart + len > LLNI_array_size(src)) ||
+ (destStart + len < 0) || (destStart + len > LLNI_array_size(dest))) {
exceptions_throw_arrayindexoutofboundsexception();
return false;
}
else {
/* We copy references of different type */
- java_objectarray *oas = (java_objectarray *) src;
- java_objectarray *oad = (java_objectarray *) dest;
+ java_handle_objectarray_t *oas = (java_handle_objectarray_t *) src;
+ java_handle_objectarray_t *oad = (java_handle_objectarray_t *) dest;
if (destStart <= srcStart) {
for (i = 0; i < len; i++) {
- java_objectheader *o = oas->data[srcStart + i];
+ java_handle_t *o = oas->data[srcStart + i];
- if (!builtin_canstore(oad, o)) {
- exceptions_throw_arraystoreexception();
+ if (!builtin_canstore(oad, o))
return false;
- }
oad->data[destStart + i] = o;
}
index have been copied before the throw. */
for (i = len - 1; i >= 0; i--) {
- java_objectheader *o = oas->data[srcStart + i];
+ java_handle_t *o = oas->data[srcStart + i];
- if (!builtin_canstore(oad, o)) {
- exceptions_throw_arraystoreexception();
+ if (!builtin_canstore(oad, o))
return false;
- }
oad->data[destStart + i] = o;
}
}
-/* builtin_currenttimemillis ***************************************************
+/* builtin_nanotime ************************************************************
- Return the current time in milliseconds.
+ Return the current time in nanoseconds.
*******************************************************************************/
-s8 builtin_currenttimemillis(void)
+s8 builtin_nanotime(void)
{
struct timeval tv;
- s8 result;
+ s8 usecs;
if (gettimeofday(&tv, NULL) == -1)
vm_abort("gettimeofday failed: %s", strerror(errno));
- result = (s8) tv.tv_sec;
- result *= 1000;
- result += (tv.tv_usec / 1000);
+ usecs = (s8) tv.tv_sec * (1000 * 1000) + (s8) tv.tv_usec;
- return result;
+ return usecs * 1000;
+}
+
+
+/* builtin_currenttimemillis ***************************************************
+
+ Return the current time in milliseconds.
+
+*******************************************************************************/
+
+s8 builtin_currenttimemillis(void)
+{
+ s8 msecs;
+
+ msecs = builtin_nanotime() / 1000 / 1000;
+
+ return msecs;
}
*******************************************************************************/
-java_objectheader *builtin_clone(void *env, java_objectheader *o)
+java_handle_t *builtin_clone(void *env, java_handle_t *o)
{
- arraydescriptor *ad;
- java_arrayheader *ah;
- u4 size;
- classinfo *c;
- java_objectheader *co; /* cloned object header */
+ arraydescriptor *ad;
+ java_handle_t *ah;
+ u4 size;
+ classinfo *c;
+ java_handle_t *co; /* cloned object header */
/* get the array descriptor */
/* we are cloning an array */
if (ad != NULL) {
- ah = (java_arrayheader *) o;
+ ah = (java_handle_t *) o;
- size = ad->dataoffset + ad->componentsize * ah->size;
+ size = ad->dataoffset + ad->componentsize * LLNI_array_size(ah);
co = heap_allocate(size, (ad->arraytype == ARRAYTYPE_OBJECT), NULL);
/* we are cloning a non-array */
if (!builtin_instanceof(o, class_java_lang_Cloneable)) {
- *exceptionptr =
- new_exception(string_java_lang_CloneNotSupportedException);
+ exceptions_throw_clonenotsupportedexception();
return NULL;
}
return co;
}
+#if defined(ENABLE_VMLOG)
+#define NDEBUG
+#include <vmlog_cacao.c>
+#endif
+
/*
* These are local overrides for various environment variables in Emacs.