From b2aff9b7c554d8d9752af9d87cf9a8fbca7d0875 Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Fri, 29 Jul 2005 05:46:25 +0000 Subject: [PATCH] more fix for 100442 --- .../debug/mi/core/cdi/RegisterManager.java | 121 ++++++++++++++---- .../cdt/debug/mi/core/cdi/model/Register.java | 13 +- .../cdt/debug/mi/core/cdi/model/Variable.java | 18 +-- .../mi/core/cdi/model/VariableDescriptor.java | 5 +- 4 files changed, 110 insertions(+), 47 deletions(-) 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; /**