/*
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.max.ins;
import java.lang.reflect.*;
import java.util.*;
import com.sun.cri.ci.*;
import com.sun.max.ins.gui.*;
import com.sun.max.ins.util.*;
import com.sun.max.program.*;
import com.sun.max.tele.*;
import com.sun.max.tele.method.*;
import com.sun.max.tele.object.*;
import com.sun.max.unsafe.*;
import com.sun.max.vm.actor.holder.*;
import com.sun.max.vm.actor.member.*;
/**
* Standardized ways to display textual names of common entities during Inspection sessions.
*/
public final class InspectorNameDisplay extends AbstractInspectionHolder {
public InspectorNameDisplay(Inspection inspection) {
super(inspection);
referenceRenderers.put(TeleArrayObject.class, new ArrayReferenceRenderer());
referenceRenderers.put(TeleHub.class, new HubReferenceRenderer());
referenceRenderers.put(TeleTupleObject.class, new TupleObjectReferenceRenderer());
referenceRenderers.put(TeleStaticTuple.class, new StaticTupleReferenceRenderer());
referenceRenderers.put(TeleMethodActor.class, new MethodActorReferenceRenderer());
referenceRenderers.put(TeleFieldActor.class, new FieldActorReferenceRenderer());
referenceRenderers.put(TeleClassActor.class, new ClassActorReferenceRenderer());
referenceRenderers.put(TeleString.class, new StringReferenceRenderer());
referenceRenderers.put(TeleUtf8Constant.class, new Utf8ConstantReferenceRenderer());
referenceRenderers.put(TeleStringConstant.class, new StringConstantReferenceRenderer());
referenceRenderers.put(TeleClass.class, new ClassReferenceRenderer());
referenceRenderers.put(TeleConstructor.class, new ConstructorReferenceRenderer());
referenceRenderers.put(TeleField.class, new FieldReferenceRenderer());
referenceRenderers.put(TeleMethod.class, new MethodReferenceRenderer());
referenceRenderers.put(TeleEnum.class, new EnumReferenceRenderer());
referenceRenderers.put(TeleConstantPool.class, new ConstantPoolReferenceRenderer());
referenceRenderers.put(TeleClassConstant.Resolved.class, new ClassConstantResolvedReferenceRenderer());
referenceRenderers.put(TeleFieldRefConstant.Resolved.class, new FieldRefConstantResolvedReferenceRenderer());
referenceRenderers.put(TeleClassMethodRefConstant.Resolved.class, new ClassMethodRefConstantResolvedReferenceRenderer());
referenceRenderers.put(TeleInterfaceMethodRefConstant.Resolved.class, new InterfaceMethodRefConstantResolvedReferenceRenderer());
referenceRenderers.put(TelePoolConstant.class, new PoolConstantReferenceRenderer());
referenceRenderers.put(TeleVmThread.class, new VmThreadReferenceRenderer());
}
/**
* Constants specifying where the return type should appear in the value returned by the methods in this class that
* produce a display name for a method.
*/
public enum ReturnTypeSpecification {
/**
* Denotes that the return type is to be omitted from the display name of a method.
*/
ABSENT,
/**
* Denotes that the return type is to be prefixed to the display name of a method.
*/
AS_PREFIX,
/**
* Denotes that the return type is to be suffixed to the display name of a method.
*/
AS_SUFFIX;
}
/**
* Support for a standardized way to identify a heap object in the VM.
*
* @param prefix an optional string to precede everything else
* @param object an optional surrogate for the tele object being named, null if local
* @param role an optional "role" name for low level VM objects whose implementation types aren't too interesting
* @param type a name to describe the object, type name in simple cases
* @return human readable string identifying an object in a standard format
*/
private String objectReference(String prefix, MaxObject object, String role, String type) {
final StringBuilder name = new StringBuilder(32);
if (prefix != null) {
name.append(prefix);
}
if (object != null) {
name.append('<');
name.append(object.getOID());
name.append('>');
}
if (role != null) {
name.append(role);
name.append('{');
name.append(type);
name.append('}');
} else {
name.append(type);
}
return name.toString();
}
/**
* @return a short string, suitable for label text, to use in place of data that should be read from the VM,
* but which cannot be for some reason (no process, process terminated, other i/o error).
*/
public String unreadableDataShortText() {
return "<unreadable>";
}
/**
* @return a long string, suitable for tool tip text, to use in place of data that should be read from the VM,
* but which cannot be for some reason (no process, process terminated, other i/o error).
*/
public String unreadableDataLongText() {
return "Data unreadable from VM";
}
/**
* @return a short string, suitable for label text, to use in place of data that should be read from the VM,
* but which cannot be for some reason (no process, process terminated, other i/o error).
*/
public String unavailableDataShortText() {
return "<?>";
}
/**
* @return a long string, suitable for tool tip text, to use in place of data that should be available from the VM,
* but which for some reason isn't available.
*/
public String unavailableDataLongText() {
return "<?> Data unavailable";
}
/**
* @return a short string, suitable for label text, to use in place of data that should be read from the VM,
* but which cannot be for some reason (no process, process terminated, other i/o error).
*/
public String zappedDataShortText() {
return "<ZAPPED>";
}
/**
* @return a long string, suitable for tool tip text, to use in place of data that should be read from the VM,
* but which cannot be for some reason (no process, process terminated, other i/o error).
*/
public String zappedDataLongText() {
return "Memory contents ZAPPED";
}
/**
* @return a short string, suitable for label text, to use in place of data that should be read from the VM,
* but which cannot be for some reason (no process, process terminated, other i/o error).
*/
public String noProcessShortText() {
return "<no process>";
}
/**
* @return human readable string identifying a thread in a terse standard format.
*/
public String shortName(MaxThread thread) {
if (thread == null) {
return "null";
}
if (thread.isPrimordial()) {
return "primordial";
}
if (thread.isJava()) {
final String vmThreadName = thread.vmThreadName();
return vmThreadName == null ? unavailableDataShortText() : vmThreadName;
}
return "native unnamed";
}
/**
* @return human readable string identifying a thread in a standard format.
*/
public String longName(MaxThread thread) {
if (thread == null) {
return "null";
}
return shortName(thread) + " [" + thread.id() + "]";
}
/**
* @return human readable string identifying a thread in a standard format.
*/
public String longNameWithState(MaxThread thread) {
if (thread == null) {
return "null";
}
return longName(thread) + " (" + thread.state() + ")";
}
/**
* An identifier for a particular compilation that distinguishes it from other
* compilations of the same method.
*
* E.g.: "[B]", meaning a baseline compilation
*/
public String shortMethodCompilationID(MaxCompilation compilation) {
// Only have an index if a compiled method.
if (compilation != null && compilation.getTeleClassMethodActor() != null) {
return "[" + compilation.shortDesignator() + "]";
}
return "";
}
/**
* An identifier for a particular compilation that distinguishes it from other
* compilations of the same method.
*
* E.g.: "[OPTIMIZED], meaning an optimized compilation
*/
public String longMethodCompilationID(MaxCompilation compilation) {
// Only have an index if a compiled method.
if (compilation != null && compilation.getTeleClassMethodActor() != null) {
return "[" + compilation.longDesignator() + "]";
}
return "";
}
/**
* E.g. an asterisk when a method has been substituted.
*/
public String methodSubstitutionShortAnnotation(TeleMethodActor teleMethodActor) {
if (teleMethodActor == null) {
return "";
}
try {
vm().acquireLegacyVMAccess();
try {
return teleMethodActor.isSubstituted() ? " *" : "";
} finally {
vm().releaseLegacyVMAccess();
}
} catch (MaxVMBusyException e) {
return unavailableDataShortText();
}
}
/**
* E.g. an asterisk when a method has been substituted.
*/
public String methodSubstitutionLongAnnotation(TeleMethodActor teleMethodActor) {
if (teleMethodActor == null) {
return "";
}
try {
vm().acquireLegacyVMAccess();
try {
return teleMethodActor.isSubstituted() ? " *=substituted from " + teleMethodActor.teleClassActorSubstitutedFrom().getName() : "";
} finally {
vm().releaseLegacyVMAccess();
}
} catch (MaxVMBusyException e) {
return unavailableDataLongText();
}
}
/**
* E.g. "foo()[0]"
*/
public String extremelyShortName(MaxCompilation compilation) {
if (compilation == null) {
return unavailableDataShortText();
}
return compilation.classMethodActor() == null ?
compilation.entityName() :
compilation.classMethodActor().format("%n()" + shortMethodCompilationID(compilation));
}
/**
* E.g. "Element.foo()[0]"
*/
public String veryShortName(MaxCompilation compilation) {
if (compilation == null) {
return unavailableDataShortText();
}
return compilation.classMethodActor() == null ?
compilation.entityName() :
compilation.classMethodActor().format("%h.%n()" + shortMethodCompilationID(compilation));
}
/**
* E.g. "foo(Pointer, Word, int[])[0]"
*/
public String shortName(MaxCompilation compilation) {
try {
vm().acquireLegacyVMAccess();
try {
return compilation.classMethodActor() == null ?
compilation.entityName() :
compilation.classMethodActor().format("%n(%p)" + shortMethodCompilationID(compilation));
} finally {
vm().releaseLegacyVMAccess();
}
} catch (MaxVMBusyException e) {
return unavailableDataShortText();
}
}
/**
* E.g. "int foo(Pointer, Word, int[])[0]"
*
* @param returnTypeSpecification specifies where the return type should appear in the returned value
*/
public String shortName(MaxCompilation compilation, ReturnTypeSpecification returnTypeSpecification) {
final ClassMethodActor classMethodActor = compilation.classMethodActor();
if (classMethodActor == null) {
return compilation.entityName();
}
switch (returnTypeSpecification) {
case ABSENT: {
return classMethodActor.format("%n(%p)" + shortMethodCompilationID(compilation));
}
case AS_PREFIX: {
return classMethodActor.format("%r %n(%p)" + shortMethodCompilationID(compilation));
}
case AS_SUFFIX: {
return classMethodActor.format("%n(%p)" + shortMethodCompilationID(compilation) + " %r");
}
default: {
throw InspectorError.unknownCase();
}
}
}
private String positionString(MaxCompilation compilation, Address address) {
final Address entry = compilation.getCodeStart();
final long position = address.minus(entry).toLong();
return position == 0 ? "" : "+" + InspectorLabel.longTo0xHex(position);
}
/**
* E.g. "int foo(Pointer, Word, int[])[0] in com.sun.max.ins.Bar"
*/
public String longName(MaxCompilation compilation) {
return compilation.classMethodActor() ==
null ? compilation.entityDescription() :
compilation.classMethodActor().format("%r %n(%p)" + shortMethodCompilationID(compilation) + " in %H");
}
/**
* E.g. "foo()[0]+0x7"
*/
public String veryShortName(MaxCompilation compilation, Address address) {
return compilation.classMethodActor() ==
null ? compilation.entityName() :
compilation.classMethodActor().format("%n()" + shortMethodCompilationID(compilation) + positionString(compilation, address));
}
/**
* E.g. "int foo(Pointer, Word, int[])[0]+0x7 in com.sun.max.ins.Bar"
*/
public String longName(MaxCompilation compilation, Address address) {
if (compilation == null) {
return unavailableDataLongText();
}
if (compilation.classMethodActor() != null) {
return compilation.classMethodActor().format("%r %n(%p)" + shortMethodCompilationID(compilation) + positionString(compilation, address) + " in %H");
}
return compilation.entityName();
}
/**
* E.g. "foo()"
*/
public String veryShortName(TeleClassMethodActor teleClassMethodActor) {
final ClassMethodActor classMethodActor = teleClassMethodActor.classMethodActor();
return classMethodActor.format("%n()");
}
/**
* E.g. "int foo(Pointer, Word, int[])"
*/
public String shortName(TeleClassMethodActor teleClassMethodActor, ReturnTypeSpecification returnTypeSpecification) {
final ClassMethodActor classMethodActor = teleClassMethodActor.classMethodActor();
switch (returnTypeSpecification) {
case ABSENT: {
return classMethodActor.format("%n(%p)");
}
case AS_PREFIX: {
return classMethodActor.format("%r %n(%p)");
}
case AS_SUFFIX: {
return classMethodActor.format("%n(%p) %r");
}
default: {
throw InspectorError.unknownCase();
}
}
}
/**
* E.g. "int foo(Pointer, Word, int[]) in com.sun.max.ins.Bar"
*/
public String longName(TeleClassMethodActor teleClassMethodActor) {
if (teleClassMethodActor == null) {
return "<no method actor>";
}
return teleClassMethodActor.classMethodActor().format("%r %n(%p)" + " in %H");
}
/**
* E.g. "virtualMemory_pageAlign" if known, default "@0xffffffffffffffff"
*/
public String shortName(MaxNativeFunction nativeFunction) {
final String title = nativeFunction.name();
return title == null ? "@0x" + nativeFunction.getCodeStart().toHexString() : title;
}
/**
* E.g. "libjvmlinkage:virtualMemory_pageAlign" if known, default "@0xffffffffffffffff"
*/
public String longName(MaxNativeFunction nativeFunction) {
final String title = nativeFunction.qualName();
return title == null ? "Native function @" + nativeFunction.getCodeStart().to0xHexString() : title;
}
/**
* E.g. "int foo(Pointer, Word, int[]) in com.sun.max.ins.Bar"
* E.g. "int foo(Pointer, Word, int[])+14 in com.sun.max.ins.Bar"
*/
public String longName(CiCodePos codePos) {
final int position = codePos.bci;
ClassMethodActor classMethodActor = (ClassMethodActor) codePos.method;
return classMethodActor.format("%r %n(%p)" + (position != 0 ? " +" + codePos.bci : "") + " in %H");
}
/**
* E.g. "int foo(Pointer, Word, int[]) in com.sun.max.ins.Bar"
*/
public String longName(MethodKey key) {
final StringBuilder name = new StringBuilder();
name.append(key.signature().resultDescriptor().toJavaString(false)).append(" ").append(key.name()).append(key.signature().toJavaString(false, false));
name.append(" in ").append(key.holder().toJavaString());
return name.toString();
}
/**
* E.g. "foo() in com.sun.max.ins.Bar"
*/
public String shortName(MethodKey key) {
final StringBuilder name = new StringBuilder();
name.append(key.name()).append(key.signature().toJavaString(false, false));
name.append(" in ").append(key.holder().toJavaString());
return name.toString();
}
/**
* E.g. "0x11111111, int foo(int, int)[0]+0x235 in com.sun.Example, bci=-1.
*/
public String longName(MaxCodeLocation codeLocation) {
if (codeLocation == null) {
return unavailableDataShortText();
}
final StringBuilder name = new StringBuilder();
if (codeLocation.hasAddress()) {
final Address address = codeLocation.address();
name.append(address.to0xHexString());
TeleNativeFunction nativeFunction = vm().machineCode().findNativeFunction(address);
if (nativeFunction != null) {
name.append(" in " + longName(nativeFunction));
} else {
final MaxCompilation compilation = vm().machineCode().findCompilation(address);
if (compilation != null) {
name.append(", ").append(longName(compilation, address));
}
if (codeLocation.hasTeleClassMethodActor()) {
name.append(", bci=").append(codeLocation.bci());
} else if (codeLocation.methodKey() != null) {
name.append(", MethodKey=").append(longName(codeLocation.methodKey()));
}
}
} else if (codeLocation.hasTeleClassMethodActor()) {
name.append(longName(codeLocation.teleClassMethodActor())).append(", bci=").append(codeLocation.bci());
} else if (codeLocation.methodKey() != null) {
name.append("MethodKey=").append(longName(codeLocation.methodKey()));
}
return name.toString();
}
/**
* E.g. "0x11111111 foo()[0] com.sun.Example bci=-1.
*/
public String shortName(MaxCodeLocation codeLocation) {
if (codeLocation == null) {
return unavailableDataShortText();
}
final StringBuilder name = new StringBuilder();
if (codeLocation.hasAddress()) {
final Address address = codeLocation.address();
name.append(address.to0xHexString()).append(" ");
TeleNativeFunction nativeFunction = vm().machineCode().findNativeFunction(address);
if (nativeFunction != null) {
name.append(" in " + shortName(nativeFunction));
} else {
final MaxCompilation compilation = vm().machineCode().findCompilation(address);
if (compilation != null) {
name.append(extremelyShortName(compilation)).append(" ");
}
if (codeLocation.hasTeleClassMethodActor()) {
name.append(" bci=").append(codeLocation.bci());
} else if (codeLocation.methodKey() != null) {
name.append(shortName(codeLocation.methodKey()));
}
}
} else if (codeLocation.hasTeleClassMethodActor()) {
name.append(veryShortName(codeLocation.teleClassMethodActor())).append(" bci=").append(codeLocation.bci());
} else if (codeLocation.methodKey() != null) {
name.append(shortName(codeLocation.methodKey()));
}
return name.toString();
}
public String shortName(MaxMemoryRegion memoryRegion) {
return memoryRegion.regionName();
}
public String longName(MaxMemoryRegion memoryRegion) {
assert memoryRegion != null;
final String regionName = memoryRegion.regionName();
// Is it a heap region?
if (memoryRegion.sameAs(vm().heap().bootHeapRegion().memoryRegion())) {
return "boot heap region";
}
for (MaxHeapRegion heapRegion : vm().heap().heapRegions()) {
if (memoryRegion.sameAs(heapRegion.memoryRegion())) {
return "dynamic heap region \"" + regionName + "\"";
}
}
final MaxHeapRegion immortalHeapRegion = vm().heap().immortalHeapRegion();
if (immortalHeapRegion != null && memoryRegion.sameAs(immortalHeapRegion.memoryRegion())) {
return "immortal heap \"" + regionName + "\"";
}
// Is it a compiled code region?
if (memoryRegion.sameAs(vm().codeCache().bootCodeRegion().memoryRegion())) {
return "boot code region \"" + regionName + "\"";
}
for (MaxCodeCacheRegion codeRegion : vm().codeCache().codeCacheRegions()) {
if (memoryRegion.sameAs(codeRegion.memoryRegion())) {
return "dynamic code region \"" + regionName + "\"";
}
}
// Is it a thread-related region?
for (MaxThread thread : vm().threadManager().threads()) {
if (memoryRegion.sameAs(thread.stack().memoryRegion())) {
return "stack region for thread: " + longName(thread);
}
if (memoryRegion.sameAs(thread.localsBlock().memoryRegion())) {
return "locals region for thread: " + longName(thread);
}
}
return regionName;
}
/**
* Creates a comma-separated list of register names.
*
* @param registers a possibly empty list of registers
* @return a string containing the register names, separated by comma-space
*/
public String registerNameList(List<MaxRegister> registers) {
String nameList = "";
for (MaxRegister register : registers) {
if (nameList.length() > 0) {
nameList += ",";
}
nameList += register.name();
}
return nameList;
}
/**
* Renderer for a textual label reference pointing at heap objects in the VM.
*/
private interface ReferenceRenderer {
/**
* @return a short string suitable for a text label display of the object reference.
*/
String referenceLabelText(MaxObject object);
/**
* @return a short string suitable for a text label display of the object reference,
* with a limited number of characters.
*/
String referenceLabelText(MaxObject object, int maxLength);
/**
* @return a longer string suitable for a tooltip display over the object reference.
*/
String referenceToolTipText(MaxObject object);
/**
* @return a longer string suitable for a tooltip display over the object reference,
* with a limited number of characters.
*/
String referenceToolTipText(MaxObject object, int maxLength);
}
private static abstract class AbstractReferenceRenderer implements ReferenceRenderer {
/**
* {@inheritDoc}
* <p>
* Default implementation of character limits for renderers.
*/
public String referenceLabelText(MaxObject object, int maxLength) {
final String text = referenceLabelText(object);
if (text.length() < maxLength) {
return text;
}
return text.substring(0, maxLength - 4) + "...";
}
/**
* {@inheritDoc}
* <p>
* Default implementation of character limits for renderers.
*/
public String referenceToolTipText(MaxObject object, int maxLength) {
final String text = referenceToolTipText(object);
if (text.length() < maxLength) {
return text;
}
return text.substring(0, maxLength - 1);
}
}
/**
* Renderers for specific classes of objects in the heap in the VM.
* The most specific class that matches a particular {@link MaxObject} will
* be used, in an emulation of virtual method dispatch. All heap objects are
* implemented as tuples, hubs. or arrays, so there should always be at least
* a generic match for every type.
*/
private final Map<Class, ReferenceRenderer> referenceRenderers = new HashMap<Class, ReferenceRenderer>();
/**
* Creates a short textual presentation of a reference to a heap object in the VM, if possible, null if not.
*
* @param object surrogate for a heap object in the VM
* @return a textual presentation of a reference to a heap object
*/
public String referenceLabelText(MaxObject object) {
return referenceLabelText(object, Integer.MAX_VALUE);
}
/**
* Creates a short textual presentation of a reference to a heap object in the VM, if possible, null if not.
*
* @param object surrogate for a heap object in the VM
* @param maxLength maximum number of characters that should be produced, thought not guaranteed
* @return a textual presentation of a reference to a heap object
*/
public String referenceLabelText(MaxObject object, int maxLength) {
if (object != null) {
Class objectClass = object.getClass();
while (objectClass != null) {
final ReferenceRenderer objectReferenceRenderer = referenceRenderers.get(objectClass);
if (objectReferenceRenderer != null) {
try {
vm().acquireLegacyVMAccess();
try {
return objectReferenceRenderer.referenceLabelText(object, maxLength);
} finally {
vm().releaseLegacyVMAccess();
}
} catch (MaxVMBusyException maxVMBusyException) {
return unavailableDataShortText();
} catch (Throwable throwable) {
throwable.printStackTrace(Trace.stream());
return "(Unexpected error when getting reference label: " + throwable + ")";
}
}
objectClass = objectClass.getSuperclass();
}
InspectorError.unexpected("InspectorNameDisplay failed to find renderer for maxObject = " + object);
}
return null;
}
/**
* @return a long textual presentation of a reference to a heap object in the VM, if possible, null if not.
*/
public String referenceToolTipText(MaxObject object) {
if (object != null) {
try {
final Class leafClass = object.getClass();
Class objectClass = leafClass;
do {
final ReferenceRenderer objectReferenceRenderer = referenceRenderers.get(objectClass);
if (objectReferenceRenderer != null) {
if (leafClass != objectClass) {
// cache it so we will not have to search for it next time.
referenceRenderers.put(leafClass, objectReferenceRenderer);
}
try {
vm().acquireLegacyVMAccess();
try {
return objectReferenceRenderer.referenceToolTipText(object);
} finally {
vm().releaseLegacyVMAccess();
}
} catch (MaxVMBusyException maxVMBusyException) {
return unavailableDataLongText();
} catch (Throwable throwable) {
throwable.printStackTrace(Trace.stream());
return "(Unexpected error when getting tool tip label: " + throwable + ")";
}
}
objectClass = objectClass.getSuperclass();
} while (objectClass != null);
InspectorError.unexpected("InspectorNameDisplay failed to find renderer for maxObject = " + object);
} catch (Throwable e) {
e.printStackTrace(Trace.stream());
return "<html><b><font color=\"red\">" + e + "</font></b><br>See log for complete stack trace.";
}
}
return null;
}
/**
* E.g. "Object 0x01234567890 <99>ClassActor in BootHeap Region"
*/
public String longName(MaxObject object) {
final Pointer origin = object.origin();
final MaxMemoryRegion memoryRegion = vm().state().findMemoryRegion(origin);
final String name = "Object " + origin.toHexString() + inspection().nameDisplay().referenceLabelText(object);
final String suffix = " in "
+ (memoryRegion == null ? "unknown region" : memoryRegion.regionName());
String prefix = "";
final ObjectStatus memoryStatus = object.status();
if (!memoryStatus.isLive()) {
prefix = memoryStatus.label() + " ";
}
return prefix + name + suffix;
}
/**
* Textual renderer for references to arrays.
*/
private class ArrayReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleArrayObject teleArrayObject = (TeleArrayObject) object;
final ClassActor classActorForType = teleArrayObject.classActorForObjectType();
final String name = classActorForType.simpleName();
final int length = teleArrayObject.length();
return objectReference(null, teleArrayObject, null, name.substring(0, name.length() - 1) + length + "]");
}
public String referenceToolTipText(MaxObject object) {
final TeleArrayObject teleArrayObject = (TeleArrayObject) object;
final ClassActor classActorForType = teleArrayObject.classActorForObjectType();
final String name = classActorForType.name.toString();
final int length = teleArrayObject.length();
return objectReference(null, teleArrayObject, null, name.substring(0, name.length() - 1) + length + "]");
}
}
/**
* Textual renderer for references to static and dynamic hubs.
*/
private class HubReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleHub teleHub = (TeleHub) object;
//final Class javaType = teleHub.classActorForType().toJava();
final ClassActor classActor = teleHub.hub().classActor;
if (vm().classes().isUnregisteredClassName(classActor.name.string)) {
return objectReference(null, teleHub, teleHub.maxineTerseRole(), "*\"" + classActor.name.string + "\"");
}
final Class javaType = classActor.toJava();
return objectReference(null, teleHub, teleHub.maxineTerseRole(), javaType.getSimpleName());
}
public String referenceToolTipText(MaxObject object) {
final TeleHub teleHub = (TeleHub) object;
//final Class javaType = teleHub.classActorForType().toJava();
final ClassActor classActor = teleHub.hub().classActor;
if (vm().classes().isUnregisteredClassName(classActor.name.string)) {
return objectReference(null, teleHub, teleHub.maxineRole(), "(unregistered) \"" + classActor.name.string + "\"");
}
final Class javaType = classActor.toJava();
if (!(javaType.isPrimitive() || Word.class.isAssignableFrom(javaType))) {
return objectReference(null, teleHub, teleHub.maxineRole(), javaType.getName());
}
return null;
}
}
/**
* Textual renderer for references to ordinary objects, represented as tuples, for which there is no more specific renderer registered.
*/
private class TupleObjectReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleObject teleTupleObject = (TeleObject) object;
final ClassActor classActorForType = teleTupleObject.classActorForObjectType();
if (classActorForType != null) {
return objectReference(null, teleTupleObject, null, classActorForType.simpleName());
}
return null;
}
public String referenceToolTipText(MaxObject object) {
final TeleObject teleTupleObject = (TeleObject) object;
final ClassActor classActorForType = teleTupleObject.classActorForObjectType();
if (classActorForType != null) {
return objectReference(null, teleTupleObject, null, classActorForType.name.toString());
}
return null;
}
}
private class StaticTupleReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleStaticTuple teleStaticTuple = (TeleStaticTuple) object;
final ClassActor classActorForType = teleStaticTuple.classActorForObjectType();
return objectReference(null, teleStaticTuple, teleStaticTuple.maxineTerseRole(), classActorForType.simpleName());
}
public String referenceToolTipText(MaxObject object) {
final TeleStaticTuple teleStaticTuple = (TeleStaticTuple) object;
final ClassActor classActorForType = teleStaticTuple.classActorForObjectType();
return objectReference(null, teleStaticTuple, teleStaticTuple.maxineRole(), classActorForType.qualifiedName());
}
}
private class MethodActorReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleMethodActor teleMethodActor = (TeleMethodActor) object;
final MethodActor methodActor = teleMethodActor.methodActor();
return objectReference(null, object, object.maxineTerseRole(), methodActor.name.toString() + "()") + methodSubstitutionShortAnnotation(teleMethodActor);
}
public String referenceToolTipText(MaxObject object) {
final TeleMethodActor teleMethodActor = (TeleMethodActor) object;
final MethodActor methodActor = teleMethodActor.methodActor();
return objectReference(null, object, object.maxineRole(), methodActor.format("%r %n(%p)")) + methodSubstitutionLongAnnotation(teleMethodActor);
}
}
private class FieldActorReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleFieldActor teleFieldActor = (TeleFieldActor) object;
final FieldActor fieldActor = teleFieldActor.fieldActor();
return objectReference(null, object, object.maxineTerseRole(), fieldActor.name.toString());
}
public String referenceToolTipText(MaxObject object) {
final TeleFieldActor teleFieldActor = (TeleFieldActor) object;
final FieldActor fieldActor = teleFieldActor.fieldActor();
return objectReference(null, object, object.maxineRole(), fieldActor.format("%t %n"));
}
}
private class ClassActorReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleClassActor teleClassActor = (TeleClassActor) object;
final ClassActor classActor = teleClassActor.classActor();
if (vm().classes().isUnregisteredClassName(classActor.name.string)) {
return objectReference(null, object, object.maxineTerseRole(), "*\"" + classActor.name.string + "\"");
}
return objectReference(null, object, object.maxineTerseRole(), classActor.toJava().getSimpleName());
}
public String referenceToolTipText(MaxObject object) {
final TeleClassActor teleClassActor = (TeleClassActor) object;
final ClassActor classActor = teleClassActor.classActor();
if (vm().classes().isUnregisteredClassName(classActor.name.string)) {
return objectReference(null, object, object.maxineRole(), "(unregistered) \"" + classActor.name.string + "\"");
}
return objectReference(null, object, object.maxineRole(), classActor.name.toString());
}
}
private class StringReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleString teleString = (TeleString) object;
final String string = teleString.getString();
final String stringText = string == null ? unavailableDataShortText() : "\"" + string + "\"";
return objectReference(null, object, null, stringText);
}
@Override
public String referenceLabelText(MaxObject object, int maxLength) {
final String defaultLabelText = referenceLabelText(object);
final int trimLength = defaultLabelText.length() - maxLength;
if (trimLength <= 0) {
return defaultLabelText;
}
// The default's too long, try again with some trimming
final TeleString teleString = (TeleString) object;
final String stringText = teleString.getString();
if (stringText != null) {
if (trimLength <= stringText.length() - 3) {
// We can trim the string's text sufficiently and still leave room for the elipsis
return objectReference(null, object, null, "\"" + stringText.substring(0, stringText.length() - trimLength) + "...\"");
}
}
// Give up showing string contents; just show the standard object reference text
return objectReference(null, object, null, "");
}
public String referenceToolTipText(MaxObject object) {
final TeleString teleString = (TeleString) object;
final ClassActor classActorForType = teleString.classActorForObjectType();
final String s = teleString.getString();
return objectReference(null, object, classActorForType.qualifiedName(), "\"" + s + "\"");
}
}
private class Utf8ConstantReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleUtf8Constant teleUtf8Constant = (TeleUtf8Constant) object;
final String string = teleUtf8Constant.utf8Constant().string;
final String stringText = string == null ? unavailableDataShortText() : "\"" + string + "\"";
return objectReference(null, object, null, stringText);
}
@Override
public String referenceLabelText(MaxObject object, int maxLength) {
final String defaultLabelText = referenceLabelText(object);
final int trimLength = defaultLabelText.length() - maxLength;
if (trimLength <= 0) {
return defaultLabelText;
}
// The default's too long, try again with some trimming
final TeleUtf8Constant teleUtf8Constant = (TeleUtf8Constant) object;
final String stringText = teleUtf8Constant.utf8Constant().string;
if (stringText != null) {
if (trimLength <= stringText.length() - 3) {
// We can trim the string's text sufficiently and still leave room for the elipsis
return objectReference(null, object, null, "\"" + stringText.substring(0, stringText.length() - trimLength) + "...\"");
}
}
// Give up showing string contents; just show the standard object reference text
return objectReference(null, object, null, "");
}
public String referenceToolTipText(MaxObject object) {
final TeleUtf8Constant teleUtf8Constant = (TeleUtf8Constant) object;
final ClassActor classActorForType = teleUtf8Constant.classActorForObjectType();
final String s = teleUtf8Constant.utf8Constant().string;
return objectReference(null, object, classActorForType.qualifiedName(), "\"" + s + "\"");
}
}
private class StringConstantReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleStringConstant teleStringConstant = (TeleStringConstant) object;
final String string = teleStringConstant.getString();
final String stringText = string == null ? unavailableDataShortText() : "\"" + string + "\"";
return objectReference(null, object, null, stringText);
}
@Override
public String referenceLabelText(MaxObject object, int maxLength) {
final String defaultLabelText = referenceLabelText(object);
final int trimLength = defaultLabelText.length() - maxLength;
if (trimLength <= 0) {
return defaultLabelText;
}
// The default's too long, try again with some trimming
final TeleStringConstant teleStringConstant = (TeleStringConstant) object;
final String stringText = teleStringConstant.getString();
if (stringText != null) {
if (trimLength <= stringText.length() - 3) {
// We can trim the string's text sufficiently and still leave room for the elipsis
return objectReference(null, object, null, "\"" + stringText.substring(0, stringText.length() - trimLength) + "...\"");
}
}
// Give up showing string contents; just show the standard object reference text
return objectReference(null, object, null, "");
}
public String referenceToolTipText(MaxObject object) {
final TeleStringConstant teleStringConstant = (TeleStringConstant) object;
final ClassActor classActorForType = teleStringConstant.classActorForObjectType();
final String s = teleStringConstant.getString();
return objectReference(null, object, classActorForType.qualifiedName(), "\"" + s + "\"");
}
}
private class ClassReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleClass teleClass = (TeleClass) object;
final Class mirrorJavaClass = teleClass.toJava();
return objectReference(null, object, object.maxineTerseRole(), mirrorJavaClass.getSimpleName() + ".class");
}
public String referenceToolTipText(MaxObject object) {
final TeleClass teleClass = (TeleClass) object;
final Class mirrorJavaClass = teleClass.toJava();
return objectReference(null, object, object.maxineRole(), mirrorJavaClass.getName() + ".class");
}
}
private class ConstructorReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleConstructor teleConstructor = (TeleConstructor) object;
final Constructor mirrorJavaConstructor = teleConstructor.toJava();
if (mirrorJavaConstructor != null) {
return objectReference(null, object, object.maxineTerseRole(), mirrorJavaConstructor.getName() + "()");
}
return null;
}
public String referenceToolTipText(MaxObject object) {
final TeleConstructor teleConstructor = (TeleConstructor) object;
final Constructor mirrorJavaConstructor = teleConstructor.toJava();
if (mirrorJavaConstructor != null) {
return objectReference(null, object, object.maxineRole(), mirrorJavaConstructor.toString());
}
return null;
}
}
private class FieldReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleField teleField = (TeleField) object;
final Field mirrorJavaField = teleField.toJava();
if (mirrorJavaField != null) {
return objectReference(null, object, object.maxineTerseRole(), mirrorJavaField.getName());
}
return null;
}
public String referenceToolTipText(MaxObject object) {
final TeleField teleField = (TeleField) object;
final Field mirrorJavaField = teleField.toJava();
if (mirrorJavaField != null) {
return objectReference(null, object, object.maxineRole(), mirrorJavaField.toString());
}
return null;
}
}
private class MethodReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleMethod teleMethod = (TeleMethod) object;
final Method mirrorJavaMethod = teleMethod.toJava();
if (mirrorJavaMethod != null) {
return objectReference(null, object, object.maxineTerseRole(), mirrorJavaMethod.getName() + "()");
}
return null;
}
public String referenceToolTipText(MaxObject object) {
final TeleMethod teleMethod = (TeleMethod) object;
final Method mirrorJavaMethod = teleMethod.toJava();
if (mirrorJavaMethod != null) {
return objectReference(null, object, object.maxineRole(), mirrorJavaMethod.toString());
}
return null;
}
}
private class EnumReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleEnum teleEnum = (TeleEnum) object;
final ClassActor classActorForType = teleEnum.classActorForObjectType();
final String name = teleEnum.toJava().name();
return objectReference(null, object, null, classActorForType.toJava().getSimpleName() + "." + name);
}
public String referenceToolTipText(MaxObject object) {
final TeleEnum teleEnum = (TeleEnum) object;
final ClassActor classActorForType = teleEnum.classActorForObjectType();
final String name = teleEnum.toJava().name();
final int ordinal = teleEnum.toJava().ordinal();
return objectReference(null, object, null, classActorForType.qualifiedName() + "." + name + " ordinal=" + ordinal);
}
}
private class ConstantPoolReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleConstantPool teleConstantPool = (TeleConstantPool) object;
final ClassActor classActor = teleConstantPool.getTeleHolder().classActor();
return objectReference(null, object, object.maxineTerseRole(), classActor.toJava().getSimpleName());
}
public String referenceToolTipText(MaxObject object) {
final TeleConstantPool teleConstantPool = (TeleConstantPool) object;
final ClassActor classActor = teleConstantPool.getTeleHolder().classActor();
return objectReference(null, object, object.maxineRole(), classActor.name.toString());
}
}
private class ClassConstantResolvedReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleClassConstant.Resolved teleClassConstantResolved = (TeleClassConstant.Resolved) object;
final ClassActor classActor = teleClassConstantResolved.getTeleClassActor().classActor();
return objectReference(null, object, object.maxineTerseRole(), classActor.toJava().getSimpleName());
}
public String referenceToolTipText(MaxObject object) {
final TeleClassConstant.Resolved teleClassConstantResolved = (TeleClassConstant.Resolved) object;
final ClassActor classActor = teleClassConstantResolved.getTeleClassActor().classActor();
return objectReference(null, object, object.maxineRole(), classActor.name.toString());
}
}
private class FieldRefConstantResolvedReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleFieldRefConstant.Resolved teleFieldRefConstantResolved = (TeleFieldRefConstant.Resolved) object;
final FieldActor fieldActor = teleFieldRefConstantResolved.getTeleFieldActor().fieldActor();
return objectReference(null, object, object.maxineTerseRole(), fieldActor.name.toString());
}
public String referenceToolTipText(MaxObject object) {
final TeleFieldRefConstant.Resolved teleFieldRefConstantResolved = (TeleFieldRefConstant.Resolved) object;
final FieldActor fieldActor = teleFieldRefConstantResolved.getTeleFieldActor().fieldActor();
return objectReference(null, object, object.maxineRole(), fieldActor.format("%T %n"));
}
}
private class ClassMethodRefConstantResolvedReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleClassMethodRefConstant.Resolved teleClassMethodRefConstantResolved = (TeleClassMethodRefConstant.Resolved) object;
final MethodActor methodActor = teleClassMethodRefConstantResolved.getTeleClassMethodActor().methodActor();
return objectReference(null, object, object.maxineTerseRole(), methodActor.name.toString());
}
public String referenceToolTipText(MaxObject object) {
final TeleClassMethodRefConstant.Resolved teleClassMethodRefConstantResolved = (TeleClassMethodRefConstant.Resolved) object;
final MethodActor methodActor = teleClassMethodRefConstantResolved.getTeleClassMethodActor().methodActor();
return objectReference(null, object, object.maxineRole(), methodActor.format("%r %n(%p)"));
}
}
private class InterfaceMethodRefConstantResolvedReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleInterfaceMethodRefConstant.Resolved teleInterfaceMethodRefConstantResolved = (TeleInterfaceMethodRefConstant.Resolved) object;
final MethodActor methodActor = teleInterfaceMethodRefConstantResolved.getTeleInterfaceMethodActor().methodActor();
return objectReference(null, object, object.maxineTerseRole(), methodActor.name.toString());
}
public String referenceToolTipText(MaxObject object) {
final TeleInterfaceMethodRefConstant.Resolved teleInterfaceMethodRefConstantResolved = (TeleInterfaceMethodRefConstant.Resolved) object;
final MethodActor methodActor = teleInterfaceMethodRefConstantResolved.getTeleInterfaceMethodActor().methodActor();
return objectReference(null, object, object.maxineRole(), methodActor.format("%r %n(%p)"));
}
}
private class PoolConstantReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TelePoolConstant telePoolConstant = (TelePoolConstant) object;
final ClassActor classActorForType = telePoolConstant.classActorForObjectType();
return objectReference(null, object, null, classActorForType.simpleName());
}
public String referenceToolTipText(MaxObject object) {
final TelePoolConstant telePoolConstant = (TelePoolConstant) object;
final ClassActor classActorForType = telePoolConstant.classActorForObjectType();
return objectReference(null, object, null, "PoolConstant: " + classActorForType.qualifiedName());
}
}
private class VmThreadReferenceRenderer extends AbstractReferenceRenderer {
public String referenceLabelText(MaxObject object) {
final TeleVmThread teleVmThread = (TeleVmThread) object;
return objectReference(null, object, "VmThread", longName(teleVmThread.maxThread()));
}
public String referenceToolTipText(MaxObject object) {
final TeleVmThread teleVmThread = (TeleVmThread) object;
return objectReference(null, object, "VmThread", longName(teleVmThread.maxThread()));
}
}
}