This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java 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]

4.0 patch: Implement gij -Xss option


This is a simple subset of a larger patch I was working on to change the default stack size and implement stack overflow detection. Unfortunately, it turns out that there are currently some CG issues that prevent stack overflow detection from working robustly. Specifically, because the GC can run on any thread, and itself requires some stack, there must be plenty of stack available for the signal handler to execute as the signal handler needs to allocate. One solution might be to ensure that the GC always runs on its own thread(s) which are guaranteed to have plenty of stack space.

Limitations of this patch:

- There is no support for detecting stack overflow and throwing StackOverflowException. If a stack overflows, it will bring down the whole runtime (this is the same as what happens currently). Not good behaviour!
- The default stack size remains unchanged.
- It does not limit the size of the initial thread's stack. The initial patch I wrote implements this by inserting a guard page, but it seems pointless to do so when we don't have StackOverflowException.


Another issue is that code running in our interpreter currently uses substantially more stack than on other implementations, or with gcj native code (I suspect this is due largely to libffi's stack allocated closures). This means that interpreted code, given the same stack size, is more likely to hit the stack limit on libgcj than in other implementations.

Despite these issues, the ability to control the stack size is necessary for large applications such as Jonas which can quickly run out of address space when spawning many threads on a 32-bit machine. I plan to post the more extensive (but problematic) implementation soon, but it will still need some work before it can be committed.

I'm checking this in to both the 4.0 branch and trunk.

Bryce


2005-11-17  Bryce McKinlay  <mckinlay@redhat.com>

	Implement -Xss.
	* include/jvm.h (gcj::stack_size): Declare.
	(_Jv_StackSize): Declare.
	* posix-threads.cc (_Jv_InitThreads): Validate gcj::stack_size. 
	(_Jv_ThreadStart): Set stack size if specified.
	* prims.cc (gcj::stack_size): Define.
	(parse_memory_size): Renamed from parse_heap_size.
	(_Jv_SetStackSize): Parse stack size argument and set gcj::stack_size.

Index: include/jvm.h
===================================================================
--- include/jvm.h	(revision 107124)
+++ include/jvm.h	(working copy)
@@ -247,6 +247,9 @@
   
   /* When true, enable the bytecode verifier and BC-ABI verification. */
   extern bool verifyClasses;
+
+  /* Thread stack size specified by the -Xss runtime argument. */
+  extern size_t stack_size;
 }
 
 // This class handles all aspects of class preparation and linking.
@@ -373,6 +376,10 @@
    _Jv_GCSetMaximumHeapSize.  */
 void _Jv_SetMaximumHeapSize (const char *arg);
 
+/* Set the stack size for threads.  Parses ARG, a number which can 
+   optionally have "k" or "m" appended.  */
+void _Jv_SetStackSize (const char *arg);
+
 extern "C" void JvRunMain (jclass klass, int argc, const char **argv);
 void _Jv_RunMain (jclass klass, const char *name, int argc, const char **argv, 
 		  bool is_jar);
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 107124)
+++ ChangeLog	(working copy)
@@ -1,3 +1,14 @@
+2005-11-17  Bryce McKinlay  <mckinlay@redhat.com>
+
+	Implement -Xss.
+	* include/jvm.h (gcj::stack_size): Declare.
+	(_Jv_StackSize): Declare.
+	* posix-threads.cc (_Jv_InitThreads): Validate gcj::stack_size. 
+	(_Jv_ThreadStart): Set stack size if specified.
+	* prims.cc (gcj::stack_size): Define.
+	(parse_memory_size): Renamed from parse_heap_size.
+	(_Jv_SetStackSize): Parse stack size argument and set gcj::stack_size.
+
 2005-11-10  Andrew Haley  <aph@redhat.com>
 
 	Patch from GNU Classpath 2005-06-01  <sven@physto.se>
Index: posix-threads.cc
===================================================================
--- posix-threads.cc	(revision 107124)
+++ posix-threads.cc	(working copy)
@@ -311,6 +311,19 @@
   // Block SIGCHLD here to ensure that any non-Java threads inherit the new 
   // signal mask.
   block_sigchld();
+
+  // Check/set the thread stack size.
+  size_t min_ss = 32 * 1024;
+  
+  if (sizeof (void *) == 8)
+    // Bigger default on 64-bit systems.
+    min_ss *= 2;
+
+  if (min_ss < PTHREAD_STACK_MIN)
+    min_ss = PTHREAD_STACK_MIN;
+  
+  if (gcj::stack_size > 0 && gcj::stack_size < min_ss)
+    gcj::stack_size = min_ss;
 }
 
 _Jv_Thread_t *
@@ -430,6 +443,14 @@
   pthread_attr_init (&attr);
   pthread_attr_setschedparam (&attr, &param);
   pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+  
+  // Set stack size if -Xss option was given.
+  if (gcj::stack_size > 0)
+    {
+      int e = pthread_attr_setstacksize (&attr, gcj::stack_size);
+      if (e != 0)
+	JvFail (strerror (e));
+    }
 
   info = (struct starter *) _Jv_AllocBytes (sizeof (struct starter));
   info->method = meth;
Index: prims.cc
===================================================================
--- prims.cc	(revision 107124)
+++ prims.cc	(working copy)
@@ -926,6 +926,9 @@
   
   // When true, enable the bytecode verifier and BC-ABI type verification. 
   bool verifyClasses = true;
+
+  // Thread stack size specified by the -Xss runtime argument.
+  size_t stack_size = 0;
 }
 
 // We accept all non-standard options accepted by Sun's java command,
@@ -1012,7 +1015,7 @@
     }
   else if (! strncmp (option_string, "ss", 2))
     {
-      // FIXME: set thread stack size
+      _Jv_SetStackSize (option_string + 2);
     }
   else if (! strcmp (option_string, "X:+UseAltSigs"))
     {
@@ -1374,7 +1377,7 @@
 
 // Parse a string and return a heap size.
 static size_t
-parse_heap_size (const char *spec)
+parse_memory_size (const char *spec)
 {
   char *end;
   unsigned long val = strtoul (spec, &end, 10);
@@ -1390,7 +1393,7 @@
 void
 _Jv_SetInitialHeapSize (const char *arg)
 {
-  size_t size = parse_heap_size (arg);
+  size_t size = parse_memory_size (arg);
   _Jv_GCSetInitialHeapSize (size);
 }
 
@@ -1399,11 +1402,16 @@
 void
 _Jv_SetMaximumHeapSize (const char *arg)
 {
-  size_t size = parse_heap_size (arg);
+  size_t size = parse_memory_size (arg);
   _Jv_GCSetMaximumHeapSize (size);
 }
 
-
+void
+_Jv_SetStackSize (const char *arg)
+{
+  size_t size = parse_memory_size (arg);
+  gcj::stack_size = size;
+}
 
 void *
 _Jv_Malloc (jsize size)

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