Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2032893 | 1.3.0 | Coleen Phillimore | P3 | Closed | Fixed | 1.3 |
CLASS_UNLOCK(EE2SysThread(ee));
+ mb = cbMethods(cbCalled);
+ for (; --n >= 0; mb++) {
+ if ((mb->fb.name == cp[name_index].cp) &&
+ (mb->fb.signature == cp[signature_index].cp)) {
+ return mb->fb.access & ACC_WRITTEN_FLAGS;
+ }
}
+ return -1;
}
- return -1;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
}
+ case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ return cp[cp_index].mb->fb.access & ACC_WRITTEN_FLAGS;
default:
(*env)->FatalError(env, "JVM_GetCPMethodModifiers: illegal constant");
}
return 0; /* never reached */
}
JNIEXPORT void JNICALL
JVM_ReleaseUTF(const char *utf)
{
}
JNIEXPORT jboolean JNICALL
JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2)
{
ClassClass *cb1 = (ClassClass *)DeRef(env, class1);
ClassClass *cb2 = (ClassClass *)DeRef(env, class2);
return IsSameClassPackage(cb1, cb2);
}
/*
* Thread class calls
*/
(Review ID: 102695)
======================================================================
Name: clC74495 Date: 03/22/2000
In
src/share/javavm/runtime/jvm.c
the accesses of unresolved constant pool entries are not thread safe.
JVM_GetCPFieldNameUTF() is a good example. This thread interaction is
possible:
switch(type_table[cp_index]) {
case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
return cp[cp_index].fb->name;
case CONSTANT_Fieldref: {
>>> ANOTHER THREAD RESOLVES CONSTANT POOL ENTRY!
int index = cp[cp_index].i; /* value of Fieldref field */
The constant pool entry will have changed before JVM_GetCPFieldNameUTF()
has read it!
A locking mechanism similar to that used in ResolveClassConstant0()
or GetClassConstantClassName() should be used here too. In that code
all accesses to unresolved constant pool entries are guarded using the
LINKCLASS lock.
The other JVM_GetCP*UTF() functions have the same problem. The diffs
below show the way I fixed this. The changes for each function are
very similar. The changes should be similar for JDK 1.3.
--------
--- current/jvm.c Tue Dec 1 13:43:12 1998
+++ fix/jvm.c Mon Mar 20 17:58:42 2000
@@ -1721,237 +1721,301 @@
JVM_GetMethodIxNameUTF(JNIEnv *env, jclass c, jint index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
struct methodblock *mb = cbMethods(cb) + index;
return mb->fb.name;
}
JNIEXPORT const char * JNICALL
JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass c, jint index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
struct methodblock *mb = cbMethods(cb) + index;
return mb->fb.signature;
}
JNIEXPORT const char * JNICALL
JVM_GetCPFieldNameUTF(JNIEnv *env, jclass c, jint cp_index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
+ case CONSTANT_Fieldref: {
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned index = cp[cp_index].i; /* value of Fieldref field */
+ unsigned key2 = index & 0xFFFF; /* index to NameAndType */
+ unsigned name_index = cp[key2].i >> 16;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ return cp[name_index].cp;
+ }
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
+ }
case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
return cp[cp_index].fb->name;
- case CONSTANT_Fieldref: {
- int index = cp[cp_index].i; /* value of Fieldref field */
- int key2 = index & 0xFFFF; /* index to NameAndType */
- int name_index = cp[key2].i >> 16;
- return cp[name_index].cp;
- }
default:
(*env)->FatalError(env, "JVM_GetCPFieldNameUTF: illegal constant");
return NULL; /* Keep lint happy */
}
}
JNIEXPORT const char * JNICALL
JVM_GetCPMethodNameUTF(JNIEnv *env, jclass c, jint cp_index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
- case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
- case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
- return cp[cp_index].mb->fb.name;
case CONSTANT_InterfaceMethodref:
case CONSTANT_Methodref: {
- int index = cp[cp_index].i;
- int key2 = index & 0xFFFF; /* index to NameAndType */
- int name_index = cp[key2].i >> 16;
- return cp[name_index].cp;
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned index = cp[cp_index].i; /* value of Fieldref field */
+ unsigned key2 = index & 0xFFFF; /* index to NameAndType */
+ unsigned name_index = cp[key2].i >> 16;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ return cp[name_index].cp;
+ }
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
}
+ case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ return cp[cp_index].mb->fb.name;
default:
(*env)->FatalError(env, "JVM_GetCPMethodNameUTF: illegal constant");
return NULL; /* Keep lint happy */
}
}
JNIEXPORT const char * JNICALL
JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass c, jint cp_index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
+ case CONSTANT_Fieldref: {
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned index = cp[cp_index].i; /* value of Fieldref field */
+ unsigned key2 = index & 0xFFFF; /* index to NameAndType */
+ unsigned signature_index = cp[key2].i & 0xFFFF;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ return cp[signature_index].cp;
+ }
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
+ }
case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
return cp[cp_index].fb->signature;
- case CONSTANT_Fieldref: {
- int index = cp[cp_index].i; /* value of Fieldref field */
- int key2 = index & 0xFFFF; /* index to NameAndType */
- int signature_index = cp[key2].i & 0xFFFF;
- return cp[signature_index].cp;
- }
default:
(*env)->FatalError(env, "JVM_GetCPFieldSignatureUTF: illegal constant");
return NULL; /* Keep lint happy */
}
}
JNIEXPORT const char * JNICALL
JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass c, jint cp_index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
- case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
- case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
- return cp[cp_index].mb->fb.signature;
case CONSTANT_InterfaceMethodref:
case CONSTANT_Methodref: {
- int index = cp[cp_index].i;
- int key2 = index & 0xFFFF; /* index to NameAndType */
- int signature_index = cp[key2].i & 0xFFFF;
- return cp[signature_index].cp;
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned index = cp[cp_index].i; /* value of Fieldref field */
+ unsigned key2 = index & 0xFFFF; /* index to NameAndType */
+ unsigned signature_index = cp[key2].i & 0xFFFF;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ return cp[signature_index].cp;
+ }
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
}
+ case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ return cp[cp_index].mb->fb.signature;
default:
(*env)->FatalError(env, "JVM_GetCPMethodSignatureUTF: illegal constant");
return NULL; /* Keep lint happy */
}
}
JNIEXPORT const char * JNICALL
JVM_GetCPClassNameUTF(JNIEnv *env, jclass c, jint cp_index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
union cp_item_type *cp = cbConstantPool(cb);
return GetClassConstantClassName(cp, cp_index);
}
JNIEXPORT const char * JNICALL
JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass c, jint cp_index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
+ case CONSTANT_Fieldref: {
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned classkey = cp[cp_index].i >> 16;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ return GetClassConstantClassName(cp, classkey);
+ }
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
+ }
case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
return cbName(cp[cp_index].fb->clazz);
- case CONSTANT_Fieldref: {
- unsigned classkey = cp[cp_index].i >> 16;
- return GetClassConstantClassName(cp, classkey);
- }
default:
(*env)->FatalError(env, "JVM_GetCPFieldClassNameUTF: illegal constant");
return NULL; /* Keep lint happy */
}
}
JNIEXPORT const char * JNICALL
JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass c, jint cp_index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
- case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
- case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
- return cbName(cp[cp_index].mb->fb.clazz);
case CONSTANT_InterfaceMethodref:
case CONSTANT_Methodref: {
- unsigned classkey = cp[cp_index].i >> 16;
- return GetClassConstantClassName(cp, classkey);
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned classkey = cp[cp_index].i >> 16;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ return GetClassConstantClassName(cp, classkey);
+ }
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
}
+ case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ return cbName(cp[cp_index].mb->fb.clazz);
default:
(*env)->FatalError(env, "JVM_GetCPMethodClassNameUTF: illegal constant");
return NULL; /* Keep lint happy */
}
}
JNIEXPORT jint JNICALL
JVM_GetCPFieldModifiers(JNIEnv *env, jclass c, int cp_index,
jclass calledClass)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
ClassClass *cbCalled = (ClassClass *)DeRef(env, calledClass);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
- case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
- return cp[cp_index].fb->access & ACC_WRITTEN_FLAGS;
- case CONSTANT_Fieldref: {
- int index = cp[cp_index].i; /* value of Fieldref field */
- int key2 = index & 0xFFFF; /* index to NameAndType */
- int signature_index = cp[key2].i & 0xFFFF;
- int name_index = cp[key2].i >> 16;
- struct fieldblock *fb;
- int n = cbFieldsCount(cbCalled);
-
- fb = cbFields(cbCalled);
- for (; --n >= 0; fb++) {
- if ((fb->name == cp[name_index].cp) &&
- (fb->signature == cp[signature_index].cp)) {
- return fb->access & ACC_WRITTEN_FLAGS;
+ case CONSTANT_Fieldref: {
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned index = cp[cp_index].i; /* value of Fieldref field */
+ unsigned key2 = index & 0xFFFF; /* index to NameAndType */
+ unsigned signature_index = cp[key2].i & 0xFFFF;
+ unsigned name_index = cp[key2].i >> 16;
+ struct fieldblock *fb;
+ int n = cbFieldsCount(cbCalled);
+
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ fb = cbFields(cbCalled);
+ for (; --n >= 0; fb++) {
+ if ((fb->name == cp[name_index].cp) &&
+ (fb->signature == cp[signature_index].cp)) {
+ return fb->access & ACC_WRITTEN_FLAGS;
+ }
}
+ return -1;
}
- return -1;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
}
+ case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
+ return cp[cp_index].fb->access & ACC_WRITTEN_FLAGS;
default:
(*env)->FatalError(env, "JVM_GetCPFieldModifiers: illegal constant");
}
return 0; /* never reached */
}
JNIEXPORT jint JNICALL
JVM_GetCPMethodModifiers(JNIEnv *env, jclass c, int cp_index,
jclass calledClass)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
ClassClass *cbCalled = (ClassClass *)DeRef(env, calledClass);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
- case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
- case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
- return cp[cp_index].mb->fb.access & ACC_WRITTEN_FLAGS;
case CONSTANT_InterfaceMethodref:
case CONSTANT_Methodref: {
- int index = cp[cp_index].i; /* value of Fieldref field */
- int key2 = index & 0xFFFF; /* index to NameAndType */
- int signature_index = cp[key2].i & 0xFFFF;
- int name_index = cp[key2].i >> 16;
- struct methodblock *mb;
- int n = cbMethodsCount(cbCalled);
- mb = cbMethods(cbCalled);
-
- for (; --n >= 0; mb++) {
- if ((mb->fb.name == cp[name_index].cp) &&
- (mb->fb.signature == cp[signature_index].cp)) {
- return mb->fb.access & ACC_WRITTEN_FLAGS;
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned index = cp[cp_index].i; /* value of Fieldref field */
+ unsigned key2 = index & 0xFFFF; /* index to NameAndType */
+ unsigned signature_index = cp[key2].i & 0xFFFF;
+ unsigned name_index = cp[key2].i >> 16;
+ struct methodblock *mb;
+ int n = cbMethodsCount(cbCalled);
+
+ LINK
+ mb = cbMethods(cbCalled);
+ for (; --n >= 0; mb++) {
+ if ((mb->fb.name == cp[name_index].cp) &&
+ (mb->fb.signature == cp[signature_index].cp)) {
+ return mb->fb.access & ACC_WRITTEN_FLAGS;
+ }
}
+ return -1;
}
- return -1;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
}
+ case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ return cp[cp_index].mb->fb.access & ACC_WRITTEN_FLAGS;
default:
(*env)->FatalError(env, "JVM_GetCPMethodModifiers: illegal constant");
}
return 0; /* never reached */
}
JNIEXPORT void JNICALL
JVM_ReleaseUTF(const char *utf)
{
}
JNIEXPORT jboolean JNICALL
JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2)
{
ClassClass *cb1 = (ClassClass *)DeRef(env, class1);
ClassClass *cb2 = (ClassClass *)DeRef(env, class2);
return IsSameClassPackage(cb1, cb2);
}
/*
* Thread class calls
*/
(Review ID: 102695)
======================================================================
Name: clC74495 Date: 03/22/2000
In
src/share/javavm/runtime/jvm.c
the accesses of unresolved constant pool entries are not thread safe.
JVM_GetCPFieldNameUTF() is a good example. This thread interaction is
possible:
switch(type_table[cp_index]) {
case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
return cp[cp_index].fb->name;
case CONSTANT_Fieldref: {
>>> ANOTHER THREAD RESOLVES CONSTANT POOL ENTRY!
int index = cp[cp_index].i; /* value of Fieldref field */
The constant pool entry will have changed before JVM_GetCPFieldNameUTF()
has read it!
A locking mechanism similar to that used in ResolveClassConstant0()
or GetClassConstantClassName() should be used here too. In that code
all accesses to unresolved constant pool entries are guarded using the
LINKCLASS lock.
The other JVM_GetCP*UTF() functions have the same problem. The diffs
below show the way I fixed this. The changes for each function are
very similar. The changes should be similar for JDK 1.3.
--------
--- current/jvm.c Tue Dec 1 13:43:12 1998
+++ fix/jvm.c Mon Mar 20 17:58:42 2000
@@ -1721,237 +1721,301 @@
JVM_GetMethodIxNameUTF(JNIEnv *env, jclass c, jint index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
struct methodblock *mb = cbMethods(cb) + index;
return mb->fb.name;
}
JNIEXPORT const char * JNICALL
JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass c, jint index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
struct methodblock *mb = cbMethods(cb) + index;
return mb->fb.signature;
}
JNIEXPORT const char * JNICALL
JVM_GetCPFieldNameUTF(JNIEnv *env, jclass c, jint cp_index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
+ case CONSTANT_Fieldref: {
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned index = cp[cp_index].i; /* value of Fieldref field */
+ unsigned key2 = index & 0xFFFF; /* index to NameAndType */
+ unsigned name_index = cp[key2].i >> 16;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ return cp[name_index].cp;
+ }
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
+ }
case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
return cp[cp_index].fb->name;
- case CONSTANT_Fieldref: {
- int index = cp[cp_index].i; /* value of Fieldref field */
- int key2 = index & 0xFFFF; /* index to NameAndType */
- int name_index = cp[key2].i >> 16;
- return cp[name_index].cp;
- }
default:
(*env)->FatalError(env, "JVM_GetCPFieldNameUTF: illegal constant");
return NULL; /* Keep lint happy */
}
}
JNIEXPORT const char * JNICALL
JVM_GetCPMethodNameUTF(JNIEnv *env, jclass c, jint cp_index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
- case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
- case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
- return cp[cp_index].mb->fb.name;
case CONSTANT_InterfaceMethodref:
case CONSTANT_Methodref: {
- int index = cp[cp_index].i;
- int key2 = index & 0xFFFF; /* index to NameAndType */
- int name_index = cp[key2].i >> 16;
- return cp[name_index].cp;
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned index = cp[cp_index].i; /* value of Fieldref field */
+ unsigned key2 = index & 0xFFFF; /* index to NameAndType */
+ unsigned name_index = cp[key2].i >> 16;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ return cp[name_index].cp;
+ }
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
}
+ case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ return cp[cp_index].mb->fb.name;
default:
(*env)->FatalError(env, "JVM_GetCPMethodNameUTF: illegal constant");
return NULL; /* Keep lint happy */
}
}
JNIEXPORT const char * JNICALL
JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass c, jint cp_index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
+ case CONSTANT_Fieldref: {
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned index = cp[cp_index].i; /* value of Fieldref field */
+ unsigned key2 = index & 0xFFFF; /* index to NameAndType */
+ unsigned signature_index = cp[key2].i & 0xFFFF;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ return cp[signature_index].cp;
+ }
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
+ }
case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
return cp[cp_index].fb->signature;
- case CONSTANT_Fieldref: {
- int index = cp[cp_index].i; /* value of Fieldref field */
- int key2 = index & 0xFFFF; /* index to NameAndType */
- int signature_index = cp[key2].i & 0xFFFF;
- return cp[signature_index].cp;
- }
default:
(*env)->FatalError(env, "JVM_GetCPFieldSignatureUTF: illegal constant");
return NULL; /* Keep lint happy */
}
}
JNIEXPORT const char * JNICALL
JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass c, jint cp_index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
- case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
- case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
- return cp[cp_index].mb->fb.signature;
case CONSTANT_InterfaceMethodref:
case CONSTANT_Methodref: {
- int index = cp[cp_index].i;
- int key2 = index & 0xFFFF; /* index to NameAndType */
- int signature_index = cp[key2].i & 0xFFFF;
- return cp[signature_index].cp;
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned index = cp[cp_index].i; /* value of Fieldref field */
+ unsigned key2 = index & 0xFFFF; /* index to NameAndType */
+ unsigned signature_index = cp[key2].i & 0xFFFF;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ return cp[signature_index].cp;
+ }
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
}
+ case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ return cp[cp_index].mb->fb.signature;
default:
(*env)->FatalError(env, "JVM_GetCPMethodSignatureUTF: illegal constant");
return NULL; /* Keep lint happy */
}
}
JNIEXPORT const char * JNICALL
JVM_GetCPClassNameUTF(JNIEnv *env, jclass c, jint cp_index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
union cp_item_type *cp = cbConstantPool(cb);
return GetClassConstantClassName(cp, cp_index);
}
JNIEXPORT const char * JNICALL
JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass c, jint cp_index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
+ case CONSTANT_Fieldref: {
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned classkey = cp[cp_index].i >> 16;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ return GetClassConstantClassName(cp, classkey);
+ }
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
+ }
case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
return cbName(cp[cp_index].fb->clazz);
- case CONSTANT_Fieldref: {
- unsigned classkey = cp[cp_index].i >> 16;
- return GetClassConstantClassName(cp, classkey);
- }
default:
(*env)->FatalError(env, "JVM_GetCPFieldClassNameUTF: illegal constant");
return NULL; /* Keep lint happy */
}
}
JNIEXPORT const char * JNICALL
JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass c, jint cp_index)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
- case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
- case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
- return cbName(cp[cp_index].mb->fb.clazz);
case CONSTANT_InterfaceMethodref:
case CONSTANT_Methodref: {
- unsigned classkey = cp[cp_index].i >> 16;
- return GetClassConstantClassName(cp, classkey);
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned classkey = cp[cp_index].i >> 16;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ return GetClassConstantClassName(cp, classkey);
+ }
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
}
+ case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
+ return cbName(cp[cp_index].mb->fb.clazz);
default:
(*env)->FatalError(env, "JVM_GetCPMethodClassNameUTF: illegal constant");
return NULL; /* Keep lint happy */
}
}
JNIEXPORT jint JNICALL
JVM_GetCPFieldModifiers(JNIEnv *env, jclass c, int cp_index,
jclass calledClass)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
ClassClass *cbCalled = (ClassClass *)DeRef(env, calledClass);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
- case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
- return cp[cp_index].fb->access & ACC_WRITTEN_FLAGS;
- case CONSTANT_Fieldref: {
- int index = cp[cp_index].i; /* value of Fieldref field */
- int key2 = index & 0xFFFF; /* index to NameAndType */
- int signature_index = cp[key2].i & 0xFFFF;
- int name_index = cp[key2].i >> 16;
- struct fieldblock *fb;
- int n = cbFieldsCount(cbCalled);
-
- fb = cbFields(cbCalled);
- for (; --n >= 0; fb++) {
- if ((fb->name == cp[name_index].cp) &&
- (fb->signature == cp[signature_index].cp)) {
- return fb->access & ACC_WRITTEN_FLAGS;
+ case CONSTANT_Fieldref: {
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned index = cp[cp_index].i; /* value of Fieldref field */
+ unsigned key2 = index & 0xFFFF; /* index to NameAndType */
+ unsigned signature_index = cp[key2].i & 0xFFFF;
+ unsigned name_index = cp[key2].i >> 16;
+ struct fieldblock *fb;
+ int n = cbFieldsCount(cbCalled);
+
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ fb = cbFields(cbCalled);
+ for (; --n >= 0; fb++) {
+ if ((fb->name == cp[name_index].cp) &&
+ (fb->signature == cp[signature_index].cp)) {
+ return fb->access & ACC_WRITTEN_FLAGS;
+ }
}
+ return -1;
}
- return -1;
+ LINKCLASS_UNLOCK(EE2SysThread(ee));
+ /* FALL THROUGH */
}
+ case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
+ return cp[cp_index].fb->access & ACC_WRITTEN_FLAGS;
default:
(*env)->FatalError(env, "JVM_GetCPFieldModifiers: illegal constant");
}
return 0; /* never reached */
}
JNIEXPORT jint JNICALL
JVM_GetCPMethodModifiers(JNIEnv *env, jclass c, int cp_index,
jclass calledClass)
{
ClassClass *cb = (ClassClass *)DeRef(env, c);
ClassClass *cbCalled = (ClassClass *)DeRef(env, calledClass);
union cp_item_type *cp = cbConstantPool(cb);
unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
switch(type_table[cp_index]) {
- case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
- case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
- return cp[cp_index].mb->fb.access & ACC_WRITTEN_FLAGS;
case CONSTANT_InterfaceMethodref:
case CONSTANT_Methodref: {
- int index = cp[cp_index].i; /* value of Fieldref field */
- int key2 = index & 0xFFFF; /* index to NameAndType */
- int signature_index = cp[key2].i & 0xFFFF;
- int name_index = cp[key2].i >> 16;
- struct methodblock *mb;
- int n = cbMethodsCount(cbCalled);
- mb = cbMethods(cbCalled);
-
- for (; --n >= 0; mb++) {
- if ((mb->fb.name == cp[name_index].cp) &&
- (mb->fb.signature == cp[signature_index].cp)) {
- return mb->fb.access & ACC_WRITTEN_FLAGS;
+ ExecEnv *ee = JNIEnv2EE(env);
+ LINKCLASS_LOCK(EE2SysThread(ee));
+ /* Entry may have been resolved by another thread */
+ if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
+ unsigned index = cp[cp_index].i; /* value of Fieldref field */
+ unsigned key2 = index & 0xFFFF; /* index to NameAndType */
+ unsigned signature_index = cp[key2].i & 0xFFFF;
+ unsigned name_index = cp[key2].i >> 16;
+ struct methodblock *mb;
+ int n = cbMethodsCount(cbCalled);
+
+ LINK
- backported by
-
JDK-2032893 JVM_GetCP*UTF() functions are not thread safe
-
- Closed
-