Skip to content

Commit

Permalink
Fixed generic substitutions at class level for classloading types
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswhocodes committed Jan 4, 2015
1 parent 4798c94 commit ff3bf7a
Show file tree
Hide file tree
Showing 14 changed files with 460 additions and 221 deletions.
Expand Up @@ -203,6 +203,7 @@ public static final Set<String> getLambdaClassPrefixes()
public static final String S_DEFAULT = "default"; public static final String S_DEFAULT = "default";
public static final String S_FILE_COLON = "file:"; public static final String S_FILE_COLON = "file:";
public static final String S_DOT_CLASS = ".class"; public static final String S_DOT_CLASS = ".class";
public static final String S_GENERICS_WILDCARD = "<?>";


public static final String S_OPTIMIZED_VIRTUAL_CALL = "{optimized virtual_call}"; public static final String S_OPTIMIZED_VIRTUAL_CALL = "{optimized virtual_call}";


Expand Down Expand Up @@ -235,6 +236,7 @@ public static final Set<String> getLambdaClassPrefixes()


public static final String S_BYTECODE_MINOR_VERSION = "minor version:"; public static final String S_BYTECODE_MINOR_VERSION = "minor version:";
public static final String S_BYTECODE_MAJOR_VERSION = "major version:"; public static final String S_BYTECODE_MAJOR_VERSION = "major version:";
public static final String S_BYTECODE_SIGNATURE = "Signature:";


public static final String S_POLYMORPHIC_SIGNATURE = "PolymorphicSignature"; public static final String S_POLYMORPHIC_SIGNATURE = "PolymorphicSignature";


Expand Down
111 changes: 87 additions & 24 deletions src/main/java/org/adoptopenjdk/jitwatch/loader/BytecodeLoader.java
Expand Up @@ -5,27 +5,7 @@
*/ */
package org.adoptopenjdk.jitwatch.loader; package org.adoptopenjdk.jitwatch.loader;


import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_COLON; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.*;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_HASH;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_NEWLINE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.DEBUG_LOGGING_BYTECODE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_BYTECODE_CODE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_BYTECODE_CONSTANT_POOL;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_BYTECODE_EXCEPTIONS;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_BYTECODE_LINENUMBERTABLE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_BYTECODE_LOCALVARIABLETABLE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_BYTECODE_MAJOR_VERSION;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_BYTECODE_MINOR_VERSION;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_BYTECODE_RUNTIMEVISIBLEANNOTATIONS;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_BYTECODE_STACKMAPTABLE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_BYTECODE_STATIC_INITIALISER_SIGNATURE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_CLOSE_BRACE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_COLON;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_COMMA;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_DEFAULT;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_HASH;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_NEWLINE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_SEMICOLON;


import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
Expand Down Expand Up @@ -202,7 +182,7 @@ public static ClassBC parse(String fqClassName, String bytecode)
BytecodeSection section = BytecodeSection.NONE; BytecodeSection section = BytecodeSection.NONE;


MemberSignatureParts msp = null; MemberSignatureParts msp = null;

MemberBytecode memberBytecode = null; MemberBytecode memberBytecode = null;


while (pos < lines.length) while (pos < lines.length)
Expand Down Expand Up @@ -239,8 +219,10 @@ public static ClassBC parse(String fqClassName, String bytecode)
case NONE: case NONE:
if (couldBeMemberSignature(line)) if (couldBeMemberSignature(line))
{ {
msp = MemberSignatureParts.fromBytecodeSignature(fqClassName, line); msp = MemberSignatureParts.fromBytecodeSignature(fqClassName, line);


msp.setClassBC(classBytecode);

if (DEBUG_LOGGING_BYTECODE) if (DEBUG_LOGGING_BYTECODE)
{ {
logger.debug("New signature: {}", msp); logger.debug("New signature: {}", msp);
Expand All @@ -263,6 +245,10 @@ else if (line.startsWith(S_BYTECODE_MAJOR_VERSION))
int majorVersion = getVersionPart(line); int majorVersion = getVersionPart(line);
classBytecode.setMajorVersion(majorVersion); classBytecode.setMajorVersion(majorVersion);
} }
else if (line.startsWith(S_BYTECODE_SIGNATURE))
{
buildClassGenerics(line, classBytecode);
}
break; break;
case CODE: case CODE:
section = performCODE(fqClassName, classBytecode, builder, section, msp, memberBytecode, line); section = performCODE(fqClassName, classBytecode, builder, section, msp, memberBytecode, line);
Expand Down Expand Up @@ -304,6 +290,83 @@ else if (line.startsWith(S_BYTECODE_MAJOR_VERSION))
return classBytecode; return classBytecode;
} }


