diff options
-rw-r--r-- | libjava/ChangeLog | 16 | ||||
-rw-r--r-- | libjava/gnu/gcj/runtime/natSharedLibLoader.cc | 4 | ||||
-rw-r--r-- | libjava/include/execution.h | 110 | ||||
-rw-r--r-- | libjava/java/lang/Class.h | 2 | ||||
-rw-r--r-- | libjava/java/lang/natClassLoader.cc | 2 | ||||
-rw-r--r-- | libjava/link.cc | 3 | ||||
-rw-r--r-- | libjava/prims.cc | 3 |
7 files changed, 119 insertions, 21 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index e961817..4221240 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,19 @@ +2006-05-09 Andrew Haley <aph@redhat.com> + + * prims.cc (_Jv_soleIndirectCompiledEngine): New. + * include/execution.h (Jv_CompiledEngine::do_allocate_static_fields): + Remove body. + (_Jv_CompiledEngine::allocate_field_initializers): New. + (_Jv_CompiledEngine::_Jv_CompiledEngine): Initialize + allocate_field_initializers. + (class _Jv_IndirectCompiledClass): New. + (struct _Jv_IndirectCompiledEngine): New. + * java/lang/Class.h: (IndirectCompiledEngine): New. + * java/lang/natClassLoader.cc (_Jv_NewClassFromInitializer): Set + engine to _Jv_soleIndirectCompiledEngine + * link.cc (ensure_fields_laid_out): Call + engine->allocate_field_initializers(). + 2006-05-06 Andreas Tobler <a.tobler@schweiz.ch> * testsuite/libjava.jni/jni.exp (gcj_jni_compile_c_to_so): Add check for diff --git a/libjava/gnu/gcj/runtime/natSharedLibLoader.cc b/libjava/gnu/gcj/runtime/natSharedLibLoader.cc index fcff8f2..19d136c 100644 --- a/libjava/gnu/gcj/runtime/natSharedLibLoader.cc +++ b/libjava/gnu/gcj/runtime/natSharedLibLoader.cc @@ -44,7 +44,8 @@ _Jv_sharedlib_register_hook (jclass cls) { cls->protectionDomain = curHelper->domain; cls->loader = curLoader; - cls->engine = &_Jv_soleCompiledEngine; + if (! cls->engine) + cls->engine = &_Jv_soleCompiledEngine; curHelper->registerClass(cls->getName(), cls); } @@ -95,6 +96,7 @@ gnu::gcj::runtime::SharedLibHelper::init(void) { const char *msg = dlerror(); throw new java::lang::UnknownError(JvNewStringLatin1(msg)); + fprintf (stderr, "failed loading %s: %s\n", lname, msg); } handler = (gnu::gcj::RawData*) h; #else diff --git a/libjava/include/execution.h b/libjava/include/execution.h index f0c309c..279e9c1 100644 --- a/libjava/include/execution.h +++ b/libjava/include/execution.h @@ -24,13 +24,15 @@ struct _Jv_ExecutionEngine bool (*need_resolve_string_fields) (); void (*verify) (jclass); void (*allocate_static_fields) (jclass, int, int); + void (*allocate_field_initializers) (jclass); void (*create_ncode) (jclass); _Jv_ResolvedMethod *(*resolve_method) (_Jv_Method *, jclass, jboolean); void (*post_miranda_hook) (jclass); }; -// This handles all gcj-compiled code, including BC ABI. +// This handles gcj-compiled code except that compiled with +// -findirect-classes. struct _Jv_CompiledEngine : public _Jv_ExecutionEngine { public: @@ -55,25 +57,14 @@ struct _Jv_CompiledEngine : public _Jv_ExecutionEngine return NULL; } - static void do_allocate_static_fields (jclass klass, - int pointer_size, - int other_size) + static void do_allocate_static_fields (jclass, + int, + int) { - // Splitting the allocations here lets us scan reference fields - // and avoid scanning non-reference fields. - char *reference_fields = (char *) _Jv_AllocRawObj (pointer_size); - char *non_reference_fields = (char *) _Jv_AllocBytes (other_size); - - for (int i = 0; i < klass->field_count; i++) - { - _Jv_Field *field = &klass->fields[i]; - - if ((field->flags & java::lang::reflect::Modifier::STATIC) == 0) - continue; + } - char *base = field->isRef() ? reference_fields : non_reference_fields; - field->u.addr = base + field->u.boffset; - } + static void do_allocate_field_initializers (jclass) + { } static void do_create_ncode (jclass) @@ -92,6 +83,7 @@ struct _Jv_CompiledEngine : public _Jv_ExecutionEngine need_resolve_string_fields = do_need_resolve_string_fields; verify = do_verify; allocate_static_fields = do_allocate_static_fields; + allocate_field_initializers = do_allocate_field_initializers; create_ncode = do_create_ncode; resolve_method = do_resolve_method; post_miranda_hook = do_post_miranda_hook; @@ -109,6 +101,81 @@ struct _Jv_CompiledEngine : public _Jv_ExecutionEngine } }; +class _Jv_IndirectCompiledClass +{ +public: + void **field_initializers; +}; + +// This handles gcj-compiled code compiled with -findirect-classes. +struct _Jv_IndirectCompiledEngine : public _Jv_CompiledEngine +{ + _Jv_IndirectCompiledEngine () : _Jv_CompiledEngine () + { + allocate_static_fields = do_allocate_static_fields; + allocate_field_initializers = do_allocate_field_initializers; + } + + static void do_allocate_field_initializers (jclass klass) + { + _Jv_IndirectCompiledClass *aux + = (_Jv_IndirectCompiledClass*) + _Jv_AllocRawObj (sizeof (_Jv_IndirectCompiledClass)); + klass->aux_info = aux; + + aux->field_initializers = (void **)_Jv_Malloc (klass->field_count + * sizeof (void*)); + + for (int i = 0; i < klass->field_count; i++) + { + _Jv_Field *field = &klass->fields[i]; + if (field->flags & java::lang::reflect::Modifier::STATIC) + { + aux->field_initializers[i] = field->u.addr; + field->u.addr = NULL; + } + } + } + + static void do_allocate_static_fields (jclass klass, + int pointer_size, + int other_size) + { + // Splitting the allocations here lets us scan reference fields + // and avoid scanning non-reference fields. + char *reference_fields = (char *) _Jv_AllocRawObj (pointer_size); + char *non_reference_fields = (char *) _Jv_AllocBytes (other_size); + + _Jv_IndirectCompiledClass *aux + = (_Jv_IndirectCompiledClass*)klass->aux_info; + + for (int i = 0; i < klass->field_count; i++) + { + _Jv_Field *field = &klass->fields[i]; + + if ((field->flags & java::lang::reflect::Modifier::STATIC) == 0) + continue; + + char *base = field->isRef() ? reference_fields : non_reference_fields; + field->u.addr = base + field->u.boffset; + + if (aux->field_initializers[i]) + { + int field_size; + if (! field->isRef ()) + field_size = field->type->size (); + else + field_size = sizeof (jobject); + + memcpy (field->u.addr, aux->field_initializers[i], field_size); + } + } + _Jv_Free (aux->field_initializers); + } +}; + + + // This handles interpreted code. class _Jv_InterpreterEngine : public _Jv_ExecutionEngine { @@ -130,6 +197,10 @@ class _Jv_InterpreterEngine : public _Jv_ExecutionEngine _Jv_UnregisterClass(klass); } + static void do_allocate_field_initializers (jclass) + { + } + static void do_post_miranda_hook (jclass); _Jv_InterpreterEngine () @@ -138,6 +209,7 @@ class _Jv_InterpreterEngine : public _Jv_ExecutionEngine need_resolve_string_fields = do_need_resolve_string_fields; verify = do_verify; allocate_static_fields = do_allocate_static_fields; + allocate_field_initializers = do_allocate_field_initializers; create_ncode = do_create_ncode; resolve_method = do_resolve_method; post_miranda_hook = do_post_miranda_hook; @@ -158,5 +230,5 @@ class _Jv_InterpreterEngine : public _Jv_ExecutionEngine extern _Jv_InterpreterEngine _Jv_soleInterpreterEngine; extern _Jv_CompiledEngine _Jv_soleCompiledEngine; - +extern _Jv_IndirectCompiledEngine _Jv_soleIndirectCompiledEngine; #endif // __JAVA_EXECUTION_H__ diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h index f6ca3de..22a078d 100644 --- a/libjava/java/lang/Class.h +++ b/libjava/java/lang/Class.h @@ -96,6 +96,7 @@ struct _Jv_ArrayVTable; class _Jv_Linker; class _Jv_ExecutionEngine; class _Jv_CompiledEngine; +class _Jv_IndirectCompiledEngine; class _Jv_InterpreterEngine; #ifdef INTERPRETER @@ -538,6 +539,7 @@ private: friend class ::_Jv_Linker; friend class ::_Jv_ExecutionEngine; friend class ::_Jv_CompiledEngine; + friend class ::_Jv_IndirectCompiledEngine; friend class ::_Jv_InterpreterEngine; friend void ::_Jv_sharedlib_register_hook (jclass klass); diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc index 87419c3..43e624a 100644 --- a/libjava/java/lang/natClassLoader.cc +++ b/libjava/java/lang/natClassLoader.cc @@ -200,6 +200,8 @@ _Jv_NewClassFromInitializer (const jclass class_initializer) &java::lang::Class::class$); memcpy ((void*)new_class, (void*)class_initializer, sizeof *new_class); + new_class->engine = &_Jv_soleIndirectCompiledEngine; + if (_Jv_CheckABIVersion ((unsigned long) new_class->next_or_version)) (*_Jv_RegisterClassHook) (new_class); diff --git a/libjava/link.cc b/libjava/link.cc index 6c28151..4f01cb5 100644 --- a/libjava/link.cc +++ b/libjava/link.cc @@ -1527,6 +1527,8 @@ _Jv_Linker::ensure_fields_laid_out (jclass klass) else instance_size = java::lang::Object::class$.size(); + klass->engine->allocate_field_initializers (klass); + for (int i = 0; i < klass->field_count; i++) { int field_size; @@ -1539,7 +1541,6 @@ _Jv_Linker::ensure_fields_laid_out (jclass klass) // It is safe to resolve the field here, since it's a // primitive class, which does not cause loading to happen. resolve_field (field, klass->loader); - field_size = field->type->size (); field_align = get_alignment_from_class (field->type); } diff --git a/libjava/prims.cc b/libjava/prims.cc index e0cdc0a..2536ca4 100644 --- a/libjava/prims.cc +++ b/libjava/prims.cc @@ -74,6 +74,9 @@ details. */ // Execution engine for compiled code. _Jv_CompiledEngine _Jv_soleCompiledEngine; +// Execution engine for code compiled with -findirect-classes +_Jv_IndirectCompiledEngine _Jv_soleIndirectCompiledEngine; + // We allocate a single OutOfMemoryError exception which we keep // around for use if we run out of memory. static java::lang::OutOfMemoryError *no_memory; |