Merge remote-tracking branch

'origin/GP-4712_emteere_PR-6650_sad-dev_ParallelPerf' (Closes #6650,
Closes #6649, #2791)
This commit is contained in:
Ryan Kurtz
2024-08-08 11:32:13 -04:00
3 changed files with 37 additions and 35 deletions

View File

@@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -16,19 +15,19 @@
*/ */
package ghidra.app.plugin.processors.sleigh; package ghidra.app.plugin.processors.sleigh;
import ghidra.program.model.address.Address;
import ghidra.program.model.lang.*;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Arrays; import java.util.Arrays;
import generic.stl.Pair;
import ghidra.program.model.address.Address;
import ghidra.program.model.lang.*;
public class ContextCache { public class ContextCache {
private int context_size = 0; private int context_size = 0;
private Register contextBaseRegister = null; private Register contextBaseRegister = null;
private BigInteger lastContextValue; Pair <BigInteger, int []> lastValue = null;
private int[] lastContextWords;
public ContextCache() { public ContextCache() {
} }
@@ -57,12 +56,15 @@ public class ContextCache {
} }
} }
private synchronized int[] getWords(BigInteger value) { private int[] getWords(BigInteger value) {
if (value.equals(lastContextValue)) {
return lastContextWords;
}
Pair <BigInteger, int []> lastValueTmp = lastValue;
if (lastValueTmp != null && value.equals(lastValueTmp.first)) {
return lastValueTmp.second;
}
int[] words = new int[context_size]; int[] words = new int[context_size];
byte[] bytes = value.toByteArray(); byte[] bytes = value.toByteArray();
int byteIndexDiff = context_size * 4 - bytes.length; int byteIndexDiff = context_size * 4 - bytes.length;
for (int i = 0; i < context_size; i++) { for (int i = 0; i < context_size; i++) {
@@ -73,8 +75,10 @@ public class ContextCache {
} }
words[i] = word; words[i] = word;
} }
lastContextValue = value;
lastContextWords = words; lastValueTmp = new Pair<BigInteger, int[]>(value, words);
lastValue = lastValueTmp;
return words; return words;
} }

View File

