Merge remote-tracking branch 'origin/GT-xx-ghidravore_removing_uses_of_LongObjectHashTable'

This commit is contained in:
ghidravore 2020-06-02 13:01:31 -04:00
commit 86a884a462
23 changed files with 434 additions and 1030 deletions

View file

@ -21,7 +21,6 @@ package ghidra.program.database;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.*;
import java.util.stream.Collectors;
import db.Record;
import ghidra.program.model.address.KeyRange;
@ -199,18 +198,21 @@ public class DBObjectCache<T extends DatabaseObject> {
* @param keyRanges key ranges to delete
*/
private void deleteLargeKeyRanges(List<KeyRange> keyRanges) {
map.keySet()
.stream()
.filter(key -> keyRangesContain(keyRanges, key))
.collect(Collectors.toList())
.forEach(key -> {
KeyedSoftReference ref = map.remove(key);
DatabaseObject obj = ref.get();
if (obj != null) {
obj.setDeleted();
ref.clear();
}
});
map.values().removeIf(ref -> checkRef(ref, keyRanges));
}
private boolean checkRef(KeyedSoftReference ref, List<KeyRange> keyRanges) {
long key = ref.getKey();
if (keyRangesContain(keyRanges, key)) {
DatabaseObject obj = ref.get();
if (obj != null) {
obj.setDeleted();
ref.clear();
}
return true;
}
return false;
}
/**
@ -267,27 +269,6 @@ public class DBObjectCache<T extends DatabaseObject> {
return invalidateCount;
}
/**
* Invalidates a range of objects in the cache.
* @param startKey the first key in the range to invalidate.
* @param endKey the last key in the range to invalidate.
*/
public synchronized void invalidate(long startKey, long endKey) {
processQueue();
if (endKey - startKey < map.size()) {
for (long i = startKey; i <= endKey; i++) {
doInvalidate(i);
}
}
else {
map.keySet()
.stream()
.filter(key -> (key >= startKey && key <= endKey))
.collect(Collectors.toList())
.forEach(key -> doInvalidate(key));
}
}
/**
* Removes the object with the given key from the cache.
* @param key the key of the object to remove.
@ -305,25 +286,6 @@ public class DBObjectCache<T extends DatabaseObject> {
}
}
/**
* Invalidates the object with given key.
* @param key the key of the object to invalidate.
*/
public synchronized void invalidate(long key) {
processQueue();
doInvalidate(key);
}
private void doInvalidate(long key) {
KeyedSoftReference ref = map.get(key);
if (ref != null) {
T obj = ref.get();
if (obj != null) {
obj.setInvalid();
}
}
}
private void addToHardCache(T obj) {
hardCache.addLast(obj);
if (hardCache.size() > hardCacheSize) {

View file

@ -16,13 +16,14 @@
package ghidra.program.database;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import db.*;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.address.OverlayAddressSpace;
import ghidra.program.model.lang.Language;
import ghidra.program.util.LanguageTranslator;
import ghidra.util.datastruct.LongObjectHashtable;
import ghidra.util.exception.AssertException;
import ghidra.util.exception.DuplicateNameException;
@ -115,7 +116,7 @@ class OverlaySpaceAdapterDB {
}
void updateOverlaySpaces(ProgramAddressFactory factory) throws IOException {
LongObjectHashtable<OverlayAddressSpace> map = new LongObjectHashtable<>();
Map<Long, OverlayAddressSpace> map = new HashMap<>();
for (AddressSpace space : factory.getAllAddressSpaces()) {
if (space instanceof OverlayAddressSpace) {
OverlayAddressSpace os = (OverlayAddressSpace) space;
@ -161,12 +162,8 @@ class OverlaySpaceAdapterDB {
}
}
}
if (map.size() != 0) {
long[] keys = map.getKeys();
for (int i = 0; i < keys.length; i++) {
OverlayAddressSpace space = map.remove(keys[i]);
factory.removeOverlaySpace(space.getName());
}
for (OverlayAddressSpace space : map.values()) {
factory.removeOverlaySpace(space.getName());
}
}

View file

@ -39,7 +39,6 @@ import ghidra.program.model.lang.CompilerSpec;
import ghidra.util.*;
import ghidra.util.classfinder.ClassTranslator;
import ghidra.util.datastruct.FixedSizeHashMap;
import ghidra.util.datastruct.LongObjectHashtable;
import ghidra.util.exception.*;
import ghidra.util.task.TaskMonitor;
@ -3490,15 +3489,15 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
}
class IdsToDataTypeMap {
private Map<UniversalID, LongObjectHashtable<DataType>> map = new HashMap<>();
private Map<UniversalID, Map<Long, DataType>> map = new HashMap<>();
DataType getDataType(UniversalID sourceID, UniversalID dataTypeID) {
if (sourceID == null || sourceID.equals(universalID)) {
sourceID = LOCAL_ARCHIVE_UNIVERSAL_ID;
}
LongObjectHashtable<DataType> idMap = map.get(sourceID);
Map<Long, DataType> idMap = map.get(sourceID);
if (idMap == null) {
idMap = new LongObjectHashtable<>();
idMap = new HashMap<>();
map.put(sourceID, idMap);
}
DataType dt = idMap.get(dataTypeID.getValue());
@ -3527,7 +3526,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
else {
sourceID = sourceArchive.getSourceArchiveID();
}
LongObjectHashtable<DataType> idMap = map.get(sourceID);
Map<Long, DataType> idMap = map.get(sourceID);
if (idMap != null) {
idMap.remove(dataTypeID.getValue());
}

View file

@ -34,7 +34,6 @@ import ghidra.program.model.symbol.*;
import ghidra.program.util.LanguageTranslator;
import ghidra.util.Lock;
import ghidra.util.Msg;
import ghidra.util.datastruct.LongObjectHashtable;
import ghidra.util.exception.*;
import ghidra.util.task.TaskMonitor;
@ -122,7 +121,7 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
monitor.initialize(oldNameAdapter.getRecordCount());
int cnt = 0;
LongObjectHashtable<String> nameMap = new LongObjectHashtable<>();
Map<Long, String> nameMap = new HashMap<>();
RecordIterator iter = oldNameAdapter.getRecords();
while (iter.hasNext()) {

View file

@ -18,7 +18,8 @@ package ghidra.program.database.map;
import java.util.*;
import ghidra.program.model.address.*;
import ghidra.util.datastruct.*;
import ghidra.util.datastruct.Range;
import ghidra.util.datastruct.SortedRangeList;
/**
* AddressSetView implementation that handles image base changes. NOTE: THIS IMPLEMENTATION
@ -33,8 +34,7 @@ public class NormalizedAddressSet implements AddressSetView {
private AddressMap addrMap;
private LongObjectHashtable<SortedRangeList> baseLists =
new LongObjectHashtable<SortedRangeList>();
private Map<Long, SortedRangeList> baseLists = new HashMap<>();
private ArrayList<Long> bases = new ArrayList<Long>();
private Comparator<Long> baseComparator = new Comparator<Long>() {
@ -108,7 +108,7 @@ public class NormalizedAddressSet implements AddressSetView {
* Removes all addresses from this set.
*/
public void clear() {
baseLists = new LongObjectHashtable<SortedRangeList>();
baseLists = new HashMap<>();
bases = new ArrayList<Long>();
}
@ -251,9 +251,9 @@ public class NormalizedAddressSet implements AddressSetView {
@Override
public int getNumAddressRanges() {
int n = 0;
long[] keys = baseLists.getKeys();
for (int i = 0; i < keys.length; i++) {
SortedRangeList list = baseLists.get(keys[i]);
for (long key : baseLists.keySet()) {
SortedRangeList list = baseLists.get(key);
n += list.getNumRanges();
}
return n;
@ -286,9 +286,8 @@ public class NormalizedAddressSet implements AddressSetView {
@Override
public long getNumAddresses() {
long n = 0;
long[] keys = baseLists.getKeys();
for (int i = 0; i < keys.length; i++) {
SortedRangeList list = baseLists.get(keys[i]);
for (long key : baseLists.keySet()) {
SortedRangeList list = baseLists.get(key);
n += list.getNumValues();
}
return n;

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +15,11 @@
*/
package ghidra.program.database.properties;
import java.io.IOException;
import java.util.NoSuchElementException;
import db.*;
import db.util.ErrorHandler;
import ghidra.program.database.map.*;
import ghidra.program.database.util.DatabaseTableUtils;
import ghidra.program.model.address.*;
@ -28,12 +32,6 @@ import ghidra.util.exception.*;
import ghidra.util.task.TaskMonitor;
import ghidra.util.task.TaskMonitorAdapter;
import java.io.IOException;
import java.util.NoSuchElementException;
import db.*;
import db.util.ErrorHandler;
/**
* Abstract class which defines a map containing properties over a set of addresses.
* The map is stored within a database table.
@ -137,8 +135,9 @@ public abstract class PropertyMapDB implements PropertyMap {
monitor.setProgress(++count);
}
if (tempTable == null)
if (tempTable == null) {
return;
}
// Remove old table
dbHandle.deleteTable(getTableName());
@ -192,6 +191,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#getName()
*/
@Override
public String getName() {
return name;
}
@ -221,7 +221,7 @@ public abstract class PropertyMapDB implements PropertyMap {
lock.acquire();
try {
if (propertyTable != null) {
cache.clear();
cache = null;
dbHandle.deleteTable(getTableName());
propertyTable = null;
}
@ -234,6 +234,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#intersects(ghidra.program.model.address.Address, ghidra.program.model.address.Address)
*/
@Override
public boolean intersects(Address startAddr, Address endAddr) {
if (propertyTable == null) {
return false;
@ -252,6 +253,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#intersects(ghidra.program.model.address.AddressSetView)
*/
@Override
public boolean intersects(AddressSetView set) {
if (propertyTable == null) {
return false;
@ -270,6 +272,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#removeRange(ghidra.program.model.address.Address, ghidra.program.model.address.Address)
*/
@Override
public boolean removeRange(Address startAddr, Address endAddr) {
if (propertyTable == null) {
return false;
@ -277,7 +280,7 @@ public abstract class PropertyMapDB implements PropertyMap {
lock.acquire();
try {
if (AddressRecordDeleter.deleteRecords(propertyTable, addrMap, startAddr, endAddr)) {
cache.clear();
cache = new ObjectCache(DEFAULT_CACHE_SIZE);
return true;
}
}
@ -293,6 +296,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#remove(ghidra.program.model.address.Address)
*/
@Override
public boolean remove(Address addr) {
if (propertyTable == null) {
return false;
@ -317,6 +321,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#hasProperty(ghidra.program.model.address.Address)
*/
@Override
public boolean hasProperty(Address addr) {
if (propertyTable == null) {
return false;
@ -341,6 +346,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#getNextPropertyAddress(ghidra.program.model.address.Address)
*/
@Override
public Address getNextPropertyAddress(Address addr) {
if (propertyTable == null) {
return null;
@ -360,6 +366,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#getPreviousPropertyAddress(ghidra.program.model.address.Address)
*/
@Override
public Address getPreviousPropertyAddress(Address addr) {
if (propertyTable == null) {
return null;
@ -379,6 +386,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#getFirstPropertyAddress()
*/
@Override
public Address getFirstPropertyAddress() {
if (propertyTable == null) {
return null;
@ -398,6 +406,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#getLastPropertyAddress()
*/
@Override
public Address getLastPropertyAddress() {
if (propertyTable == null) {
return null;
@ -419,6 +428,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#getSize()
*/
@Override
public int getSize() {
return propertyTable != null ? propertyTable.getRecordCount() : 0;
}
@ -434,8 +444,9 @@ public abstract class PropertyMapDB implements PropertyMap {
public AddressKeyIterator getAddressKeyIterator(AddressSetView set, boolean atStart)
throws IOException {
if (propertyTable == null)
if (propertyTable == null) {
return new AddressKeyIterator();
}
if (atStart) {
return new AddressKeyIterator(propertyTable, addrMap, set, set.getMinAddress(), true);
}
@ -452,8 +463,9 @@ public abstract class PropertyMapDB implements PropertyMap {
public AddressKeyIterator getAddressKeyIterator(Address start, boolean before)
throws IOException {
if (propertyTable == null)
if (propertyTable == null) {
return new AddressKeyIterator();
}
return new AddressKeyIterator(propertyTable, addrMap, start, before);
}
@ -469,8 +481,9 @@ public abstract class PropertyMapDB implements PropertyMap {
public AddressKeyIterator getAddressKeyIterator(Address start, Address end, boolean atStart)
throws IOException {
if (propertyTable == null)
if (propertyTable == null) {
return new AddressKeyIterator();
}
if (atStart) {
return new AddressKeyIterator(propertyTable, addrMap, start, end, start, true);
}
@ -480,6 +493,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#getPropertyIterator(ghidra.program.model.address.Address, ghidra.program.model.address.Address)
*/
@Override
public AddressIterator getPropertyIterator(Address start, Address end) {
AddressKeyIterator keyIter = null;
try {
@ -494,6 +508,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#getPropertyIterator(ghidra.program.model.address.Address, ghidra.program.model.address.Address, boolean)
*/
@Override
public AddressIterator getPropertyIterator(Address start, Address end, boolean forward) {
AddressKeyIterator keyIter = null;
try {
@ -508,6 +523,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#getPropertyIterator()
*/
@Override
public AddressIterator getPropertyIterator() {
if (propertyTable == null) {
return new EmptyAddressIterator();
@ -525,6 +541,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#getPropertyIterator(ghidra.program.model.address.AddressSetView)
*/
@Override
public AddressIterator getPropertyIterator(AddressSetView asv) {
if (propertyTable == null) {
return new EmptyAddressIterator();
@ -543,6 +560,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#getPropertyIterator(ghidra.program.model.address.AddressSetView, boolean)
*/
@Override
public AddressIterator getPropertyIterator(AddressSetView asv, boolean forward) {
if (propertyTable == null) {
return new EmptyAddressIterator();
@ -567,6 +585,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#getPropertyIterator(ghidra.program.model.address.Address, boolean)
*/
@Override
public AddressIterator getPropertyIterator(Address start, boolean forward) {
if (propertyTable == null) {
return new EmptyAddressIterator();
@ -588,7 +607,7 @@ public abstract class PropertyMapDB implements PropertyMap {
lock.acquire();
try {
propertyTable = dbHandle.getTable(getTableName());
cache.clear();
cache = new ObjectCache(DEFAULT_CACHE_SIZE);
}
finally {
lock.release();
@ -599,10 +618,11 @@ public abstract class PropertyMapDB implements PropertyMap {
/**
* @see ghidra.program.model.util.PropertyMap#moveRange(ghidra.program.model.address.Address, ghidra.program.model.address.Address, ghidra.program.model.address.Address)
*/
@Override
public void moveRange(Address start, Address end, Address newStart) {
lock.acquire();
try {
cache.clear();
cache = new ObjectCache(DEFAULT_CACHE_SIZE);
if (propertyTable != null) {
try {
DatabaseTableUtils.updateAddressKey(propertyTable, addrMap, start, end,

View file

@ -32,9 +32,7 @@ import ghidra.program.model.listing.ProgramContext;
import ghidra.program.util.RangeMapAdapter;
import ghidra.program.util.RegisterValueStore;
import ghidra.util.Lock;
import ghidra.util.datastruct.LongObjectHashtable;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
/**
@ -61,7 +59,7 @@ public class OldProgramContextDB implements ProgramContext, DefaultProgramContex
* address ranges using the PropertyMap utilities.
*/
private HashMap<String, Register> registersMap;
private LongObjectHashtable<AddressRangeMapDB> valueMaps;
private Map<Integer, AddressRangeMapDB> valueMaps;
private Register baseContextRegister;
protected Map<Register, RegisterValueStore> defaultRegisterValueMap;
@ -88,7 +86,7 @@ public class OldProgramContextDB implements ProgramContext, DefaultProgramContex
defaultRegisterValueMap = new HashMap<Register, RegisterValueStore>();
registersMap = new HashMap<String, Register>();
valueMaps = new LongObjectHashtable<AddressRangeMapDB>();
valueMaps = new HashMap<>();
registerSpaceSize = 0;
for (Register register : registers) {
@ -350,7 +348,7 @@ public class OldProgramContextDB implements ProgramContext, DefaultProgramContex
public void invalidateCache(boolean all) throws IOException {
lock.acquire();
try {
valueMaps.removeAll();
valueMaps.clear();
}
finally {
lock.release();

View file

@ -306,29 +306,11 @@ public abstract class DefaultPropertyMap implements PropertyMap {
* @throws ClassNotFoundException if the class for the object being
* read is not in the class path
*/
public void restoreProperties(ObjectInputStream ois) throws IOException, ClassNotFoundException {
public void restoreProperties(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
propertyMgr.restoreProperties(ois);
}
/**
* Write all properties in the map to the given output stream.
* @throws IOException if there is a problem writing to the stream
*/
public void saveAll(ObjectOutputStream out) throws IOException {
propertyMgr.saveAll(out);
}
/**
* Restore properties read from the given input stream.
* @param in input stream
* @throws IOException if there is a problem reading from the stream
* @throws ClassNotFoundException if the class for the object being
* read is not in the class path
*/
public void restoreAll(ObjectInputStream in) throws IOException, ClassNotFoundException {
propertyMgr.restoreAll(in);
}
private class AddressPropertyIterator implements AddressIterator {
private LongIterator iter;
@ -350,7 +332,8 @@ public abstract class DefaultPropertyMap implements PropertyMap {
AddressPropertyIterator(Address start, Address end, boolean forward) {
iter =
propertyMgr.getPropertyIterator(addrMap.getKey(start), addrMap.getKey(end), forward);
propertyMgr.getPropertyIterator(addrMap.getKey(start), addrMap.getKey(end),
forward);
this.forward = forward;
}