GP-4568 Improving program lock performance when getting bytes for Instructions and Data

This commit is contained in:
emteere 2024-04-30 18:16:04 -04:00
parent 586fc9efcd
commit 6095d4c4e3

View file

@ -622,65 +622,54 @@ abstract class CodeUnitDB extends DatabaseObject implements CodeUnit, ProcessorC
@Override @Override
public int getBytes(byte[] b, int offset) { public int getBytes(byte[] b, int offset) {
lock.acquire(); refreshIfNeeded();
try { byte localBytes[] = populateByteArray();
checkIsValid(); if (offset >= 0 && (offset + b.length) <= localBytes.length) {
populateByteArray(); System.arraycopy(localBytes, offset, b, 0, b.length);
if (offset < 0 || (offset + b.length) > bytes.length) {
return program.getMemory().getBytes(address.add(offset), b);
}
System.arraycopy(bytes, offset, b, 0, b.length);
return b.length; return b.length;
} }
catch (AddressOutOfBoundsException | MemoryAccessException e) {
return 0; try {
return program.getMemory().getBytes(address.add(offset), b);
} }
finally { catch (MemoryAccessException | AddressOutOfBoundsException e) {
lock.release(); return 0;
} }
} }
@Override @Override
public byte[] getBytes() throws MemoryAccessException { public byte[] getBytes() throws MemoryAccessException {
lock.acquire(); refreshIfNeeded();
try { byte localBytes[] = populateByteArray();
checkIsValid(); int locallen = getLength();
populateByteArray(); if (localBytes.length >= locallen ) {
int len = getLength(); byte[] b = new byte[locallen];
byte[] b = new byte[len]; System.arraycopy(localBytes, 0, b, 0, b.length);
if (bytes.length < len) {
if (program.getMemory().getBytes(address, b) != len) {
throw new MemoryAccessException("Couldn't get all bytes for CodeUnit");
}
}
else {
System.arraycopy(bytes, 0, b, 0, b.length);
}
return b; return b;
} }
finally {
lock.release(); int len = getLength();
byte[] b = new byte[len];
if (program.getMemory().getBytes(address, b) != len) {
throw new MemoryAccessException("Couldn't get all bytes for CodeUnit");
} }
return b;
} }
@Override @Override
public byte getByte(int offset) throws MemoryAccessException { public byte getByte(int offset) throws MemoryAccessException {
lock.acquire(); refreshIfNeeded();
try { byte localBytes[] = populateByteArray();
checkIsValid(); if (offset >= 0 && offset < localBytes.length) {
populateByteArray(); return localBytes[offset];
if (offset < 0 || offset >= bytes.length) {
try {
return program.getMemory().getByte(address.add(offset));
}
catch (AddressOutOfBoundsException e) {
throw new MemoryAccessException(e.getMessage());
}
}
return bytes[offset];
} }
finally {
lock.release(); try {
return program.getMemory().getByte(address.add(offset));
}
catch (AddressOutOfBoundsException e) {
throw new MemoryAccessException(e.getMessage());
} }
} }
@ -785,24 +774,27 @@ abstract class CodeUnitDB extends DatabaseObject implements CodeUnit, ProcessorC
} }
} }
private void populateByteArray() { private byte[] populateByteArray() {
if (bytes != null) { byte[] localBytes = bytes;
return; if (localBytes != null) {
return localBytes;
} }
int cacheLength = getPreferredCacheLength(); int cacheLength = getPreferredCacheLength();
bytes = new byte[cacheLength]; localBytes = new byte[cacheLength];
if (cacheLength != 0) { if (cacheLength != 0) {
int nbytes = 0; int nbytes = 0;
try { try {
nbytes = program.getMemory().getBytes(address, bytes); nbytes = program.getMemory().getBytes(address, localBytes);
} }
catch (MemoryAccessException e) { catch (MemoryAccessException e) {
// ignore // ignore
} }
if (nbytes != bytes.length) { if (nbytes != localBytes.length) {
bytes = new byte[0]; localBytes = new byte[0];
} }
} }
bytes = localBytes;
return localBytes;
} }
protected int getPreferredCacheLength() { protected int getPreferredCacheLength() {