Merge remote-tracking branch 'origin/GP_1417_DataDB_lazylength'

This commit is contained in:
ghidra1 2021-11-09 20:11:29 -05:00
commit 216ef3a414
3 changed files with 81 additions and 40 deletions

View file

@ -2825,31 +2825,37 @@ public class CodeManager implements ErrorHandler, ManagerDB {
}
Address getDefinedAddressAfter(Address address) {
DBRecord dataRec = null;
DBRecord instRec = null;
lock.acquire();
try {
dataRec = dataAdapter.getRecordAfter(address);
instRec = instAdapter.getRecordAfter(address);
DBRecord dataRec = null;
DBRecord instRec = null;
try {
dataRec = dataAdapter.getRecordAfter(address);
instRec = instAdapter.getRecordAfter(address);
}
catch (IOException e) {
program.dbError(e);
return null;
}
if (dataRec == null && instRec == null) {
return null;
}
if (dataRec == null) {
return addrMap.decodeAddress(instRec.getKey());
}
if (instRec == null) {
return addrMap.decodeAddress(dataRec.getKey());
}
Address dataAddr = addrMap.decodeAddress(dataRec.getKey());
Address instAddr = addrMap.decodeAddress(instRec.getKey());
if (dataAddr.compareTo(instAddr) < 0) {
return dataAddr;
}
return instAddr;
}
catch (IOException e) {
program.dbError(e);
return null;
finally {
lock.release();
}
if (dataRec == null && instRec == null) {
return null;
}
if (dataRec == null) {
return addrMap.decodeAddress(instRec.getKey());
}
if (instRec == null) {
return addrMap.decodeAddress(dataRec.getKey());
}
Address dataAddr = addrMap.decodeAddress(dataRec.getKey());
Address instAddr = addrMap.decodeAddress(instRec.getKey());
if (dataAddr.compareTo(instAddr) < 0) {
return dataAddr;
}
return instAddr;
}
///////////////////////////////////////////////////////////////////
@ -3117,12 +3123,16 @@ public class CodeManager implements ErrorHandler, ManagerDB {
}
int getLength(Address addr) {
lock.acquire();
try {
return lengthMgr.getInt(addr);
}
catch (NoValueException e) {
return -1;
}
finally {
lock.release();
}
}
private InstructionDB getInstructionDB(long addr) throws IOException {

View file

@ -284,7 +284,7 @@ abstract class CodeUnitDB extends DatabaseObject implements CodeUnit, ProcessorC
public Address getMaxAddress() {
refreshIfNeeded();
if (endAddr == null) {
endAddr = length == 0 ? address : address.add(length - 1);
endAddr = getLength() == 0 ? address : address.add(getLength() - 1);
}
return endAddr;
}
@ -669,9 +669,10 @@ abstract class CodeUnitDB extends DatabaseObject implements CodeUnit, ProcessorC
try {
checkIsValid();
populateByteArray();
byte[] b = new byte[length];
if (bytes.length < length) {
if (program.getMemory().getBytes(address, b) != length) {
int len = getLength();
byte[] b = new byte[len];
if (bytes.length < len) {
if (program.getMemory().getBytes(address, b) != len) {
throw new MemoryAccessException("Couldn't get all bytes for CodeUnit");
}
}
@ -829,7 +830,7 @@ abstract class CodeUnitDB extends DatabaseObject implements CodeUnit, ProcessorC
}
protected int getPreferredCacheLength() {
return length;
return getLength();
}
private void validateOpIndex(int opIndex) {

View file

@ -71,10 +71,7 @@ class DataDB extends CodeUnitDB implements Data {
baseDataType = getBaseDataType(dataType);
defaultSettings = dataType.getDefaultSettings();
computeLength();
if (length < 0) {
Msg.error(this, " bad bad");
}
length = -1; // lazy compute
}
protected static DataType getBaseDataType(DataType dataType) {
@ -121,12 +118,27 @@ class DataDB extends CodeUnitDB implements Data {
dataType = dt;
baseDataType = getBaseDataType(dataType);
defaultSettings = dataType.getDefaultSettings();
computeLength();
length = -1; // set to compute lazily later
bytes = null;
return false;
}
@Override
public int getLength() {
if (length == -1) {
computeLength();
}
return length;
}
private void computeLength() {
length = dataType.getLength();
// undefined will never change their size
if (dataType instanceof Undefined) {
return;
}
if (length < 1) {
length = codeMgr.getLength(address);
}
@ -139,6 +151,11 @@ class DataDB extends CodeUnitDB implements Data {
}
}
// no need to do all that follow on checking when length == 1
if (length == 1) {
return;
}
// FIXME Trying to get Data to display for External.
if (address.isExternalAddress()) { // FIXME
return; // FIXME
@ -165,11 +182,24 @@ class DataDB extends CodeUnitDB implements Data {
}
}
// if this is not a component where the size could change and
// the length restricted by the following instruction/data item, assume
// the createData method stopped fixed code units that won't fit from being added
//
// TODO: If the data organization for a program changes, for example a long was 32-bits
// and is changed to 64-bits, that could cause an issue.
// If the data organization changing could be detected, this could be done.
//
// if (!(baseDataType instanceof Composite || baseDataType instanceof ArrayDataType)) {
// return;
// }
// This is potentially expensive! So only do if necessary
// see if the datatype length is restricted by a following codeunit
Address nextAddr = codeMgr.getDefinedAddressAfter(address);
if ((nextAddr != null) && nextAddr.compareTo(endAddress) <= 0) {
length = (int) nextAddr.subtract(address);
}
bytes = null;
}
@Override
@ -269,7 +299,7 @@ class DataDB extends CodeUnitDB implements Data {
lock.acquire();
try {
checkIsValid();
return dataType.getRepresentation(this, this, length);
return dataType.getRepresentation(this, this, getLength());
}
finally {
lock.release();
@ -501,7 +531,7 @@ class DataDB extends CodeUnitDB implements Data {
lock.acquire();
try {
checkIsValid();
if (offset < 0 || offset > length) {
if (offset < 0 || offset > getLength()) {
return null;
}
@ -538,7 +568,7 @@ class DataDB extends CodeUnitDB implements Data {
lock.acquire();
try {
checkIsValid();
if (offset < 0 || offset >= length) {
if (offset < 0 || offset >= getLength()) {
return null;
}
if (baseDataType instanceof Array) {
@ -662,7 +692,7 @@ class DataDB extends CodeUnitDB implements Data {
lock.acquire();
try {
checkIsValid();
if (length < dataType.getLength()) {
if (getLength() < dataType.getLength()) {
return -1;
}
if (baseDataType instanceof Composite) {
@ -715,7 +745,7 @@ class DataDB extends CodeUnitDB implements Data {
lock.acquire();
try {
checkIsValid();
if (offset < 0 || offset >= length) {
if (offset < 0 || offset >= getLength()) {
return null;
}
Data dc = getComponentContaining(offset);
@ -744,7 +774,7 @@ class DataDB extends CodeUnitDB implements Data {
lock.acquire();
try {
checkIsValid();
return baseDataType.getValue(this, this, length);
return baseDataType.getValue(this, this, getLength());
}
finally {
lock.release();
@ -773,7 +803,7 @@ class DataDB extends CodeUnitDB implements Data {
if (options == null) {
options = DataTypeDisplayOptions.DEFAULT;
}
return dataType.getDefaultLabelPrefix(this, this, length, options);
return dataType.getDefaultLabelPrefix(this, this, getLength(), options);
}
@Override