/* * 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.value; import java.awt.event.*; import com.sun.max.ins.*; import com.sun.max.ins.gui.*; import com.sun.max.tele.*; import com.sun.max.unsafe.*; import com.sun.max.vm.monitor.*; import com.sun.max.vm.monitor.modal.modehandlers.*; import com.sun.max.vm.monitor.modal.modehandlers.inflated.*; import com.sun.max.vm.monitor.modal.modehandlers.lightweight.biased.*; import com.sun.max.vm.monitor.modal.modehandlers.lightweight.thin.*; import com.sun.max.vm.monitor.modal.schemes.*; import com.sun.max.vm.monitor.modal.schemes.ModalMonitorScheme.ModalLockwordDecoder; import com.sun.max.vm.value.*; /** * A label specialized for displaying the contents of the "misc." word value in * the header of an object in the VM. */ public final class MiscWordLabel extends ValueLabel { private final MaxObject object; private MaxObject javaMonitor = null; public MiscWordLabel(Inspection inspection, MaxObject object) { super(inspection, null); this.object = object; addMouseListener(new InspectorMouseClickAdapter(inspection()) { @Override public void procedure(final MouseEvent mouseEvent) { switch (inspection().gui().getButton(mouseEvent)) { case MouseEvent.BUTTON1: { final InspectorAction inspectAction = getInspectJavaMonitorAction(); if (inspectAction.isEnabled()) { inspectAction.perform(); } break; } case MouseEvent.BUTTON2: { // No toggle display action yet break; } case MouseEvent.BUTTON3: { final InspectorPopupMenu menu = new InspectorPopupMenu("Header Misc. Word"); menu.add(getCopyWordAction()); menu.add(getInspectJavaMonitorAction()); menu.show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY()); } } } }); initializeValue(); redisplay(); } @Override public Value fetchValue() { return new WordValue(object.readMiscWord()); } public void redisplay() { setFont(preference().style().hexDataFont()); updateText(); } private static ModalLockwordDecoder modalLockwordDecoder; @Override public void updateText() { if (vm().memoryIO().isZappedValue(value())) { setText(inspection().nameDisplay().zappedDataShortText()); setToolTipText(inspection().nameDisplay().zappedDataLongText()); } else { final Word miscWord = value().asWord(); final String hexString = miscWord.toHexString(); final MonitorScheme monitorScheme = vm().bootImage().vmConfiguration.monitorScheme(); if (monitorScheme instanceof ModalMonitorScheme) { javaMonitor = null; if (modalLockwordDecoder == null) { final ModalMonitorScheme modalMonitorScheme = (ModalMonitorScheme) monitorScheme; modalLockwordDecoder = modalMonitorScheme.getModalLockwordDecoder(); } final ModalLockword64 modalLockword = ModalLockword64.from(miscWord); if (modalLockwordDecoder.isLockwordInMode(modalLockword, BiasedLockword64.class)) { final BiasedLockword64 biasedLockword = BiasedLockword64.from(modalLockword); final int hashcode = biasedLockword.getHashcode(); final int recursion = biasedLockword.getRecursionCount(); final int ownerThreadID = BiasedLockModeHandler.decodeBiasOwnerThreadID(biasedLockword); final MaxThread thread = vm().threadManager().getThread(ownerThreadID); final String threadName = inspection().nameDisplay().longName(thread); final int biasEpoch = biasedLockword.getEpoch().toInt(); setText("BiasedLock(" + recursion + "): " + hexString); setToolTipText("BiasedLockword64: recursion=" + recursion + "; thread=" + threadName + "; biasEpoch=" + biasEpoch + "; hashcode=" + hashcode); } else if (modalLockwordDecoder.isLockwordInMode(modalLockword, ThinLockword64.class)) { final ThinLockword64 thinLockword = ThinLockword64.from(modalLockword); final int hashcode = thinLockword.getHashcode(); final int recursionCount = thinLockword.getRecursionCount(); final int ownerThreadID = ThinLockModeHandler.decodeLockOwnerThreadID(thinLockword); final MaxThread thread = vm().threadManager().getThread(ownerThreadID); final String threadName = inspection().nameDisplay().longName(thread); setText("ThinLock(" + recursionCount + "): " + hexString); setToolTipText("ThinLockword64: recursion=" + recursionCount + "; thread=" + threadName + "; hashcode=" + hashcode); } else if (modalLockwordDecoder.isLockwordInMode(modalLockword, InflatedMonitorLockword64.class)) { setText("InflatedMonitorLock: " + hexString); final InflatedMonitorLockword64 inflatedLockword = InflatedMonitorLockword64.from(modalLockword); final boolean isBound = inflatedLockword.isBound(); if (isBound) { // JavaMonitor is a proper object, not just a Word. try { javaMonitor = vm().objects().findObjectAt(inflatedLockword.getBoundMonitorReferenceAsWord().asAddress()); } catch (MaxVMBusyException e) { } if (javaMonitor == null) { setToolTipText("InflatedMonitorLockword64: bound, monitor=" + inspection().nameDisplay().unavailableDataLongText()); } else { final String name = javaMonitor.classActorForObjectType().qualifiedName(); setToolTipText("InflatedMonitorLockword64: bound, monitor=" + name); } } else { // Field access final int hashcode = inflatedLockword.getHashcode(); setToolTipText("InflatedMonitorLockword64: unbound, hashcode=" + hashcode); } } else { setText(hexString); setToolTipText("Non-decodable ModalLockword64"); } } else { setText(hexString); setToolTipText(null); } } } private InspectorAction getCopyWordAction() { return actions().copyWord(value().asWord(), "Copy word to clipboard"); } private InspectorAction getInspectJavaMonitorAction() { final InspectorAction action = views().objects().makeViewAction(javaMonitor, "View JavaMonitor (left-button)"); action.setEnabled(javaMonitor != null); return action; } }