This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
4.0 patch: Implement gij -Xss option
- From: Bryce McKinlay <mckinlay at redhat dot com>
- To: java-patches at gcc dot gnu dot org
- Date: Thu, 17 Nov 2005 14:07:33 -0500
- Subject: 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, ¶m);
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)