jni.cc (nathash, [...]): New globals.
* jni.cc (nathash, nathash_count, nathash_size): New globals. (DELETED_ENTRY): New define. (hash): New function. (nathash_find_slot): Likewise. (natrehash): Likewise. (nathash_add): Likewise. (_Jv_JNI_RegisterNatives): No longer interpreter-specific. Use nathash_add. (nathash_find): New function. (_Jv_LookupJNIMethod): Use it. Synchronize body. (call): Synchronize around assignment. From-SVN: r45060
This commit is contained in:
parent
010dc908b2
commit
a4f291fc90
2 changed files with 166 additions and 21 deletions
|
@ -1,3 +1,17 @@
|
||||||
|
2001-08-20 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
* jni.cc (nathash, nathash_count, nathash_size): New globals.
|
||||||
|
(DELETED_ENTRY): New define.
|
||||||
|
(hash): New function.
|
||||||
|
(nathash_find_slot): Likewise.
|
||||||
|
(natrehash): Likewise.
|
||||||
|
(nathash_add): Likewise.
|
||||||
|
(_Jv_JNI_RegisterNatives): No longer interpreter-specific. Use
|
||||||
|
nathash_add.
|
||||||
|
(nathash_find): New function.
|
||||||
|
(_Jv_LookupJNIMethod): Use it. Synchronize body.
|
||||||
|
(call): Synchronize around assignment.
|
||||||
|
|
||||||
2001-08-17 Jeff Sturm <jsturm@one-point.com>
|
2001-08-17 Jeff Sturm <jsturm@one-point.com>
|
||||||
|
|
||||||
* gnu/gcj/convert/UnicodeToBytes.java (write): Write work buffer
|
* gnu/gcj/convert/UnicodeToBytes.java (write): Write work buffer
|
||||||
|
|
165
libjava/jni.cc
165
libjava/jni.cc
|
@ -1543,19 +1543,131 @@ _Jv_JNI_FromReflectedMethod (JNIEnv *, jobject method)
|
||||||
_Jv_FromReflectedConstructor (reinterpret_cast<Constructor *> (method));
|
_Jv_FromReflectedConstructor (reinterpret_cast<Constructor *> (method));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Hash table of native methods.
|
||||||
|
static JNINativeMethod *nathash;
|
||||||
|
// Number of slots used.
|
||||||
|
static int nathash_count = 0;
|
||||||
|
// Number of slots available. Must be power of 2.
|
||||||
|
static int nathash_size = 0;
|
||||||
|
|
||||||
|
#define DELETED_ENTRY ((char *) (~0))
|
||||||
|
|
||||||
|
// Compute a hash value for a native method descriptor.
|
||||||
|
static int
|
||||||
|
hash (const JNINativeMethod *method)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
int hash = 0;
|
||||||
|
|
||||||
|
ptr = method->name;
|
||||||
|
while (*ptr)
|
||||||
|
hash = (31 * hash) + *ptr++;
|
||||||
|
|
||||||
|
ptr = method->signature;
|
||||||
|
while (*ptr)
|
||||||
|
hash = (31 * hash) + *ptr++;
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the slot where a native method goes.
|
||||||
|
static JNINativeMethod *
|
||||||
|
nathash_find_slot (const JNINativeMethod *method)
|
||||||
|
{
|
||||||
|
jint h = hash (method);
|
||||||
|
int step = (h ^ (h >> 16)) | 1;
|
||||||
|
int w = h & (nathash_size - 1);
|
||||||
|
int del = -1;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
JNINativeMethod *slotp = &nathash[w];
|
||||||
|
if (slotp->name == NULL)
|
||||||
|
{
|
||||||
|
if (del >= 0)
|
||||||
|
return &nathash[del];
|
||||||
|
else
|
||||||
|
return slotp;
|
||||||
|
}
|
||||||
|
else if (slotp->name == DELETED_ENTRY)
|
||||||
|
del = w;
|
||||||
|
else if (! strcmp (slotp->name, method->name)
|
||||||
|
&& ! strcmp (slotp->signature, method->signature))
|
||||||
|
return slotp;
|
||||||
|
w = (w + step) & (nathash_size - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find a method. Return NULL if it isn't in the hash table.
|
||||||
|
static void *
|
||||||
|
nathash_find (JNINativeMethod *method)
|
||||||
|
{
|
||||||
|
if (nathash == NULL)
|
||||||
|
return NULL;
|
||||||
|
JNINativeMethod *slot = nathash_find_slot (method);
|
||||||
|
if (slot->name == NULL || slot->name == DELETED_ENTRY)
|
||||||
|
return NULL;
|
||||||
|
return slot->fnPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
natrehash ()
|
||||||
|
{
|
||||||
|
if (nathash == NULL)
|
||||||
|
{
|
||||||
|
nathash_size = 1024;
|
||||||
|
nathash =
|
||||||
|
(JNINativeMethod *) _Jv_AllocBytes (nathash_size
|
||||||
|
* sizeof (JNINativeMethod));
|
||||||
|
memset (nathash, 0, nathash_size * sizeof (JNINativeMethod));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int savesize = nathash_size;
|
||||||
|
JNINativeMethod *savehash = nathash;
|
||||||
|
nathash_size *= 2;
|
||||||
|
nathash =
|
||||||
|
(JNINativeMethod *) _Jv_AllocBytes (nathash_size
|
||||||
|
* sizeof (JNINativeMethod));
|
||||||
|
memset (nathash, 0, nathash_size * sizeof (JNINativeMethod));
|
||||||
|
|
||||||
|
for (int i = 0; i < savesize; ++i)
|
||||||
|
{
|
||||||
|
if (savehash[i].name != NULL && savehash[i].name != DELETED_ENTRY)
|
||||||
|
{
|
||||||
|
JNINativeMethod *slot = nathash_find_slot (&savehash[i]);
|
||||||
|
*slot = savehash[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nathash_add (const JNINativeMethod *method)
|
||||||
|
{
|
||||||
|
if (3 * nathash_count >= 2 * nathash_size)
|
||||||
|
natrehash ();
|
||||||
|
JNINativeMethod *slot = nathash_find_slot (method);
|
||||||
|
// If the slot has a real entry in it, then there is no work to do.
|
||||||
|
if (slot->name != NULL && slot->name != DELETED_ENTRY)
|
||||||
|
return;
|
||||||
|
// FIXME
|
||||||
|
slot->name = strdup (method->name);
|
||||||
|
slot->signature = strdup (method->signature);
|
||||||
|
slot->fnPtr = method->fnPtr;
|
||||||
|
}
|
||||||
|
|
||||||
static jint
|
static jint
|
||||||
_Jv_JNI_RegisterNatives (JNIEnv *env, jclass k,
|
_Jv_JNI_RegisterNatives (JNIEnv *env, jclass klass,
|
||||||
const JNINativeMethod *methods,
|
const JNINativeMethod *methods,
|
||||||
jint nMethods)
|
jint nMethods)
|
||||||
{
|
{
|
||||||
#ifdef INTERPRETER
|
// Synchronize while we do the work. This must match
|
||||||
// For now, this only matters for interpreted methods. FIXME.
|
// synchronization in some other functions that manipulate or use
|
||||||
if (! _Jv_IsInterpretedClass (k))
|
// the nathash table.
|
||||||
{
|
JvSynchronize sync (global_ref_table);
|
||||||
// FIXME: throw exception.
|
|
||||||
return JNI_ERR;
|
|
||||||
}
|
|
||||||
_Jv_InterpClass *klass = reinterpret_cast<_Jv_InterpClass *> (k);
|
|
||||||
|
|
||||||
// Look at each descriptor given us, and find the corresponding
|
// Look at each descriptor given us, and find the corresponding
|
||||||
// method in the class.
|
// method in the class.
|
||||||
|
@ -1563,11 +1675,10 @@ _Jv_JNI_RegisterNatives (JNIEnv *env, jclass k,
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
_Jv_MethodBase **imeths = _Jv_GetFirstMethod (klass);
|
_Jv_Method *imeths = JvGetFirstMethod (klass);
|
||||||
for (int i = 0; i < JvNumMethods (klass); ++i)
|
for (int i = 0; i < JvNumMethods (klass); ++i)
|
||||||
{
|
{
|
||||||
_Jv_MethodBase *meth = imeths[i];
|
_Jv_Method *self = &imeths[i];
|
||||||
_Jv_Method *self = meth->get_method ();
|
|
||||||
|
|
||||||
if (! strcmp (self->name->data, methods[j].name)
|
if (! strcmp (self->name->data, methods[j].name)
|
||||||
&& ! strcmp (self->signature->data, methods[j].signature))
|
&& ! strcmp (self->signature->data, methods[j].signature))
|
||||||
|
@ -1577,9 +1688,9 @@ _Jv_JNI_RegisterNatives (JNIEnv *env, jclass k,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Found a match that is native.
|
// Found a match that is native.
|
||||||
_Jv_JNIMethod *jmeth = reinterpret_cast<_Jv_JNIMethod *> (meth);
|
|
||||||
jmeth->set_function (methods[i].fnPtr);
|
|
||||||
found = true;
|
found = true;
|
||||||
|
nathash_add (&methods[j]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1600,14 +1711,12 @@ _Jv_JNI_RegisterNatives (JNIEnv *env, jclass k,
|
||||||
}
|
}
|
||||||
|
|
||||||
return JNI_OK;
|
return JNI_OK;
|
||||||
#else /* INTERPRETER */
|
|
||||||
return JNI_ERR;
|
|
||||||
#endif /* INTERPRETER */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static jint
|
static jint
|
||||||
_Jv_JNI_UnregisterNatives (JNIEnv *, jclass)
|
_Jv_JNI_UnregisterNatives (JNIEnv *, jclass)
|
||||||
{
|
{
|
||||||
|
// FIXME -- we could implement this.
|
||||||
return JNI_ERR;
|
return JNI_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1751,6 +1860,22 @@ _Jv_LookupJNIMethod (jclass klass, _Jv_Utf8Const *name,
|
||||||
int long_start;
|
int long_start;
|
||||||
void *function;
|
void *function;
|
||||||
|
|
||||||
|
// Synchronize on something convenient. Right now we use the hash.
|
||||||
|
JvSynchronize sync (global_ref_table);
|
||||||
|
|
||||||
|
// First see if we have an override in the hash table.
|
||||||
|
strncpy (buf, name->data, name->length);
|
||||||
|
buf[name->length] = '\0';
|
||||||
|
strncpy (buf + name->length + 1, signature->data, signature->length);
|
||||||
|
buf[name->length + signature->length + 1] = '\0';
|
||||||
|
JNINativeMethod meth;
|
||||||
|
meth.name = buf;
|
||||||
|
meth.signature = buf + name->length + 1;
|
||||||
|
function = nathash_find (&meth);
|
||||||
|
if (function != NULL)
|
||||||
|
return function;
|
||||||
|
|
||||||
|
// If there was no override, then look in the symbol table.
|
||||||
mangled_name (klass, name, signature, buf, &long_start);
|
mangled_name (klass, name, signature, buf, &long_start);
|
||||||
char c = buf[long_start];
|
char c = buf[long_start];
|
||||||
buf[long_start] = '\0';
|
buf[long_start] = '\0';
|
||||||
|
@ -1787,10 +1912,16 @@ _Jv_JNIMethod::call (ffi_cif *, void *ret, ffi_raw *args, void *__this)
|
||||||
// We cache the value that we find, of course, but if we don't find
|
// We cache the value that we find, of course, but if we don't find
|
||||||
// a value we don't cache that fact -- we might subsequently load a
|
// a value we don't cache that fact -- we might subsequently load a
|
||||||
// library which finds the function in question.
|
// library which finds the function in question.
|
||||||
|
{
|
||||||
|
// Synchronize on a convenient object to ensure sanity in case two
|
||||||
|
// threads reach this point for the same function at the same
|
||||||
|
// time.
|
||||||
|
JvSynchronize sync (global_ref_table);
|
||||||
if (_this->function == NULL)
|
if (_this->function == NULL)
|
||||||
_this->function = _Jv_LookupJNIMethod (_this->defining_class,
|
_this->function = _Jv_LookupJNIMethod (_this->defining_class,
|
||||||
_this->self->name,
|
_this->self->name,
|
||||||
_this->self->signature);
|
_this->self->signature);
|
||||||
|
}
|
||||||
|
|
||||||
JvAssert (_this->args_raw_size % sizeof (ffi_raw) == 0);
|
JvAssert (_this->args_raw_size % sizeof (ffi_raw) == 0);
|
||||||
ffi_raw real_args[2 + _this->args_raw_size / sizeof (ffi_raw)];
|
ffi_raw real_args[2 + _this->args_raw_size / sizeof (ffi_raw)];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue