8241080: Consolidate signature parsing code in serviceability tools

Reviewed-by: sspitsyn, cjplummer
This commit is contained in:
Daniil Titov 2020-05-19 09:40:21 -07:00
parent fa36d28aff
commit 9d4872f612
21 changed files with 548 additions and 411 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -59,7 +59,8 @@ public class ArrayTypeImpl extends ReferenceTypeImpl
}
public String componentSignature() {
return signature().substring(1); // Just skip the leading '['
JNITypeParser sig = new JNITypeParser(signature());
return sig.componentSignature();
}
public String componentTypeName() {
@ -90,8 +91,9 @@ public class ArrayTypeImpl extends ReferenceTypeImpl
* this method is sometimes needed for proper type checking.
*/
Type findComponentType(String signature) throws ClassNotLoadedException {
byte tag = (byte)signature.charAt(0);
if (PacketStream.isObjectTag(tag)) {
JNITypeParser sig = new JNITypeParser(signature);
if (sig.isReference()) {
// It's a reference type
JNITypeParser parser = new JNITypeParser(componentSignature());
List<ReferenceType> list = vm.classesByName(parser.typeName());
@ -109,7 +111,7 @@ public class ArrayTypeImpl extends ReferenceTypeImpl
throw new ClassNotLoadedException(componentTypeName());
} else {
// It's a primitive type
return vm.primitiveTypeMirror(tag);
return vm.primitiveTypeMirror(sig.jdwpTag());
}
}

View File

@ -425,19 +425,7 @@ public class EventSetImpl extends ArrayList<Event> implements EventSet {
}
public String className() {
assert classSignature.startsWith("L") && classSignature.endsWith(";");
// trim leading "L" and trailing ";"
String name = classSignature.substring(1, classSignature.length() - 1);
int index = name.indexOf("."); // check if it is a hidden class
if (index < 0) {
return name.replace('/', '.');
} else {
// map the type descriptor from: "L" + N + "." + <suffix> + ";"
// to class name: N.replace('/', '.') + "/" + <suffix>
return name.substring(0, index).replace('/', '.')
+ "/" + name.substring(index + 1);
}
return JNITypeParser.convertSignatureToClassname(classSignature);
}
public String classSignature() {

View File

@ -113,10 +113,69 @@ public class JNITypeParser {
return count;
}
byte jdwpTag() {
return (byte) signature().charAt(0);
}
String componentSignature(int level) {
assert level <= dimensionCount();
return signature().substring(level);
}
String componentSignature() {
assert isArray();
return componentSignature(1);
}
boolean isArray() {
return jdwpTag() == JDWP.Tag.ARRAY;
}
boolean isVoid() {
return jdwpTag() == JDWP.Tag.VOID;
}
boolean isBoolean() {
return jdwpTag() == JDWP.Tag.BOOLEAN;
}
boolean isReference() {
byte tag = jdwpTag();
return tag == JDWP.Tag.ARRAY ||
tag == JDWP.Tag.OBJECT;
}
boolean isPrimitive() {
switch (jdwpTag()) {
case (JDWP.Tag.BOOLEAN):
case (JDWP.Tag.BYTE):
case (JDWP.Tag.CHAR):
case (JDWP.Tag.SHORT):
case (JDWP.Tag.INT):
case (JDWP.Tag.LONG):
case (JDWP.Tag.FLOAT):
case (JDWP.Tag.DOUBLE):
return true;
}
return false;
}
static String convertSignatureToClassname(String classSignature) {
assert classSignature.startsWith("L") && classSignature.endsWith(";");
// trim leading "L" and trailing ";"
String name = classSignature.substring(1, classSignature.length() - 1);
int index = name.indexOf("."); // check if it is a hidden class
if (index < 0) {
return name.replace('/', '.');
} else {
// map the type descriptor from: "L" + N + "." + <suffix> + ";"
// to class name: N.replace('/', '.') + "/" + <suffix>
return name.substring(0, index).replace('/', '.')
+ "/" + name.substring(index + 1);
}
}
private synchronized List<String> signatureList() {
if (signatureList == null) {
signatureList = new ArrayList<>(10);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -584,17 +584,16 @@ public class ObjectReferenceImpl extends ValueImpl
* type which might cause a confusing ClassNotLoadedException if
* the destination is primitive or an array.
*/
/*
* TO DO: Centralize JNI signature knowledge
*/
if (destination.signature().length() == 1) {
JNITypeParser destSig = new JNITypeParser(destination.signature());
JNITypeParser sourceSig = new JNITypeParser(type().signature());
if (destSig.isPrimitive()) {
throw new InvalidTypeException("Can't assign object value to primitive");
}
if ((destination.signature().charAt(0) == '[') &&
(type().signature().charAt(0) != '[')) {
if (destSig.isArray() && !sourceSig.isArray()) {
throw new InvalidTypeException("Can't assign non-array value to an array");
}
if ("void".equals(destination.typeName())) {
if (destSig.isVoid()) {
throw new InvalidTypeException("Can't assign object value to a void");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -105,24 +105,22 @@ public abstract class PrimitiveValueImpl extends ValueImpl
ValueImpl convertForAssignmentTo(ValueContainer destination)
throws InvalidTypeException
{
/*
* TO DO: Centralize JNI signature knowledge
*/
if (destination.signature().length() > 1) {
JNITypeParser destSig = new JNITypeParser(destination.signature());
JNITypeParser sourceSig = new JNITypeParser(type().signature());
if (destSig.isReference()) {
throw new InvalidTypeException("Can't assign primitive value to object");
}
if ((destination.signature().charAt(0) == 'Z') &&
(type().signature().charAt(0) != 'Z')) {
if (destSig.isBoolean() && !sourceSig.isBoolean()) {
throw new InvalidTypeException("Can't assign non-boolean value to a boolean");
}
if ((destination.signature().charAt(0) != 'Z') &&
(type().signature().charAt(0) == 'Z')) {
if (!destSig.isBoolean() && sourceSig.isBoolean()) {
throw new InvalidTypeException("Can't assign boolean value to an non-boolean");
}
if ("void".equals(destination.typeName())) {
if (destSig.isVoid()) {
throw new InvalidTypeException("Can't assign primitive value to a void");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -1151,40 +1151,28 @@ public abstract class ReferenceTypeImpl extends TypeImpl implements ReferenceTyp
}
private static boolean isOneDimensionalPrimitiveArray(String signature) {
int i = signature.lastIndexOf('[');
/*
* TO DO: Centralize JNI signature knowledge.
*
* Ref:
* jdk1.4/doc/guide/jpda/jdi/com/sun/jdi/doc-files/signature.html
*/
boolean isPA;
if (i < 0 || signature.startsWith("[[")) {
isPA = false;
} else {
char c = signature.charAt(i + 1);
isPA = (c != 'L');
JNITypeParser sig = new JNITypeParser(signature);
if (sig.isArray()) {
JNITypeParser componentSig = new JNITypeParser(sig.componentSignature());
return componentSig.isPrimitive();
}
return isPA;
return false;
}
Type findType(String signature) throws ClassNotLoadedException {
Type type;
if (signature.length() == 1) {
/* OTI FIX: Must be a primitive type or the void type */
char sig = signature.charAt(0);
if (sig == 'V') {
type = vm.theVoidType();
} else {
type = vm.primitiveTypeMirror((byte)sig);
}
JNITypeParser sig = new JNITypeParser(signature);
if (sig.isVoid()) {
type = vm.theVoidType();
} else if (sig.isPrimitive()) {
type = vm.primitiveTypeMirror(sig.jdwpTag());
} else {
// Must be a reference type.
ClassLoaderReferenceImpl loader =
(ClassLoaderReferenceImpl)classLoader();
(ClassLoaderReferenceImpl) classLoader();
if ((loader == null) ||
(isOneDimensionalPrimitiveArray(signature)) //Work around 4450091
) {
(isOneDimensionalPrimitiveArray(signature)) //Work around 4450091
) {
// Caller wants type of boot class field
type = vm.findBootType(signature);
} else {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -40,10 +40,8 @@ abstract class ValueImpl extends MirrorImpl implements Value {
ValueContainer destination)
throws InvalidTypeException, ClassNotLoadedException {
if (value == null) {
/*
* TO DO: Centralize JNI signature knowledge
*/
if (destination.signature().length() == 1) {
JNITypeParser sig = new JNITypeParser(destination.signature());
if (sig.isPrimitive()) {
throw new InvalidTypeException("Can't set a primitive type to null");
}
return null; // no further checking or conversion necessary

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -54,7 +54,8 @@ public class VoidValueImpl extends ValueImpl implements VoidValue {
ValueImpl prepareForAssignmentTo(ValueContainer destination)
throws InvalidTypeException
{
if ("void".equals(destination.typeName())) {
JNITypeParser sig = new JNITypeParser(destination.signature());
if (sig.isVoid()) {
return this;
}
throw new InvalidTypeException();

View File

@ -27,6 +27,7 @@
#include "ArrayReferenceImpl.h"
#include "inStream.h"
#include "outStream.h"
#include "signature.h"
static jboolean
length(PacketInputStream *in, PacketOutputStream *out)
@ -204,7 +205,7 @@ writeDoubleComponents(JNIEnv *env, PacketOutputStream *out,
static void
writeObjectComponents(JNIEnv *env, PacketOutputStream *out,
jarray array, jint index, jint length)
jarray array, jint index, jint length)
{
WITH_LOCAL_REFS(env, length) {
@ -225,6 +226,9 @@ writeObjectComponents(JNIEnv *env, PacketOutputStream *out,
} END_WITH_LOCAL_REFS(env);
}
static void writeComponents(JNIEnv *env, PacketOutputStream *out, char *signature,
jarray array, jint index, jint length);
static jboolean
getValues(PacketInputStream *in, PacketOutputStream *out)
{
@ -265,68 +269,14 @@ getValues(PacketInputStream *in, PacketOutputStream *out)
WITH_LOCAL_REFS(env, 1) {
jclass arrayClass;
char *signature = NULL;
char *componentSignature;
jbyte typeKey;
jvmtiError error;
arrayClass = JNI_FUNC_PTR(env,GetObjectClass)(env, array);
error = classSignature(arrayClass, &signature, NULL);
if (error != JVMTI_ERROR_NONE) {
goto err;
jclass arrayClass = JNI_FUNC_PTR(env,GetObjectClass)(env, array);
jvmtiError error = classSignature(arrayClass, &signature, NULL);
if (error == JVMTI_ERROR_NONE) {
writeComponents(env, out, signature, array, index, length);
jvmtiDeallocate(signature);
}
componentSignature = &signature[1];
typeKey = componentSignature[0];
(void)outStream_writeByte(out, typeKey);
(void)outStream_writeInt(out, length);
if (isObjectTag(typeKey)) {
writeObjectComponents(env, out, array, index, length);
} else {
switch (typeKey) {
case JDWP_TAG(BYTE):
writeByteComponents(env, out, array, index, length);
break;
case JDWP_TAG(CHAR):
writeCharComponents(env, out, array, index, length);
break;
case JDWP_TAG(FLOAT):
writeFloatComponents(env, out, array, index, length);
break;
case JDWP_TAG(DOUBLE):
writeDoubleComponents(env, out, array, index, length);
break;
case JDWP_TAG(INT):
writeIntComponents(env, out, array, index, length);
break;
case JDWP_TAG(LONG):
writeLongComponents(env, out, array, index, length);
break;
case JDWP_TAG(SHORT):
writeShortComponents(env, out, array, index, length);
break;
case JDWP_TAG(BOOLEAN):
writeBooleanComponents(env, out, array, index, length);
break;
default:
outStream_setError(out, JDWP_ERROR(INVALID_TAG));
break;
}
}
jvmtiDeallocate(signature);
err:;
} END_WITH_LOCAL_REFS(env);
@ -338,6 +288,58 @@ getValues(PacketInputStream *in, PacketOutputStream *out)
return JNI_TRUE;
}
static void writeComponents(JNIEnv *env, PacketOutputStream *out, char *signature,
jarray array, jint index, jint length) {
char * componentSignature = componentTypeSignature(signature);
jbyte typeKey = jdwpTag(componentSignature);
(void)outStream_writeByte(out, typeKey);
(void)outStream_writeInt(out, length);
if (isReferenceTag(typeKey)) {
writeObjectComponents(env, out, array, index, length);
return;
}
switch (typeKey) {
case JDWP_TAG(BYTE):
writeByteComponents(env, out, array, index, length);
break;
case JDWP_TAG(CHAR):
writeCharComponents(env, out, array, index, length);
break;
case JDWP_TAG(FLOAT):
writeFloatComponents(env, out, array, index, length);
break;
case JDWP_TAG(DOUBLE):
writeDoubleComponents(env, out, array, index, length);
break;
case JDWP_TAG(INT):
writeIntComponents(env, out, array, index, length);
break;
case JDWP_TAG(LONG):
writeLongComponents(env, out, array, index, length);
break;
case JDWP_TAG(SHORT):
writeShortComponents(env, out, array, index, length);
break;
case JDWP_TAG(BOOLEAN):
writeBooleanComponents(env, out, array, index, length);
break;
default:
outStream_setError(out, JDWP_ERROR(INVALID_TAG));
break;
}
}
static jdwpError
readBooleanComponents(JNIEnv *env, PacketInputStream *in,
jarray array, int index, int length)
@ -477,6 +479,8 @@ readObjectComponents(JNIEnv *env, PacketInputStream *in,
return JDWP_ERROR(NONE);
}
static jdwpError readComponents(JNIEnv *env, PacketInputStream *in, char *signature,
jarray array, jint index, jint length);
static jboolean
setValues(PacketInputStream *in, PacketOutputStream *out)
@ -515,69 +519,14 @@ setValues(PacketInputStream *in, PacketOutputStream *out)
WITH_LOCAL_REFS(env, 1) {
jclass arrayClass;
char *signature = NULL;
char *componentSignature;
jvmtiError error;
arrayClass = JNI_FUNC_PTR(env,GetObjectClass)(env, array);
error = classSignature(arrayClass, &signature, NULL);
if (error != JVMTI_ERROR_NONE) {
goto err;
jclass arrayClass = JNI_FUNC_PTR(env,GetObjectClass)(env, array);
jvmtiError error = classSignature(arrayClass, &signature, NULL);
if (error == JVMTI_ERROR_NONE) {
serror = readComponents(env, in, signature, array, index, length);
jvmtiDeallocate(signature);
}
componentSignature = &signature[1];
switch (componentSignature[0]) {
case JDWP_TAG(OBJECT):
case JDWP_TAG(ARRAY):
serror = readObjectComponents(env, in, array, index, length);
break;
case JDWP_TAG(BYTE):
serror = readByteComponents(env, in, array, index, length);
break;
case JDWP_TAG(CHAR):
serror = readCharComponents(env, in, array, index, length);
break;
case JDWP_TAG(FLOAT):
serror = readFloatComponents(env, in, array, index, length);
break;
case JDWP_TAG(DOUBLE):
serror = readDoubleComponents(env, in, array, index, length);
break;
case JDWP_TAG(INT):
serror = readIntComponents(env, in, array, index, length);
break;
case JDWP_TAG(LONG):
serror = readLongComponents(env, in, array, index, length);
break;
case JDWP_TAG(SHORT):
serror = readShortComponents(env, in, array, index, length);
break;
case JDWP_TAG(BOOLEAN):
serror = readBooleanComponents(env, in, array, index, length);
break;
default:
{
ERROR_MESSAGE(("Invalid array component signature: %s",
componentSignature));
EXIT_ERROR(AGENT_ERROR_INVALID_OBJECT,NULL);
}
break;
}
jvmtiDeallocate(signature);
err:;
} END_WITH_LOCAL_REFS(env);
if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
@ -592,6 +541,61 @@ setValues(PacketInputStream *in, PacketOutputStream *out)
return JNI_TRUE;
}
static jdwpError readComponents(JNIEnv *env, PacketInputStream *in, char *signature,
jarray array, jint index, jint length) {
jdwpError serror = JDWP_ERROR(NONE);
char *componentSignature = componentTypeSignature(signature);
jbyte typeKey = jdwpTag(componentSignature);
if (isReferenceTag(typeKey)) {
serror = readObjectComponents(env, in, array, index, length);
return serror;
}
switch (typeKey) {
case JDWP_TAG(BYTE):
serror = readByteComponents(env, in, array, index, length);
break;
case JDWP_TAG(CHAR):
serror = readCharComponents(env, in, array, index, length);
break;
case JDWP_TAG(FLOAT):
serror = readFloatComponents(env, in, array, index, length);
break;
case JDWP_TAG(DOUBLE):
serror = readDoubleComponents(env, in, array, index, length);
break;
case JDWP_TAG(INT):
serror = readIntComponents(env, in, array, index, length);
break;
case JDWP_TAG(LONG):
serror = readLongComponents(env, in, array, index, length);
break;
case JDWP_TAG(SHORT):
serror = readShortComponents(env, in, array, index, length);
break;
case JDWP_TAG(BOOLEAN):
serror = readBooleanComponents(env, in, array, index, length);
break;
default:
{
ERROR_MESSAGE(("Invalid array component signature: %s",
componentSignature));
EXIT_ERROR(AGENT_ERROR_INVALID_OBJECT,NULL);
}
break;
}
return serror;
}
Command ArrayReference_Commands[] = {
{length, "Length"},
{getValues, "GetValues"},

View File

@ -27,6 +27,8 @@
#include "util.h"
#include "inStream.h"
#include "outStream.h"
#include "signature.h"
/*
* Determine the component class by looking thru all classes for
@ -148,7 +150,7 @@ writeNewPrimitiveArray(JNIEnv *env, PacketOutputStream *out,
jarray array = NULL;
switch (componentSignature[0]) {
switch (jdwpTag(componentSignature)) {
case JDWP_TAG(BYTE):
array = JNI_FUNC_PTR(env,NewByteArray)(env, size);
break;
@ -227,10 +229,10 @@ newInstance(PacketInputStream *in, PacketOutputStream *out)
outStream_setError(out, map2jdwpError(error));
return JNI_FALSE;
}
componentSignature = &signature[1];
componentSignature = componentTypeSignature(signature);
if ((componentSignature[0] == JDWP_TAG(OBJECT)) ||
(componentSignature[0] == JDWP_TAG(ARRAY))) {
jbyte typeKey = jdwpTag(componentSignature);
if (isReferenceTag(typeKey)) {
writeNewObjectArray(env, out, arrayClass, size, componentSignature);
} else {
writeNewPrimitiveArray(env, out, arrayClass, size, componentSignature);

View File

@ -27,6 +27,7 @@
#include "ClassTypeImpl.h"
#include "inStream.h"
#include "outStream.h"
#include "signature.h"
static jboolean
superclass(PacketInputStream *in, PacketOutputStream *out)
@ -58,15 +59,18 @@ readStaticFieldValue(JNIEnv *env, PacketInputStream *in, jclass clazz,
jfieldID field, char *signature)
{
jvalue value;
jdwpError serror = JDWP_ERROR(NONE);
jbyte typeKey = jdwpTag(signature);
switch (signature[0]) {
case JDWP_TAG(ARRAY):
case JDWP_TAG(OBJECT):
value.l = inStream_readObjectRef(env, in);
JNI_FUNC_PTR(env,SetStaticObjectField)(env, clazz, field, value.l);
break;
if (isReferenceTag(typeKey)) {
value.l = inStream_readObjectRef(env, in);
JNI_FUNC_PTR(env,SetStaticObjectField)(env, clazz, field, value.l);
if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
return JDWP_ERROR(INTERNAL);
}
return JDWP_ERROR(NONE);
}
switch (typeKey) {
case JDWP_TAG(BYTE):
value.b = inStream_readByte(in);
JNI_FUNC_PTR(env,SetStaticByteField)(env, clazz, field, value.b);
@ -109,10 +113,9 @@ readStaticFieldValue(JNIEnv *env, PacketInputStream *in, jclass clazz,
}
if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
serror = JDWP_ERROR(INTERNAL);
return JDWP_ERROR(INTERNAL);
}
return serror;
return JDWP_ERROR(NONE);
}
static jboolean

View File

@ -28,6 +28,7 @@
#include "commonRef.h"
#include "inStream.h"
#include "outStream.h"
#include "signature.h"
static jboolean
referenceType(PacketInputStream *in, PacketOutputStream *out)
@ -65,21 +66,22 @@ getValues(PacketInputStream *in, PacketOutputStream *out)
return JNI_TRUE;
}
static jvmtiError
readFieldValue(JNIEnv *env, PacketInputStream *in, jclass clazz,
jobject object, jfieldID field, char *signature)
{
jvalue value;
jvmtiError error;
switch (signature[0]) {
case JDWP_TAG(ARRAY):
case JDWP_TAG(OBJECT):
value.l = inStream_readObjectRef(env, in);
JNI_FUNC_PTR(env,SetObjectField)(env, object, field, value.l);
break;
jbyte typeKey = jdwpTag(signature);
if (isReferenceTag(typeKey)) {
value.l = inStream_readObjectRef(env, in);
JNI_FUNC_PTR(env,SetObjectField)(env, object, field, value.l);
if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
return AGENT_ERROR_JNI_EXCEPTION;
}
return JVMTI_ERROR_NONE;
}
switch (typeKey) {
case JDWP_TAG(BYTE):
value.b = inStream_readByte(in);
JNI_FUNC_PTR(env,SetByteField)(env, object, field, value.b);
@ -121,12 +123,10 @@ readFieldValue(JNIEnv *env, PacketInputStream *in, jclass clazz,
break;
}
error = JVMTI_ERROR_NONE;
if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
error = AGENT_ERROR_JNI_EXCEPTION;
return AGENT_ERROR_JNI_EXCEPTION;
}
return error;
return JVMTI_ERROR_NONE;
}
static jboolean

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -67,6 +67,7 @@
#include "classTrack.h"
#include "commonRef.h"
#include "debugLoop.h"
#include "signature.h"
static HandlerID requestIdCounter;
static jbyte currentSessionID;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,6 +28,7 @@
#include "eventHandler.h"
#include "threadControl.h"
#include "invoker.h"
#include "signature.h"
#define COMMAND_LOOP_THREAD_NAME "JDWP Event Helper Thread"
@ -479,7 +480,7 @@ handleFrameEventCommandSingle(JNIEnv* env, PacketOutputStream *out,
writeCodeLocation(out, command->clazz, command->method, command->location);
if (command->typeKey) {
(void)outStream_writeValue(env, out, command->typeKey, command->returnValue);
if (isObjectTag(command->typeKey) &&
if (isReferenceTag(command->typeKey) &&
command->returnValue.l != NULL) {
tossGlobalRef(env, &(command->returnValue.l));
}
@ -851,7 +852,7 @@ saveEventInfoRefs(JNIEnv *env, EventInfo *evinfo)
saveGlobalRef(env, clazz, pclazz);
}
sig = evinfo->u.field_modification.signature_type;
if ((sig == JDWP_TAG(ARRAY)) || (sig == JDWP_TAG(OBJECT))) {
if (isReferenceTag(sig)) {
if ( evinfo->u.field_modification.new_value.l != NULL ) {
pobject = &(evinfo->u.field_modification.new_value.l);
object = *pobject;
@ -904,7 +905,7 @@ tossEventInfoRefs(JNIEnv *env, EventInfo *evinfo)
tossGlobalRef(env, &(evinfo->u.field_modification.field_clazz));
}
sig = evinfo->u.field_modification.signature_type;
if ((sig == JDWP_TAG(ARRAY)) || (sig == JDWP_TAG(OBJECT))) {
if (isReferenceTag(sig)) {
if ( evinfo->u.field_modification.new_value.l != NULL ) {
tossGlobalRef(env, &(evinfo->u.field_modification.new_value.l));
}
@ -1108,7 +1109,7 @@ eventHelper_recordFrameEvent(jint id, jbyte suspendPolicy, EventIndex ei,
/*
* V or B C D F I J S Z L <classname> ; [ ComponentType
*/
if (isObjectTag(frameCommand->typeKey) &&
if (isReferenceTag(frameCommand->typeKey) &&
returnValue.l != NULL) {
saveGlobalRef(env, returnValue.l, &(frameCommand->returnValue.l));
} else {

View File

@ -424,7 +424,7 @@ inStream_clearError(PacketInputStream *stream)
}
jvalue
inStream_readValue(PacketInputStream *stream, jbyte *typeKeyPtr)
inStream_readValue(PacketInputStream *stream)
{
jvalue value;
jbyte typeKey = inStream_readByte(stream);
@ -473,9 +473,6 @@ inStream_readValue(PacketInputStream *stream, jbyte *typeKeyPtr)
break;
}
}
if (typeKeyPtr) {
*typeKeyPtr = typeKey;
}
return value;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -70,7 +70,7 @@ jstring inStream_readStringRef(JNIEnv *env, PacketInputStream *stream);
jarray inStream_readArrayRef(JNIEnv *env, PacketInputStream *stream);
char *inStream_readString(PacketInputStream *stream);
jvalue inStream_readValue(struct PacketInputStream *in, jbyte *typeKeyPtr);
jvalue inStream_readValue(struct PacketInputStream *in);
jdwpError inStream_skipBytes(PacketInputStream *stream, jint count);

View File

@ -28,6 +28,7 @@
#include "eventHandler.h"
#include "threadControl.h"
#include "outStream.h"
#include "signature.h"
static jrawMonitorID invokerLock;
@ -52,66 +53,21 @@ void invoker_unlock(void)
debugMonitorExit(invokerLock);
}
static jbyte
returnTypeTag(char *signature)
{
char *tagPtr = strchr(signature, SIGNATURE_END_ARGS);
JDI_ASSERT(tagPtr);
tagPtr++; /* 1st character after the end of args */
return (jbyte)*tagPtr;
}
static jbyte
nextArgumentTypeTag(void **cursor)
{
char *tagPtr = *cursor;
jbyte argumentTag = (jbyte)*tagPtr;
if (*tagPtr != SIGNATURE_END_ARGS) {
/* Skip any array modifiers */
while (*tagPtr == JDWP_TAG(ARRAY)) {
tagPtr++;
}
/* Skip class name */
if (*tagPtr == JDWP_TAG(OBJECT)) {
tagPtr = strchr(tagPtr, SIGNATURE_END_CLASS) + 1;
JDI_ASSERT(tagPtr);
} else {
/* Skip primitive sig */
tagPtr++;
}
}
*cursor = tagPtr;
return argumentTag;
}
static jbyte
firstArgumentTypeTag(char *signature, void **cursor)
{
JDI_ASSERT(signature[0] == SIGNATURE_BEGIN_ARGS);
*cursor = signature + 1; /* skip to the first arg */
return nextArgumentTypeTag(cursor);
}
/*
* Note: argument refs may be destroyed on out-of-memory error
*/
static jvmtiError
createGlobalRefs(JNIEnv *env, InvokeRequest *request)
{
jvmtiError error;
jvmtiError error = JVMTI_ERROR_NONE;
void *cursor = NULL;
jbyte argumentTag = 0;
jint argIndex = 0;
jvalue *argument = request->arguments;
jclass clazz = NULL;
jobject instance = NULL;
jint argIndex;
jbyte argumentTag;
jvalue *argument;
void *cursor;
jobject *argRefs = NULL;
error = JVMTI_ERROR_NONE;
if ( request->argumentCount > 0 ) {
/*LINTED*/
argRefs = jvmtiAllocate((jint)(request->argumentCount*sizeof(jobject)));
@ -138,15 +94,12 @@ createGlobalRefs(JNIEnv *env, InvokeRequest *request)
}
if ( error == JVMTI_ERROR_NONE && argRefs!=NULL ) {
argIndex = 0;
argumentTag = firstArgumentTypeTag(request->methodSignature, &cursor);
argument = request->arguments;
while (argumentTag != SIGNATURE_END_ARGS) {
methodSignature_init(request->methodSignature, &cursor);
while (methodSignature_nextArgumentExists(&cursor, &argumentTag)) {
if ( argIndex > request->argumentCount ) {
break;
}
if ((argumentTag == JDWP_TAG(OBJECT)) ||
(argumentTag == JDWP_TAG(ARRAY))) {
if (isReferenceTag(argumentTag)) {
/* Create a global ref for any non-null argument */
if (argument->l != NULL) {
saveGlobalRef(env, argument->l, &argRefs[argIndex]);
@ -158,7 +111,6 @@ createGlobalRefs(JNIEnv *env, InvokeRequest *request)
}
argument++;
argIndex++;
argumentTag = nextArgumentTypeTag(&cursor);
}
}
@ -175,16 +127,15 @@ createGlobalRefs(JNIEnv *env, InvokeRequest *request)
request->instance = instance;
if ( argRefs!=NULL ) {
argIndex = 0;
argumentTag = firstArgumentTypeTag(request->methodSignature, &cursor);
methodSignature_init(request->methodSignature, &cursor);
argument = request->arguments;
while ( argIndex < request->argumentCount ) {
if ((argumentTag == JDWP_TAG(OBJECT)) ||
(argumentTag == JDWP_TAG(ARRAY))) {
while ( methodSignature_nextArgumentExists(&cursor, &argumentTag) &&
argIndex < request->argumentCount ) {
if ( isReferenceTag(argumentTag) ) {
argument->l = argRefs[argIndex];
}
argument++;
argIndex++;
argumentTag = nextArgumentTypeTag(&cursor);
}
jvmtiDeallocate(argRefs);
}
@ -218,10 +169,11 @@ createGlobalRefs(JNIEnv *env, InvokeRequest *request)
static void
deleteGlobalArgumentRefs(JNIEnv *env, InvokeRequest *request)
{
void *cursor;
void *cursor = NULL;
jint argIndex = 0;
jbyte argumentTag = 0;
jvalue *argument = request->arguments;
jbyte argumentTag = firstArgumentTypeTag(request->methodSignature, &cursor);
methodSignature_init(request->methodSignature, &cursor);
if (request->clazz != NULL) {
tossGlobalRef(env, &(request->clazz));
@ -230,16 +182,15 @@ deleteGlobalArgumentRefs(JNIEnv *env, InvokeRequest *request)
tossGlobalRef(env, &(request->instance));
}
/* Delete global argument references */
while (argIndex < request->argumentCount) {
if ((argumentTag == JDWP_TAG(OBJECT)) ||
(argumentTag == JDWP_TAG(ARRAY))) {
while (methodSignature_nextArgumentExists(&cursor, &argumentTag) &&
argIndex < request->argumentCount) {
if (isReferenceTag(argumentTag)) {
if (argument->l != NULL) {
tossGlobalRef(env, &(argument->l));
}
}
argument++;
argIndex++;
argumentTag = nextArgumentTypeTag(&cursor);
}
}
@ -404,23 +355,23 @@ invokeConstructor(JNIEnv *env, InvokeRequest *request)
static void
invokeStatic(JNIEnv *env, InvokeRequest *request)
{
switch(returnTypeTag(request->methodSignature)) {
case JDWP_TAG(OBJECT):
case JDWP_TAG(ARRAY): {
jobject object;
JDI_ASSERT_MSG(request->clazz, "Request clazz null");
object = JNI_FUNC_PTR(env,CallStaticObjectMethodA)(env,
request->clazz,
request->method,
request->arguments);
request->returnValue.l = NULL;
if (object != NULL) {
saveGlobalRef(env, object, &(request->returnValue.l));
}
break;
jbyte returnType = methodSignature_returnTag(request->methodSignature);
if (isReferenceTag(returnType)) {
jobject object;
JDI_ASSERT_MSG(request->clazz, "Request clazz null");
object = JNI_FUNC_PTR(env,CallStaticObjectMethodA)(env,
request->clazz,
request->method,
request->arguments);
request->returnValue.l = NULL;
if (object != NULL) {
saveGlobalRef(env, object, &(request->returnValue.l));
}
return;
}
switch (returnType) {
case JDWP_TAG(BYTE):
request->returnValue.b = JNI_FUNC_PTR(env,CallStaticByteMethodA)(env,
request->clazz,
@ -493,22 +444,22 @@ invokeStatic(JNIEnv *env, InvokeRequest *request)
static void
invokeVirtual(JNIEnv *env, InvokeRequest *request)
{
switch(returnTypeTag(request->methodSignature)) {
case JDWP_TAG(OBJECT):
case JDWP_TAG(ARRAY): {
jobject object;
JDI_ASSERT_MSG(request->instance, "Request instance null");
object = JNI_FUNC_PTR(env,CallObjectMethodA)(env,
request->instance,
request->method,
request->arguments);
request->returnValue.l = NULL;
if (object != NULL) {
saveGlobalRef(env, object, &(request->returnValue.l));
}
break;
jbyte returnType = methodSignature_returnTag(request->methodSignature);
if (isReferenceTag(returnType)) {
jobject object;
JDI_ASSERT_MSG(request->instance, "Request instance null");
object = JNI_FUNC_PTR(env,CallObjectMethodA)(env,
request->instance,
request->method,
request->arguments);
request->returnValue.l = NULL;
if (object != NULL) {
saveGlobalRef(env, object, &(request->returnValue.l));
}
return;
}
switch (returnType) {
case JDWP_TAG(BYTE):
request->returnValue.b = JNI_FUNC_PTR(env,CallByteMethodA)(env,
request->instance,
@ -581,24 +532,24 @@ invokeVirtual(JNIEnv *env, InvokeRequest *request)
static void
invokeNonvirtual(JNIEnv *env, InvokeRequest *request)
{
switch(returnTypeTag(request->methodSignature)) {
case JDWP_TAG(OBJECT):
case JDWP_TAG(ARRAY): {
jobject object;
JDI_ASSERT_MSG(request->clazz, "Request clazz null");
JDI_ASSERT_MSG(request->instance, "Request instance null");
object = JNI_FUNC_PTR(env,CallNonvirtualObjectMethodA)(env,
request->instance,
request->clazz,
request->method,
request->arguments);
request->returnValue.l = NULL;
if (object != NULL) {
saveGlobalRef(env, object, &(request->returnValue.l));
}
break;
jbyte returnType = methodSignature_returnTag(request->methodSignature);
if (isReferenceTag(returnType)) {
jobject object;
JDI_ASSERT_MSG(request->clazz, "Request clazz null");
JDI_ASSERT_MSG(request->instance, "Request instance null");
object = JNI_FUNC_PTR(env,CallNonvirtualObjectMethodA)(env,
request->instance,
request->clazz,
request->method,
request->arguments);
request->returnValue.l = NULL;
if (object != NULL) {
saveGlobalRef(env, object, &(request->returnValue.l));
}
return;
}
switch (returnType) {
case JDWP_TAG(BYTE):
request->returnValue.b = JNI_FUNC_PTR(env,CallNonvirtualByteMethodA)(env,
request->instance,
@ -797,7 +748,7 @@ invoker_completeInvokeRequest(jthread thread)
*/
tag = specificTypeKey(env, request->returnValue.l);
} else {
tag = returnTypeTag(request->methodSignature);
tag = methodSignature_returnTag(request->methodSignature);
}
id = request->id;
exc = request->exception;
@ -805,9 +756,9 @@ invoker_completeInvokeRequest(jthread thread)
/* Release return value and exception references, but delay the release
* until after the return packet was sent. */
jbyte returnType = methodSignature_returnTag(request->methodSignature);
mustReleaseReturnValue = request->invokeType == INVOKE_CONSTRUCTOR ||
returnTypeTag(request->methodSignature) == JDWP_TAG(OBJECT) ||
returnTypeTag(request->methodSignature) == JDWP_TAG(ARRAY);
isReferenceTag(returnType);
}
/*

View File

@ -0,0 +1,112 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "util.h"
#include "signature.h"
/*
* JNI signature constants, beyond those defined in JVM_TYPE(*)
*/
#define SIGNATURE_BEGIN_ARGS '('
#define SIGNATURE_END_ARGS ')'
#define SIGNATURE_END_CLASS ';'
char* componentTypeSignature(const char *signature) {
jbyte typeKey = jdwpTag(signature);
JDI_ASSERT(isArrayTag(typeKey));
JVM_TYPE_ASSERT(signature[1]);
return (char*)&signature[1];
}
jbyte methodSignature_returnTag(char *signature)
{
char *tagPtr = strchr(signature, SIGNATURE_END_ARGS);
JDI_ASSERT(tagPtr);
tagPtr++; /* 1st character after the end of args */
JVM_TYPE_ASSERT((jbyte)*tagPtr);
return (jbyte)*tagPtr;
}
void methodSignature_init(char *signature, void **cursor)
{
JDI_ASSERT(signature[0] == SIGNATURE_BEGIN_ARGS);
*cursor = signature + 1; /* skip to the first arg */
}
jboolean methodSignature_nextArgumentExists(void **cursor, jbyte *argumentTag)
{
char *tagPtr = *cursor;
jbyte nextType = (jbyte)*tagPtr;
if (*tagPtr != SIGNATURE_END_ARGS) {
/* Skip any array modifiers */
while (*tagPtr == JDWP_TAG(ARRAY)) {
tagPtr++;
}
/* Skip class name */
if (*tagPtr == JDWP_TAG(OBJECT)) {
tagPtr = strchr(tagPtr, SIGNATURE_END_CLASS) + 1;
JDI_ASSERT(tagPtr);
} else {
/* Skip primitive sig */
tagPtr++;
}
}
*cursor = tagPtr;
if (nextType != SIGNATURE_END_ARGS) {
JVM_TYPE_ASSERT(nextType);
*argumentTag = nextType;
return JNI_TRUE;
}
return JNI_FALSE;
}
/*
* Convert the signature "Ljava/lang/Foo;" to a
* classname "java.lang.Foo" compatible with the pattern.
* Signature is overwritten in-place.
*/
void convertSignatureToClassname(char *convert)
{
char *p;
p = convert + 1;
while ((*p != ';') && (*p != '\0')) {
char c = *p;
if (c == '/') {
*(p-1) = '.';
} else if (c == '.') {
// class signature of a hidden class is "Ljava/lang/Foo.1234;"
// map to "java.lang.Foo/1234"
*(p-1) = '/';
} else {
*(p-1) = c;
}
p++;
}
*(p-1) = '\0';
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef JDWP_SIGNATURE_H
#define JDWP_SIGNATURE_H
#define JVM_TYPE_ASSERT(typeKey)\
JDI_ASSERT_MSG(JDWP_Tag_OBJECT == typeKey || \
JDWP_Tag_ARRAY == typeKey || \
JDWP_Tag_BOOLEAN == typeKey || \
JDWP_Tag_BYTE == typeKey || \
JDWP_Tag_CHAR == typeKey || \
JDWP_Tag_DOUBLE == typeKey || \
JDWP_Tag_FLOAT == typeKey || \
JDWP_Tag_INT == typeKey || \
JDWP_Tag_LONG == typeKey || \
JDWP_Tag_SHORT == typeKey || \
JDWP_Tag_VOID == typeKey, \
"Tag is not a JVM basic type")
static inline jbyte jdwpTag(const char *signature) {
JVM_TYPE_ASSERT(signature[0]);
return signature[0];
}
static inline jboolean isReferenceTag(jbyte typeKey) {
JVM_TYPE_ASSERT(typeKey);
return (typeKey == JDWP_TAG(OBJECT)) || (typeKey == JDWP_TAG(ARRAY));
}
static inline jboolean isArrayTag(jbyte typeKey) {
JVM_TYPE_ASSERT(typeKey);
return (typeKey == JDWP_TAG(ARRAY));
}
char* componentTypeSignature(const char *signature);
void convertSignatureToClassname(char *convert);
void methodSignature_init(char *signature, void **cursor);
jboolean methodSignature_nextArgumentExists(void **cursor, jbyte *argumentTag);
jbyte methodSignature_returnTag(char *signature);
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -32,6 +32,8 @@
#include "outStream.h"
#include "inStream.h"
#include "invoker.h"
#include "signature.h"
/* Global data area */
BackendGlobalData *gdata = NULL;
@ -171,6 +173,8 @@ getStaticMethod(JNIEnv *env, jclass clazz, const char * name, const char *signat
return method;
}
void
util_initialize(JNIEnv *env)
{
@ -343,26 +347,25 @@ writeFieldValue(JNIEnv *env, PacketOutputStream *out, jobject object,
outStream_setError(out, map2jdwpError(error));
return;
}
typeKey = signature[0];
typeKey = jdwpTag(signature);
jvmtiDeallocate(signature);
/*
* For primitive types, the type key is bounced back as is. Objects
* are handled in the switch statement below.
*/
if ((typeKey != JDWP_TAG(OBJECT)) && (typeKey != JDWP_TAG(ARRAY))) {
(void)outStream_writeByte(out, typeKey);
if (isReferenceTag(typeKey)) {
jobject value = JNI_FUNC_PTR(env,GetObjectField)(env, object, field);
(void)outStream_writeByte(out, specificTypeKey(env, value));
(void)outStream_writeObjectRef(env, out, value);
return;
}
switch (typeKey) {
case JDWP_TAG(OBJECT):
case JDWP_TAG(ARRAY): {
jobject value = JNI_FUNC_PTR(env,GetObjectField)(env, object, field);
(void)outStream_writeByte(out, specificTypeKey(env, value));
(void)outStream_writeObjectRef(env, out, value);
break;
}
/*
* For primitive types, the type key is bounced back as is.
*/
(void)outStream_writeByte(out, typeKey);
switch (typeKey) {
case JDWP_TAG(BYTE):
(void)outStream_writeByte(out,
JNI_FUNC_PTR(env,GetByteField)(env, object, field));
@ -418,26 +421,24 @@ writeStaticFieldValue(JNIEnv *env, PacketOutputStream *out, jclass clazz,
outStream_setError(out, map2jdwpError(error));
return;
}
typeKey = signature[0];
typeKey = jdwpTag(signature);
jvmtiDeallocate(signature);
/*
* For primitive types, the type key is bounced back as is. Objects
* are handled in the switch statement below.
*/
if ((typeKey != JDWP_TAG(OBJECT)) && (typeKey != JDWP_TAG(ARRAY))) {
(void)outStream_writeByte(out, typeKey);
if (isReferenceTag(typeKey)) {
jobject value = JNI_FUNC_PTR(env,GetStaticObjectField)(env, clazz, field);
(void)outStream_writeByte(out, specificTypeKey(env, value));
(void)outStream_writeObjectRef(env, out, value);
return;
}
/*
* For primitive types, the type key is bounced back as is.
*/
(void)outStream_writeByte(out, typeKey);
switch (typeKey) {
case JDWP_TAG(OBJECT):
case JDWP_TAG(ARRAY): {
jobject value = JNI_FUNC_PTR(env,GetStaticObjectField)(env, clazz, field);
(void)outStream_writeByte(out, specificTypeKey(env, value));
(void)outStream_writeObjectRef(env, out, value);
break;
}
case JDWP_TAG(BYTE):
(void)outStream_writeByte(out,
JNI_FUNC_PTR(env,GetStaticByteField)(env, clazz, field));
@ -570,7 +571,7 @@ sharedInvoke(PacketInputStream *in, PacketOutputStream *out)
return JNI_TRUE;
}
for (i = 0; (i < argumentCount) && !inStream_error(in); i++) {
arguments[i] = inStream_readValue(in, NULL);
arguments[i] = inStream_readValue(in);
}
if (inStream_error(in)) {
return JNI_TRUE;
@ -977,32 +978,6 @@ getSourceDebugExtension(jclass clazz, char **extensionPtr)
(gdata->jvmti, clazz, extensionPtr);
}
/*
* Convert the signature "Ljava/lang/Foo;" to a
* classname "java.lang.Foo" compatible with the pattern.
* Signature is overwritten in-place.
*/
void
convertSignatureToClassname(char *convert)
{
char *p;
p = convert + 1;
while ((*p != ';') && (*p != '\0')) {
char c = *p;
if (c == '/') {
*(p-1) = '.';
} else if (c == '.') {
// class signature of a hidden class is "Ljava/lang/Foo.1234;"
// map to "java.lang.Foo/1234"
*(p-1) = '/';
} else {
*(p-1) = c;
}
p++;
}
*(p-1) = '\0';
}
static void
handleInterrupt(void)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -251,13 +251,6 @@ typedef struct ObjectBatch {
jint count;
} ObjectBatch;
/*
* JNI signature constants, beyond those defined in JDWP_TAG(*)
*/
#define SIGNATURE_BEGIN_ARGS '('
#define SIGNATURE_END_ARGS ')'
#define SIGNATURE_END_CLASS ';'
/*
* Modifier flags for classes, fields, methods
*/
@ -291,7 +284,6 @@ jbyte referenceTypeTag(jclass clazz);
jbyte specificTypeKey(JNIEnv *env, jobject object);
jboolean isObjectTag(jbyte tag);
jvmtiError spawnNewThread(jvmtiStartFunction func, void *arg, char *name);
void convertSignatureToClassname(char *convert);
void writeCodeLocation(struct PacketOutputStream *out, jclass clazz,
jmethodID method, jlocation location);