OSDN Git Service

2008-07-06 Kai Tietz <kai.tietz@onevision.com>
[pf3gnuchains/gcc-fork.git] / libjava / include / execution.h
index 88189f6..c48b2fc 100644 (file)
@@ -1,6 +1,6 @@
 // execution.h - Execution engines. -*- c++ -*-
 
-/* Copyright (C) 2004, 2006  Free Software Foundation
+/* Copyright (C) 2004, 2006, 2007  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -24,13 +24,16 @@ 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, jint);
+                                        jboolean);
   void (*post_miranda_hook) (jclass);
+  _Jv_ClosureList **(*get_closure_list) (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:
@@ -50,14 +53,19 @@ struct _Jv_CompiledEngine : public _Jv_ExecutionEngine
   }
 
   static _Jv_ResolvedMethod *do_resolve_method (_Jv_Method *, jclass,
-                                               jboolean, jint)
+                                               jboolean)
   {
     return NULL;
   }
 
-  static void do_allocate_static_fields (jclass, int, int)
+  static void do_allocate_static_fields (jclass,
+                                        int,
+                                        int)
+  {
+  }
+
+  static void do_allocate_field_initializers (jclass)
   {
-    // Compiled classes don't need this.
   }
 
   static void do_create_ncode (jclass)
@@ -70,15 +78,22 @@ struct _Jv_CompiledEngine : public _Jv_ExecutionEngine
     // Not needed.
   }
 
+  static _Jv_ClosureList **do_get_closure_list (jclass)
+  {
+    return NULL;
+  }
+
   _Jv_CompiledEngine ()
   {
     unregister = do_unregister;
     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;
+    get_closure_list = do_get_closure_list;
   }
 
   // These operators make it so we don't have to link in libstdc++.
@@ -93,6 +108,112 @@ struct _Jv_CompiledEngine : public _Jv_ExecutionEngine
   }
 };
 
+class _Jv_IndirectCompiledClass
+{
+public:
+  void **field_initializers;
+  _Jv_ClosureList **closures;
+};
+
+// 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;
+    get_closure_list = do_get_closure_list;
+  }
+  
+  static _Jv_IndirectCompiledClass *get_aux_info (jclass klass)
+  {
+    _Jv_IndirectCompiledClass *aux =
+      (_Jv_IndirectCompiledClass*)klass->aux_info;
+    if (!aux)
+      {
+       aux = (_Jv_IndirectCompiledClass*)
+         _Jv_AllocRawObj (sizeof (_Jv_IndirectCompiledClass));
+       klass->aux_info = aux;
+      }
+
+    return aux;
+  }
+
+  static void do_allocate_field_initializers (jclass klass)
+  {
+    _Jv_IndirectCompiledClass *aux = get_aux_info (klass);
+    if (!aux)
+      {
+       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);
+  }
+
+#ifdef INTERPRETER
+  static _Jv_ClosureList **do_get_closure_list (jclass klass)
+  {
+    _Jv_IndirectCompiledClass *aux = get_aux_info (klass);
+
+    if (!aux->closures)
+      aux->closures = _Jv_ClosureListFinalizer ();
+
+    return aux->closures;
+  }
+#endif
+};
+
+#ifdef INTERPRETER
+
 // This handles interpreted code.
 class _Jv_InterpreterEngine : public _Jv_ExecutionEngine
 {
@@ -102,7 +223,7 @@ class _Jv_InterpreterEngine : public _Jv_ExecutionEngine
   static void do_allocate_static_fields (jclass, int, int);
   static void do_create_ncode (jclass);
   static _Jv_ResolvedMethod *do_resolve_method (_Jv_Method *, jclass,
-                                               jboolean, jint);
+                                               jboolean);
 
   static bool do_need_resolve_string_fields ()
   {
@@ -114,17 +235,25 @@ class _Jv_InterpreterEngine : public _Jv_ExecutionEngine
     _Jv_UnregisterClass(klass);
   }
 
+  static void do_allocate_field_initializers (jclass)
+  {
+  }
+
   static void do_post_miranda_hook (jclass);
 
+  static _Jv_ClosureList **do_get_closure_list (jclass klass);
+
   _Jv_InterpreterEngine ()
   {
     unregister = do_unregister;
     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;
+    get_closure_list = do_get_closure_list;
   }
 
   // These operators make it so we don't have to link in libstdc++.
@@ -139,8 +268,9 @@ class _Jv_InterpreterEngine : public _Jv_ExecutionEngine
   }
 };
 
-
 extern _Jv_InterpreterEngine _Jv_soleInterpreterEngine;
-extern _Jv_CompiledEngine _Jv_soleCompiledEngine;
+#endif // INTERPRETER
 
+extern _Jv_CompiledEngine _Jv_soleCompiledEngine;
+extern _Jv_IndirectCompiledEngine _Jv_soleIndirectCompiledEngine;
 #endif // __JAVA_EXECUTION_H__