Improved bulk addDatatypes performance (experimental method) and

corrected structure editor help text.
This commit is contained in:
ghidra1 2020-06-04 19:38:45 -04:00
parent 4406b8a7a8
commit bdbbca30a1
5 changed files with 41 additions and 20 deletions

View file

@ -179,14 +179,12 @@
<H3>Unaligned Structures</H3>
<BLOCKQUOTE>
<P>When a structure is unaligned, with the exception of bitfields, each component immediately
follows the one before it. In
other words no automatic alignment or padding occurs. Unaligned structures can contain
Unaligned structures should be used to position components with known data
types at specific offsets within the structure. Therefore the structure editor tries to
prevent defined components (those other than Undefined bytes) from accidentally being moved
to a different offset when performing operations like drag and drop, although undefined bytes
may be consumed. <BR>
<P>When a structure is unaligned, with the exception of bitfields, each component shown within
the editor immediately follows the one before it. In other words, no automatic alignment or padding occurs.
Unaligned structures may be used to position components with known data
types at specific offsets within a structure. Therefore, when editing an unaligned structure,
the structure editor attempts to prevent defined components from moving
to a different offset when performing operations like drag and drop which may consume undefined bytes. <BR>
</P>
<DIV style="text-align: center; margin-top: 10px;">

View file

@ -812,7 +812,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
}
finally {
if (isResolveCacheOwner) {
flushResolveCacheAndClearQueue();
flushResolveQueue(true);
}
if (isEquivalenceCacheOwner) {
clearEquivalenceCache();
@ -1142,15 +1142,26 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
lock.acquire();
boolean isEquivalenceCacheOwner = activateEquivalenceCache();
boolean isResolveCacheOwner = activateResolveCache();
// TODO: extended hold time on lock may cause the GUI to become
// unresponsive. Consider releasing lock between resolves, although
// this exposes risk of having active resolve queue/cache without lock
try {
monitor.setMessage("Adding datatypes...");
monitor.setMaximum(dataTypes.size());
monitor.setProgress(0);
int i = 0;
for (DataType dt : dataTypes) {
monitor.checkCanceled();
resolve(dt, handler);
if (isResolveCacheOwner) {
flushResolveQueue(false);
}
monitor.setProgress(++i);
}
}
finally {
if (isResolveCacheOwner) {
flushResolveCacheAndClearQueue();
flushResolveQueue(true);
}
if (isEquivalenceCacheOwner) {
clearEquivalenceCache();
@ -3764,19 +3775,17 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
/**
* Activate resolveCache and associated resolveQueue if not already active. If
* this method returns true caller is responsible for flushing resolveQueue and
* invoking {@link #flushResolveCacheAndClearQueue(DataTypeConflictHandler)}
* when resolve. For each completed resolve
* {@link #cacheResolvedDataType(DataType, DataType)} should be called.
* invoking {@link #flushResolveQueue(boolean)} when resolve complete.
* For each completed resolve {@link #cacheResolvedDataType(DataType, DataType)}
* should be invoked.
*
* @return true if resolveCache and resolveQueue activated else false if
* previously activated.
* @return true if resolveCache activated else false if already active.
*/
boolean activateResolveCache() {
if (resolveCache != null) {
return false;
}
resolveCache = new IdentityHashMap<>();
resolveQueue = new TreeSet<>();
return true;
}
@ -3788,10 +3797,19 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
*/
void queuePostResolve(DataTypeDB resolvedDt, DataType definitionDt) {
resolvedDt.resolving = true;
if (resolveQueue == null) {
resolveQueue = new TreeSet<>();
}
resolveQueue.add(new ResolvePair(resolvedDt, definitionDt));
}
void flushResolveCacheAndClearQueue() {
void flushResolveQueue(boolean deactivateCache) {
if (resolveQueue == null) {
if (deactivateCache) {
resolveCache = null;
}
return;
}
DataTypeConflictHandler handler = getDependencyConflictHandler();
while (!resolveQueue.isEmpty()) {
ResolvePair resolvePair = resolveQueue.pollFirst();
@ -3805,8 +3823,10 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
resolvedDt.pointerPostResolveRequired = false;
}
}
resolveCache = null;
resolveQueue = null;
if (deactivateCache) {
resolveCache = null;
}
}
private DataType getCachedResolve(DataType dt) {

View file

@ -1168,7 +1168,7 @@ class StructureDB extends CompositeDB implements Structure {
}
finally {
if (isResolveCacheOwner) {
dataMgr.flushResolveCacheAndClearQueue();
dataMgr.flushResolveQueue(true);
}
lock.release();
}

View file

@ -257,7 +257,7 @@ class UnionDB extends CompositeDB implements Union {
}
finally {
if (isResolveCacheOwner) {
dataMgr.flushResolveCacheAndClearQueue();
dataMgr.flushResolveQueue(true);
}
lock.release();
}

View file

@ -101,6 +101,9 @@ public interface DataTypeManager {
* Sequentially adds a collection of datatypes to this data manager.
* This method provides the added benefit of equivalence caching
* for improved performance.
* <br>
* WARNING: This is an experimental method whoose use may cause the GUI and
* task monitor to become unresponsive due to extended hold times on the manager lock.
* @param dataTypes collection of datatypes
* @param handler conflict handler
* @param monitor task monitor