public static void buildClassGenerics(String line, ClassBC classBytecode)
{
StringBuilder keyBuilder = new StringBuilder();
StringBuilder valBuilder = new StringBuilder();

boolean inKey = false;
boolean inVal = false;

for (int i = 0; i < line.length(); i++)
{
char c = line.charAt(i);

if (c == C_OPEN_ANGLE)
{
inKey = true;
inVal = false;
}
else if (c == C_COLON)
{
if (inKey && !inVal)
{
inKey = false;
inVal = true;
}
}
else if (c == C_SEMICOLON)
{
if (!inKey && inVal)
{
String key = keyBuilder.toString();
String val = valBuilder.toString();

if (val.length() > 0)
{
val = val.substring(1); // string leading 'L'
val = val.replace(S_SLASH, S_DOT);
}

classBytecode.addGenericsMapping(key, val);

keyBuilder.setLength(0);
valBuilder.setLength(0);

inKey = true;
inVal = false;
}
}
else if (inKey)
{
keyBuilder.append(c);
}
else if (inVal)
{
valBuilder.append(c);
}
}

if (!inKey && inVal)
{
String key = keyBuilder.toString();
String val = valBuilder.toString();

if (val.length() > 0)
{
val = val.substring(1); // string leading 'L'
val = val.replace(S_SLASH, S_DOT);
}

classBytecode.addGenericsMapping(key, val);
keyBuilder.setLength(0);
valBuilder.setLength(0);

inKey = false;
inVal = false;
}
}

private static BytecodeSection performLINETABLE(String fqClassName, ClassBC classBytecode, StringBuilder builder, BytecodeSection section, private static BytecodeSection performLINETABLE(String fqClassName, ClassBC classBytecode, StringBuilder builder, BytecodeSection section,
MemberSignatureParts msp, MemberBytecode memberBytecode, String line) MemberSignatureParts msp, MemberBytecode memberBytecode, String line)
{ {
Expand Down
Expand Up @@ -119,10 +119,6 @@ public static String readFile(File sourceFile)
logger.error("Failed to read file: {}", sourceFile, ioe); logger.error("Failed to read file: {}", sourceFile, ioe);
} }
} }
else
{
logger.debug("File {} not found", sourceFile);
}


