diff --git a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/RegisterManager.java b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/RegisterManager.java
index 8901bcc189f..327f9377550 100644
--- a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/RegisterManager.java
+++ b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/RegisterManager.java
@@ -13,14 +13,16 @@ package org.eclipse.cdt.debug.mi.core.cdi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
+
import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.model.ICDIRegisterDescriptor;
import org.eclipse.cdt.debug.core.cdi.model.ICDIRegisterGroup;
import org.eclipse.cdt.debug.mi.core.MIException;
import org.eclipse.cdt.debug.mi.core.MISession;
-import org.eclipse.cdt.debug.mi.core.cdi.model.LocalVariable;
import org.eclipse.cdt.debug.mi.core.cdi.model.Register;
import org.eclipse.cdt.debug.mi.core.cdi.model.RegisterDescriptor;
import org.eclipse.cdt.debug.mi.core.cdi.model.RegisterGroup;
@@ -49,14 +51,86 @@ import org.eclipse.cdt.debug.mi.core.output.MIVarUpdateInfo;
*/
public class RegisterManager extends Manager {
+ final int MAX_ENTRIES = 150;
+
+ /**
+ *
+ * LRUMap.
+ * Simple LRU cache using a LinkedHashMap
+ */
+ class LRUMap extends LinkedHashMap {
+ private static final long serialVersionUID = 1L;
+ LRUMap() {
+ super(MAX_ENTRIES+1, .75F, true);
+ }
+ /* (non-Javadoc)
+ * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry)
+ */
+ protected boolean removeEldestEntry(Entry eldest) {
+ boolean toRemove = size() > MAX_ENTRIES;
+ if (toRemove) {
+ ShadowRegister v = (ShadowRegister)eldest.getValue();
+ try {
+ Target target = (Target)v.getTarget();
+ removeMIVar(target.getMISession(), v.getMIVar());
+ } catch (Exception e) {
+ // ignore all
+ }
+ v.setMIVar(null);
+ }
+ return toRemove;
+ }
+ }
+
+ /**
+ *
+ * ShadowRegister.
+ * To keep track of the register value we can a shadow variable. If the
+ * the variable MIVar was destroy by the LRUCache we try to recreate it.
+ */
+ class ShadowRegister extends Register {
+
+ public ShadowRegister(Register reg, StackFrame frame, String n, MIVar v) {
+ super((Target)reg.getTarget(), (Thread)frame.getThread(), frame, n, null, 0, 0, v);
+ try {
+ fTypename = reg.getTypeName();
+ } catch (CDIException e) {
+ // ignore
+ }
+ try {
+ fType = reg.getType();
+ } catch (CDIException e) {
+ // ignore
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.debug.mi.core.cdi.model.Variable#getMIVar()
+ */
+ public MIVar getMIVar() {
+ if (fMiVar == null) {
+ try {
+ fMiVar = createMiVar((StackFrame)getStackFrame(), getName());
+ } catch (CDIException e) {
+ //
+ }
+ }
+ return fMiVar;
+ }
+
+ public void setMIVar(MIVar newMIVar) {
+ fMiVar = newMIVar;
+ }
+ }
+
Map regsMap;
- Map varMap;
+ Map varsMap;
MIVarChange[] noChanges = new MIVarChange[0];
public RegisterManager(Session session) {
super(session, true);
regsMap = new Hashtable();
- varMap = new Hashtable();
+ varsMap = new Hashtable();
// The register bookkeeping provides better update control.
setAutoUpdate( true );
}
@@ -70,13 +144,13 @@ public class RegisterManager extends Manager {
return regsList;
}
- synchronized List getVariableList(Target target) {
- List varList = (List)varMap.get(target);
- if (varList == null) {
- varList = Collections.synchronizedList(new ArrayList());
- varMap.put(target, varList);
+ synchronized Map getVariableMap(Target target) {
+ Map varMap = (Map)varsMap.get(target);
+ if (varMap == null) {
+ varMap = Collections.synchronizedMap(new LRUMap());
+ varsMap.put(target, varMap);
}
- return varList;
+ return varMap;
}
public ICDIRegisterGroup[] getRegisterGroups(Target target) throws CDIException {
@@ -135,7 +209,6 @@ public class RegisterManager extends Manager {
}
}
return reg;
- //throw new CDIException(CdiResources.getString("cdi.RegisterManager.Wrong_register_type")); //$NON-NLS-1$
}
public void destroyRegister(Register reg) {
@@ -167,7 +240,7 @@ public class RegisterManager extends Manager {
}
}
- public Variable createVariable(StackFrame frame, String reg) throws CDIException {
+ public MIVar createMiVar(StackFrame frame, String regName) throws CDIException {
Target target = (Target)frame.getTarget();
Thread currentThread = (Thread)target.getCurrentThread();
StackFrame currentFrame = currentThread.getCurrentStackFrame();
@@ -176,16 +249,13 @@ public class RegisterManager extends Manager {
try {
MISession mi = target.getMISession();
CommandFactory factory = mi.getCommandFactory();
- MIVarCreate var = factory.createMIVarCreate(reg);
+ MIVarCreate var = factory.createMIVarCreate(regName);
mi.postCommand(var);
MIVarCreateInfo info = var.getMIVarCreateInfo();
if (info == null) {
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
}
- Variable variable = new LocalVariable(target, null, frame, reg, null, 0, 0, info.getMIVar());
- List varList = getVariableList(target);
- varList.add(variable);
- return variable;
+ return info.getMIVar();
} catch (MIException e) {
throw new MI2CDIException(e);
} finally {
@@ -194,6 +264,15 @@ public class RegisterManager extends Manager {
}
}
+ public Variable createShadowRegister(Register register, StackFrame frame, String regName) throws CDIException {
+ Target target = (Target)frame.getTarget();
+ MIVar miVar = createMiVar(frame, regName);
+ ShadowRegister variable = new ShadowRegister(register, frame, regName, miVar);
+ Map varMap = getVariableMap(target);
+ varMap.put(miVar.getVarName(), variable);
+ return variable;
+ }
+
/**
* Use by the eventManager to find the Register;
*/
@@ -234,13 +313,6 @@ public class RegisterManager extends Manager {
public void update(Target target) throws CDIException {
MISession mi = target.getMISession();
-
-// Variable[] vars = getVariables(target);
-// for (int i = 0; i < vars.length; ++i) {
-// removeMIVar(mi, vars[i].getMIVar());
-// List varList = getVariableList(target);
-// varList.remove(vars[i]);
-// }
CommandFactory factory = mi.getCommandFactory();
MIDataListChangedRegisters changed = factory.createMIDataListChangedRegisters();
try {
@@ -301,7 +373,7 @@ public class RegisterManager extends Manager {
}
private Variable[] getVariables(Target target) {
- List varList = (List)varMap.get(target);
+ List varList = (List)varsMap.get(target);
if (varList != null) {
return (Variable[]) varList.toArray(new Variable[varList.size()]);
}
@@ -331,5 +403,4 @@ public class RegisterManager extends Manager {
return null;
}
-
}
diff --git a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Register.java b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Register.java
index 1ef44a0563e..3d2f5c89674 100644
--- a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Register.java
+++ b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Register.java
@@ -10,24 +10,15 @@
*******************************************************************************/
package org.eclipse.cdt.debug.mi.core.cdi.model;
-import java.util.List;
import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.model.ICDIRegister;
import org.eclipse.cdt.debug.core.cdi.model.ICDIStackFrame;
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
import org.eclipse.cdt.debug.core.cdi.model.ICDIValue;
-import org.eclipse.cdt.debug.mi.core.MIException;
-import org.eclipse.cdt.debug.mi.core.MISession;
-import org.eclipse.cdt.debug.mi.core.cdi.CdiResources;
-import org.eclipse.cdt.debug.mi.core.cdi.ExpressionManager;
-import org.eclipse.cdt.debug.mi.core.cdi.MI2CDIException;
import org.eclipse.cdt.debug.mi.core.cdi.RegisterManager;
import org.eclipse.cdt.debug.mi.core.cdi.Session;
-import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
-import org.eclipse.cdt.debug.mi.core.command.MIVarCreate;
import org.eclipse.cdt.debug.mi.core.output.MIVar;
-import org.eclipse.cdt.debug.mi.core.output.MIVarCreateInfo;
/**
*/
@@ -60,6 +51,8 @@ public class Register extends Variable implements ICDIRegister {
String n = getName();
if (!n.startsWith("$")) { //$NON-NLS-1$
fFullName = "$" + n; //$NON-NLS-1$
+ } else {
+ fFullName = n;
}
}
return fFullName;
@@ -84,7 +77,7 @@ public class Register extends Variable implements ICDIRegister {
public ICDIValue getValue(ICDIStackFrame context) throws CDIException {
Session session = (Session)getTarget().getSession();
RegisterManager mgr = session.getRegisterManager();
- Variable var = mgr.createVariable((StackFrame)context, getQualifiedName());
+ Variable var = mgr.createShadowRegister(this, (StackFrame)context, getQualifiedName());
return var.getValue();
}
diff --git a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Variable.java b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Variable.java
index abf53f959bf..192256d0070 100644
--- a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Variable.java
+++ b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Variable.java
@@ -73,7 +73,7 @@ import org.eclipse.cdt.debug.mi.core.output.MIVarShowAttributesInfo;
*/
public abstract class Variable extends VariableDescriptor implements ICDIVariable {
- MIVar fMiVar;
+ protected MIVar fMiVar;
Value value;
public ICDIVariable[] children = new ICDIVariable[0];
String editable = null;
@@ -273,7 +273,7 @@ public abstract class Variable extends VariableDescriptor implements ICDIVariabl
String name, String fullName, int pos, int depth, MIVar miVar);
public int getChildrenNumber() throws CDIException {
- return fMiVar.getNumChild();
+ return getMIVar().getNumChild();
}
/**
@@ -333,7 +333,7 @@ public abstract class Variable extends VariableDescriptor implements ICDIVariabl
Target target = (Target)getTarget();
MISession miSession = target.getMISession();
CommandFactory factory = miSession.getCommandFactory();
- MIVarAssign var = factory.createMIVarAssign(fMiVar.getVarName(), expression);
+ MIVarAssign var = factory.createMIVarAssign(getMIVar().getVarName(), expression);
try {
miSession.postCommand(var);
MIInfo info = var.getMIInfo();
@@ -346,7 +346,7 @@ public abstract class Variable extends VariableDescriptor implements ICDIVariabl
// If the assign was succesfull fire a MIVarChangedEvent() for the variable
// Note GDB will not fire an event for the changed variable we have to do it manually.
- MIVarChangedEvent change = new MIVarChangedEvent(miSession, var.getToken(), fMiVar.getVarName());
+ MIVarChangedEvent change = new MIVarChangedEvent(miSession, var.getToken(), getMIVar().getVarName());
miSession.fireEvent(change);
// Changing values may have side effects i.e. affecting other variables
@@ -382,7 +382,7 @@ public abstract class Variable extends VariableDescriptor implements ICDIVariabl
if (editable == null) {
MISession mi = ((Target) getTarget()).getMISession();
CommandFactory factory = mi.getCommandFactory();
- MIVarShowAttributes var = factory.createMIVarShowAttributes(fMiVar.getVarName());
+ MIVarShowAttributes var = factory.createMIVarShowAttributes(getMIVar().getVarName());
try {
mi.postCommand(var);
MIVarShowAttributesInfo info = var.getMIVarShowAttributesInfo();
@@ -404,7 +404,7 @@ public abstract class Variable extends VariableDescriptor implements ICDIVariabl
int fmt = Format.toMIFormat(format);
MISession mi = ((Target) getTarget()).getMISession();
CommandFactory factory = mi.getCommandFactory();
- MIVarSetFormat var = factory.createMIVarSetFormat(fMiVar.getVarName(), fmt);
+ MIVarSetFormat var = factory.createMIVarSetFormat(getMIVar().getVarName(), fmt);
try {
mi.postCommand(var);
MIInfo info = var.getMIInfo();
@@ -432,7 +432,7 @@ public abstract class Variable extends VariableDescriptor implements ICDIVariabl
* @return
*/
public boolean equals(Variable variable) {
- return fMiVar.getVarName().equals(variable.getMIVar().getVarName());
+ return getMIVar().getVarName().equals(variable.getMIVar().getVarName());
}
/* (non-Javadoc)
@@ -449,11 +449,11 @@ public abstract class Variable extends VariableDescriptor implements ICDIVariabl
*/
public String getTypeName() throws CDIException {
if (fTypename == null) {
- fTypename = fMiVar.getType();
+ fTypename = getMIVar().getType();
if (fTypename == null || fTypename.length() == 0) {
MISession mi = ((Target) getTarget()).getMISession();
CommandFactory factory = mi.getCommandFactory();
- MIVarInfoType infoType = factory.createMIVarInfoType(fMiVar.getVarName());
+ MIVarInfoType infoType = factory.createMIVarInfoType(getMIVar().getVarName());
try {
mi.postCommand(infoType);
MIVarInfoTypeInfo info = infoType.getMIVarInfoTypeInfo();
diff --git a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/VariableDescriptor.java b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/VariableDescriptor.java
index 439e61d6475..491ee38c054 100644
--- a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/VariableDescriptor.java
+++ b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/VariableDescriptor.java
@@ -13,7 +13,6 @@ package org.eclipse.cdt.debug.mi.core.cdi.model;
import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.model.ICDIStackFrame;
import org.eclipse.cdt.debug.core.cdi.model.ICDIThread;
-import org.eclipse.cdt.debug.core.cdi.model.ICDIVariable;
import org.eclipse.cdt.debug.core.cdi.model.ICDIVariableDescriptor;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIType;
import org.eclipse.cdt.debug.mi.core.MIException;
@@ -45,8 +44,8 @@ public abstract class VariableDescriptor extends CObject implements ICDIVariable
String qualifiedName = null;
String fFullName = null;
- ICDIType fType = null;
- String fTypename = null;
+ protected ICDIType fType = null;
+ protected String fTypename = null;
String sizeof = null;
/**