This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

BC ABI: Don't initialize vtable pointer


We were setting the vtable pointer of a read-only object.  This has
the side-effect of creating a copy reloc in an executable, and we
don't want that.

The best way to solve the problem is not to initialize the vtable
pointer at compile time but leave it a NULL in the object file: It'll
get filled in at DSO startup.

Andrew.


2006-06-15  Andrew Haley  <aph@redhat.com>

	* class.c (make_class_data): When using flag_indirect_classes,
	don't initialize the vtable of Class instances.

Index: gcc/java/class.c
===================================================================
--- gcc/java/class.c	(revision 114609)
+++ gcc/java/class.c	(working copy)
@@ -1874,10 +1874,12 @@
 
   START_RECORD_CONSTRUCTOR (temp, object_type_node);
   PUSH_FIELD_VALUE (temp, "vtable",
-		    build2 (PLUS_EXPR, dtable_ptr_type,
-			    build1 (ADDR_EXPR, dtable_ptr_type,
-				    class_dtable_decl),
-			    dtable_start_offset));
+		    (flag_indirect_classes 
+		     ? null_pointer_node
+		     : build2 (PLUS_EXPR, dtable_ptr_type,
+			       build1 (ADDR_EXPR, dtable_ptr_type,
+				       class_dtable_decl),
+			       dtable_start_offset)));
   if (! flag_hash_synchronization)
     PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
   FINISH_RECORD_CONSTRUCTOR (temp);


2006-06-15  Andrew Haley  <aph@redhat.com>

	* java/lang/natClassLoader.cc (_Jv_NewClassFromInitializer): Don't
	copy the whole Class instance from the initializer: instead, copy
	everything but the first word (the vtable pointer).
	Change prototype to (const char* class_initializer).
	(_Jv_RegisterNewClasses): Change prototype to (const char**).
	* java/lang/Class.h (_Jv_RegisterNewClasses): Change prototype to
	(const char**).

Index: java/lang/natClassLoader.cc
===================================================================
--- java/lang/natClassLoader.cc	(revision 114609)
+++ java/lang/natClassLoader.cc	(working copy)
@@ -218,11 +218,20 @@
 
 // Create a class on the heap from an initializer struct.
 jclass
-_Jv_NewClassFromInitializer (const jclass class_initializer)
+_Jv_NewClassFromInitializer (const char *class_initializer)
 {
-  jclass new_class = (jclass)_Jv_AllocObj (sizeof *new_class,
-					   &java::lang::Class::class$);  
-  memcpy ((void*)new_class, (void*)class_initializer, sizeof *new_class);
+  /* We create an instance of java::lang::Class and copy all of its
+     fields except the first word (the vtable pointer) from
+     CLASS_INITIALIZER.  This first word is pre-initialized by
+     _Jv_AllocObj, and we don't want to overwrite it.  */
+
+  volatile jclass new_class
+    = (jclass)_Jv_AllocObj (sizeof (java::lang::Class),
+			    &java::lang::Class::class$);
+  const char *src = class_initializer + sizeof (void*);
+  volatile char *dst = (volatile char*)new_class + sizeof (void*);
+  size_t len = sizeof (*new_class) - sizeof (void*);
+  memcpy ((void*)dst, src, len);
 
   new_class->engine = &_Jv_soleIndirectCompiledEngine;
 
@@ -240,13 +249,13 @@
 // heap) and we write the address of the new class into the address
 // pointed to by the second word.
 void
-_Jv_RegisterNewClasses (void **classes)
+_Jv_RegisterNewClasses (char **classes)
 {
   _Jv_InitGC ();
 
-  jclass initializer;
+  char *initializer;
 
-  while ((initializer = (jclass)*classes++))
+  while ((initializer = *classes++))
     {
       jclass *class_ptr = (jclass *)*classes++;
       *class_ptr = _Jv_NewClassFromInitializer (initializer);
Index: java/lang/Class.h
===================================================================
--- java/lang/Class.h	(revision 114609)
+++ java/lang/Class.h	(working copy)
@@ -40,8 +40,8 @@
 // We declare these here to avoid including gcj/cni.h.
 extern "C" void _Jv_InitClass (jclass klass);
 extern "C" jclass _Jv_NewClassFromInitializer 
-   (const jclass class_initializer);
-extern "C" void _Jv_RegisterNewClasses (void **classes);
+   (const char *class_initializer);
+extern "C" void _Jv_RegisterNewClasses (char **classes);
 extern "C" void _Jv_RegisterClasses (const jclass *classes);
 extern "C" void _Jv_RegisterClasses_Counted (const jclass *classes,
 					     size_t count);
@@ -447,7 +447,7 @@
 					       int method_idx);
 
   friend void ::_Jv_InitClass (jclass klass);
-  friend java::lang::Class* ::_Jv_NewClassFromInitializer (const jclass class_initializer);
+  friend java::lang::Class* ::_Jv_NewClassFromInitializer (const char *class_initializer);
   friend void _Jv_RegisterNewClasses (void **classes);
 
   friend _Jv_Method* ::_Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *, 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]