return result; return result;
} }
Expand Down
Expand Up @@ -125,7 +125,7 @@ private boolean returnTypeMatches(MemberSignatureParts msp) throws ClassNotFound
{ {
boolean matched = false; boolean matched = false;


String returnTypeClassName = msp.applyGenericSubstitutions(msp.getReturnType()); String returnTypeClassName = msp.applyGenericSubstitutionsForClassLoading(msp.getReturnType());


if (returnTypeClassName != null) if (returnTypeClassName != null)
{ {
Expand Down Expand Up @@ -208,7 +208,7 @@ private List<Class<?>> getClassesForParamTypes(MemberSignatureParts msp) throws


for (String param : msp.getParamTypes()) for (String param : msp.getParamTypes())
{ {
String paramClassName = msp.applyGenericSubstitutions(param); String paramClassName = msp.applyGenericSubstitutionsForClassLoading(param);


Class<?> clazz = ParseUtil.findClassForLogCompilationParameter(paramClassName); Class<?> clazz = ParseUtil.findClassForLogCompilationParameter(paramClassName);


Expand Down
Expand Up @@ -5,7 +5,7 @@
*/ */
package org.adoptopenjdk.jitwatch.model; package org.adoptopenjdk.jitwatch.model;


import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_CLOSE_ANGLE; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.*;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_COLON; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_COLON;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_COMMA; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_COMMA;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_DOT; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_DOT;
Expand Down Expand Up @@ -35,6 +35,7 @@
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;


import org.adoptopenjdk.jitwatch.model.bytecode.ClassBC;
import org.adoptopenjdk.jitwatch.util.ParseUtil; import org.adoptopenjdk.jitwatch.util.ParseUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
Expand All @@ -48,6 +49,7 @@ public class MemberSignatureParts
private String returnType; private String returnType;
private String memberName; private String memberName;
private List<String> paramTypeList; private List<String> paramTypeList;
private ClassBC classBytecode;


private static final Pattern PATTERN_ASSEMBLY_SIGNATURE = Pattern.compile("^(.*)\\s'(.*)'\\s'(\\(.*\\))(.*)'\\sin\\s'(.*)'"); private static final Pattern PATTERN_ASSEMBLY_SIGNATURE = Pattern.compile("^(.*)\\s'(.*)'\\s'(\\(.*\\))(.*)'\\sin\\s'(.*)'");


Expand Down Expand Up @@ -77,10 +79,15 @@ private static void addModifierMapping(int modifier)
private MemberSignatureParts() private MemberSignatureParts()
{ {
modifierList = new ArrayList<>(); modifierList = new ArrayList<>();
genericsMap = new LinkedHashMap<>(); genericsMap = new LinkedHashMap<>(); // preserve order
paramTypeList = new ArrayList<>(); paramTypeList = new ArrayList<>();
modifier = 0; modifier = 0;
} }

public void setClassBC(ClassBC classBytecode)
{
this.classBytecode = classBytecode;
}


private static void completeSignature(String origSig, MemberSignatureParts msp) private static void completeSignature(String origSig, MemberSignatureParts msp)
{ {
Expand Down Expand Up @@ -185,7 +192,7 @@ public static MemberSignatureParts fromBytecodeSignature(String fqClassName, Str
builder.append(S_OPEN_PARENTHESES).append(mod).append(S_SPACE).append(S_CLOSE_PARENTHESES).append(C_QUESTION); builder.append(S_OPEN_PARENTHESES).append(mod).append(S_SPACE).append(S_CLOSE_PARENTHESES).append(C_QUESTION);
} }


String regexGenerics = "(<.*> )?"; String regexGenerics = "(<[\\p{L}0-9_\\.\\$\\ ,/]+> )?";
String regexReturnType = "(.* )?"; // optional could be constructor String regexReturnType = "(.* )?"; // optional could be constructor
String regexMethodName = ParseUtil.METHOD_NAME_REGEX_GROUP; String regexMethodName = ParseUtil.METHOD_NAME_REGEX_GROUP;
String regexParams = "(\\(.*\\))"; String regexParams = "(\\(.*\\))";
Expand All @@ -197,6 +204,8 @@ public static MemberSignatureParts fromBytecodeSignature(String fqClassName, Str
builder.append(regexParams); builder.append(regexParams);
builder.append(regexRest); builder.append(regexRest);


//logger.info("\n{}\n{}", toParse, builder);

final Pattern patternBytecodeSignature = Pattern.compile(builder.toString()); final Pattern patternBytecodeSignature = Pattern.compile(builder.toString());


Matcher matcher = patternBytecodeSignature.matcher(toParse); Matcher matcher = patternBytecodeSignature.matcher(toParse);
Expand Down Expand Up @@ -452,14 +461,21 @@ public String getReturnType()
{ {
return returnType; return returnType;
} }

public String applyGenericSubstitutions(final String typeName) public String applyGenericSubstitutionsForClassLoading(final String typeName)
{ {
String result = typeName; String result = typeName;

if (typeName != null && genericsMap.containsKey(typeName)) if (typeName != null)
{ {
result = genericsMap.get(typeName); if (genericsMap.containsKey(typeName))
{
result = genericsMap.get(typeName);
}
else if (classBytecode != null && classBytecode.getGenericsMap().containsKey(typeName))
{
result = classBytecode.getGenericsMap().get(typeName);
}
} }


return result; return result;
Expand Down
Expand Up @@ -12,7 +12,9 @@


import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;


import org.adoptopenjdk.jitwatch.model.IMetaMember; import org.adoptopenjdk.jitwatch.model.IMetaMember;
import org.adoptopenjdk.jitwatch.model.MemberSignatureParts; import org.adoptopenjdk.jitwatch.model.MemberSignatureParts;
Expand All @@ -27,6 +29,8 @@ public class ClassBC
private int minorVersion; private int minorVersion;
private List<MemberBytecode> memberBytecodeList = new ArrayList<>(); private List<MemberBytecode> memberBytecodeList = new ArrayList<>();


private Map<String, String> classGenericsMap = new LinkedHashMap<>();

private LineTable compositeLineTable = null; private LineTable compositeLineTable = null;


private static final Logger logger = LoggerFactory.getLogger(ClassBC.class); private static final Logger logger = LoggerFactory.getLogger(ClassBC.class);
Expand Down Expand Up @@ -73,7 +77,17 @@ public LineTableEntry findLineTableEntryForSourceLine(int sourceLine)


return compositeLineTable.getEntryForSourceLine(sourceLine); return compositeLineTable.getEntryForSourceLine(sourceLine);
} }

public void addGenericsMapping(String key, String value)
{
classGenericsMap.put(key, value);
}


public Map<String, String> getGenericsMap()
{
return Collections.unmodifiableMap(classGenericsMap);
}

private void buildCompositeLineTable() private void buildCompositeLineTable()
{ {
compositeLineTable = new LineTable(); compositeLineTable = new LineTable();
Expand Down
Expand Up @@ -63,7 +63,7 @@ public class AttributeSuggestionWalker extends AbstractSuggestionVisitable imple
private static final String REASON_NO_STATIC_BINDING = "no static binding"; private static final String REASON_NO_STATIC_BINDING = "no static binding";
private static final String REASON_NOT_INLINEABLE = "not inlineable"; private static final String REASON_NOT_INLINEABLE = "not inlineable";
private static final String REASON_NOT_AN_ACCESSOR = "not an accessor"; private static final String REASON_NOT_AN_ACCESSOR = "not an accessor";

private static final String REASON_RECURSIVE_INLINING_IS_TOO_DEEP = "recursive inlining is too deep";


static static
{ {
Expand All @@ -76,6 +76,7 @@ public class AttributeSuggestionWalker extends AbstractSuggestionVisitable imple
scoreMap.put(REASON_EXEC_LESS_MIN_INLINING_THRESHOLD, 0.2); scoreMap.put(REASON_EXEC_LESS_MIN_INLINING_THRESHOLD, 0.2);
scoreMap.put(REASON_NO_STATIC_BINDING, 0.2); scoreMap.put(REASON_NO_STATIC_BINDING, 0.2);
scoreMap.put(REASON_NOT_INLINEABLE, 0.4); scoreMap.put(REASON_NOT_INLINEABLE, 0.4);
scoreMap.put(REASON_RECURSIVE_INLINING_IS_TOO_DEEP, 0.4);
scoreMap.put(REASON_NOT_AN_ACCESSOR, 0.1); scoreMap.put(REASON_NOT_AN_ACCESSOR, 0.1);
scoreMap.put(REASON_NEVER_EXECUTED, 0.0); scoreMap.put(REASON_NEVER_EXECUTED, 0.0);
scoreMap.put(REASON_NATIVE_METHOD, 0.0); scoreMap.put(REASON_NATIVE_METHOD, 0.0);
Expand All @@ -99,7 +100,11 @@ public class AttributeSuggestionWalker extends AbstractSuggestionVisitable imple


explanationMap explanationMap
.put(REASON_NOT_AN_ACCESSOR, .put(REASON_NOT_AN_ACCESSOR,
"The callee method is not an accessor"); "The callee method is not an accessor.");

explanationMap
.put(REASON_RECURSIVE_INLINING_IS_TOO_DEEP,
"The recursive inlining is too deep.");
} }


private static final int MIN_BRANCH_INVOCATIONS = 1000; private static final int MIN_BRANCH_INVOCATIONS = 1000;
Expand Down

0 comments on commit ff3bf7a

Please sign in to comment.