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]

C++/Java: Don't use type size in object allocation


Currently, calls to the Java object allocation routines (eg _Jv_AllocObject) pass both a class parameter and a size parameter. Hard coding the size parameter at the call site contradicts binary compatibility, since the size of the object being created may change at runtime. Even without binary compatibility, passing the size parameter is redundant because the size of the type can be trivially obtained from class metadata.

As a side benefit, this change shaves 70k off libgcj.so sinces it reduces the code needed to push parameters for each "new".

This patch consists of front-end and runtime changes. Since C++ also calls _Jv_AllocObject for extern "Java" types, it needed to be updated as well. So, I need approval from a C++ maintainer for this, please! OK to commit?

Regards

Bryce


libjava:

2004-04-15  Bryce McKinlay  <mckinlay@redhat.com>

	* prims.cc (_Jv_AllocObject): Remove `size' argument.
	(_Jv_AllocObjectNoFinalizer): Likewise.
	(_Jv_AllocObjectNoInitNoFinalizer): Likewise.
	(_Jv_AllocPtrFreeObject): Likewise.
	(_Jv_AllocString): Moved from natString.cc. Call collector interface
	directly even in the JVMPI case.	
	* gcj/cni.h (JvAllocObject): Remove `size' argument from 
	_Jv_AllocObject calls.
	* gcj/javaprims.h: Update prototypes.
	* gnu/gcj/natCore.cc (_Jv_create_core): Use `new', not _Jv_AllocObject.
	* java/lang/Class.h: Update _Jv_AllocObject friend prototype.
	* java/lang/natString.cc (_Jv_AllocString): Move to prims.cc.
	

Index: prims.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/prims.cc,v
retrieving revision 1.87
diff -u -r1.87 prims.cc
--- prims.cc	14 Jan 2004 22:49:58 -0000	1.87
+++ prims.cc	15 Apr 2004 21:36:15 -0000
@@ -397,8 +397,9 @@
 // If we know that JVMPI is disabled, this can be replaced by a direct call
 // to the allocator for the appropriate GC.
 jobject
-_Jv_AllocObjectNoInitNoFinalizer (jclass klass, jint size)
+_Jv_AllocObjectNoInitNoFinalizer (jclass klass)
 {
+  jint size = klass->size ();
   jobject obj = (jobject) _Jv_AllocObj (size, klass);
   jvmpi_notify_alloc (klass, size, obj);
   return obj;
@@ -406,9 +407,10 @@
 
 // And now a version that initializes if necessary.
 jobject
-_Jv_AllocObjectNoFinalizer (jclass klass, jint size)
+_Jv_AllocObjectNoFinalizer (jclass klass)
 {
   _Jv_InitClass (klass);
+  jint size = klass->size ();
   jobject obj = (jobject) _Jv_AllocObj (size, klass);
   jvmpi_notify_alloc (klass, size, obj);
   return obj;
@@ -416,10 +418,10 @@
 
 // And now the general version that registers a finalizer if necessary.
 jobject
-_Jv_AllocObject (jclass klass, jint size)
+_Jv_AllocObject (jclass klass)
 {
-  jobject obj = _Jv_AllocObjectNoFinalizer (klass, size);
-
+  jobject obj = _Jv_AllocObjectNoFinalizer (klass);
+  
   // We assume that the compiler only generates calls to this routine
   // if there really is an interesting finalizer.
   // Unfortunately, we still have to the dynamic test, since there may
@@ -432,14 +434,62 @@
   return obj;
 }
 
+// Allocate a String, including variable length storage.
+jstring
+_Jv_AllocString(jsize len)
+{
+  using namespace java::lang;
+
+  jsize sz = sizeof(java::lang::String) + len * sizeof(jchar);
+
+  // We assert that for strings allocated this way, the data field
+  // will always point to the object itself.  Thus there is no reason
+  // for the garbage collector to scan any of it.
+  // Furthermore, we're about to overwrite the string data, so
+  // initialization of the object is not an issue.
+
+  // String needs no initialization, and there is no finalizer, so
+  // we can go directly to the collector's allocator interface.
+  jstring obj = (jstring) _Jv_AllocPtrFreeObj(sz, &String::class$);
+
+  obj->data = obj;
+  obj->boffset = sizeof(java::lang::String);
+  obj->count = len;
+  obj->cachedHashCode = 0;
+  
+#ifdef ENABLE_JVMPI
+  // Service JVMPI request.
+
+  if (__builtin_expect (_Jv_JVMPI_Notify_OBJECT_ALLOC != 0, false))
+    {
+      JVMPI_Event event;
+
+      event.event_type = JVMPI_EVENT_OBJECT_ALLOC;
+      event.env_id = NULL;
+      event.u.obj_alloc.arena_id = 0;
+      event.u.obj_alloc.class_id = (jobjectID) &Class::class$;
+      event.u.obj_alloc.is_array = 0;
+      event.u.obj_alloc.size = sz;
+      event.u.obj_alloc.obj_id = (jobjectID) obj;
+
+      _Jv_DisableGC ();
+      (*_Jv_JVMPI_Notify_OBJECT_ALLOC) (&event);
+      _Jv_EnableGC ();
+    }
+#endif  
+  
+  return obj;
+}
+
 // A version of the above that assumes the object contains no pointers,
 // and requires no finalization.  This can't happen if we need pointers
 // to locks.
 #ifdef JV_HASH_SYNCHRONIZATION
 jobject
-_Jv_AllocPtrFreeObject (jclass klass, jint size)
+_Jv_AllocPtrFreeObject (jclass klass)
 {
   _Jv_InitClass (klass);
+  jint size = klass->size ();
 
   jobject obj = (jobject) _Jv_AllocPtrFreeObj (size, klass);
 
Index: gcj/cni.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gcj/cni.h,v
retrieving revision 1.10
diff -u -r1.10 cni.h
--- gcj/cni.h	8 Jul 2003 21:27:37 -0000	1.10
+++ gcj/cni.h	15 Apr 2004 21:36:15 -0000
@@ -23,13 +23,13 @@
 extern inline jobject
 JvAllocObject (jclass cls)
 {
-  return _Jv_AllocObject (cls, cls->size());
+  return _Jv_AllocObject (cls);
 }
 
 extern inline jobject
 JvAllocObject (jclass cls, jsize sz)
 {
-  return _Jv_AllocObject (cls, sz);
+  return _Jv_AllocObject (cls);
 }
 
 extern "C" jstring _Jv_NewStringUTF (const char *bytes);
Index: gcj/javaprims.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gcj/javaprims.h,v
retrieving revision 1.48
diff -u -r1.48 javaprims.h
--- gcj/javaprims.h	25 Nov 2003 18:26:08 -0000	1.48
+++ gcj/javaprims.h	15 Apr 2004 21:36:15 -0000
@@ -450,17 +450,17 @@
 typedef struct _Jv_Field *jfieldID;
 typedef struct _Jv_Method *jmethodID;
 
-extern "C" jobject _Jv_AllocObject (jclass, jint) __attribute__((__malloc__));
-extern "C" jobject _Jv_AllocObjectNoFinalizer (jclass, jint) __attribute__((__malloc__));
-extern "C" jobject _Jv_AllocObjectNoInitNoFinalizer (jclass, jint) __attribute__((__malloc__));
+extern "C" jobject _Jv_AllocObject (jclass) __attribute__((__malloc__));
+extern "C" jobject _Jv_AllocObjectNoFinalizer (jclass) __attribute__((__malloc__));
+extern "C" jobject _Jv_AllocObjectNoInitNoFinalizer (jclass) __attribute__((__malloc__));
 #ifdef JV_HASH_SYNCHRONIZATION
-  extern "C" jobject _Jv_AllocPtrFreeObject (jclass, jint)
+  extern "C" jobject _Jv_AllocPtrFreeObject (jclass)
   			    __attribute__((__malloc__));
 #else
   // Collector still needs to scan sync_info
-  static inline jobject _Jv_AllocPtrFreeObject (jclass klass, jint sz)
+  static inline jobject _Jv_AllocPtrFreeObject (jclass klass)
   {
-    return _Jv_AllocObject(klass, sz);
+    return _Jv_AllocObject(klass);
   }
 #endif
 extern "C" jboolean _Jv_IsInstanceOf(jobject, jclass);
Index: gnu/gcj/natCore.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/natCore.cc,v
retrieving revision 1.3
diff -u -r1.3 natCore.cc
--- gnu/gcj/natCore.cc	28 Aug 2003 22:17:35 -0000	1.3
+++ gnu/gcj/natCore.cc	15 Apr 2004 21:36:15 -0000
@@ -96,8 +96,7 @@
   gnu::gcj::Core *core = NULL;
   if (node)
     {
-      core = (gnu::gcj::Core *) _Jv_AllocObject(&gnu::gcj::Core::class$,
-						sizeof (gnu::gcj::Core));
+      core = new gnu::gcj::Core ();
       core->ptr = (gnu::gcj::RawData *) node->data;
       core->length = node->data_length;
     }
Index: java/lang/Class.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/Class.h,v
retrieving revision 1.63
diff -u -r1.63 Class.h
--- java/lang/Class.h	3 Dec 2003 21:26:59 -0000	1.63
+++ java/lang/Class.h	15 Apr 2004 21:36:15 -0000
@@ -286,7 +286,7 @@
   friend jfieldID JvGetFirstStaticField (jclass);
   friend jint JvNumStaticFields (jclass);
 
-  friend jobject _Jv_AllocObject (jclass, jint);
+  friend jobject _Jv_AllocObject (jclass);
   friend void *_Jv_AllocObj (jint, jclass);
   friend void *_Jv_AllocPtrFreeObj (jint, jclass);
   friend void *_Jv_AllocArray (jint, jclass);
 
Index: java/lang/natString.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natString.cc,v
retrieving revision 1.33
diff -u -r1.33 natString.cc
--- java/lang/natString.cc	16 Oct 2003 21:28:23 -0000	1.33
+++ java/lang/natString.cc	15 Apr 2004 21:36:15 -0000
@@ -402,30 +402,6 @@
 }
 
 jstring
-_Jv_AllocString(jsize len)
-{
-  jsize sz = sizeof(java::lang::String) + len * sizeof(jchar);
-
-  // We assert that for strings allocated this way, the data field
-  // will always point to the object itself.  Thus there is no reason
-  // for the garbage collector to scan any of it.
-  // Furthermore, we're about to overwrite the string data, so
-  // initialization of the object is not an issue.
-#ifdef ENABLE_JVMPI
-  jstring obj = (jstring) _Jv_AllocPtrFreeObject(&StringClass, sz);
-#else
-  // Class needs no initialization, and there is no finalizer, so
-  // we can go directly to the collector's allocator interface.
-  jstring obj = (jstring) _Jv_AllocPtrFreeObj(sz, &StringClass);
-#endif
-  obj->data = obj;
-  obj->boffset = sizeof(java::lang::String);
-  obj->count = len;
-  obj->cachedHashCode = 0;
-  return obj;
-}
-
-jstring
 _Jv_NewString(const jchar *chars, jsize len)
 {
   jstring str = _Jv_AllocString(len);
   
   
gcc/java:
	
2004-04-15  Bryce McKinlay  <mckinlay@redhat.com>

	* expr.c (expand_java_NEW): Don't use size argument for 
	_Jv_AllocObject calls.
	* parse.y (patch_invoke): Likewise.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v
retrieving revision 1.187
diff -u -r1.187 expr.c
--- expr.c	14 Apr 2004 19:35:18 -0000	1.187
+++ expr.c	15 Apr 2004 21:46:05 -0000
@@ -1150,9 +1150,7 @@
   safe_layout_class (type);
   push_value (build (CALL_EXPR, promote_type (type),
 		     build_address_of (alloc_node),
-		     tree_cons (NULL_TREE, build_class_ref (type),
-				build_tree_list (NULL_TREE,
-						 size_in_bytes (type))),
+		     build_tree_list (NULL_TREE, build_class_ref (type)),
 		     NULL_TREE));
 }
 
Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.474
diff -u -r1.474 parse.y
--- parse.y	19 Mar 2004 23:10:55 -0000	1.474
+++ parse.y	15 Apr 2004 21:46:09 -0000
@@ -10863,11 +10863,9 @@
 	(class_has_finalize_method (class) ? alloc_object_node
 		  			   : alloc_no_finalizer_node);
       new = build (CALL_EXPR, promote_type (class),
-		   build_address_of (alloc_node),
-		   tree_cons (NULL_TREE, build_class_ref (class),
-			      build_tree_list (NULL_TREE,
-					       size_in_bytes (class))),
-		   NULL_TREE);
+		     build_address_of (alloc_node),
+		     build_tree_list (NULL_TREE, build_class_ref (class)),
+		     NULL_TREE);
       saved_new = save_expr (new);
       c1 = build_tree_list (NULL_TREE, saved_new);
       TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);


gcc/cp:

2004-04-15  Bryce McKinlay  <mckinlay@redhat.com>

	* init.c (build_new_1): Don't use type size argument for Java
	_Jv_AllocObject call.

Index: init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.366
diff -u -r1.366 init.c
--- init.c	5 Apr 2004 12:25:15 -0000	1.366
+++ init.c	15 Apr 2004 21:50:34 -0000
@@ -2019,7 +2019,6 @@
     {
       tree class_addr, alloc_decl;
       tree class_decl = build_java_class_ref (true_type);
-      tree class_size = size_in_bytes (true_type);
       static const char alloc_name[] = "_Jv_AllocObject";
       use_java_new = 1;
       if (!get_global_value_if_present (get_identifier (alloc_name), 
@@ -2037,8 +2036,7 @@
       class_addr = build1 (ADDR_EXPR, jclass_node, class_decl);
       alloc_call = (build_function_call
 		    (alloc_decl,
-		     tree_cons (NULL_TREE, class_addr,
-				build_tree_list (NULL_TREE, class_size))));
+		     build_tree_list (NULL_TREE, class_addr)));
     }
   else
     {

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