@@ -20,6 +20,7 @@ import static ghidra.pcode.utils.SlaFormat.*;
import java.io.*; import java.io.*;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -88,7 +89,7 @@ public class SleighLanguage implements Language {
/** /**
* Cached instruction prototypes * Cached instruction prototypes
*/ */
private LinkedHashMap<Integer, SleighInstructionPrototype> instructProtoMap; private ConcurrentHashMap<Integer, SleighInstructionPrototype> instructProtoMap;
private DecisionNode root = null; private DecisionNode root = null;
/** /**
* table of AddressSpaces * table of AddressSpaces
@@ -148,7 +149,7 @@ public class SleighLanguage implements Language {
buildVolatileSymbolAddresses(); buildVolatileSymbolAddresses();
xrefRegisters(); xrefRegisters();
instructProtoMap = new LinkedHashMap<>(); instructProtoMap = new ConcurrentHashMap<>();
initParallelHelper(); initParallelHelper();
} }
@@ -374,20 +375,15 @@ public class SleighLanguage implements Language {
new SleighInstructionPrototype(this, buf, context, contextcache, inDelaySlot, null); new SleighInstructionPrototype(this, buf, context, contextcache, inDelaySlot, null);
Integer hashcode = newProto.hashCode(); Integer hashcode = newProto.hashCode();
if (!instructProtoMap.containsKey(hashcode)) { // get existing proto and use it
newProto.cacheInfo(buf, context, true); // if doesn't exist in map, cache info and store new proto
} res = instructProtoMap.computeIfAbsent(hashcode, h -> {
newProto.cacheInfo(buf, context, true);
synchronized (instructProtoMap) { return newProto;
res = instructProtoMap.get(hashcode); });
if (res == null) { // We have a prototype we have never seen
// before, build it fully if (inDelaySlot && res.hasDelaySlots()) {
instructProtoMap.put(hashcode, newProto); throw new NestedDelaySlotException();
res = newProto;
}
if (inDelaySlot && res.hasDelaySlots()) {
throw new NestedDelaySlotException();
}
} }
} }
catch (MemoryAccessException e) { catch (MemoryAccessException e) {

View File

@@ -50,6 +50,7 @@ public class HighFunction extends PcodeSyntaxTree {
private GlobalSymbolMap globalSymbols; private GlobalSymbolMap globalSymbols;
private List<JumpTable> jumpTables; private List<JumpTable> jumpTables;
private List<DataTypeSymbol> protoOverrides; private List<DataTypeSymbol> protoOverrides;
private Address entryPoint;
/** /**
* @param function function associated with the higher level function abstraction. * @param function function associated with the higher level function abstraction.
@@ -64,6 +65,7 @@ public class HighFunction extends PcodeSyntaxTree {
this.language = language; this.language = language;
this.compilerSpec = compilerSpec; this.compilerSpec = compilerSpec;
AddressSpace stackSpace = function.getProgram().getAddressFactory().getStackSpace(); AddressSpace stackSpace = function.getProgram().getAddressFactory().getStackSpace();
entryPoint = function.getEntryPoint();
localSymbols = new LocalSymbolMap(this, stackSpace); localSymbols = new LocalSymbolMap(this, stackSpace);
globalSymbols = new GlobalSymbolMap(this); globalSymbols = new GlobalSymbolMap(this);
proto = new FunctionPrototype(localSymbols, function); proto = new FunctionPrototype(localSymbols, function);
@@ -87,7 +89,7 @@ public class HighFunction extends PcodeSyntaxTree {
if (func instanceof FunctionDB) { if (func instanceof FunctionDB) {
return func.getSymbol().getID(); return func.getSymbol().getID();
} }
return func.getProgram().getSymbolTable().getDynamicSymbolID(func.getEntryPoint()); return func.getProgram().getSymbolTable().getDynamicSymbolID(entryPoint);
} }
/** /**
@@ -255,7 +257,7 @@ public class HighFunction extends PcodeSyntaxTree {
} }
if (subel == ELEM_ADDR.id()) { if (subel == ELEM_ADDR.id()) {
Address addr = AddressXML.decode(decoder); Address addr = AddressXML.decode(decoder);
if (!func.getEntryPoint().equals(addr)) { if (!entryPoint.equals(addr)) {
throw new DecoderException("Mismatched address in function tag"); throw new DecoderException("Mismatched address in function tag");
} }
} }
@@ -300,7 +302,7 @@ public class HighFunction extends PcodeSyntaxTree {
private void decodeJumpTableList(Decoder decoder) throws DecoderException { private void decodeJumpTableList(Decoder decoder) throws DecoderException {
int el = decoder.openElement(ELEM_JUMPTABLELIST); int el = decoder.openElement(ELEM_JUMPTABLELIST);
while (decoder.peekElement() != 0) { while (decoder.peekElement() != 0) {
JumpTable table = new JumpTable(func.getEntryPoint().getAddressSpace()); JumpTable table = new JumpTable(entryPoint.getAddressSpace());
table.decode(decoder); table.decode(decoder);
if (!table.isEmpty()) { if (!table.isEmpty()) {
if (jumpTables == null) { if (jumpTables == null) {
@@ -318,10 +320,10 @@ public class HighFunction extends PcodeSyntaxTree {
pcaddr = rep.getPCAddress(); pcaddr = rep.getPCAddress();
if (pcaddr == Address.NO_ADDRESS) { if (pcaddr == Address.NO_ADDRESS) {
try { try {
pcaddr = func.getEntryPoint().add(-1); pcaddr = entryPoint.add(-1);
} }
catch (AddressOutOfBoundsException e) { catch (AddressOutOfBoundsException e) {
pcaddr = func.getEntryPoint(); pcaddr = entryPoint;
} }
} }
} }
@@ -446,7 +448,7 @@ public class HighFunction extends PcodeSyntaxTree {
encoder.writeBool(ATTRIB_NORETURN, true); encoder.writeBool(ATTRIB_NORETURN, true);
} }
if (entryPoint == null) { if (entryPoint == null) {
AddressXML.encode(encoder, func.getEntryPoint()); AddressXML.encode(encoder, this.entryPoint);
} }
else { else {
AddressXML.encode(encoder, entryPoint); // Address is forced on XML AddressXML.encode(encoder, entryPoint); // Address is forced on XML