Mercurial > hg > truffle
view graal/com.oracle.max.asmdis/src/com/sun/max/asm/dis/AddressMapper.java @ 4138:82af018d61db
Merge fixes.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 17 Dec 2011 22:03:44 +0100 |
parents | e233f5660da4 |
children | bc8527f3071c |
line wrap: on
line source
/* * Copyright (c) 2008, 2011, 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.asm.dis; import java.util.*; import com.sun.max.asm.gen.*; /** * A facility for mapping addresses to {@linkplain DisassembledLabel labels} and {@linkplain DisassembledObject * disassembled objects}. Labels are only used to identify addresses that are a) explicitly targeted by an operand of a * disassembled object {@linkplain #add(DisassembledObject) added} to the map or b) explicitly * {@linkplain #add(ImmediateArgument, String) added}. */ public class AddressMapper { private int serial; private int unnamedLabels; private final Map<ImmediateArgument, DisassembledObject> objectMap = new HashMap<ImmediateArgument, DisassembledObject>(); private final Map<ImmediateArgument, DisassembledLabel> labelMap = new TreeMap<ImmediateArgument, DisassembledLabel>(new Comparator<ImmediateArgument>() { public int compare(ImmediateArgument o1, ImmediateArgument o2) { final long l1 = o1.asLong(); final long l2 = o2.asLong(); if (l1 < l2) { return -1; } else if (l1 > l2) { return 1; } return 0; } }); /** * Gets the label for a given address. * * @param address the address for which a label is requested * @return the label for {@code address} or null if no label exists for that address */ public synchronized DisassembledLabel labelAt(ImmediateArgument address) { fixupUnnamedLabels(); return labelMap.get(address); } /** * Gets the label for a given disassembled object. * * @param disassembledObject the disassembled object for which a label is requested * @return the label corresponding to {@code disassembledObject}'s start address or null if no label exists for that address */ public synchronized DisassembledLabel labelAt(DisassembledObject disassembledObject) { fixupUnnamedLabels(); return labelAt(disassembledObject.startAddress()); } /** * Adds a mapping from a given address to a given name. * * @return the previous mapping (if any) for {@code address} */ public synchronized DisassembledLabel add(ImmediateArgument address, String name) { return labelMap.put(address, new DisassembledLabel(address, name)); } /** * Adds a mapping for the address {@linkplain DisassembledObject#targetAddress() targeted} by a given disassembled object. * If {@code disassembledObject} does not target another object, then no update is made to this mapping. * * @param disassembledObject the disassembled object to consider */ public void add(DisassembledObject disassembledObject) { add(Arrays.asList(new DisassembledObject[] {disassembledObject})); } /** * Adds a mapping for the addresses {@linkplain DisassembledObject#targetAddress() targeted} by a given sequence of * disassembled objects. If none of {@code disassembledObjects} target other objects, then no update is made to * this mapping. * * @param disassembledObjects the disassembled objects to consider */ public synchronized void add(List<DisassembledObject> disassembledObjects) { for (DisassembledObject disassembledObject : disassembledObjects) { final ImmediateArgument address = disassembledObject.startAddress(); objectMap.put(address, disassembledObject); } for (DisassembledObject disassembledObject : disassembledObjects) { final ImmediateArgument targetAddress = disassembledObject.targetAddress(); if (targetAddress != null) { final DisassembledObject targetDisassembledObject = objectMap.get(targetAddress); if (targetDisassembledObject == null) { labelMap.remove(targetAddress); } else { DisassembledLabel label = labelMap.get(targetAddress); if (label == null || label.target() != targetDisassembledObject) { label = new UnnamedLabel(targetDisassembledObject); final DisassembledLabel oldValue = labelMap.put(targetAddress, label); if (!(oldValue instanceof UnnamedLabel)) { unnamedLabels++; } } } } } } private static class UnnamedLabel extends DisassembledLabel { UnnamedLabel(DisassembledObject targetDisassembledObject) { super(targetDisassembledObject, "L?"); } } private void fixupUnnamedLabels() { while (unnamedLabels != 0) { for (Map.Entry<ImmediateArgument, DisassembledLabel> entry : labelMap.entrySet()) { final DisassembledLabel label = entry.getValue(); if (label instanceof UnnamedLabel) { entry.setValue(new DisassembledLabel(label.target(), "L" + (++serial))); unnamedLabels--; } } } } /** * Computes the maximum length of any label name in this mapping. */ public synchronized int maximumLabelNameLength() { fixupUnnamedLabels(); int max = 0; for (DisassembledLabel label : labelMap.values()) { final String name = label.name(); if (name.length() > max) { max = name.length(); } } return max; } }