aboutsummaryrefslogtreecommitdiff
path: root/libjava/interpret.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/interpret.cc')
-rw-r--r--libjava/interpret.cc86
1 files changed, 49 insertions, 37 deletions
diff --git a/libjava/interpret.cc b/libjava/interpret.cc
index 331424f0834..109ee10ff8b 100644
--- a/libjava/interpret.cc
+++ b/libjava/interpret.cc
@@ -54,6 +54,21 @@ static void throw_null_pointer_exception ()
__attribute__ ((__noreturn__));
#endif
+#ifdef DIRECT_THREADED
+// Lock to ensure that methods are not compiled concurrently.
+// We could use a finer-grained lock here, however it is not safe to use
+// the Class monitor as user code in another thread could hold it.
+static _Jv_Mutex_t compile_mutex;
+
+void
+_Jv_InitInterpreter()
+{
+ _Jv_MutexInit (&compile_mutex);
+}
+#else
+void _Jv_InitInterpreter() {}
+#endif
+
extern "C" double __ieee754_fmod (double,double);
// This represents a single slot in the "compiled" form of the
@@ -1032,9 +1047,14 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
#define PCVAL(unionval) unionval.p
#define AMPAMP(label) &&label
- // Compile if we must.
+ // Compile if we must. NOTE: Double-check locking.
if (prepared == NULL)
- compile (insn_target);
+ {
+ _Jv_MutexLock (&compile_mutex);
+ if (prepared == NULL)
+ compile (insn_target);
+ _Jv_MutexUnlock (&compile_mutex);
+ }
pc = (insn_slot *) prepared;
#else
@@ -1156,7 +1176,7 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
ffi_cif *cif = &rmeth->cif;
ffi_raw *raw = (ffi_raw*) sp;
- jdouble rvalue;
+ _Jv_value rvalue;
#if FFI_NATIVE_RAW_API
/* We assume that this is only implemented if it's correct */
@@ -1172,11 +1192,11 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
* so those are checked before the switch */
if (rtype == FFI_TYPE_POINTER)
{
- PUSHA (*(jobject*)&rvalue);
+ PUSHA (rvalue.object_value);
}
else if (rtype == FFI_TYPE_SINT32)
{
- PUSHI (*(jint*)&rvalue);
+ PUSHI (rvalue.int_value);
}
else if (rtype == FFI_TYPE_VOID)
{
@@ -1187,36 +1207,27 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
switch (rtype)
{
case FFI_TYPE_SINT8:
- {
- jbyte value = (*(jint*)&rvalue) & 0xff;
- PUSHI (value);
- }
+ PUSHI ((jbyte)(rvalue.int_value & 0xff));
break;
case FFI_TYPE_SINT16:
- {
- jshort value = (*(jint*)&rvalue) & 0xffff;
- PUSHI (value);
- }
+ PUSHI ((jshort)(rvalue.int_value & 0xffff));
break;
case FFI_TYPE_UINT16:
- {
- jint value = (*(jint*)&rvalue) & 0xffff;
- PUSHI (value);
- }
+ PUSHI (rvalue.int_value & 0xffff);
break;
case FFI_TYPE_FLOAT:
- PUSHF (*(jfloat*)&rvalue);
+ PUSHF (rvalue.float_value);
break;
case FFI_TYPE_DOUBLE:
- PUSHD (rvalue);
+ PUSHD (rvalue.double_value);
break;
case FFI_TYPE_SINT64:
- PUSHL (*(jlong*)&rvalue);
+ PUSHL (rvalue.long_value);
break;
default:
@@ -2408,37 +2419,37 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
switch (type->size_in_bytes)
{
case 1:
- PUSHI (*(jbyte*) (field->u.addr));
+ PUSHI (*field->u.byte_addr);
newinsn = AMPAMP (getstatic_resolved_1);
break;
case 2:
if (type == JvPrimClass (char))
{
- PUSHI(*(jchar*) (field->u.addr));
+ PUSHI (*field->u.char_addr);
newinsn = AMPAMP (getstatic_resolved_char);
}
else
{
- PUSHI(*(jshort*) (field->u.addr));
+ PUSHI (*field->u.short_addr);
newinsn = AMPAMP (getstatic_resolved_short);
}
break;
case 4:
- PUSHI(*(jint*) (field->u.addr));
+ PUSHI(*field->u.int_addr);
newinsn = AMPAMP (getstatic_resolved_4);
break;
case 8:
- PUSHL(*(jlong*) (field->u.addr));
+ PUSHL(*field->u.long_addr);
newinsn = AMPAMP (getstatic_resolved_8);
break;
}
}
else
{
- PUSHA(*(jobject*) (field->u.addr));
+ PUSHA(*field->u.object_addr);
newinsn = AMPAMP (getstatic_resolved_obj);
}
@@ -2494,42 +2505,43 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
NULLCHECK(obj);
void *newinsn = NULL;
+ _Jv_value *val = (_Jv_value *) ((char *)obj + field_offset);
if (type->isPrimitive ())
{
switch (type->size_in_bytes)
{
case 1:
- PUSHI (*(jbyte*) ((char*)obj + field_offset));
+ PUSHI (val->byte_value);
newinsn = AMPAMP (getfield_resolved_1);
break;
case 2:
if (type == JvPrimClass (char))
{
- PUSHI (*(jchar*) ((char*)obj + field_offset));
+ PUSHI (val->char_value);
newinsn = AMPAMP (getfield_resolved_char);
}
else
{
- PUSHI (*(jshort*) ((char*)obj + field_offset));
+ PUSHI (val->short_value);
newinsn = AMPAMP (getfield_resolved_short);
}
break;
case 4:
- PUSHI (*(jint*) ((char*)obj + field_offset));
+ PUSHI (val->int_value);
newinsn = AMPAMP (getfield_resolved_4);
break;
case 8:
- PUSHL(*(jlong*) ((char*)obj + field_offset));
+ PUSHL (val->long_value);
newinsn = AMPAMP (getfield_resolved_8);
break;
}
}
else
{
- PUSHA(*(jobject*) ((char*)obj + field_offset));
+ PUSHA (val->object_value);
newinsn = AMPAMP (getfield_resolved_obj);
}
@@ -2611,7 +2623,7 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
case 1:
{
jint value = POPI();
- *(jbyte*) (field->u.addr) = value;
+ *field->u.byte_addr = value;
newinsn = AMPAMP (putstatic_resolved_1);
break;
}
@@ -2619,7 +2631,7 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
case 2:
{
jint value = POPI();
- *(jchar*) (field->u.addr) = value;
+ *field->u.char_addr = value;
newinsn = AMPAMP (putstatic_resolved_2);
break;
}
@@ -2627,7 +2639,7 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
case 4:
{
jint value = POPI();
- *(jint*) (field->u.addr) = value;
+ *field->u.int_addr = value;
newinsn = AMPAMP (putstatic_resolved_4);
break;
}
@@ -2635,7 +2647,7 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
case 8:
{
jlong value = POPL();
- *(jlong*) (field->u.addr) = value;
+ *field->u.long_addr = value;
newinsn = AMPAMP (putstatic_resolved_8);
break;
}
@@ -2644,7 +2656,7 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
else
{
jobject value = POPA();
- *(jobject*) (field->u.addr) = value;
+ *field->u.object_addr = value;
newinsn = AMPAMP (putstatic_resolved_obj);
}