diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c0b57257caa06317dd3a0a3b90ba80f66cc435bc..a3a2c6abea53c156b15da177b061f928ed85e1da 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2004-04-15  Bryce McKinlay  <mckinlay@redhat.com>
+
+	* init.c (build_new_1): Don't use type size argument for Java
+	_Jv_AllocObject call.
+
 2004-04-09  Danny Smith  <dannysmith@users.sourceforge.net>
 
 	* method.c (make_alias_for_thunk): Remove preprocessor guard on
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index e9142b775e0ed362519dae6efd1e29c61f082800..5a64ed51bada65d00623087763e43ac61414d19e 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -2019,7 +2019,6 @@ build_new_1 (tree exp)
     {
       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 @@ build_new_1 (tree exp)
       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
     {
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 6336c2ec985eb1e5822b18b27ea7707c5d83b542..ac5a568024b02e302f88ceaeae75994fbac8384f 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,9 @@
+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.
+
 2004-04-12  Bryce McKinlay  <mckinlay@redhat.com>
 
 	* expr.c (build_invokeinterface): Remove unused variables to
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 2c0312ea8100f9a8dbcb388283142021416ae137..839480b5b6413ff9dd862cba5c7a8a4f68afb673 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -1150,9 +1150,7 @@ expand_java_NEW (tree type)
   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));
 }
 
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index a21fc2a09195edc132ec7e41e62f81b0e95221dc..7d4c2de1ddb372b533875fc87c7276a5019535c7 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -10863,11 +10863,9 @@ patch_invoke (tree patch, tree method, tree args)
 	(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);
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 297bd7066cbcfb30cb43146533deedaceb18da9e..bae0343ccfb3900f75b5a018f8f1e84ed552238a 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,18 @@
+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.
+
 2004-04-14  Andrew Haley  <aph@redhat.com>
             Bryce McKinlay  <mckinlay@redhat.com>
 
diff --git a/libjava/gcj/cni.h b/libjava/gcj/cni.h
index 3790dc4d564b1bd21073f0ffad7b9b9221c4c099..4040f199cc0fa3c3eb0dc3c0ad7746efb37e0b19 100644
--- a/libjava/gcj/cni.h
+++ b/libjava/gcj/cni.h
@@ -23,13 +23,13 @@ details.  */
 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);
diff --git a/libjava/gcj/javaprims.h b/libjava/gcj/javaprims.h
index 60f99cfdedaf479895be50eab33f54727cf232cb..0cdd55071e0ec6233abff6c84aaa59c088c060d4 100644
--- a/libjava/gcj/javaprims.h
+++ b/libjava/gcj/javaprims.h
@@ -450,17 +450,17 @@ struct _Jv_JNIEnv;
 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);
diff --git a/libjava/gnu/gcj/natCore.cc b/libjava/gnu/gcj/natCore.cc
index 91b02479fd8be9d63639aa725f9ccfa60aa864cf..bb3fd57f6fb181099292b149f4489d6540ac00ff 100644
--- a/libjava/gnu/gcj/natCore.cc
+++ b/libjava/gnu/gcj/natCore.cc
@@ -96,8 +96,7 @@ _Jv_create_core (_Jv_core_chain *node, jstring name)
   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;
     }
diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h
index 1577628cb98e445930c8048ebe5316a95e3f8cfe..b8a8d90fa0a6e5dcf898e2b17ba6318206fd240f 100644
--- a/libjava/java/lang/Class.h
+++ b/libjava/java/lang/Class.h
@@ -286,7 +286,7 @@ private:
   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);
diff --git a/libjava/java/lang/natString.cc b/libjava/java/lang/natString.cc
index 8217f70399541a0aabfbc6828335b43c2414da2e..e01f467b79f51d7077d882d2930470d28fd0c8a7 100644
--- a/libjava/java/lang/natString.cc
+++ b/libjava/java/lang/natString.cc
@@ -401,30 +401,6 @@ java::lang::String::valueOf (jint num)
   return _Jv_NewString (buffer+11-i, i);
 }
 
-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)
 {
diff --git a/libjava/prims.cc b/libjava/prims.cc
index 06791d388f393e00eebe07b005ecc4aa61ddc58e..29f2b2090e8168cf064d34c1d87e7686d02022ed 100644
--- a/libjava/prims.cc
+++ b/libjava/prims.cc
@@ -389,16 +389,15 @@ jvmpi_notify_alloc(jclass klass, jint size, jobject obj)
 # define jvmpi_notify_alloc(klass,size,obj) /* do nothing */
 #endif
 
-// Allocate a new object of class KLASS.  SIZE is the size of the object
-// to allocate.  You might think this is redundant, but it isn't; some
-// classes, such as String, aren't of fixed size.
+// Allocate a new object of class KLASS.
 // First a version that assumes that we have no finalizer, and that
 // the class is already initialized.
 // 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 +405,10 @@ _Jv_AllocObjectNoInitNoFinalizer (jclass klass, jint size)
 
 // 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 +416,10 @@ _Jv_AllocObjectNoFinalizer (jclass klass, jint size)
 
 // 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 +432,62 @@ _Jv_AllocObject (jclass klass, jint size)
   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) &String::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);