Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,11 @@ public static List<Class<?>> injectClasses(Map<String, byte[]> bytecode, Protect
private ClassInjector() {}

private static BiFunction classDefiner() {
if (defineClassGlue == null) {
BiFunction glue = defineClassGlue;
if (glue == null) {
throw new IllegalStateException("Class injection not enabled");
}
return defineClassGlue;
return glue;
}

private static volatile BiFunction defineClassGlue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ public final class ClassFile {
private static final int ACC_INTERFACE = 0x0200;
private static final int ACC_MODULE = 0x8000;

private static final byte[] JAVA_LANG_OBJECT_BYTES = JAVA_LANG_OBJECT.getBytes(US_ASCII);
private static final byte[] CONSTRUCTOR_BYTES = CONSTRUCTOR.getBytes(US_ASCII);
private static final byte[] SIMPLE_CALL_BYTES = SIMPLE_CALL.getBytes(US_ASCII);

// attribute header for annotations that are visible at runtime
private static final byte[] RUNTIME_ANNOTATIONS = "RuntimeVisibleAnnotations".getBytes(US_ASCII);

Expand Down Expand Up @@ -210,10 +214,11 @@ private static ClassHeader parse(byte[] bytecode, int offset, boolean onlyHeader
if ((access & ACC_INTERFACE) != 0) {
superName = JAVA_LANG_OBJECT;
} else if (access != ACC_MODULE) {
superName = utf(bytecode, cp[cp[u2(bytecode, cursor)]]);
if (JAVA_LANG_OBJECT.equals(superName)) {
superName = JAVA_LANG_OBJECT;
}
int superNameOffset = cp[cp[u2(bytecode, cursor)]];
superName =
utfEquals(bytecode, superNameOffset, JAVA_LANG_OBJECT_BYTES)
? JAVA_LANG_OBJECT
: utf(bytecode, superNameOffset);
} else {
superName = null;
}
Expand Down Expand Up @@ -266,6 +271,8 @@ private static ClassHeader parse(byte[] bytecode, int offset, boolean onlyHeader
fields = NO_FIELDS;
}

final Map<UtfKey, String> ofInterest = annotationsOfInterest;

// optional list of methods
MethodOutline[] methods;
int methodsCount = u2(bytecode, cursor);
Expand All @@ -275,18 +282,20 @@ private static ClassHeader parse(byte[] bytecode, int offset, boolean onlyHeader
for (int i = 0; i < methodsCount; i++) {
int methodAccess = u2(bytecode, cursor);
cursor += 2;
String methodName = utf(bytecode, cp[u2(bytecode, cursor)]);
if (CONSTRUCTOR.equals(methodName)) {
methodName = CONSTRUCTOR;
}
int methodNameOffset = cp[u2(bytecode, cursor)];
String methodName =
utfEquals(bytecode, methodNameOffset, CONSTRUCTOR_BYTES)
? CONSTRUCTOR
: utf(bytecode, methodNameOffset);
cursor += 2;
String descriptor = utf(bytecode, cp[u2(bytecode, cursor)]);
if (SIMPLE_CALL.equals(descriptor)) {
descriptor = SIMPLE_CALL;
}
int descriptorOffset = cp[u2(bytecode, cursor)];
String descriptor =
utfEquals(bytecode, descriptorOffset, SIMPLE_CALL_BYTES)
? SIMPLE_CALL
: utf(bytecode, descriptorOffset);
cursor += 2;
String[] annotations = NO_ANNOTATIONS;
Map<UtfKey, String> ofInterest = annotationsOfInterest;
boolean scanAnnotations = ofInterest != null;
int attributesCount = u2(bytecode, cursor);
cursor += 2;
for (int j = 0; j < attributesCount; j++) {
Expand All @@ -295,9 +304,9 @@ private static ClassHeader parse(byte[] bytecode, int offset, boolean onlyHeader
int attributeLength = u4(bytecode, cursor);
cursor += 4;
// only interested in the attribute that lists runtime visible annotations
if (ofInterest != null && utfEquals(bytecode, cp[nameIndex], RUNTIME_ANNOTATIONS)) {
if (scanAnnotations && utfEquals(bytecode, cp[nameIndex], RUNTIME_ANNOTATIONS)) {
annotations = parseAnnotations(ofInterest, bytecode, cursor, cp);
ofInterest = null; // there's at most one of these attributes per-table
scanAnnotations = false; // there's at most one of these attributes per-table
}
cursor += attributeLength; // jump to end of attribute
}
Expand All @@ -309,7 +318,7 @@ private static ClassHeader parse(byte[] bytecode, int offset, boolean onlyHeader
}

String[] annotations = NO_ANNOTATIONS;
Map<UtfKey, String> ofInterest = annotationsOfInterest;
boolean scanAnnotations = ofInterest != null;
int attributesCount = u2(bytecode, cursor);
cursor += 2;
for (int j = 0; j < attributesCount; j++) {
Expand All @@ -318,9 +327,9 @@ private static ClassHeader parse(byte[] bytecode, int offset, boolean onlyHeader
int attributeLength = u4(bytecode, cursor);
cursor += 4;
// only interested in the attribute that lists runtime visible annotations
if (ofInterest != null && utfEquals(bytecode, cp[nameIndex], RUNTIME_ANNOTATIONS)) {
if (scanAnnotations && utfEquals(bytecode, cp[nameIndex], RUNTIME_ANNOTATIONS)) {
annotations = parseAnnotations(ofInterest, bytecode, cursor, cp);
ofInterest = null; // there's at most one of these attributes per-table
scanAnnotations = false; // there's at most one of these attributes per-table
}
cursor += attributeLength; // jump to end of attribute
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ TypeString typeString() {
}
int start = 1;
int end = descriptor.length() - 1;
if (typeStringHash == 0) {
typeStringHash = TypeString.computeHash(descriptor, start, end);
int hash = typeStringHash;
if (hash == 0) {
typeStringHash = hash = TypeString.computeHash(descriptor, start, end);
}
return new TypeString(descriptor, start, end, typeStringHash);
return new TypeString(descriptor, start, end, hash);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,14 @@ TypeString returnTypeString() {

/** Gets a previously cached {@link TypeString} hash; otherwise computes and caches a new hash. */
private int getHash(int typeStringIndex, int start, int end) {
if (typeStringHashes == null) {
int[] hashes = typeStringHashes;
if (hashes == null) {
// allow for one hash per parameter, plus one for return type
typeStringHashes = new int[descriptorBoundaries.length + 1];
typeStringHashes = hashes = new int[descriptorBoundaries.length + 1];
}
int hash = typeStringHashes[typeStringIndex];
int hash = hashes[typeStringIndex];
if (hash == 0) {
typeStringHashes[typeStringIndex] = hash = TypeString.computeHash(descriptor, start, end);
hashes[typeStringIndex] = hash = TypeString.computeHash(descriptor, start, end);
}
return hash;
}
Expand All @@ -119,10 +120,11 @@ private int getHash(int typeStringIndex, int start, int end) {
* parameters then the return descriptor always starts at index 2.)
*/
int[] descriptorBoundaries() {
if (descriptorBoundaries == null) {
descriptorBoundaries = parseBoundaries(descriptor);
int[] boundaries = descriptorBoundaries;
if (boundaries == null) {
descriptorBoundaries = boundaries = parseBoundaries(descriptor);
}
return descriptorBoundaries;
return boundaries;
}

/** Partitions method descriptor into boundaries between each parameter/return descriptor. */
Expand Down
Loading