Author: archie
Date: Mon Dec 19 19:04:00 2005
New Revision: 357888
URL: http://svn.apache.org/viewcvs?rev=357888&view=rev
Log:
- Optimize handling of the Java stack by maintaining a separate stack
for Java operations for each thread. Avoid copying of method parameters
by reserving the locals area on the Java stack and having parameters sit
above the top of the Java stack on method entry, so they already occupy
the first N locals.
- Separately check for C stack overflow and Java stack overflow. Leave some
margin on the Java and C stacks for handling StackOverflowError.
- Create a new configurable system property "jc.java.stack.size" for
setting the size of the Java stack; default is 4090 Java words.
Modified:
incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/definitions.h
incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/gc_root.c
incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/interp.c
incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/properties.c
incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/structures.h
incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/thread.c
Modified: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/definitions.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/definitions.h?rev=357888&r1=357887&r2=357888&view=diff
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/definitions.h (original)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/definitions.h Mon
Dec 19 19:04:00 2005
@@ -287,6 +287,12 @@
#define _JC_CL_ALLOC_IMPLICIT_REFS 32
/*
+ * Java stack parameters
+ */
+#define _JC_JAVA_STACK_DEFAULT "4090"
+#define _JC_JAVA_STACK_MARGIN 100
+
+/*
* Short name for internal java.lang native library.
*/
#define _JC_INTERNAL_NATIVE_LIBRARY "JC virtual machine"
Modified: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/gc_root.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/gc_root.c?rev=357888&r1=357887&r2=357888&view=diff
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/gc_root.c (original)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/gc_root.c Mon Dec
19 19:04:00 2005
@@ -33,8 +33,6 @@
_jc_object ***refsp);
static int _jc_scan_c_stack(_jc_jvm *vm, _jc_c_stack *cstack,
const _jc_word *info, _jc_object ***refsp);
-static int _jc_scan_java_stack(_jc_jvm *vm, _jc_java_stack *jstack,
- const _jc_word *info, _jc_object ***refsp);
/* Internal variables */
static const int _jc_register_offs[] = _JC_REGISTER_OFFS;
@@ -236,6 +234,7 @@
_jc_object **refs = *refsp;
_jc_java_stack *jstack;
_jc_c_stack *cstack;
+ _jc_word *sp;
int count = 0;
/* Scan each contiguous C stack chunk */
@@ -248,17 +247,26 @@
count += _jc_scan_c_stack(vm, cstack, info, &refs);
}
- /*
- * Scan each Java stack frame. Also get implicit references
- * from Java methods to their classes.
- */
- for (jstack = thread->java_stack;
- jstack != NULL; jstack = jstack->next) {
+ /* Scan the Java stack */
+ _JC_ASSERT(thread->sp >= thread->stack_data
+ && thread->sp <= thread->stack_data + vm->java_stack_size);
+ for (sp = thread->stack_data; sp < thread->sp; sp++) {
+ _jc_object *const ref = (_jc_object *)*sp;
+ _jc_object *obj;
- /* Scan the Java stack frame */
- count += _jc_scan_java_stack(vm, jstack, info, &refs);
+ /* Find object pointed to, if any */
+ if ((obj = _jc_locate_object(vm, info, ref)) == NULL)
+ continue;
+
+ /* Add object to list */
+ if (refs != NULL)
+ *refs++ = obj;
+ count++;
+ }
- /* Scan the Class instance */
+ /* Get implicit references from Java methods to their classes */
+ for (jstack = thread->java_stack;
+ jstack != NULL; jstack = jstack->next) {
if (refs != NULL)
*refs++ = jstack->method->class->instance;
count++;
@@ -285,43 +293,6 @@
if (thread->cross_exception != NULL) {
if (refs != NULL)
*refs++ = thread->cross_exception;
- count++;
- }
-
- /* Done */
- *refsp = refs;
- return count;
-}
-
-/*
- * Scan an interpreter stack frame.
- */
-static int
-_jc_scan_java_stack(_jc_jvm *vm, _jc_java_stack *jstack,
- const _jc_word *info, _jc_object ***refsp)
-{
- _jc_method *const method = jstack->method;
- _jc_method_code *const code = &method->code;
- _jc_object **refs = *refsp;
- _jc_object *obj;
- int count = 0;
- int i;
-
- /* Any state in this method yet? */
- if (jstack->locals == NULL)
- return 0;
-
- /* Scan stack frame's locals and Java operand stack */
- for (i = 0; i < code->max_locals + code->max_stack; i++) {
- _jc_object *const ref = (_jc_object *)jstack->locals[i];
-
- /* Find object pointed to, if any */
- if ((obj = _jc_locate_object(vm, info, ref)) == NULL)
- continue;
-
- /* Add object to list */
- if (refs != NULL)
- *refs++ = obj;
count++;
}
Modified: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/interp.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/interp.c?rev=357888&r1=357887&r2=357888&view=diff
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/interp.c (original)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/interp.c Mon Dec
19 19:04:00 2005
@@ -21,8 +21,7 @@
#include "libjc.h"
/* Internal functions */
-static jint _jc_interp(_jc_env *env, _jc_method *const method,
- _jc_object *this, _jc_word *args);
+static jint _jc_interp(_jc_env *env, _jc_method *const method);
static int _jc_lookup_compare(const void *v1, const void *v2);
static void _jc_vinterp(_jc_env *env, va_list args);
static void _jc_vinterp_native(_jc_env *env, va_list args);
@@ -35,9 +34,9 @@
#define JUMP(_pc) \
do { \
pc = (_pc); \
- _JC_ASSERT(sp >= state.locals + code->max_locals); \
- _JC_ASSERT(sp <= state.locals \
- + code->max_locals + code->max_stack); \
+ _JC_ASSERT(env->sp >= locals + code->max_locals); \
+ _JC_ASSERT(env->sp <= locals + code->max_locals \
+ + code->max_stack); \
_JC_ASSERT(pc >= 0 && pc < code->num_insns); \
_JC_ASSERT(actions[code->opcodes[pc]] != NULL); \
_JC_ASSERT(ticker > 0); \
@@ -65,23 +64,23 @@
#endif /* !NDEBUG */
-#define STACKI(i) (*(jint *)(sp + (i)))
-#define STACKF(i) (*(jfloat *)(sp + (i)))
-#define STACKJ(i) (*(jlong *)(sp + (i)))
-#define STACKD(i) (*(jdouble *)(sp + (i)))
-#define STACKL(i) (*(_jc_object **)(sp + (i)))
-#define LOCALI(i) (*(jint *)(state.locals + i))
-#define LOCALF(i) (*(jfloat *)(state.locals + i))
-#define LOCALJ(i) (*(jlong *)(state.locals + i))
-#define LOCALD(i) (*(jdouble *)(state.locals + i))
-#define LOCALL(i) (*(_jc_object **)(state.locals + i))
-#define PUSHI(v) do { STACKI(0) = (v); sp++; } while (0)
-#define PUSHF(v) do { STACKF(0) = (v); sp++; } while (0)
-#define PUSHJ(v) do { STACKJ(0) = (v); sp += 2; } while (0)
-#define PUSHD(v) do { STACKD(0) = (v); sp += 2; } while (0)
-#define PUSHL(v) do { STACKL(0) = (v); sp++; } while (0)
-#define POP(i) (sp -= (i))
-#define POP2(i) (sp -= 2 * (i))
+#define STACKI(i) (*(jint *)(env->sp + (i)))
+#define STACKF(i) (*(jfloat *)(env->sp + (i)))
+#define STACKJ(i) (*(jlong *)(env->sp + (i)))
+#define STACKD(i) (*(jdouble *)(env->sp + (i)))
+#define STACKL(i) (*(_jc_object **)(env->sp + (i)))
+#define LOCALI(i) (*(jint *)(locals + i))
+#define LOCALF(i) (*(jfloat *)(locals + i))
+#define LOCALJ(i) (*(jlong *)(locals + i))
+#define LOCALD(i) (*(jdouble *)(locals + i))
+#define LOCALL(i) (*(_jc_object **)(locals + i))
+#define PUSHI(v) do { STACKI(0) = (v); env->sp++; } while (0)
+#define PUSHF(v) do { STACKF(0) = (v); env->sp++; } while (0)
+#define PUSHJ(v) do { STACKJ(0) = (v); env->sp += 2; } while (0)
+#define PUSHD(v) do { STACKD(0) = (v); env->sp += 2; } while (0)
+#define PUSHL(v) do { STACKL(0) = (v); env->sp++; } while (0)
+#define POP(i) (env->sp -= (i))
+#define POP2(i) (env->sp -= 2 * (i))
#define INFO(f) (code->info[pc].f)
@@ -108,8 +107,7 @@
* Otherwise, an exception is posted and JNI_ERR is returned.
*/
static jint
-_jc_interp(_jc_env *const env, _jc_method *const method,
- _jc_object *const this, _jc_word *args)
+_jc_interp(_jc_env *const env, _jc_method *const method)
{
#define ACTION(name) [_JC_ ## name]= &&do_ ## name
static const void *const actions[0x100] = {
@@ -257,22 +255,40 @@
};
_jc_method_code *const code = &method->code;
int ticker = PERIODIC_CHECK_TICKS;
- _jc_java_stack state;
+ _jc_java_stack stack_frame;
+ _jc_word *const locals = env->sp;
_jc_object *lock = NULL;
- _jc_word *sp;
int pc = 0;
- /* Stack overflow check */
+ /* Sanity check */
+ _JC_ASSERT(env->sp != NULL);
+ _JC_ASSERT(env->sp >= env->stack_data);
+ _JC_ASSERT(env->sp <= env->stack_data + env->vm->java_stack_size);
+
+ /* Stack overflow check for C stack */
#if _JC_DOWNWARD_STACK
- if ((char *)&env < env->stack_limit)
+ if ((char *)&env < env->stack_limit
+ && (env->in_vmex & (1 << _JC_StackOverflowError)) == 0)
#else
- if ((char *)&env > env->stack_limit)
+ if ((char *)&env > env->stack_limit
+ && (env->in_vmex & (1 << _JC_StackOverflowError)) == 0)
#endif
{
_jc_post_exception(env, _JC_StackOverflowError);
return JNI_ERR;
}
+ /* Check Java stack overflow; release secret space during exception */
+ if (env->sp + code->max_locals + code->max_stack
+ > env->stack_data_end) {
+ if ((env->in_vmex & (1 << _JC_StackOverflowError)) == 0
+ || env->sp + code->max_locals + code->max_stack
+ > env->stack_data_end + _JC_JAVA_STACK_MARGIN) {
+ _jc_post_exception(env, _JC_StackOverflowError);
+ return JNI_ERR;
+ }
+ }
+
/* Is method abstract? */
if (_JC_ACC_TEST(method, ABSTRACT)) {
_jc_post_exception_msg(env, _JC_AbstractMethodError,
@@ -282,44 +298,27 @@
}
/* Sanity check */
- _JC_ASSERT((this == NULL) == _JC_ACC_TEST(method, STATIC));
_JC_ASSERT(!_JC_ACC_TEST(method->class, INTERFACE)
|| strcmp(method->name, "<clinit>") == 0);
_JC_ASSERT(_JC_FLG_TEST(method->class, RESOLVED));
_JC_ASSERT(!_JC_ACC_TEST(method, NATIVE));
/* Push Java stack frame */
- memset(&state, 0, sizeof(state));
- state.next = env->java_stack;
- state.method = method;
- state.pcp = &pc;
- env->java_stack = &state;
-
- /* Allocate combined space for locals and stack */
- if ((state.locals = _JC_STACK_ALLOC(env,
- (code->max_locals + code->max_stack)
- * sizeof(*state.locals))) == NULL) {
- _jc_post_exception_info(env);
- goto exception;
- }
- sp = &state.locals[code->max_locals];
+ memset(&stack_frame, 0, sizeof(stack_frame));
+ stack_frame.next = env->java_stack;
+ stack_frame.method = method;
+ stack_frame.pcp = &pc;
+ env->java_stack = &stack_frame;
+ env->sp += code->max_locals;
/* Sanity check */
_JC_ASSERT(code->opcodes != NULL);
_JC_ASSERT(code->num_insns > 0);
- /* Copy method parameters into local variables */
- if (!_JC_ACC_TEST(method, STATIC)) {
- state.locals[0] = (_jc_word)this;
- memcpy(state.locals + 1, args,
- code->num_params2 * sizeof(*args));
- } else
- memcpy(state.locals, args, code->num_params2 * sizeof(*args));
-
/* Synchronize */
if (_JC_ACC_TEST(method, SYNCHRONIZED)) {
lock = _JC_ACC_TEST(method, STATIC) ?
- method->class->instance : this;
+ method->class->instance : LOCALL(0);
if (_jc_lock_object(env, lock) != JNI_OK) {
lock = NULL;
goto exception;
@@ -933,32 +932,23 @@
{
const _jc_invoke *const invoke = &INFO(invoke);
_jc_method *imethod = invoke->method;
- _jc_word *params;
- _jc_object *obj;
jint status;
- /* Pop the stack and check for null */
- POP(invoke->pop);
- if (code->opcodes[pc] == _JC_invokestatic)
- obj = NULL;
- else {
- if ((obj = STACKL(0)) == NULL)
- goto null_pointer_exception;
- }
-
/* Sanity check */
_JC_ASSERT((code->opcodes[pc] == _JC_invokeinterface)
== _JC_ACC_TEST(imethod->class, INTERFACE));
- /* Do method lookup */
+ /* Check for null and do method lookup */
switch (code->opcodes[pc]) {
case _JC_invokeinterface:
{
_jc_method *const *methodp;
_jc_method *quick;
+ _jc_object *obj;
- /* Sanity check */
- _JC_ASSERT(_JC_ACC_TEST(imethod->class, INTERFACE));
+ /* Check for null */
+ if ((obj = STACKL(-invoke->pop)) == NULL)
+ goto null_pointer_exception;
/* Verify object implements the interface */
switch (_jc_instance_of(env, obj, imethod->class)) {
@@ -1025,14 +1015,22 @@
}
case _JC_invokevirtual:
{
+ _jc_object *obj;
_jc_type *vtype;
+ /* Check for null */
+ if ((obj = STACKL(-invoke->pop)) == NULL)
+ goto null_pointer_exception;
+
+ /* Resolve virtual method */
vtype = _JC_LW_TEST(obj->lockword, ARRAY) ?
env->vm->boot.types.Object : obj->type;
imethod = vtype->u.nonarray.mtable[imethod->vtable_index];
break;
}
case _JC_invokespecial:
+ if (STACKL(-invoke->pop) == NULL)
+ goto null_pointer_exception;
break;
case _JC_invokestatic:
if (!_JC_FLG_TEST(imethod->class, INITIALIZED)
@@ -1044,14 +1042,23 @@
break;
}
- /* Get pointer to parameters */
- params = sp + (code->opcodes[pc] != _JC_invokestatic);
-
/* Invoke the method */
- if (_JC_ACC_TEST(imethod, NATIVE))
- status = _jc_invoke_native_method(env, imethod, JNI_TRUE, sp);
- else
- status = _jc_interp(env, imethod, obj, params);
+ if (_JC_ACC_TEST(imethod, NATIVE)) {
+
+ /* Invoke native method */
+ status = _jc_invoke_native_method(env,
+ imethod, JNI_TRUE, env->sp - invoke->pop);
+
+ /* Pop the stack */
+ POP(invoke->pop);
+ } else {
+
+ /* Pop the stack, leaving parameters above the top */
+ POP(invoke->pop);
+
+ /* Invoke the method */
+ status = _jc_interp(env, imethod);
+ }
/* Did method throw an exception? */
if (status != JNI_OK)
@@ -1183,7 +1190,7 @@
PUSHI(_JC_LCMP(STACKJ(0), STACKJ(2)));
NEXT();
do_ldc:
- memcpy(sp, &INFO(constant), sizeof(_jc_word));
+ memcpy(env->sp, &INFO(constant), sizeof(_jc_word));
POP(-1);
NEXT();
do_ldc_string:
@@ -1216,7 +1223,7 @@
JUMP(pc);
}
do_ldc2_w:
- memcpy(sp, &INFO(constant), 2 * sizeof(_jc_word));
+ memcpy(env->sp, &INFO(constant), 2 * sizeof(_jc_word));
POP(-2);
NEXT();
do_ldiv:
@@ -1546,9 +1553,9 @@
_jc_printf(vm, "]\n");
}
- /* Push exception and proceed with handler */
- state.locals[code->max_locals] = (_jc_word)e;
- sp = &state.locals[code->max_locals + 1];
+ /* Clear stack, push exception, and proceed with handler */
+ env->sp = locals + code->max_locals;
+ PUSHL(e);
JUMP(trap->target);
}
@@ -1579,7 +1586,8 @@
}
/* Pop Java stack frame */
- env->java_stack = state.next;
+ env->java_stack = stack_frame.next;
+ env->sp = locals;
/* Done */
return status;
@@ -1677,78 +1685,109 @@
#ifndef NDEBUG
const jboolean was_interpreting = env->interpreting;
#endif
+ jboolean allocated_stack = JNI_FALSE;
_jc_method *const method = env->interp;
- _jc_word *params;
- _jc_object *this;
+ _jc_word *sp;
jint status;
- int pnum;
int i;
/* Sanity check */
_JC_ASSERT(!_JC_ACC_TEST(method, NATIVE));
_JC_ASSERT(_JC_FLG_TEST(method->class, RESOLVED));
- /* Allocate space for parameter array */
- if ((params = _JC_STACK_ALLOC(env, method->code.num_params2)) == NULL) {
- _jc_post_exception_info(env);
- _jc_throw_exception(env);
+ /* For a brand new thread, allocate its Java stack here */
+ if (env->sp == NULL) {
+ _jc_jvm *const vm = env->vm;
+
+ /* Sanity check */
+ _JC_ASSERT(env->stack_data == NULL);
+ _JC_ASSERT(env->stack_data_end == NULL);
+
+ /* Allocate Java stack */
+ if ((env->stack_data = _jc_vm_alloc(env,
+ vm->java_stack_size * sizeof(*env->stack_data))) == NULL) {
+ _jc_post_exception_info(env);
+ _jc_throw_exception(env);
+ }
+ env->stack_data_end = env->stack_data
+ + vm->java_stack_size - _JC_JAVA_STACK_MARGIN;
+ env->sp = env->stack_data;
+ allocated_stack = JNI_TRUE;
+ }
+
+ /* Place paramters over top of the stack like _jc_interp() expects */
+ sp = env->sp;
+
+ /* Check Java stack overflow; release secret space during exception */
+ if (sp + 1 + method->code.num_params2 > env->stack_data_end) {
+ if ((env->in_vmex & (1 << _JC_StackOverflowError)) == 0
+ || sp + 1 + method->code.num_params2
+ > env->stack_data_end + _JC_JAVA_STACK_MARGIN) {
+ _jc_post_exception(env, _JC_StackOverflowError);
+ _jc_throw_exception(env);
+ }
}
- /* Get 'this' if method is non-static */
- this = !_JC_ACC_TEST(method, STATIC) ?
- va_arg(args, _jc_object *) : NULL;
+ /* Push 'this' if method is non-static */
+ if (!_JC_ACC_TEST(method, STATIC)) {
+ _jc_object *const this = va_arg(args, _jc_object *);
+
+ _JC_ASSERT(this != NULL);
+ *sp++ = (_jc_word)this;
+ }
- /* Get method parameters, occupying two slots for long/double */
- for (pnum = i = 0; i < method->num_parameters; i++) {
+ /* Push method parameters, occupying two slots for long/double */
+ for (i = 0; i < method->num_parameters; i++) {
switch (method->param_ptypes[i]) {
case _JC_TYPE_BOOLEAN:
- params[pnum++] = (jint)(jboolean)va_arg(args, jint);
+ *sp++ = (jint)(jboolean)va_arg(args, jint);
break;
case _JC_TYPE_BYTE:
- params[pnum++] = (jint)(jbyte)va_arg(args, jint);
+ *sp++ = (jint)(jbyte)va_arg(args, jint);
break;
case _JC_TYPE_CHAR:
- params[pnum++] = (jint)(jchar)va_arg(args, jint);
+ *sp++ = (jint)(jchar)va_arg(args, jint);
break;
case _JC_TYPE_SHORT:
- params[pnum++] = (jint)(jshort)va_arg(args, jint);
+ *sp++ = (jint)(jshort)va_arg(args, jint);
break;
case _JC_TYPE_INT:
- params[pnum++] = va_arg(args, jint);
+ *sp++ = va_arg(args, jint);
break;
case _JC_TYPE_FLOAT:
{
jfloat param = (jfloat)va_arg(args, jdouble);
- memcpy(params + pnum, ¶m, sizeof(param));
- pnum++;
+ memcpy(sp, ¶m, sizeof(param));
+ sp++;
break;
}
case _JC_TYPE_LONG:
{
jlong param = va_arg(args, jlong);
- memcpy(params + pnum, ¶m, sizeof(param));
- pnum += 2;
+ memcpy(sp, ¶m, sizeof(param));
+ sp += 2;
break;
}
case _JC_TYPE_DOUBLE:
{
jdouble param = va_arg(args, jdouble);
- memcpy(params + pnum, ¶m, sizeof(param));
- pnum += 2;
+ memcpy(sp, ¶m, sizeof(param));
+ sp += 2;
break;
}
case _JC_TYPE_REFERENCE:
- params[pnum++] = (_jc_word)va_arg(args, _jc_object *);
+ *sp++ = (_jc_word)va_arg(args, _jc_object *);
break;
default:
_JC_ASSERT(JNI_FALSE);
break;
}
}
- _JC_ASSERT(pnum == method->code.num_params2);
+ _JC_ASSERT(sp - env->sp == method->code.num_params2
+ + !_JC_ACC_TEST(method, STATIC));
#ifndef NDEBUG
/* Signals are not OK now */
@@ -1756,12 +1795,20 @@
#endif
/* Invoke method */
- status = _jc_interp(env, method, this, params);
+ status = _jc_interp(env, method);
#ifndef NDEBUG
/* Restore debug flag */
env->interpreting = was_interpreting;
#endif
+
+ /* Free Java stack */
+ if (allocated_stack) {
+ _JC_ASSERT(env->sp == env->stack_data);
+ _jc_vm_free(&env->stack_data);
+ env->stack_data_end = NULL;
+ env->sp = NULL;
+ }
/* Throw exception if any */
if (status != JNI_OK)
Modified: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/properties.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/properties.c?rev=357888&r1=357887&r2=357888&view=diff
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/properties.c (original)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/properties.c Mon
Dec 19 19:04:00 2005
@@ -55,6 +55,7 @@
{ "jc.stack.minimum", _JC_STACK_MINIMUM },
{ "jc.stack.maximum", _JC_STACK_MAXIMUM },
{ "jc.stack.default", _JC_STACK_DEFAULT },
+{ "jc.java.stack.size", _JC_JAVA_STACK_DEFAULT },
{ "jc.heap.size", _JC_DEFAULT_HEAP_SIZE },
{ "jc.loader.size", _JC_DEFAULT_LOADER_SIZE },
{ "jc.heap.granularity", _JC_DEFAULT_HEAP_GRANULARITY },
@@ -275,6 +276,10 @@
_JC_ASSERT(prop != NULL);
if (_jc_digest_size(env, &vm->threads.stack_default, prop, 0) != JNI_OK)
return JNI_ERR;
+ prop = _jc_property_get(vm, "jc.java.stack.size");
+ _JC_ASSERT(prop != NULL);
+ if (_jc_digest_size(env, &vm->java_stack_size, prop, 0) != JNI_OK)
+ return JNI_ERR;
/* Get heap size and granularity factor */
prop = _jc_property_get(vm, "jc.heap.size");
@@ -303,6 +308,13 @@
"jc.stack.minimum", vm->threads.stack_minimum,
"jc.stack.maximum", vm->threads.stack_maximum,
"jc.stack.default", vm->threads.stack_default);
+ return JNI_ERR;
+ }
+ if (vm->java_stack_size < _JC_JAVA_STACK_MARGIN) {
+ _JC_EX_STORE(env, InternalError,
+ "too small value %d < %d for `%s'",
+ vm->java_stack_size, _JC_JAVA_STACK_MARGIN,
+ "jc.java.stack.size");
return JNI_ERR;
}
Modified: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/structures.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/structures.h?rev=357888&r1=357887&r2=357888&view=diff
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/structures.h (original)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/structures.h Mon
Dec 19 19:04:00 2005
@@ -190,7 +190,6 @@
struct _jc_java_stack {
_jc_java_stack *next;
_jc_method *method;
- _jc_word *locals;
const int *pcp;
};
@@ -221,7 +220,15 @@
* The JC internal structure that corresponds to a Java thread.
*/
struct _jc_env {
- _jc_jvm *vm; /* vm that owns me */
+
+ /* Java stack info */
+ _jc_word *sp; /* java stack pointer */
+ _jc_word *stack_data; /* java stack memory */
+ _jc_word *stack_data_end;
+ _jc_java_stack *java_stack; /* java method stack */
+
+ /* The VM that owns me */
+ _jc_jvm *vm;
/* Exception info */
_jc_catch_frame *catch_list; /* exception traps */
@@ -237,11 +244,8 @@
char *stack_limit; /* c stack limit */
_jc_c_stack *c_stack; /* c stack chunks */
- /* Java stack info */
- _jc_java_stack *java_stack; /* java stack info */
- _jc_value retval; /* invoke rtn value */
-
/* Thread info */
+ _jc_value retval; /* invoke rtn value */
volatile _jc_word status; /* JC_THRDSTAT_* */
jint thread_id; /* unique thread id */
_jc_object *instance; /* java.lang.Thread */
@@ -792,6 +796,7 @@
*/
_jc_properties system_properties;
int max_loader_pages;
+ int java_stack_size;
/*
* This is non-NULL during bootstrap only.
Modified: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/thread.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/thread.c?rev=357888&r1=357887&r2=357888&view=diff
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/thread.c (original)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/thread.c Mon Dec
19 19:04:00 2005
@@ -946,6 +946,9 @@
_JC_ASSERT(!new_env->resumption_initialized);
_JC_ASSERT(vm->threads.next_free_id > 0
&& vm->threads.next_free_id < _JC_MAX_THREADS);
+ _JC_ASSERT(new_env->sp == NULL);
+ _JC_ASSERT(new_env->stack_data == NULL);
+ _JC_ASSERT(new_env->stack_data_end == NULL);
/* Assign next free thread ID to the thread */
new_env->thread_id = vm->threads.next_free_id;
@@ -1032,7 +1035,7 @@
}
/*
- * Free stacks associated with free'd threads.
+ * Free C stacks associated with free'd threads.
*
* We maintain the invariant that free'd threads whose stacks still
* need to be free'd are all at the front of the thread free list.
@@ -1044,7 +1047,7 @@
{
_jc_env *env;
- /* Free thread stack */
+ /* Free thread's C stack */
LIST_FOREACH(env, &vm->threads.free_list, link) {
if (env->stack == NULL)
return;
@@ -1067,8 +1070,13 @@
return;
*envp = NULL;
- /* Stack must be freed already */
+ /* C stack must be freed already */
_JC_ASSERT(env->stack == NULL);
+
+ /* Java stack must be freed already */
+ _JC_ASSERT(env->sp == NULL);
+ _JC_ASSERT(env->stack_data == NULL);
+ _JC_ASSERT(env->stack_data_end == NULL);
/* Destroy thread structure */
_jc_cond_destroy(&env->lock.waiter.cond);
|