Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JITWatch initial support for ARM CPUs
- Loading branch information
1 parent
1120f1d
commit 4d1d360
Showing
22 changed files
with
1,073 additions
and
546 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
185 changes: 185 additions & 0 deletions
185
core/src/main/java/org/adoptopenjdk/jitwatch/model/assembly/AbstractAssemblyParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,185 @@ | |||
package org.adoptopenjdk.jitwatch.model.assembly; | |||
|
|||
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.DEBUG_LOGGING_ASSEMBLY; | |||
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.NATIVE_CODE_ENTRY_POINT; | |||
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_ENTITY_APOS; | |||
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_HASH; | |||
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_HEX_POSTFIX; | |||
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_HEX_PREFIX; | |||
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_NEWLINE; | |||
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_OPEN_SQUARE_BRACKET; | |||
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_QUOTE; | |||
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_SEMICOLON; | |||
|
|||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
|
|||
public abstract class AbstractAssemblyParser implements IAssemblyParser | |||
{ | |||
protected static final Logger logger = LoggerFactory.getLogger(AbstractAssemblyParser.class); | |||
|
|||
protected Architecture architecture; | |||
|
|||
public AbstractAssemblyParser(Architecture architecture) | |||
{ | |||
this.architecture = architecture; | |||
} | |||
|
|||
public Architecture getArchitecture() | |||
{ | |||
return architecture; | |||
} | |||
|
|||
// TODO this is too much work | |||
// save the string blocks and parse on demand | |||
public AssemblyMethod parseAssembly(final String assemblyString) | |||
{ | |||
final AssemblyLabels labels = new AssemblyLabels(); | |||
|
|||
String[] lines = assemblyString.split(S_NEWLINE); | |||
|
|||
StringBuilder headerBuilder = new StringBuilder(); | |||
|
|||
AssemblyBlock currentBlock = new AssemblyBlock(); | |||
currentBlock.setTitle(NATIVE_CODE_ENTRY_POINT); | |||
|
|||
AssemblyInstruction lastInstruction = null; | |||
|
|||
String lastLine = null; | |||
|
|||
AssemblyMethod method = null; | |||
|
|||
for (int i = 0; i < lines.length; i++) | |||
{ | |||
if (DEBUG_LOGGING_ASSEMBLY) | |||
{ | |||
logger.debug("line: '{}'", lines[i]); | |||
} | |||
|
|||
if (i == 0) | |||
{ | |||
method = new AssemblyMethod(lines[i], architecture); | |||
} | |||
|
|||
String line = lines[i].replace(S_ENTITY_APOS, S_QUOTE); | |||
line = line.replaceFirst("^ +", ""); | |||
|
|||
if (line.startsWith(S_HASH)) | |||
{ | |||
if (DEBUG_LOGGING_ASSEMBLY) | |||
{ | |||
logger.debug("Assembly header: {}", line); | |||
} | |||
|
|||
headerBuilder.append(line).append(S_NEWLINE); | |||
} | |||
else if (line.startsWith(S_OPEN_SQUARE_BRACKET)) | |||
{ | |||
if (DEBUG_LOGGING_ASSEMBLY) | |||
{ | |||
logger.debug("new AssemblyBlock: {}", line); | |||
} | |||
|
|||
method.addBlock(currentBlock); | |||
currentBlock = new AssemblyBlock(); | |||
currentBlock.setTitle(line); | |||
} | |||
else if (line.startsWith(S_SEMICOLON)) | |||
{ | |||
if (DEBUG_LOGGING_ASSEMBLY) | |||
{ | |||
logger.debug("Extended comment? '{}'", line); | |||
} | |||
|
|||
if (lastInstruction != null) | |||
{ | |||
lastInstruction.addCommentLine(line); | |||
} | |||
} | |||
else | |||
{ | |||
AssemblyInstruction instr = createInstruction(labels, line); | |||
|
|||
if (instr == null && lastLine.trim().startsWith(S_HASH) && !line.startsWith(S_HEX_PREFIX) | |||
&& !line.contains(' ' + S_HEX_PREFIX)) | |||
{ | |||
// remove last newline | |||
headerBuilder.setLength(headerBuilder.length() - S_NEWLINE.length()); | |||
|
|||
headerBuilder.append(line).append(S_NEWLINE); | |||
|
|||
// update untrimmedLine since it is used to update | |||
// lastUntrimmedLine at end of loop | |||
line = lastLine + line; | |||
} | |||
else if (instr == null && lastLine.trim().startsWith(S_SEMICOLON) && lastInstruction != null) | |||
{ | |||
lastInstruction.appendToLastCommentLine(line); | |||
|
|||
// update untrimmedLine since it is used to update | |||
// lastUntrimmedLine at end of loop | |||
line = lastLine + line; | |||
} | |||
else | |||
{ | |||
boolean replaceLast = false; | |||
if (instr == null && i < lines.length - 1) | |||
{ | |||
// try appending current and next lines together | |||
String nextUntrimmedLine = lines[i + 1].replace(S_ENTITY_APOS, S_QUOTE); | |||
|
|||
instr = createInstruction(labels, line + nextUntrimmedLine); | |||
|
|||
if (instr != null) | |||
{ | |||
i++; | |||
} | |||
} | |||
|
|||
if (instr == null && lastInstruction != null) | |||
{ | |||
// try appending last and current lines together | |||
instr = createInstruction(labels, lastLine + line); | |||
if (instr != null) | |||
{ | |||
replaceLast = true; | |||
} | |||
} | |||
|
|||
if (instr != null) | |||
{ | |||
if (replaceLast) | |||
{ | |||
currentBlock.replaceLastInstruction(instr); | |||
} | |||
else | |||
{ | |||
currentBlock.addInstruction(instr); | |||
} | |||
|
|||
lastInstruction = instr; | |||
} | |||
else | |||
{ | |||
logger.error("Could not parse assembly: {}", line); | |||
} | |||
} | |||
} | |||
lastLine = line; | |||
} | |||
|
|||
method.addBlock(currentBlock); | |||
|
|||
method.setHeader(headerBuilder.toString()); | |||
|
|||
labels.buildLabels(); | |||
|
|||
return method; | |||
} | |||
|
|||
@Override | |||
public boolean isAddress(String mnemonic, String operand) | |||
{ | |||
return (operand.startsWith(S_HEX_PREFIX) || operand.endsWith(S_HEX_POSTFIX)) && isJump(mnemonic); | |||
} | |||
} |
37 changes: 34 additions & 3 deletions
37
core/src/main/java/org/adoptopenjdk/jitwatch/model/assembly/Architecture.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,11 +1,42 @@ | |||
/* | |||
* Copyright (c) 2017 Chris Newland. | |||
* Licensed under https://github.com/AdoptOpenJDK/jitwatch/blob/master/LICENSE-BSD | |||
* Instructions: https://github.com/AdoptOpenJDK/jitwatch/wiki | |||
*/ | |||
package org.adoptopenjdk.jitwatch.model.assembly; | package org.adoptopenjdk.jitwatch.model.assembly; | ||
|
|
||
import org.adoptopenjdk.jitwatch.util.StringUtil; | |||
|
|||
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_APOSTROPHE; | |||
|
|||
public enum Architecture | public enum Architecture | ||
{ | { | ||
X86_32, X86_64, ARM_32, ARM_64; | X86_32, X86_64, ARM_32, ARM_64; | ||
|
|
||
private static final String ARCH_X86_32 = "i386"; | |||
private static final String ARCH_X86_64 = "i386:x86-64"; | |||
private static final String ARCH_ARM_32 = "arm"; | |||
private static final String ARCH_ARM_64 = "arm-64"; | |||
|
|||
public static Architecture parseFromLogLine(String line) | public static Architecture parseFromLogLine(String line) | ||
{ | { | ||
return X86_64; | String arch = StringUtil.getSubstringBetween(line, S_APOSTROPHE, S_APOSTROPHE); | ||
|
|||
if (arch != null) | |||
{ | |||
switch (arch) | |||
{ | |||
case ARCH_X86_32: | |||
return X86_32; | |||
case ARCH_X86_64: | |||
return X86_64; | |||
case ARCH_ARM_32: | |||
return ARM_32; | |||
case ARCH_ARM_64: | |||
return ARM_64; | |||
} | |||
} | |||
|
|||
return null; | |||
} | } | ||
} | } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.