in analysis/heap-dump/impl/src/main/java/org/eclipse/jifa/hda/impl/HeapDumpAnalyzerImpl.java [1424:1473]
public List<Model.Thread.LocalVariable> getLocalVariables(int objectId, int depth, boolean firstNonNativeFrame) {
return $(() -> {
Map<String, Object> args = new HashMap<>();
args.put("objects", Helper.buildHeapObjectArgument(new int[]{objectId}));
IResultTree result = queryByCommand(context, "thread_overview", args);
List<?> elements = result.getElements();
if (result.hasChildren(elements.get(0))) {
List<?> frames = result.getChildren(elements.get(0));
Object frame = frames.get(depth - 1);
if (result.hasChildren(frame)) {
List<?> locals = result.getChildren(frame);
return locals.stream().map(local -> {
int id = result.getContext(local).getObjectId();
Model.Thread.LocalVariable var = new Model.Thread.LocalVariable();
var.setObjectId(id);
try {
IObject object = context.snapshot.getObject(id);
var.setLabel(object.getDisplayName());
var.setShallowSize(object.getUsedHeapSize());
var.setRetainedSize(object.getRetainedHeapSize());
var.setObjectType(typeOf(object));
var.setGCRoot(context.snapshot.isGCRoot(id));
var.setHasOutbound(result.hasChildren(var));
// ThreadStackQuery_Label_Local
var.setPrefix("<local>");
if (firstNonNativeFrame) {
GCRootInfo[] gcRootInfos = object.getGCRootInfo();
if (gcRootInfos != null) {
for (GCRootInfo gcRootInfo : gcRootInfos) {
if (gcRootInfo.getContextId() != 0 &&
(gcRootInfo.getType() & GCRootInfo.Type.BUSY_MONITOR) != 0 &&
gcRootInfo.getContextId() == objectId) {
// ThreadStackQuery_Label_Local_Blocked_On
var.setPrefix("<local, blocked on>");
}
}
}
}
var.setSuffix(Helper.suffix(context.snapshot, id));
return var;
} catch (SnapshotException e) {
throw new CommonException(e);
}
}).collect(Collectors.toList());
}
}
return Collections.emptyList();
});
}