This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
BC ABI: Don't initialize vtable pointer
- From: Andrew Haley <aph at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org, java-patches at gcc dot gnu dot org
- Date: Thu, 15 Jun 2006 17:12:59 +0100
- Subject: 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 *,