mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-15 16:11:24 +08:00
jni.h (_Jv_JNIEnv::bottom_locals): New field.
2005-01-13 Graydon Hoare <graydon@redhat.com> * include/jni.h (_Jv_JNIEnv::bottom_locals): New field. * include/jvm.h (_Jv_FreeJNIEnv): Declare. * java/lang/natThread.cc (finalize_native): Call _Jv_FreeJNIEnv. * jni.cc: Reuse bottom frame between calls, avoid clearing frame when no local references are made. From-SVN: r93632
This commit is contained in:
parent
a0ee8b5f99
commit
84973b27e8
@ -1,3 +1,11 @@
|
||||
2005-01-13 Graydon Hoare <graydon@redhat.com>
|
||||
|
||||
* include/jni.h (_Jv_JNIEnv::bottom_locals): New field.
|
||||
* include/jvm.h (_Jv_FreeJNIEnv): Declare.
|
||||
* java/lang/natThread.cc (finalize_native): Call _Jv_FreeJNIEnv.
|
||||
* jni.cc: Reuse bottom frame between calls, avoid clearing
|
||||
frame when no local references are made.
|
||||
|
||||
2005-01-13 Michael Koch <konqueror@gmx.de>
|
||||
|
||||
PR libgcj/17784
|
||||
|
@ -693,6 +693,10 @@ private:
|
||||
/* The chain of local frames. */
|
||||
struct _Jv_JNI_LocalFrame *locals;
|
||||
|
||||
/* The bottom-most element of the chain, initialized with the env and
|
||||
reused between non-nesting JNI calls. */
|
||||
struct _Jv_JNI_LocalFrame *bottom_locals;
|
||||
|
||||
public:
|
||||
jint GetVersion ()
|
||||
{ return p->GetVersion (this); }
|
||||
|
@ -522,6 +522,9 @@ extern void _Jv_JNI_Init (void);
|
||||
_Jv_JNIEnv *_Jv_GetCurrentJNIEnv ();
|
||||
void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *);
|
||||
|
||||
/* Free a JNIEnv. */
|
||||
void _Jv_FreeJNIEnv (_Jv_JNIEnv *);
|
||||
|
||||
struct _Jv_JavaVM;
|
||||
_Jv_JavaVM *_Jv_GetJavaVM ();
|
||||
|
||||
|
@ -84,6 +84,7 @@ finalize_native (jobject ptr)
|
||||
#ifdef _Jv_HaveMutexDestroy
|
||||
_Jv_MutexDestroy (&nt->join_mutex);
|
||||
#endif
|
||||
_Jv_FreeJNIEnv(nt->jni_env);
|
||||
}
|
||||
|
||||
jint
|
||||
|
103
libjava/jni.cc
103
libjava/jni.cc
@ -71,7 +71,7 @@ extern struct JNIInvokeInterface _Jv_JNI_InvokeFunctions;
|
||||
|
||||
// Number of slots in the default frame. The VM must allow at least
|
||||
// 16.
|
||||
#define FRAME_SIZE 32
|
||||
#define FRAME_SIZE 16
|
||||
|
||||
// Mark value indicating this is an overflow frame.
|
||||
#define MARK_NONE 0
|
||||
@ -85,10 +85,13 @@ struct _Jv_JNI_LocalFrame
|
||||
{
|
||||
// This is true if this frame object represents a pushed frame (eg
|
||||
// from PushLocalFrame).
|
||||
int marker : 2;
|
||||
int marker;
|
||||
|
||||
// Flag to indicate some locals were allocated.
|
||||
int allocated_p;
|
||||
|
||||
// Number of elements in frame.
|
||||
int size : 30;
|
||||
int size;
|
||||
|
||||
// Next frame in chain.
|
||||
_Jv_JNI_LocalFrame *next;
|
||||
@ -289,6 +292,7 @@ _Jv_JNI_EnsureLocalCapacity (JNIEnv *env, jint size)
|
||||
|
||||
frame->marker = MARK_NONE;
|
||||
frame->size = size;
|
||||
frame->allocated_p = 0;
|
||||
memset (&frame->vec[0], 0, size * sizeof (jobject));
|
||||
frame->next = env->locals;
|
||||
env->locals = frame;
|
||||
@ -327,6 +331,7 @@ _Jv_JNI_NewLocalRef (JNIEnv *env, jobject obj)
|
||||
set = true;
|
||||
done = true;
|
||||
frame->vec[i] = obj;
|
||||
frame->allocated_p = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -344,6 +349,7 @@ _Jv_JNI_NewLocalRef (JNIEnv *env, jobject obj)
|
||||
_Jv_JNI_EnsureLocalCapacity (env, 16);
|
||||
// We know the first element of the new frame will be ok.
|
||||
env->locals->vec[0] = obj;
|
||||
env->locals->allocated_p = 1;
|
||||
}
|
||||
|
||||
mark_for_gc (obj, local_ref_table);
|
||||
@ -366,12 +372,14 @@ _Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result, int stop)
|
||||
done = (rf->marker == stop);
|
||||
|
||||
_Jv_JNI_LocalFrame *n = rf->next;
|
||||
// When N==NULL, we've reached the stack-allocated frame, and we
|
||||
// must not free it. However, we must be sure to clear all its
|
||||
// elements, since we might conceivably reuse it.
|
||||
// When N==NULL, we've reached the reusable bottom_locals, and we must
|
||||
// not free it. However, we must be sure to clear all its elements.
|
||||
if (n == NULL)
|
||||
{
|
||||
memset (&rf->vec[0], 0, rf->size * sizeof (jobject));
|
||||
if (rf->allocated_p)
|
||||
memset (&rf->vec[0], 0, rf->size * sizeof (jobject));
|
||||
rf->allocated_p = 0;
|
||||
rf = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -412,9 +420,17 @@ _Jv_JNI_check_types (JNIEnv *env, JArray<T> *array, jclass K)
|
||||
extern "C" void
|
||||
_Jv_JNI_PopSystemFrame (JNIEnv *env)
|
||||
{
|
||||
_Jv_JNI_PopLocalFrame (env, NULL, MARK_SYSTEM);
|
||||
// Only enter slow path when we're not at the bottom, or there have been
|
||||
// allocations. Usually this is false and we can just null out the locals
|
||||
// field.
|
||||
|
||||
if (env->ex)
|
||||
if (__builtin_expect ((env->locals->next
|
||||
|| env->locals->allocated_p), false))
|
||||
_Jv_JNI_PopLocalFrame (env, NULL, MARK_SYSTEM);
|
||||
else
|
||||
env->locals = NULL;
|
||||
|
||||
if (__builtin_expect (env->ex != NULL, false))
|
||||
{
|
||||
jthrowable t = env->ex;
|
||||
env->ex = NULL;
|
||||
@ -2030,7 +2046,7 @@ extern "C" JNIEnv *
|
||||
_Jv_GetJNIEnvNewFrame (jclass klass)
|
||||
{
|
||||
JNIEnv *env = _Jv_GetCurrentJNIEnv ();
|
||||
if (env == NULL)
|
||||
if (__builtin_expect (env == NULL, false))
|
||||
{
|
||||
env = (JNIEnv *) _Jv_MallocUnchecked (sizeof (JNIEnv));
|
||||
env->p = &_Jv_JNIFunctions;
|
||||
@ -2038,27 +2054,70 @@ _Jv_GetJNIEnvNewFrame (jclass klass)
|
||||
env->locals = NULL;
|
||||
// We set env->ex below.
|
||||
|
||||
// Set up the bottom, reusable frame.
|
||||
env->bottom_locals = (_Jv_JNI_LocalFrame *)
|
||||
_Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
|
||||
+ (FRAME_SIZE
|
||||
* sizeof (jobject)));
|
||||
|
||||
env->bottom_locals->marker = MARK_SYSTEM;
|
||||
env->bottom_locals->size = FRAME_SIZE;
|
||||
env->bottom_locals->next = NULL;
|
||||
env->bottom_locals->allocated_p = 0;
|
||||
memset (&env->bottom_locals->vec[0], 0,
|
||||
env->bottom_locals->size * sizeof (jobject));
|
||||
|
||||
_Jv_SetCurrentJNIEnv (env);
|
||||
}
|
||||
|
||||
_Jv_JNI_LocalFrame *frame
|
||||
= (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
|
||||
+ (FRAME_SIZE
|
||||
* sizeof (jobject)));
|
||||
// If we're in a simple JNI call (non-nested), we can just reuse the
|
||||
// locals frame we allocated many calls ago, back when the env was first
|
||||
// built, above.
|
||||
|
||||
frame->marker = MARK_SYSTEM;
|
||||
frame->size = FRAME_SIZE;
|
||||
frame->next = env->locals;
|
||||
if (__builtin_expect (env->locals == NULL, true))
|
||||
env->locals = env->bottom_locals;
|
||||
|
||||
for (int i = 0; i < frame->size; ++i)
|
||||
frame->vec[i] = NULL;
|
||||
else
|
||||
{
|
||||
// Alternatively, we might be re-entering JNI, in which case we can't
|
||||
// reuse the bottom_locals frame, because it is already underneath
|
||||
// us. So we need to make a new one.
|
||||
|
||||
_Jv_JNI_LocalFrame *frame
|
||||
= (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
|
||||
+ (FRAME_SIZE
|
||||
* sizeof (jobject)));
|
||||
|
||||
frame->marker = MARK_SYSTEM;
|
||||
frame->size = FRAME_SIZE;
|
||||
frame->allocated_p = 0;
|
||||
frame->next = env->locals;
|
||||
|
||||
memset (&frame->vec[0], 0,
|
||||
frame->size * sizeof (jobject));
|
||||
|
||||
env->locals = frame;
|
||||
}
|
||||
|
||||
env->locals = frame;
|
||||
env->ex = NULL;
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
// Destroy the env's reusable resources. This is called from the thread
|
||||
// destructor "finalize_native" in natThread.cc
|
||||
void
|
||||
_Jv_FreeJNIEnv (_Jv_JNIEnv *env)
|
||||
{
|
||||
if (env == NULL)
|
||||
return;
|
||||
|
||||
if (env->bottom_locals != NULL)
|
||||
_Jv_Free (env->bottom_locals);
|
||||
|
||||
_Jv_Free (env);
|
||||
}
|
||||
|
||||
// Return the function which implements a particular JNI method. If
|
||||
// we can't find the function, we throw the appropriate exception.
|
||||
// This is `extern "C"' because the compiler uses it.
|
||||
@ -2274,16 +2333,18 @@ _Jv_JNI_AttachCurrentThread (JavaVM *, jstring name, void **penv,
|
||||
env->p = &_Jv_JNIFunctions;
|
||||
env->ex = NULL;
|
||||
env->klass = NULL;
|
||||
env->locals
|
||||
env->bottom_locals
|
||||
= (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
|
||||
+ (FRAME_SIZE
|
||||
* sizeof (jobject)));
|
||||
env->locals = env->bottom_locals;
|
||||
if (env->locals == NULL)
|
||||
{
|
||||
_Jv_Free (env);
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
env->locals->allocated_p = 0;
|
||||
env->locals->marker = MARK_SYSTEM;
|
||||
env->locals->size = FRAME_SIZE;
|
||||
env->locals->next = NULL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user