diff options
Diffstat (limited to 'libjava/interpret.cc')
-rw-r--r-- | libjava/interpret.cc | 86 |
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); } |