提交 42108633 编写于 作者: N never

Merge

...@@ -2615,7 +2615,8 @@ void MacroAssembler::cas_under_lock(Register top_ptr_reg, Register top_reg, Regi ...@@ -2615,7 +2615,8 @@ void MacroAssembler::cas_under_lock(Register top_ptr_reg, Register top_reg, Regi
} }
} }
void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, Register temp_reg, void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg,
Register temp_reg,
Label& done, Label* slow_case, Label& done, Label* slow_case,
BiasedLockingCounters* counters) { BiasedLockingCounters* counters) {
assert(UseBiasedLocking, "why call this otherwise?"); assert(UseBiasedLocking, "why call this otherwise?");
...@@ -2691,8 +2692,7 @@ void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, R ...@@ -2691,8 +2692,7 @@ void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, R
markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place, markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place,
mark_reg); mark_reg);
or3(G2_thread, mark_reg, temp_reg); or3(G2_thread, mark_reg, temp_reg);
casx_under_lock(mark_addr.base(), mark_reg, temp_reg, casn(mark_addr.base(), mark_reg, temp_reg);
(address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
// If the biasing toward our thread failed, this means that // If the biasing toward our thread failed, this means that
// another thread succeeded in biasing it toward itself and we // another thread succeeded in biasing it toward itself and we
// need to revoke that bias. The revocation will occur in the // need to revoke that bias. The revocation will occur in the
...@@ -2721,8 +2721,7 @@ void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, R ...@@ -2721,8 +2721,7 @@ void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, R
load_klass(obj_reg, temp_reg); load_klass(obj_reg, temp_reg);
ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg); ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg);
or3(G2_thread, temp_reg, temp_reg); or3(G2_thread, temp_reg, temp_reg);
casx_under_lock(mark_addr.base(), mark_reg, temp_reg, casn(mark_addr.base(), mark_reg, temp_reg);
(address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
// If the biasing toward our thread failed, this means that // If the biasing toward our thread failed, this means that
// another thread succeeded in biasing it toward itself and we // another thread succeeded in biasing it toward itself and we
// need to revoke that bias. The revocation will occur in the // need to revoke that bias. The revocation will occur in the
...@@ -2752,8 +2751,7 @@ void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, R ...@@ -2752,8 +2751,7 @@ void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, R
// bits in this situation. Should attempt to preserve them. // bits in this situation. Should attempt to preserve them.
load_klass(obj_reg, temp_reg); load_klass(obj_reg, temp_reg);
ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg); ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg);
casx_under_lock(mark_addr.base(), mark_reg, temp_reg, casn(mark_addr.base(), mark_reg, temp_reg);
(address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
// Fall through to the normal CAS-based lock, because no matter what // Fall through to the normal CAS-based lock, because no matter what
// the result of the above CAS, some thread must have succeeded in // the result of the above CAS, some thread must have succeeded in
// removing the bias bit from the object's header. // removing the bias bit from the object's header.
...@@ -2815,8 +2813,10 @@ void MacroAssembler::casn (Register addr_reg, Register cmp_reg, Register set_reg ...@@ -2815,8 +2813,10 @@ void MacroAssembler::casn (Register addr_reg, Register cmp_reg, Register set_reg
// effect). // effect).
void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch, void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark,
BiasedLockingCounters* counters) { Register Rbox, Register Rscratch,
BiasedLockingCounters* counters,
bool try_bias) {
Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes()); Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes());
verify_oop(Roop); verify_oop(Roop);
...@@ -2838,7 +2838,7 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Registe ...@@ -2838,7 +2838,7 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Registe
// Fetch object's markword // Fetch object's markword
ld_ptr(mark_addr, Rmark); ld_ptr(mark_addr, Rmark);
if (UseBiasedLocking) { if (try_bias) {
biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters); biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
} }
...@@ -2881,7 +2881,7 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Registe ...@@ -2881,7 +2881,7 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Registe
ld_ptr (mark_addr, Rmark); // fetch obj->mark ld_ptr (mark_addr, Rmark); // fetch obj->mark
// Triage: biased, stack-locked, neutral, inflated // Triage: biased, stack-locked, neutral, inflated
if (UseBiasedLocking) { if (try_bias) {
biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters); biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
// Invariant: if control reaches this point in the emitted stream // Invariant: if control reaches this point in the emitted stream
// then Rmark has not been modified. // then Rmark has not been modified.
...@@ -2945,7 +2945,7 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Registe ...@@ -2945,7 +2945,7 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Registe
ld_ptr (mark_addr, Rmark); // fetch obj->mark ld_ptr (mark_addr, Rmark); // fetch obj->mark
// Triage: biased, stack-locked, neutral, inflated // Triage: biased, stack-locked, neutral, inflated
if (UseBiasedLocking) { if (try_bias) {
biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters); biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
// Invariant: if control reaches this point in the emitted stream // Invariant: if control reaches this point in the emitted stream
// then Rmark has not been modified. // then Rmark has not been modified.
...@@ -3039,7 +3039,9 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Registe ...@@ -3039,7 +3039,9 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Registe
bind (done) ; bind (done) ;
} }
void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch) { void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark,
Register Rbox, Register Rscratch,
bool try_bias) {
Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes()); Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes());
Label done ; Label done ;
...@@ -3050,7 +3052,7 @@ void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark, Regis ...@@ -3050,7 +3052,7 @@ void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark, Regis
} }
if (EmitSync & 8) { if (EmitSync & 8) {
if (UseBiasedLocking) { if (try_bias) {
biased_locking_exit(mark_addr, Rscratch, done); biased_locking_exit(mark_addr, Rscratch, done);
} }
...@@ -3077,7 +3079,7 @@ void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark, Regis ...@@ -3077,7 +3079,7 @@ void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark, Regis
// I$ effects. // I$ effects.
Label LStacked ; Label LStacked ;
if (UseBiasedLocking) { if (try_bias) {
// TODO: eliminate redundant LDs of obj->mark // TODO: eliminate redundant LDs of obj->mark
biased_locking_exit(mark_addr, Rscratch, done); biased_locking_exit(mark_addr, Rscratch, done);
} }
......
...@@ -2220,9 +2220,13 @@ class MacroAssembler: public Assembler { ...@@ -2220,9 +2220,13 @@ class MacroAssembler: public Assembler {
// These set the icc condition code to equal if the lock succeeded // These set the icc condition code to equal if the lock succeeded
// and notEqual if it failed and requires a slow case // and notEqual if it failed and requires a slow case
void compiler_lock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch, void compiler_lock_object(Register Roop, Register Rmark, Register Rbox,
BiasedLockingCounters* counters = NULL); Register Rscratch,
void compiler_unlock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch); BiasedLockingCounters* counters = NULL,
bool try_bias = UseBiasedLocking);
void compiler_unlock_object(Register Roop, Register Rmark, Register Rbox,
Register Rscratch,
bool try_bias = UseBiasedLocking);
// Biased locking support // Biased locking support
// Upon entry, lock_reg must point to the lock record on the stack, // Upon entry, lock_reg must point to the lock record on the stack,
......
此差异已折叠。
...@@ -621,6 +621,10 @@ address Assembler::locate_operand(address inst, WhichOperand which) { ...@@ -621,6 +621,10 @@ address Assembler::locate_operand(address inst, WhichOperand which) {
debug_only(has_disp32 = true); debug_only(has_disp32 = true);
break; break;
case 0xF0: // Lock
assert(os::is_MP(), "only on MP");
goto again_after_prefix;
case 0xF3: // For SSE case 0xF3: // For SSE
case 0xF2: // For SSE2 case 0xF2: // For SSE2
switch (0xFF & *ip++) { switch (0xFF & *ip++) {
......
...@@ -1780,7 +1780,8 @@ class MacroAssembler: public Assembler { ...@@ -1780,7 +1780,8 @@ class MacroAssembler: public Assembler {
// check info (currently consumed only by C1). If // check info (currently consumed only by C1). If
// swap_reg_contains_mark is true then returns -1 as it is assumed // swap_reg_contains_mark is true then returns -1 as it is assumed
// the calling code has already passed any potential faults. // the calling code has already passed any potential faults.
int biased_locking_enter(Register lock_reg, Register obj_reg, Register swap_reg, Register tmp_reg, int biased_locking_enter(Register lock_reg, Register obj_reg,
Register swap_reg, Register tmp_reg,
bool swap_reg_contains_mark, bool swap_reg_contains_mark,
Label& done, Label* slow_case = NULL, Label& done, Label* slow_case = NULL,
BiasedLockingCounters* counters = NULL); BiasedLockingCounters* counters = NULL);
......
此差异已折叠。
此差异已折叠。
...@@ -103,16 +103,16 @@ encode %{ ...@@ -103,16 +103,16 @@ encode %{
// This name is KNOWN by the ADLC and cannot be changed. // This name is KNOWN by the ADLC and cannot be changed.
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
// for this guy. // for this guy.
instruct tlsLoadP(eAXRegP dst, eFlagsReg cr) %{ instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
match(Set dst (ThreadLocal)); match(Set dst (ThreadLocal));
effect(DEF dst, KILL cr); effect(DEF dst, KILL cr);
format %{ "MOV EAX, Thread::current()" %} format %{ "MOV $dst, Thread::current()" %}
ins_encode( linux_tlsencode(dst) ); ins_encode( linux_tlsencode(dst) );
ins_pipe( ialu_reg_fat ); ins_pipe( ialu_reg_fat );
%} %}
instruct TLS(eAXRegP dst) %{ instruct TLS(eRegP dst) %{
match(Set dst (ThreadLocal)); match(Set dst (ThreadLocal));
expand %{ expand %{
......
...@@ -110,16 +110,16 @@ encode %{ ...@@ -110,16 +110,16 @@ encode %{
// This name is KNOWN by the ADLC and cannot be changed. // This name is KNOWN by the ADLC and cannot be changed.
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
// for this guy. // for this guy.
instruct tlsLoadP(eAXRegP dst, eFlagsReg cr) %{ instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
match(Set dst (ThreadLocal)); match(Set dst (ThreadLocal));
effect(DEF dst, KILL cr); effect(DEF dst, KILL cr);
format %{ "MOV EAX, Thread::current()" %} format %{ "MOV $dst, Thread::current()" %}
ins_encode( solaris_tlsencode(dst) ); ins_encode( solaris_tlsencode(dst) );
ins_pipe( ialu_reg_fat ); ins_pipe( ialu_reg_fat );
%} %}
instruct TLS(eAXRegP dst) %{ instruct TLS(eRegP dst) %{
match(Set dst (ThreadLocal)); match(Set dst (ThreadLocal));
expand %{ expand %{
......
...@@ -28,6 +28,7 @@ import com.sun.hotspot.igv.data.InputGraph; ...@@ -28,6 +28,7 @@ import com.sun.hotspot.igv.data.InputGraph;
import com.sun.hotspot.igv.data.services.InputGraphProvider; import com.sun.hotspot.igv.data.services.InputGraphProvider;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.io.Serializable; import java.io.Serializable;
import javax.swing.SwingUtilities;
import org.openide.ErrorManager; import org.openide.ErrorManager;
import org.openide.explorer.ExplorerManager; import org.openide.explorer.ExplorerManager;
import org.openide.explorer.ExplorerUtils; import org.openide.explorer.ExplorerUtils;
...@@ -151,14 +152,18 @@ final class BytecodeViewTopComponent extends TopComponent implements ExplorerMan ...@@ -151,14 +152,18 @@ final class BytecodeViewTopComponent extends TopComponent implements ExplorerMan
} }
public void resultChanged(LookupEvent lookupEvent) { public void resultChanged(LookupEvent lookupEvent) {
InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class); final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
if (p != null) { if (p != null) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
InputGraph graph = p.getGraph(); InputGraph graph = p.getGraph();
if (graph != null) { if (graph != null) {
Group g = graph.getGroup(); Group g = graph.getGroup();
rootNode.update(graph, g.getMethod()); rootNode.update(graph, g.getMethod());
} }
} }
});
}
} }
final static class ResolvableHelper implements Serializable { final static class ResolvableHelper implements Serializable {
......
...@@ -33,7 +33,7 @@ import java.awt.Point; ...@@ -33,7 +33,7 @@ import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Hashtable; import java.util.HashMap;
import java.util.Set; import java.util.Set;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import org.netbeans.api.visual.action.ActionFactory; import org.netbeans.api.visual.action.ActionFactory;
...@@ -44,7 +44,6 @@ import org.netbeans.api.visual.action.SelectProvider; ...@@ -44,7 +44,6 @@ import org.netbeans.api.visual.action.SelectProvider;
import org.netbeans.api.visual.action.WidgetAction; import org.netbeans.api.visual.action.WidgetAction;
import org.netbeans.api.visual.anchor.AnchorFactory; import org.netbeans.api.visual.anchor.AnchorFactory;
import org.netbeans.api.visual.anchor.AnchorShape; import org.netbeans.api.visual.anchor.AnchorShape;
import com.sun.hotspot.igv.controlflow.HierarchicalGraphLayout;
import org.netbeans.api.visual.layout.LayoutFactory; import org.netbeans.api.visual.layout.LayoutFactory;
import org.netbeans.api.visual.router.RouterFactory; import org.netbeans.api.visual.router.RouterFactory;
import org.netbeans.api.visual.widget.LayerWidget; import org.netbeans.api.visual.widget.LayerWidget;
...@@ -61,8 +60,8 @@ import org.openide.util.Lookup; ...@@ -61,8 +60,8 @@ import org.openide.util.Lookup;
*/ */
public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> implements SelectProvider, MoveProvider, RectangularSelectDecorator, RectangularSelectProvider { public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> implements SelectProvider, MoveProvider, RectangularSelectDecorator, RectangularSelectProvider {
private Set<BlockWidget> selection; private HashSet<BlockWidget> selection;
private Hashtable<InputBlock, BlockWidget> blockMap; private HashMap<InputBlock, BlockWidget> blockMap;
private InputGraph oldGraph; private InputGraph oldGraph;
private LayerWidget edgeLayer; private LayerWidget edgeLayer;
private LayerWidget mainLayer; private LayerWidget mainLayer;
......
...@@ -28,6 +28,7 @@ import com.sun.hotspot.igv.data.services.InputGraphProvider; ...@@ -28,6 +28,7 @@ import com.sun.hotspot.igv.data.services.InputGraphProvider;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.io.Serializable; import java.io.Serializable;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import org.openide.ErrorManager; import org.openide.ErrorManager;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.openide.util.LookupEvent; import org.openide.util.LookupEvent;
...@@ -143,13 +144,17 @@ final class ControlFlowTopComponent extends TopComponent implements LookupListen ...@@ -143,13 +144,17 @@ final class ControlFlowTopComponent extends TopComponent implements LookupListen
public void resultChanged(LookupEvent lookupEvent) { public void resultChanged(LookupEvent lookupEvent) {
InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class); final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
if (p != null) { if (p != null) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
InputGraph g = p.getGraph(); InputGraph g = p.getGraph();
if (g != null) { if (g != null) {
scene.setGraph(g); scene.setGraph(g);
} }
} }
});
}
} }
@Override @Override
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
package com.sun.hotspot.igv.coordinator; package com.sun.hotspot.igv.coordinator;
import com.sun.hotspot.igv.coordinator.actions.RemoveCookie; import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
import com.sun.hotspot.igv.data.ChangedListener;
import com.sun.hotspot.igv.data.Group; import com.sun.hotspot.igv.data.Group;
import com.sun.hotspot.igv.data.services.GroupOrganizer; import com.sun.hotspot.igv.data.services.GroupOrganizer;
import com.sun.hotspot.igv.data.InputGraph; import com.sun.hotspot.igv.data.InputGraph;
...@@ -50,17 +51,24 @@ public class FolderNode extends AbstractNode { ...@@ -50,17 +51,24 @@ public class FolderNode extends AbstractNode {
private List<String> subFolders; private List<String> subFolders;
private FolderChildren children; private FolderChildren children;
private static class FolderChildren extends Children.Keys { private static class FolderChildren extends Children.Keys implements ChangedListener<Group> {
private FolderNode parent; private FolderNode parent;
private List<Group> registeredGroups;
public void setParent(FolderNode parent) { public void setParent(FolderNode parent) {
this.parent = parent; this.parent = parent;
this.registeredGroups = new ArrayList<Group>();
} }
@Override @Override
protected Node[] createNodes(Object arg0) { protected Node[] createNodes(Object arg0) {
for(Group g : registeredGroups) {
g.getChangedEvent().removeListener(this);
}
registeredGroups.clear();
Pair<String, List<Group>> p = (Pair<String, List<Group>>) arg0; Pair<String, List<Group>> p = (Pair<String, List<Group>>) arg0;
if (p.getLeft().length() == 0) { if (p.getLeft().length() == 0) {
...@@ -69,6 +77,8 @@ public class FolderNode extends AbstractNode { ...@@ -69,6 +77,8 @@ public class FolderNode extends AbstractNode {
for (InputGraph graph : g.getGraphs()) { for (InputGraph graph : g.getGraphs()) {
curNodes.add(new GraphNode(graph)); curNodes.add(new GraphNode(graph));
} }
g.getChangedEvent().addListener(this);
registeredGroups.add(g);
} }
Node[] result = new Node[curNodes.size()]; Node[] result = new Node[curNodes.size()];
...@@ -85,7 +95,13 @@ public class FolderNode extends AbstractNode { ...@@ -85,7 +95,13 @@ public class FolderNode extends AbstractNode {
@Override @Override
public void addNotify() { public void addNotify() {
this.setKeys(parent.structure); this.setKeys(parent.structure);
}
public void changed(Group source) {
List<Pair<String, List<Group>>> newStructure = new ArrayList<Pair<String, List<Group>>>();
for(Pair<String, List<Group>> p : parent.structure) {
refreshKey(p);
}
} }
} }
......
...@@ -31,7 +31,7 @@ import java.util.List; ...@@ -31,7 +31,7 @@ import java.util.List;
* *
* @author Thomas Wuerthinger * @author Thomas Wuerthinger
*/ */
public class GraphDocument extends Properties.Object implements ChangedEventProvider<GraphDocument> { public class GraphDocument extends Properties.Entity implements ChangedEventProvider<GraphDocument> {
private List<Group> groups; private List<Group> groups;
private ChangedEvent<GraphDocument> changedEvent; private ChangedEvent<GraphDocument> changedEvent;
......
...@@ -37,7 +37,7 @@ import java.util.Set; ...@@ -37,7 +37,7 @@ import java.util.Set;
* *
* @author Thomas Wuerthinger * @author Thomas Wuerthinger
*/ */
public class Group extends Properties.Object implements ChangedEventProvider<Group> { public class Group extends Properties.Entity implements ChangedEventProvider<Group> {
private List<InputGraph> graphs; private List<InputGraph> graphs;
private transient ChangedEvent<Group> changedEvent; private transient ChangedEvent<Group> changedEvent;
......
...@@ -23,26 +23,25 @@ ...@@ -23,26 +23,25 @@
*/ */
package com.sun.hotspot.igv.data; package com.sun.hotspot.igv.data;
import com.sun.hotspot.igv.data.Properties; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Hashtable; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
/** /**
* *
* @author Thomas Wuerthinger * @author Thomas Wuerthinger
*/ */
public class InputGraph extends Properties.Object { public class InputGraph extends Properties.Entity {
private Map<Integer, InputNode> nodes; private HashMap<Integer, InputNode> nodes;
private Set<InputEdge> edges; private ArrayList<InputEdge> edges;
private Group parent; private Group parent;
private Map<String, InputBlock> blocks; private HashMap<String, InputBlock> blocks;
private Map<Integer, InputBlock> nodeToBlock; private HashMap<Integer, InputBlock> nodeToBlock;
private boolean isDifferenceGraph; private boolean isDifferenceGraph;
public InputGraph(Group parent) { public InputGraph(Group parent) {
...@@ -61,10 +60,10 @@ public class InputGraph extends Properties.Object { ...@@ -61,10 +60,10 @@ public class InputGraph extends Properties.Object {
public InputGraph(Group parent, InputGraph last, String name) { public InputGraph(Group parent, InputGraph last, String name) {
this.parent = parent; this.parent = parent;
setName(name); setName(name);
nodes = new Hashtable<Integer, InputNode>(); nodes = new HashMap<Integer, InputNode>();
edges = new HashSet<InputEdge>(); edges = new ArrayList<InputEdge>();
blocks = new Hashtable<String, InputBlock>(); blocks = new HashMap<String, InputBlock>();
nodeToBlock = new Hashtable<Integer, InputBlock>(); nodeToBlock = new HashMap<Integer, InputBlock>();
if (last != null) { if (last != null) {
for (InputNode n : last.getNodes()) { for (InputNode n : last.getNodes()) {
...@@ -182,8 +181,8 @@ public class InputGraph extends Properties.Object { ...@@ -182,8 +181,8 @@ public class InputGraph extends Properties.Object {
return nodes.remove(index); return nodes.remove(index);
} }
public Set<InputEdge> getEdges() { public Collection<InputEdge> getEdges() {
return Collections.unmodifiableSet(edges); return Collections.unmodifiableList(edges);
} }
public void removeEdge(InputEdge c) { public void removeEdge(InputEdge c) {
......
...@@ -32,7 +32,7 @@ import java.util.List; ...@@ -32,7 +32,7 @@ import java.util.List;
* *
* @author Thomas Wuerthinger * @author Thomas Wuerthinger
*/ */
public class InputMethod extends Properties.Object { public class InputMethod extends Properties.Entity {
private String name; private String name;
private int bci; private int bci;
......
...@@ -27,7 +27,7 @@ package com.sun.hotspot.igv.data; ...@@ -27,7 +27,7 @@ package com.sun.hotspot.igv.data;
* *
* @author Thomas Wuerthinger * @author Thomas Wuerthinger
*/ */
public class InputNode extends Properties.Object { public class InputNode extends Properties.Entity {
private int id; private int id;
......
...@@ -26,24 +26,22 @@ package com.sun.hotspot.igv.data; ...@@ -26,24 +26,22 @@ package com.sun.hotspot.igv.data;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Iterator;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
* *
* @author Thomas Wuerthinger * @author Thomas Wuerthinger
*/ */
public class Properties implements Serializable { public class Properties implements Serializable, Iterable<Property> {
public static final long serialVersionUID = 1L; public static final long serialVersionUID = 1L;
private Map<String, Property> map; private String[] map = new String[4];
public Properties() { public Properties() {
map = new HashMap<String, Property>(5);
} }
@Override @Override
...@@ -54,10 +52,7 @@ public class Properties implements Serializable { ...@@ -54,10 +52,7 @@ public class Properties implements Serializable {
Properties p = (Properties) o; Properties p = (Properties) o;
if (getProperties().size() != p.getProperties().size()) { for (Property prop : this) {
return false;
}
for (Property prop : getProperties()) {
String value = p.get(prop.getName()); String value = p.get(prop.getName());
if (value == null || !value.equals(prop.getValue())) { if (value == null || !value.equals(prop.getValue())) {
return false; return false;
...@@ -75,32 +70,33 @@ public class Properties implements Serializable { ...@@ -75,32 +70,33 @@ public class Properties implements Serializable {
public Properties(String name, String value) { public Properties(String name, String value) {
this(); this();
this.add(new Property(name, value)); this.setProperty(name, value);
} }
public Properties(String name, String value, String name1, String value1) { public Properties(String name, String value, String name1, String value1) {
this(name, value); this(name, value);
this.add(new Property(name1, value1)); this.setProperty(name1, value1);
} }
public Properties(String name, String value, String name1, String value1, String name2, String value2) { public Properties(String name, String value, String name1, String value1, String name2, String value2) {
this(name, value, name1, value1); this(name, value, name1, value1);
this.add(new Property(name2, value2)); this.setProperty(name2, value2);
} }
public Properties(Properties p) { public Properties(Properties p) {
map = new HashMap<String, Property>(p.map); map = new String[p.map.length];
System.arraycopy(map, 0, p.map, 0, p.map.length);
} }
public static class Object implements Provider { public static class Entity implements Provider {
private Properties properties; private Properties properties;
public Object() { public Entity() {
properties = new Properties(); properties = new Properties();
} }
public Object(Properties.Object object) { public Entity(Properties.Entity object) {
properties = new Properties(object.getProperties()); properties = new Properties(object.getProperties());
} }
...@@ -109,6 +105,14 @@ public class Properties implements Serializable { ...@@ -109,6 +105,14 @@ public class Properties implements Serializable {
} }
} }
private String getProperty(String key) {
for (int i = 0; i < map.length; i += 2)
if (map[i] != null && map[i].equals(key)) {
return map[i + 1];
}
return null;
}
public interface PropertyMatcher { public interface PropertyMatcher {
String getName(); String getName();
...@@ -173,13 +177,15 @@ public class Properties implements Serializable { ...@@ -173,13 +177,15 @@ public class Properties implements Serializable {
} }
public Property selectSingle(PropertyMatcher matcher) { public Property selectSingle(PropertyMatcher matcher) {
String value = null;
Property p = this.map.get(matcher.getName()); for (int i = 0; i < map.length; i += 2) {
if (p == null) { if (map[i] != null && matcher.getName().equals(map[i])) {
return null; value = map[i + 1];
break;
}
} }
if (matcher.match(p.getValue())) { if (value != null && matcher.match(value)) {
return p; return new Property(matcher.getName(), value);
} else { } else {
return null; return null;
} }
...@@ -194,8 +200,11 @@ public class Properties implements Serializable { ...@@ -194,8 +200,11 @@ public class Properties implements Serializable {
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("["); sb.append("[");
for (Property p : map.values()) { for (int i = 0; i < map.length; i += 2) {
sb.append(p.toString()); if (map[i + 1] != null) {
String p = map[i + 1];
sb.append(map[i] + " = " + map[i + 1] + "; ");
}
} }
return sb.append("]").toString(); return sb.append("]").toString();
} }
...@@ -241,41 +250,51 @@ public class Properties implements Serializable { ...@@ -241,41 +250,51 @@ public class Properties implements Serializable {
} }
public String get(String key) { public String get(String key) {
Property p = map.get(key); for (int i = 0; i < map.length; i += 2) {
if (p == null) { if (map[i] != null && map[i].equals(key)) {
return null; return map[i + 1];
} else { }
return p.getValue();
} }
return null;
} }
public String getProperty(String string) { public void setProperty(String name, String value) {
return get(string); for (int i = 0; i < map.length; i += 2) {
} if (map[i] != null && map[i].equals(name)) {
String p = map[i + 1];
public Property setProperty(String name, String value) { if (value == null) {
// remove this property
map[i] = null;
map[i + 1] = null;
} else {
map[i + 1] = value;
}
return;
}
}
if (value == null) { if (value == null) {
// remove this property return;
return map.remove(name); }
} else { for (int i = 0; i < map.length; i += 2) {
Property p = map.get(name); if (map[i] == null) {
if (p == null) { map[i] = name;
p = new Property(name, value); map[i + 1] = value;
map.put(name, p); return;
} else {
p.setValue(value);
} }
return p;
} }
String[] newMap = new String[map.length + 4];
System.arraycopy(map, 0, newMap, 0, map.length);
newMap[map.length] = name;
newMap[map.length + 1] = value;
map = newMap;
} }
public Collection<Property> getProperties() { public Iterator<Property> getProperties() {
return Collections.unmodifiableCollection(map.values()); return iterator();
} }
public void add(Properties properties) { public void add(Properties properties) {
for (Property p : properties.getProperties()) { for (Property p : properties) {
add(p); add(p);
} }
} }
...@@ -283,6 +302,35 @@ public class Properties implements Serializable { ...@@ -283,6 +302,35 @@ public class Properties implements Serializable {
public void add(Property property) { public void add(Property property) {
assert property.getName() != null; assert property.getName() != null;
assert property.getValue() != null; assert property.getValue() != null;
map.put(property.getName(), property); setProperty(property.getName(), property.getValue());
}
class PropertiesIterator implements Iterator<Property>, Iterable<Property> {
public Iterator<Property> iterator() {
return this;
}
int index;
public boolean hasNext() {
while (index < map.length && map[index + 1] == null)
index += 2;
return index < map.length;
}
public Property next() {
if (index < map.length) {
index += 2;
return new Property(map[index - 2], map[index - 1]);
}
return null;
}
public void remove() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
public Iterator<Property> iterator() {
return new PropertiesIterator();
} }
} }
...@@ -32,18 +32,19 @@ import java.io.Serializable; ...@@ -32,18 +32,19 @@ import java.io.Serializable;
public class Property implements Serializable { public class Property implements Serializable {
public static final long serialVersionUID = 1L; public static final long serialVersionUID = 1L;
private String name; private String name;
private String value; private String value;
public Property() { private Property() {
this(null, null); this(null, null);
} }
public Property(Property p) { private Property(Property p) {
this(p.getName(), p.getValue()); this(p.getName(), p.getValue());
} }
public Property(String name) { private Property(String name) {
this(name, null); this(name, null);
} }
...@@ -60,16 +61,19 @@ public class Property implements Serializable { ...@@ -60,16 +61,19 @@ public class Property implements Serializable {
return value; return value;
} }
public void setName(String s) { @Override
this.name = s; public String toString() {
return name + " = " + value + "; ";
} }
public void setValue(String s) { @Override
this.value = s; public boolean equals(Object o) {
if (!(o instanceof Property)) return false;
Property p2 = (Property)o;
return name.equals(p2.name) && value.equals(p2.value);
} }
@Override @Override
public String toString() { public int hashCode() {
return name + " = " + value + "; "; return name.hashCode() + value == null ? 0 : value.hashCode();
} }
} }
...@@ -38,6 +38,7 @@ import com.sun.hotspot.igv.data.serialization.XMLParser.HandoverElementHandler; ...@@ -38,6 +38,7 @@ import com.sun.hotspot.igv.data.serialization.XMLParser.HandoverElementHandler;
import com.sun.hotspot.igv.data.serialization.XMLParser.ParseMonitor; import com.sun.hotspot.igv.data.serialization.XMLParser.ParseMonitor;
import com.sun.hotspot.igv.data.serialization.XMLParser.TopElementHandler; import com.sun.hotspot.igv.data.serialization.XMLParser.TopElementHandler;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.XMLReader; import org.xml.sax.XMLReader;
...@@ -88,6 +89,18 @@ public class Parser { ...@@ -88,6 +89,18 @@ public class Parser {
private TopElementHandler xmlDocument = new TopElementHandler(); private TopElementHandler xmlDocument = new TopElementHandler();
private boolean difference; private boolean difference;
private GroupCallback groupCallback; private GroupCallback groupCallback;
private HashMap<String, Integer> idCache = new HashMap<String, Integer>();
private int maxId = 0;
private int lookupID(String i) {
Integer id = idCache.get(i);
if (id == null) {
id = maxId++;
idCache.put(i, id);
}
return id.intValue();
}
// <graphDocument> // <graphDocument>
private ElementHandler<GraphDocument, Object> topHandler = new ElementHandler<GraphDocument, Object>(TOP_ELEMENT) { private ElementHandler<GraphDocument, Object> topHandler = new ElementHandler<GraphDocument, Object>(TOP_ELEMENT) {
...@@ -187,13 +200,13 @@ public class Parser { ...@@ -187,13 +200,13 @@ public class Parser {
previous = null; previous = null;
} }
InputGraph curGraph = new InputGraph(getParentObject(), previous, name); InputGraph curGraph = new InputGraph(getParentObject(), previous, name);
getParentObject().addGraph(curGraph);
this.graph = curGraph; this.graph = curGraph;
return curGraph; return curGraph;
} }
@Override @Override
protected void end(String text) throws SAXException { protected void end(String text) throws SAXException {
getParentObject().addGraph(graph);
graph.resolveBlockLinks(); graph.resolveBlockLinks();
} }
}; };
...@@ -207,7 +220,7 @@ public class Parser { ...@@ -207,7 +220,7 @@ public class Parser {
@Override @Override
protected InputBlock start() throws SAXException { protected InputBlock start() throws SAXException {
InputGraph graph = getParentObject(); InputGraph graph = getParentObject();
String name = readRequiredAttribute(BLOCK_NAME_PROPERTY); String name = readRequiredAttribute(BLOCK_NAME_PROPERTY).intern();
InputBlock b = new InputBlock(getParentObject(), name); InputBlock b = new InputBlock(getParentObject(), name);
graph.addBlock(b); graph.addBlock(b);
return b; return b;
...@@ -224,7 +237,7 @@ public class Parser { ...@@ -224,7 +237,7 @@ public class Parser {
int id = 0; int id = 0;
try { try {
id = Integer.parseInt(s); id = lookupID(s);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new SAXException(e); throw new SAXException(e);
} }
...@@ -252,7 +265,7 @@ public class Parser { ...@@ -252,7 +265,7 @@ public class Parser {
String s = readRequiredAttribute(NODE_ID_PROPERTY); String s = readRequiredAttribute(NODE_ID_PROPERTY);
int id = 0; int id = 0;
try { try {
id = Integer.parseInt(s); id = lookupID(s);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new SAXException(e); throw new SAXException(e);
} }
...@@ -269,7 +282,7 @@ public class Parser { ...@@ -269,7 +282,7 @@ public class Parser {
String s = readRequiredAttribute(NODE_ID_PROPERTY); String s = readRequiredAttribute(NODE_ID_PROPERTY);
int id = 0; int id = 0;
try { try {
id = Integer.parseInt(s); id = lookupID(s);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new SAXException(e); throw new SAXException(e);
} }
...@@ -280,7 +293,7 @@ public class Parser { ...@@ -280,7 +293,7 @@ public class Parser {
private HandoverElementHandler<InputGraph> edgesHandler = new HandoverElementHandler<InputGraph>(EDGES_ELEMENT); private HandoverElementHandler<InputGraph> edgesHandler = new HandoverElementHandler<InputGraph>(EDGES_ELEMENT);
// Local class for edge elements // Local class for edge elements
private static class EdgeElementHandler extends ElementHandler<InputEdge, InputGraph> { private class EdgeElementHandler extends ElementHandler<InputEdge, InputGraph> {
public EdgeElementHandler(String name) { public EdgeElementHandler(String name) {
super(name); super(name);
...@@ -298,8 +311,8 @@ public class Parser { ...@@ -298,8 +311,8 @@ public class Parser {
toIndex = Integer.parseInt(toIndexString); toIndex = Integer.parseInt(toIndexString);
} }
from = Integer.parseInt(readRequiredAttribute(FROM_PROPERTY)); from = lookupID(readRequiredAttribute(FROM_PROPERTY));
to = Integer.parseInt(readRequiredAttribute(TO_PROPERTY)); to = lookupID(readRequiredAttribute(TO_PROPERTY));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new SAXException(e); throw new SAXException(e);
} }
...@@ -344,18 +357,16 @@ public class Parser { ...@@ -344,18 +357,16 @@ public class Parser {
} }
}; };
// <property> // <property>
private ElementHandler<Property, Properties.Provider> propertyHandler = new XMLParser.ElementHandler<Property, Properties.Provider>(PROPERTY_ELEMENT, true) { private ElementHandler<String, Properties.Provider> propertyHandler = new XMLParser.ElementHandler<String, Properties.Provider>(PROPERTY_ELEMENT, true) {
@Override @Override
public Property start() throws SAXException { public String start() throws SAXException {
String value = ""; return readRequiredAttribute(PROPERTY_NAME_PROPERTY).intern();
String name = readRequiredAttribute(PROPERTY_NAME_PROPERTY).intern();
return getParentObject().getProperties().setProperty(name, value);
} }
@Override @Override
public void end(String text) { public void end(String text) {
getObject().setValue(text.trim().intern()); getParentObject().getProperties().setProperty(getObject(), text.trim().intern());
} }
}; };
......
...@@ -67,7 +67,7 @@ public class Printer { ...@@ -67,7 +67,7 @@ public class Printer {
private void export(XMLWriter writer, Group g) throws IOException { private void export(XMLWriter writer, Group g) throws IOException {
Properties attributes = new Properties(); Properties attributes = new Properties();
attributes.add(new Property("difference", Boolean.toString(true))); attributes.setProperty("difference", Boolean.toString(true));
writer.startTag(Parser.GROUP_ELEMENT, attributes); writer.startTag(Parser.GROUP_ELEMENT, attributes);
writer.writeProperties(g.getProperties()); writer.writeProperties(g.getProperties());
......
...@@ -25,7 +25,7 @@ package com.sun.hotspot.igv.data.serialization; ...@@ -25,7 +25,7 @@ package com.sun.hotspot.igv.data.serialization;
import com.sun.hotspot.igv.data.Property; import com.sun.hotspot.igv.data.Property;
import com.sun.hotspot.igv.data.Properties; import com.sun.hotspot.igv.data.Properties;
import java.util.Hashtable; import java.util.HashMap;
import java.util.Stack; import java.util.Stack;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler; import org.xml.sax.ContentHandler;
...@@ -89,7 +89,7 @@ public class XMLParser implements ContentHandler { ...@@ -89,7 +89,7 @@ public class XMLParser implements ContentHandler {
private Attributes attr; private Attributes attr;
private StringBuilder currentText; private StringBuilder currentText;
private ParseMonitor monitor; private ParseMonitor monitor;
private Hashtable<String, ElementHandler<?, ? super T>> hashtable; private HashMap<String, ElementHandler<?, ? super T>> hashtable;
private boolean needsText; private boolean needsText;
private ElementHandler<P, ?> parentElement; private ElementHandler<P, ?> parentElement;
...@@ -110,7 +110,7 @@ public class XMLParser implements ContentHandler { ...@@ -110,7 +110,7 @@ public class XMLParser implements ContentHandler {
} }
public ElementHandler(String name, boolean needsText) { public ElementHandler(String name, boolean needsText) {
this.hashtable = new Hashtable<String, ElementHandler<?, ? super T>>(); this.hashtable = new HashMap<String, ElementHandler<?, ? super T>>();
this.name = name; this.name = name;
this.needsText = needsText; this.needsText = needsText;
} }
...@@ -153,7 +153,7 @@ public class XMLParser implements ContentHandler { ...@@ -153,7 +153,7 @@ public class XMLParser implements ContentHandler {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
String val = attr.getValue(i).intern(); String val = attr.getValue(i).intern();
String localName = attr.getLocalName(i).intern(); String localName = attr.getLocalName(i).intern();
p.add(new Property(val, localName)); p.setProperty(val, localName);
} }
} }
......
...@@ -89,7 +89,7 @@ public class XMLWriter extends Writer { ...@@ -89,7 +89,7 @@ public class XMLWriter extends Writer {
inner.write("<" + name); inner.write("<" + name);
elementStack.push(name); elementStack.push(name);
for (Property p : attributes.getProperties()) { for (Property p : attributes) {
inner.write(" " + p.getName() + "=\""); inner.write(" " + p.getName() + "=\"");
write(p.getValue().toCharArray()); write(p.getValue().toCharArray());
inner.write("\""); inner.write("\"");
...@@ -101,7 +101,7 @@ public class XMLWriter extends Writer { ...@@ -101,7 +101,7 @@ public class XMLWriter extends Writer {
public void simpleTag(String name, Properties attributes) throws IOException { public void simpleTag(String name, Properties attributes) throws IOException {
inner.write("<" + name); inner.write("<" + name);
for (Property p : attributes.getProperties()) { for (Property p : attributes) {
inner.write(" " + p.getName() + "=\""); inner.write(" " + p.getName() + "=\"");
write(p.getValue().toCharArray()); write(p.getValue().toCharArray());
inner.write("\""); inner.write("\"");
...@@ -111,13 +111,13 @@ public class XMLWriter extends Writer { ...@@ -111,13 +111,13 @@ public class XMLWriter extends Writer {
} }
public void writeProperties(Properties props) throws IOException { public void writeProperties(Properties props) throws IOException {
if (props.getProperties().size() == 0) { if (props.getProperties().hasNext() == false) {
return; return;
} }
startTag(Parser.PROPERTIES_ELEMENT); startTag(Parser.PROPERTIES_ELEMENT);
for (Property p : props.getProperties()) { for (Property p : props) {
startTag(Parser.PROPERTY_ELEMENT, new Properties(Parser.PROPERTY_NAME_PROPERTY, p.getName())); startTag(Parser.PROPERTY_ELEMENT, new Properties(Parser.PROPERTY_NAME_PROPERTY, p.getName()));
this.write(p.getValue().toCharArray()); this.write(p.getValue().toCharArray());
endTag(); endTag();
......
...@@ -29,6 +29,7 @@ import com.sun.hotspot.igv.data.InputEdge; ...@@ -29,6 +29,7 @@ import com.sun.hotspot.igv.data.InputEdge;
import com.sun.hotspot.igv.data.InputGraph; import com.sun.hotspot.igv.data.InputGraph;
import com.sun.hotspot.igv.data.InputNode; import com.sun.hotspot.igv.data.InputNode;
import com.sun.hotspot.igv.data.Property; import com.sun.hotspot.igv.data.Property;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
...@@ -124,8 +125,8 @@ public class Difference { ...@@ -124,8 +125,8 @@ public class Difference {
inputNodeMap.put(n, n2); inputNodeMap.put(n, n2);
} }
Set<InputEdge> edgesA = a.getEdges(); Collection<InputEdge> edgesA = a.getEdges();
Set<InputEdge> edgesB = b.getEdges(); Collection<InputEdge> edgesB = b.getEdges();
Set<InputEdge> newEdges = new HashSet<InputEdge>(); Set<InputEdge> newEdges = new HashSet<InputEdge>();
...@@ -182,7 +183,7 @@ public class Difference { ...@@ -182,7 +183,7 @@ public class Difference {
public double getValue() { public double getValue() {
double result = 0.0; double result = 0.0;
for (Property p : n1.getProperties().getProperties()) { for (Property p : n1.getProperties()) {
double faktor = 1.0; double faktor = 1.0;
for (String forbidden : IGNORE_PROPERTIES) { for (String forbidden : IGNORE_PROPERTIES) {
if (p.getName().equals(forbidden)) { if (p.getName().equals(forbidden)) {
...@@ -287,34 +288,34 @@ public class Difference { ...@@ -287,34 +288,34 @@ public class Difference {
private static void markAsChanged(InputNode n, InputNode firstNode, InputNode otherNode) { private static void markAsChanged(InputNode n, InputNode firstNode, InputNode otherNode) {
boolean difference = false; boolean difference = false;
for (Property p : otherNode.getProperties().getProperties()) { for (Property p : otherNode.getProperties()) {
String s = firstNode.getProperties().getProperty(p.getName()); String s = firstNode.getProperties().get(p.getName());
if (!p.getValue().equals(s)) { if (!p.getValue().equals(s)) {
difference = true; difference = true;
n.getProperties().add(new Property(OLD_PREFIX + p.getName(), p.getValue())); n.getProperties().setProperty(OLD_PREFIX + p.getName(), p.getValue());
} }
} }
for (Property p : firstNode.getProperties().getProperties()) { for (Property p : firstNode.getProperties()) {
String s = otherNode.getProperties().getProperty(p.getName()); String s = otherNode.getProperties().get(p.getName());
if (s == null && p.getValue().length() > 0) { if (s == null && p.getValue().length() > 0) {
difference = true; difference = true;
n.getProperties().add(new Property(OLD_PREFIX + p.getName(), "")); n.getProperties().setProperty(OLD_PREFIX + p.getName(), "");
} }
} }
if (difference) { if (difference) {
n.getProperties().add(new Property(PROPERTY_STATE, VALUE_CHANGED)); n.getProperties().setProperty(PROPERTY_STATE, VALUE_CHANGED);
} else { } else {
n.getProperties().add(new Property(PROPERTY_STATE, VALUE_SAME)); n.getProperties().setProperty(PROPERTY_STATE, VALUE_SAME);
} }
} }
private static void markAsDeleted(InputNode n) { private static void markAsDeleted(InputNode n) {
n.getProperties().add(new Property(PROPERTY_STATE, VALUE_DELETED)); n.getProperties().setProperty(PROPERTY_STATE, VALUE_DELETED);
} }
private static void markAsNew(InputNode n) { private static void markAsNew(InputNode n) {
n.getProperties().add(new Property(PROPERTY_STATE, VALUE_NEW)); n.getProperties().setProperty(PROPERTY_STATE, VALUE_NEW);
} }
} }
Manifest-Version: 1.0 Manifest-Version: 1.0
OpenIDE-Module: com.sun.hotspot.igv.filter OpenIDE-Module: com.sun.hotspot.igv.filter
OpenIDE-Module-Layer: com/sun/hotspot/igv/filter/layer.xml OpenIDE-Module-Layer: com/sun/hotspot/igv/filter/layer.xml
OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/filter/Bundle.properties OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/filter/Bundle.properties
OpenIDE-Module-Specification-Version: 1.0 OpenIDE-Module-Specification-Version: 1.0
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
package com.sun.hotspot.igv.filter; package com.sun.hotspot.igv.filter;
import com.sun.hotspot.igv.graph.Diagram; import com.sun.hotspot.igv.graph.Diagram;
import com.sun.hotspot.igv.data.Property;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
...@@ -56,7 +55,7 @@ public class CustomFilter extends AbstractFilter { ...@@ -56,7 +55,7 @@ public class CustomFilter extends AbstractFilter {
public CustomFilter(String name, String code) { public CustomFilter(String name, String code) {
this.name = name; this.name = name;
this.code = code; this.code = code;
getProperties().add(new Property("name", name)); getProperties().setProperty("name", name);
} }
public String getName() { public String getName() {
......
...@@ -56,8 +56,8 @@ public class SplitFilter extends AbstractFilter { ...@@ -56,8 +56,8 @@ public class SplitFilter extends AbstractFilter {
for (OutputSlot os : f.getOutputSlots()) { for (OutputSlot os : f.getOutputSlots()) {
for (Connection c : os.getConnections()) { for (Connection c : os.getConnections()) {
InputSlot is = c.getInputSlot(); InputSlot is = c.getInputSlot();
is.setName(f.getProperties().getProperty("dump_spec")); is.setName(f.getProperties().get("dump_spec"));
String s = f.getProperties().getProperty("short_name"); String s = f.getProperties().get("short_name");
if (s != null) { if (s != null) {
is.setShortName(s); is.setShortName(s);
} }
......
...@@ -35,7 +35,7 @@ import java.util.Collections; ...@@ -35,7 +35,7 @@ import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Hashtable; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
...@@ -126,7 +126,7 @@ public class Diagram { ...@@ -126,7 +126,7 @@ public class Diagram {
d.updateBlocks(); d.updateBlocks();
Collection<InputNode> nodes = graph.getNodes(); Collection<InputNode> nodes = graph.getNodes();
Hashtable<Integer, Figure> figureHash = new Hashtable<Integer, Figure>(); HashMap<Integer, Figure> figureHash = new HashMap<Integer, Figure>();
for (InputNode n : nodes) { for (InputNode n : nodes) {
Figure f = d.createFigure(); Figure f = d.createFigure();
f.getSource().addSourceNode(n); f.getSource().addSourceNode(n);
......
...@@ -42,7 +42,7 @@ import java.util.Set; ...@@ -42,7 +42,7 @@ import java.util.Set;
* *
* @author Thomas Wuerthinger * @author Thomas Wuerthinger
*/ */
public class Figure extends Properties.Object implements Source.Provider, Vertex { public class Figure extends Properties.Entity implements Source.Provider, Vertex {
public static final int INSET = 6; public static final int INSET = 6;
public static final int SLOT_WIDTH = 10; public static final int SLOT_WIDTH = 10;
......
...@@ -26,7 +26,7 @@ package com.sun.hotspot.igv.hierarchicallayout; ...@@ -26,7 +26,7 @@ package com.sun.hotspot.igv.hierarchicallayout;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Hashtable; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Queue; import java.util.Queue;
...@@ -37,13 +37,13 @@ import java.util.Queue; ...@@ -37,13 +37,13 @@ import java.util.Queue;
*/ */
public class Graph<N, E> { public class Graph<N, E> {
private Hashtable<Object, Node<N, E>> nodes; private HashMap<Object, Node<N, E>> nodes;
private Hashtable<Object, Edge<N, E>> edges; private HashMap<Object, Edge<N, E>> edges;
private List<Node<N, E>> nodeList; private List<Node<N, E>> nodeList;
public Graph() { public Graph() {
nodes = new Hashtable<Object, Node<N, E>>(); nodes = new HashMap<Object, Node<N, E>>();
edges = new Hashtable<Object, Edge<N, E>>(); edges = new HashMap<Object, Edge<N, E>>();
nodeList = new ArrayList<Node<N, E>>(); nodeList = new ArrayList<Node<N, E>>();
} }
......
...@@ -25,7 +25,7 @@ package com.sun.hotspot.igv.hierarchicallayout; ...@@ -25,7 +25,7 @@ package com.sun.hotspot.igv.hierarchicallayout;
import java.awt.Point; import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.util.Hashtable; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -69,19 +69,19 @@ public class HierarchicalClusterLayoutManager implements LayoutManager { ...@@ -69,19 +69,19 @@ public class HierarchicalClusterLayoutManager implements LayoutManager {
assert graph.verify(); assert graph.verify();
Hashtable<Cluster, List<Vertex>> lists = new Hashtable<Cluster, List<Vertex>>(); HashMap<Cluster, List<Vertex>> lists = new HashMap<Cluster, List<Vertex>>();
Hashtable<Cluster, List<Link>> listsConnection = new Hashtable<Cluster, List<Link>>(); HashMap<Cluster, List<Link>> listsConnection = new HashMap<Cluster, List<Link>>();
Hashtable<Cluster, Hashtable<Port, ClusterInputSlotNode>> clusterInputSlotHash = new Hashtable<Cluster, Hashtable<Port, ClusterInputSlotNode>>(); HashMap<Cluster, HashMap<Port, ClusterInputSlotNode>> clusterInputSlotHash = new HashMap<Cluster, HashMap<Port, ClusterInputSlotNode>>();
Hashtable<Cluster, Hashtable<Port, ClusterOutputSlotNode>> clusterOutputSlotHash = new Hashtable<Cluster, Hashtable<Port, ClusterOutputSlotNode>>(); HashMap<Cluster, HashMap<Port, ClusterOutputSlotNode>> clusterOutputSlotHash = new HashMap<Cluster, HashMap<Port, ClusterOutputSlotNode>>();
Hashtable<Cluster, ClusterNode> clusterNodes = new Hashtable<Cluster, ClusterNode>(); HashMap<Cluster, ClusterNode> clusterNodes = new HashMap<Cluster, ClusterNode>();
Hashtable<Cluster, Set<ClusterInputSlotNode>> clusterInputSlotSet = new Hashtable<Cluster, Set<ClusterInputSlotNode>>(); HashMap<Cluster, Set<ClusterInputSlotNode>> clusterInputSlotSet = new HashMap<Cluster, Set<ClusterInputSlotNode>>();
Hashtable<Cluster, Set<ClusterOutputSlotNode>> clusterOutputSlotSet = new Hashtable<Cluster, Set<ClusterOutputSlotNode>>(); HashMap<Cluster, Set<ClusterOutputSlotNode>> clusterOutputSlotSet = new HashMap<Cluster, Set<ClusterOutputSlotNode>>();
Set<Link> clusterEdges = new HashSet<Link>(); Set<Link> clusterEdges = new HashSet<Link>();
Set<Link> interClusterEdges = new HashSet<Link>(); Set<Link> interClusterEdges = new HashSet<Link>();
Hashtable<Link, ClusterOutgoingConnection> linkClusterOutgoingConnection = new Hashtable<Link, ClusterOutgoingConnection>(); HashMap<Link, ClusterOutgoingConnection> linkClusterOutgoingConnection = new HashMap<Link, ClusterOutgoingConnection>();
Hashtable<Link, InterClusterConnection> linkInterClusterConnection = new Hashtable<Link, InterClusterConnection>(); HashMap<Link, InterClusterConnection> linkInterClusterConnection = new HashMap<Link, InterClusterConnection>();
Hashtable<Link, ClusterIngoingConnection> linkClusterIngoingConnection = new Hashtable<Link, ClusterIngoingConnection>(); HashMap<Link, ClusterIngoingConnection> linkClusterIngoingConnection = new HashMap<Link, ClusterIngoingConnection>();
Set<ClusterNode> clusterNodeSet = new HashSet<ClusterNode>(); Set<ClusterNode> clusterNodeSet = new HashSet<ClusterNode>();
Set<Cluster> cluster = graph.getClusters(); Set<Cluster> cluster = graph.getClusters();
...@@ -89,8 +89,8 @@ public class HierarchicalClusterLayoutManager implements LayoutManager { ...@@ -89,8 +89,8 @@ public class HierarchicalClusterLayoutManager implements LayoutManager {
for (Cluster c : cluster) { for (Cluster c : cluster) {
lists.put(c, new ArrayList<Vertex>()); lists.put(c, new ArrayList<Vertex>());
listsConnection.put(c, new ArrayList<Link>()); listsConnection.put(c, new ArrayList<Link>());
clusterInputSlotHash.put(c, new Hashtable<Port, ClusterInputSlotNode>()); clusterInputSlotHash.put(c, new HashMap<Port, ClusterInputSlotNode>());
clusterOutputSlotHash.put(c, new Hashtable<Port, ClusterOutputSlotNode>()); clusterOutputSlotHash.put(c, new HashMap<Port, ClusterOutputSlotNode>());
clusterOutputSlotSet.put(c, new TreeSet<ClusterOutputSlotNode>()); clusterOutputSlotSet.put(c, new TreeSet<ClusterOutputSlotNode>());
clusterInputSlotSet.put(c, new TreeSet<ClusterInputSlotNode>()); clusterInputSlotSet.put(c, new TreeSet<ClusterInputSlotNode>());
ClusterNode cn = new ClusterNode(c, "" + z); ClusterNode cn = new ClusterNode(c, "" + z);
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
package com.sun.hotspot.igv.layout; package com.sun.hotspot.igv.layout;
import java.util.HashSet; import java.util.HashSet;
import java.util.Hashtable; import java.util.HashMap;
import java.util.Set; import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
...@@ -37,9 +37,9 @@ public class LayoutGraph { ...@@ -37,9 +37,9 @@ public class LayoutGraph {
private Set<? extends Link> links; private Set<? extends Link> links;
private SortedSet<Vertex> vertices; private SortedSet<Vertex> vertices;
private Hashtable<Vertex, Set<Port>> inputPorts; private HashMap<Vertex, Set<Port>> inputPorts;
private Hashtable<Vertex, Set<Port>> outputPorts; private HashMap<Vertex, Set<Port>> outputPorts;
private Hashtable<Port, Set<Link>> portLinks; private HashMap<Port, Set<Link>> portLinks;
public LayoutGraph(Set<? extends Link> links) { public LayoutGraph(Set<? extends Link> links) {
this(links, new HashSet<Vertex>()); this(links, new HashSet<Vertex>());
...@@ -50,9 +50,9 @@ public class LayoutGraph { ...@@ -50,9 +50,9 @@ public class LayoutGraph {
assert verify(); assert verify();
vertices = new TreeSet<Vertex>(); vertices = new TreeSet<Vertex>();
portLinks = new Hashtable<Port, Set<Link>>(); portLinks = new HashMap<Port, Set<Link>>();
inputPorts = new Hashtable<Vertex, Set<Port>>(); inputPorts = new HashMap<Vertex, Set<Port>>();
outputPorts = new Hashtable<Vertex, Set<Port>>(); outputPorts = new HashMap<Vertex, Set<Port>>();
for (Link l : links) { for (Link l : links) {
Port p = l.getFrom(); Port p = l.getFrom();
......
...@@ -5,21 +5,16 @@ of Linz in Austria and has been included as part of hotspot since that ...@@ -5,21 +5,16 @@ of Linz in Austria and has been included as part of hotspot since that
was the primary target of the tool. The tool itself is fairly general was the primary target of the tool. The tool itself is fairly general
with only a few modules that contain C2 specific elements. with only a few modules that contain C2 specific elements.
The tool is built on top of the NetBeans 6.0 rich client The tool is built on top of the NetBeans 6.1 rich client
infrastructure and so requires NetBeans to build. It currently infrastructure and so requires NetBeans to build. It currently
requires Java 6 to run as it needs support for JavaScript for its requires Java 6 to run as it needs support for JavaScript for its
filtering mechanism and assumes it's built into the platform. It filtering mechanism and assumes it's built into the platform. It
should build out of the box whit NetBeans 6 and Java 6 or later. It's should build out of the box with NetBeans 6.1 and Java 6 or later.
possible to run it on 1.5 by including Rhino on the classpath though It's possible to run it on 1.5 by including Rhino on the classpath
that currently isn't working correctly. Support for exporting graphs though that currently isn't working correctly. Support for exporting
as SVG can be enabled by adding batik to the classpath which isn't graphs as SVG can be enabled by adding batik to the classpath which
included by default. isn't included by default. It can be built on top of NetBeans 6.0 if
you change the required modules to be platform7 instead of platform8.
It can be built on top of NetBeans 6.1 if you change the required
modules to be platform8 instead of platform7. The tool could run on
JDK 1.5 with some reworking of the how the JavaScript support is
enabled but currently it requires some tweaking of the setup. This
will be fixed in a later setup.
The JVM support is controlled by the flag -XX:PrintIdealGraphLevel=# The JVM support is controlled by the flag -XX:PrintIdealGraphLevel=#
where # is: where # is:
......
...@@ -36,11 +36,11 @@ import org.openide.nodes.Sheet; ...@@ -36,11 +36,11 @@ import org.openide.nodes.Sheet;
*/ */
public class PropertiesSheet { public class PropertiesSheet {
public static void initializeSheet(Properties properties, Sheet s) { public static void initializeSheet(final Properties properties, Sheet s) {
Sheet.Set set1 = Sheet.createPropertiesSet(); Sheet.Set set1 = Sheet.createPropertiesSet();
set1.setDisplayName("Properties"); set1.setDisplayName("Properties");
for (final Property p : properties.getProperties()) { for (final Property p : properties) {
Node.Property<String> prop = new Node.Property<String>(String.class) { Node.Property<String> prop = new Node.Property<String>(String.class) {
@Override @Override
...@@ -60,7 +60,7 @@ public class PropertiesSheet { ...@@ -60,7 +60,7 @@ public class PropertiesSheet {
@Override @Override
public void setValue(String arg0) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void setValue(String arg0) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
p.setValue(arg0); properties.setProperty(p.getName(), arg0);
} }
}; };
prop.setName(p.getName()); prop.setName(p.getName());
......
...@@ -65,13 +65,19 @@ public class RangeSliderModel implements ChangedEventProvider<RangeSliderModel> ...@@ -65,13 +65,19 @@ public class RangeSliderModel implements ChangedEventProvider<RangeSliderModel>
public RangeSliderModel(List<String> positions) { public RangeSliderModel(List<String> positions) {
assert positions.size() > 0; assert positions.size() > 0;
this.positions = positions;
this.changedEvent = new ChangedEvent<RangeSliderModel>(this); this.changedEvent = new ChangedEvent<RangeSliderModel>(this);
this.colorChangedEvent = new ChangedEvent<RangeSliderModel>(this); this.colorChangedEvent = new ChangedEvent<RangeSliderModel>(this);
setPositions(positions);
}
protected void setPositions(List<String> positions) {
this.positions = positions;
colors = new ArrayList<Color>(); colors = new ArrayList<Color>();
for (int i = 0; i < positions.size(); i++) { for (int i = 0; i < positions.size(); i++) {
colors.add(Color.black); colors.add(Color.black);
} }
changedEvent.fire();
colorChangedEvent.fire();
} }
public void setColors(List<Color> colors) { public void setColors(List<Color> colors) {
......
...@@ -63,7 +63,7 @@ import java.util.ArrayList; ...@@ -63,7 +63,7 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Hashtable; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
...@@ -104,10 +104,10 @@ import org.openide.util.lookup.InstanceContent; ...@@ -104,10 +104,10 @@ import org.openide.util.lookup.InstanceContent;
*/ */
public class DiagramScene extends Scene implements ChangedListener<DiagramViewModel> { public class DiagramScene extends Scene implements ChangedListener<DiagramViewModel> {
private Hashtable<Figure, FigureWidget> figureWidgets; private HashMap<Figure, FigureWidget> figureWidgets;
private Hashtable<Slot, SlotWidget> slotWidgets; private HashMap<Slot, SlotWidget> slotWidgets;
private Hashtable<Connection, ConnectionWidget> connectionWidgets; private HashMap<Connection, ConnectionWidget> connectionWidgets;
private Hashtable<InputBlock, BlockWidget> blockWidgets; private HashMap<InputBlock, BlockWidget> blockWidgets;
private Widget hoverWidget; private Widget hoverWidget;
private WidgetAction hoverAction; private WidgetAction hoverAction;
private List<FigureWidget> selectedWidgets; private List<FigureWidget> selectedWidgets;
...@@ -414,7 +414,7 @@ public class DiagramScene extends Scene implements ChangedListener<DiagramViewMo ...@@ -414,7 +414,7 @@ public class DiagramScene extends Scene implements ChangedListener<DiagramViewMo
this.addChild(selectLayer); this.addChild(selectLayer);
this.getActions().addAction(ActionFactory.createRectangularSelectAction(rectangularSelectDecorator, selectLayer, rectangularSelectProvider)); this.getActions().addAction(ActionFactory.createRectangularSelectAction(rectangularSelectDecorator, selectLayer, rectangularSelectProvider));
blockWidgets = new Hashtable<InputBlock, BlockWidget>(); blockWidgets = new HashMap<InputBlock, BlockWidget>();
boolean b = this.getUndoRedoEnabled(); boolean b = this.getUndoRedoEnabled();
this.setUndoRedoEnabled(false); this.setUndoRedoEnabled(false);
...@@ -543,9 +543,9 @@ public class DiagramScene extends Scene implements ChangedListener<DiagramViewMo ...@@ -543,9 +543,9 @@ public class DiagramScene extends Scene implements ChangedListener<DiagramViewMo
blockLayer.removeChildren(); blockLayer.removeChildren();
blockWidgets.clear(); blockWidgets.clear();
figureWidgets = new Hashtable<Figure, FigureWidget>(); figureWidgets = new HashMap<Figure, FigureWidget>();
slotWidgets = new Hashtable<Slot, SlotWidget>(); slotWidgets = new HashMap<Slot, SlotWidget>();
connectionWidgets = new Hashtable<Connection, ConnectionWidget>(); connectionWidgets = new HashMap<Connection, ConnectionWidget>();
WidgetAction selectAction = new ExtendedSelectAction(selectProvider); WidgetAction selectAction = new ExtendedSelectAction(selectProvider);
Diagram d = getModel().getDiagramToView(); Diagram d = getModel().getDiagramToView();
......
...@@ -55,6 +55,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene ...@@ -55,6 +55,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
private FilterChain filterChain; private FilterChain filterChain;
private FilterChain sequenceFilterChain; private FilterChain sequenceFilterChain;
private Diagram diagram; private Diagram diagram;
private ChangedEvent<DiagramViewModel> groupChangedEvent;
private ChangedEvent<DiagramViewModel> diagramChangedEvent; private ChangedEvent<DiagramViewModel> diagramChangedEvent;
private ChangedEvent<DiagramViewModel> viewChangedEvent; private ChangedEvent<DiagramViewModel> viewChangedEvent;
private ChangedEvent<DiagramViewModel> viewPropertiesChangedEvent; private ChangedEvent<DiagramViewModel> viewPropertiesChangedEvent;
...@@ -67,6 +68,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene ...@@ -67,6 +68,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
} }
}; };
@Override
public DiagramViewModel copy() { public DiagramViewModel copy() {
DiagramViewModel result = new DiagramViewModel(group, filterChain, sequenceFilterChain); DiagramViewModel result = new DiagramViewModel(group, filterChain, sequenceFilterChain);
result.setData(this); result.setData(this);
...@@ -79,6 +81,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene ...@@ -79,6 +81,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
boolean viewChanged = false; boolean viewChanged = false;
boolean viewPropertiesChanged = false; boolean viewPropertiesChanged = false;
boolean groupChanged = (group == newModel.group);
this.group = newModel.group; this.group = newModel.group;
diagramChanged |= (filterChain != newModel.filterChain); diagramChanged |= (filterChain != newModel.filterChain);
this.filterChain = newModel.filterChain; this.filterChain = newModel.filterChain;
...@@ -97,6 +100,10 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene ...@@ -97,6 +100,10 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
viewPropertiesChanged |= (showNodeHull != newModel.showNodeHull); viewPropertiesChanged |= (showNodeHull != newModel.showNodeHull);
this.showNodeHull = newModel.showNodeHull; this.showNodeHull = newModel.showNodeHull;
if(groupChanged) {
groupChangedEvent.fire();
}
if (diagramChanged) { if (diagramChanged) {
diagramChangedEvent.fire(); diagramChangedEvent.fire();
} }
...@@ -143,11 +150,38 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene ...@@ -143,11 +150,38 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
diagramChangedEvent = new ChangedEvent<DiagramViewModel>(this); diagramChangedEvent = new ChangedEvent<DiagramViewModel>(this);
viewChangedEvent = new ChangedEvent<DiagramViewModel>(this); viewChangedEvent = new ChangedEvent<DiagramViewModel>(this);
viewPropertiesChangedEvent = new ChangedEvent<DiagramViewModel>(this); viewPropertiesChangedEvent = new ChangedEvent<DiagramViewModel>(this);
groupChangedEvent = new ChangedEvent<DiagramViewModel>(this);
groupChangedEvent.addListener(groupChangedListener);
groupChangedEvent.fire();
filterChain.getChangedEvent().addListener(filterChainChangedListener); filterChain.getChangedEvent().addListener(filterChainChangedListener);
sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener); sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
} }
private final ChangedListener<DiagramViewModel> groupChangedListener = new ChangedListener<DiagramViewModel>() {
private Group oldGroup;
public void changed(DiagramViewModel source) {
if(oldGroup != null) {
oldGroup.getChangedEvent().removeListener(groupContentChangedListener);
}
group.getChangedEvent().addListener(groupContentChangedListener);
oldGroup = group;
}
};
private final ChangedListener<Group> groupContentChangedListener = new ChangedListener<Group>() {
public void changed(Group source) {
assert source == group;
setPositions(calculateStringList(source));
setSelectedNodes(selectedNodes);
}
};
public ChangedEvent<DiagramViewModel> getDiagramChangedEvent() { public ChangedEvent<DiagramViewModel> getDiagramChangedEvent() {
return diagramChangedEvent; return diagramChangedEvent;
} }
...@@ -268,7 +302,10 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene ...@@ -268,7 +302,10 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
} }
public InputGraph getSecondGraph() { public InputGraph getSecondGraph() {
return group.getGraphs().get(getSecondPosition()); List<InputGraph> graphs = group.getGraphs();
if (graphs.size() >= getSecondPosition())
return group.getGraphs().get(getSecondPosition());
return getFirstGraph();
} }
public void selectGraph(InputGraph g) { public void selectGraph(InputGraph g) {
......
...@@ -67,7 +67,7 @@ class FindPanel extends JPanel implements KeyListener { ...@@ -67,7 +67,7 @@ class FindPanel extends JPanel implements KeyListener {
for (Figure f : figures) { for (Figure f : figures) {
Properties prop = f.getProperties(); Properties prop = f.getProperties();
for (Property p : prop.getProperties()) { for (Property p : prop) {
if (!propertyNames.contains(p.getName())) { if (!propertyNames.contains(p.getName())) {
propertyNames.add(p.getName()); propertyNames.add(p.getName());
} }
......
# Deprecated since 5.0u1; for compatibility with 5.0: # Deprecated since 5.0u1; for compatibility with 5.0:
disabled.clusters=\ disabled.clusters=\
apisupport1,\ apisupport1,\
gsf1,\
harness,\ harness,\
ide8,\ ide9,\
java1,\ java2,\
nb6.0,\ nb6.1,\
profiler2 profiler3
disabled.modules=\ disabled.modules=\
org.netbeans.core.execution,\ org.netbeans.core.execution,\
org.netbeans.core.multiview,\ org.netbeans.core.multiview,\
org.netbeans.core.output2,\ org.netbeans.core.output2,\
org.netbeans.modules.applemenu,\
org.netbeans.modules.autoupdate.services,\ org.netbeans.modules.autoupdate.services,\
org.netbeans.modules.autoupdate.ui,\ org.netbeans.modules.autoupdate.ui,\
org.netbeans.modules.core.kit,\ org.netbeans.modules.core.kit,\
...@@ -24,6 +24,6 @@ disabled.modules=\ ...@@ -24,6 +24,6 @@ disabled.modules=\
org.openide.execution,\ org.openide.execution,\
org.openide.util.enumerations org.openide.util.enumerations
enabled.clusters=\ enabled.clusters=\
platform7 platform8
nbjdk.active=default nbjdk.active=default
nbplatform.active=default nbplatform.active=default
...@@ -15,7 +15,6 @@ modules=\ ...@@ -15,7 +15,6 @@ modules=\
${project.com.sun.hotspot.igv.difference}:\ ${project.com.sun.hotspot.igv.difference}:\
${project.com.sun.hotspot.igv.settings}:\ ${project.com.sun.hotspot.igv.settings}:\
${project.com.sun.hotspot.igv.util}:\ ${project.com.sun.hotspot.igv.util}:\
${project.com.sun.hotspot.igv.rhino}:\
${project.com.sun.hotspot.igv.svg}:\ ${project.com.sun.hotspot.igv.svg}:\
${project.com.sun.hotspot.connection}:\ ${project.com.sun.hotspot.connection}:\
${project.com.sun.hotspot.igv.servercompilerscheduler}:\ ${project.com.sun.hotspot.igv.servercompilerscheduler}:\
...@@ -31,10 +30,10 @@ project.com.sun.hotspot.igv.filterwindow=FilterWindow ...@@ -31,10 +30,10 @@ project.com.sun.hotspot.igv.filterwindow=FilterWindow
project.com.sun.hotspot.igv.graph=Graph project.com.sun.hotspot.igv.graph=Graph
project.com.sun.hotspot.igv.hierarchicallayout=HierarchicalLayout project.com.sun.hotspot.igv.hierarchicallayout=HierarchicalLayout
project.com.sun.hotspot.igv.layout=Layout project.com.sun.hotspot.igv.layout=Layout
project.com.sun.hotspot.igv.rhino=RhinoScriptEngineProxy
project.com.sun.hotspot.igv.servercompilerscheduler=ServerCompiler project.com.sun.hotspot.igv.servercompilerscheduler=ServerCompiler
project.com.sun.hotspot.igv.settings=Settings project.com.sun.hotspot.igv.settings=Settings
project.com.sun.hotspot.igv.svg=BatikSVGProxy project.com.sun.hotspot.igv.svg=BatikSVGProxy
project.com.sun.hotspot.igv.view=View project.com.sun.hotspot.igv.view=View
project.com.sun.hotspot.igv.util=Util project.com.sun.hotspot.igv.util=Util
run.args = -server -J-Xms64m -J-Xmx512m -J-da run.args = -J-server -J-Xms64m -J-Xmx1g -J-da
run.args.extra = -J-server -J-Xms64m -J-Xmx1g -J-da
...@@ -33,7 +33,6 @@ ADLParser::ADLParser(FileBuff& buffer, ArchDesc& archDesc) ...@@ -33,7 +33,6 @@ ADLParser::ADLParser(FileBuff& buffer, ArchDesc& archDesc)
_globalNames(archDesc.globalNames()) { _globalNames(archDesc.globalNames()) {
_AD._syntax_errs = _AD._semantic_errs = 0; // No errors so far this file _AD._syntax_errs = _AD._semantic_errs = 0; // No errors so far this file
_AD._warnings = 0; // No warnings either _AD._warnings = 0; // No warnings either
_linenum = 0; // Will increment to first line
_curline = _ptr = NULL; // No pointers into buffer yet _curline = _ptr = NULL; // No pointers into buffer yet
_preproc_depth = 0; _preproc_depth = 0;
...@@ -76,7 +75,7 @@ ADLParser::~ADLParser() { ...@@ -76,7 +75,7 @@ ADLParser::~ADLParser() {
} }
if (!_AD._quiet_mode) if (!_AD._quiet_mode)
fprintf(stderr,"-----------------------------------------------------------------------------\n"); fprintf(stderr,"-----------------------------------------------------------------------------\n");
_AD._TotalLines += _linenum-1; // -1 for overshoot in "nextline" routine _AD._TotalLines += linenum()-1; // -1 for overshoot in "nextline" routine
// Write out information we have stored // Write out information we have stored
// // UNIXism == fsync(stderr); // // UNIXism == fsync(stderr);
...@@ -148,7 +147,7 @@ void ADLParser::instr_parse(void) { ...@@ -148,7 +147,7 @@ void ADLParser::instr_parse(void) {
if( (ident = get_unique_ident(_globalNames,"instruction")) == NULL ) if( (ident = get_unique_ident(_globalNames,"instruction")) == NULL )
return; return;
instr = new InstructForm(ident); // Create new instruction form instr = new InstructForm(ident); // Create new instruction form
instr->_linenum = _linenum; instr->_linenum = linenum();
_globalNames.Insert(ident, instr); // Add name to the name table _globalNames.Insert(ident, instr); // Add name to the name table
// Debugging Stuff // Debugging Stuff
if (_AD._adl_debug > 1) if (_AD._adl_debug > 1)
...@@ -404,7 +403,7 @@ void ADLParser::oper_parse(void) { ...@@ -404,7 +403,7 @@ void ADLParser::oper_parse(void) {
if( (ident = get_unique_ident(_globalNames,"operand")) == NULL ) if( (ident = get_unique_ident(_globalNames,"operand")) == NULL )
return; return;
oper = new OperandForm(ident); // Create new operand form oper = new OperandForm(ident); // Create new operand form
oper->_linenum = _linenum; oper->_linenum = linenum();
_globalNames.Insert(ident, oper); // Add name to the name table _globalNames.Insert(ident, oper); // Add name to the name table
// Debugging Stuff // Debugging Stuff
...@@ -774,7 +773,7 @@ void ADLParser::reg_parse(void) { ...@@ -774,7 +773,7 @@ void ADLParser::reg_parse(void) {
// Create the RegisterForm for the architecture description. // Create the RegisterForm for the architecture description.
RegisterForm *regBlock = new RegisterForm(); // Build new Source object RegisterForm *regBlock = new RegisterForm(); // Build new Source object
regBlock->_linenum = _linenum; regBlock->_linenum = linenum();
_AD.addForm(regBlock); _AD.addForm(regBlock);
skipws(); // Skip leading whitespace skipws(); // Skip leading whitespace
...@@ -847,7 +846,7 @@ void ADLParser::enc_class_parse(void) { ...@@ -847,7 +846,7 @@ void ADLParser::enc_class_parse(void) {
} }
EncClass *encoding = _AD._encode->add_EncClass(ec_name); EncClass *encoding = _AD._encode->add_EncClass(ec_name);
encoding->_linenum = _linenum; encoding->_linenum = linenum();
skipws(); // Skip leading whitespace skipws(); // Skip leading whitespace
// Check for optional parameter list // Check for optional parameter list
...@@ -905,7 +904,7 @@ void ADLParser::enc_class_parse_block(EncClass* encoding, char* ec_name) { ...@@ -905,7 +904,7 @@ void ADLParser::enc_class_parse_block(EncClass* encoding, char* ec_name) {
// Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
if (_AD._adlocation_debug) { if (_AD._adlocation_debug) {
const char* file = _AD._ADL_file._name; const char* file = _AD._ADL_file._name;
int line = _linenum; int line = linenum();
char* location = (char *)malloc(strlen(file) + 100); char* location = (char *)malloc(strlen(file) + 100);
sprintf(location, "#line %d \"%s\"\n", line, file); sprintf(location, "#line %d \"%s\"\n", line, file);
encoding->add_code(location); encoding->add_code(location);
...@@ -2776,7 +2775,7 @@ InsEncode *ADLParser::ins_encode_parse_block(InstructForm &inst) { ...@@ -2776,7 +2775,7 @@ InsEncode *ADLParser::ins_encode_parse_block(InstructForm &inst) {
assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
EncClass *encoding = _AD._encode->add_EncClass(ec_name); EncClass *encoding = _AD._encode->add_EncClass(ec_name);
encoding->_linenum = _linenum; encoding->_linenum = linenum();
// synthesize the arguments list for the enc_class from the // synthesize the arguments list for the enc_class from the
// arguments to the instruct definition. // arguments to the instruct definition.
...@@ -2852,7 +2851,7 @@ InsEncode *ADLParser::ins_encode_parse(InstructForm &inst) { ...@@ -2852,7 +2851,7 @@ InsEncode *ADLParser::ins_encode_parse(InstructForm &inst) {
skipws(); skipws();
InsEncode *encrule = new InsEncode(); // Encode class for instruction InsEncode *encrule = new InsEncode(); // Encode class for instruction
encrule->_linenum = _linenum; encrule->_linenum = linenum();
char *ec_name = NULL; // String representation of encode rule char *ec_name = NULL; // String representation of encode rule
// identifier is optional. // identifier is optional.
while (_curchar != ')') { while (_curchar != ')') {
...@@ -3203,6 +3202,12 @@ Interface *ADLParser::cond_interface_parse(void) { ...@@ -3203,6 +3202,12 @@ Interface *ADLParser::cond_interface_parse(void) {
char *greater_equal; char *greater_equal;
char *less_equal; char *less_equal;
char *greater; char *greater;
const char *equal_format = "eq";
const char *not_equal_format = "ne";
const char *less_format = "lt";
const char *greater_equal_format = "ge";
const char *less_equal_format = "le";
const char *greater_format = "gt";
if (_curchar != '%') { if (_curchar != '%') {
parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n"); parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n");
...@@ -3222,22 +3227,22 @@ Interface *ADLParser::cond_interface_parse(void) { ...@@ -3222,22 +3227,22 @@ Interface *ADLParser::cond_interface_parse(void) {
return NULL; return NULL;
} }
if ( strcmp(field,"equal") == 0 ) { if ( strcmp(field,"equal") == 0 ) {
equal = interface_field_parse(); equal = interface_field_parse(&equal_format);
} }
else if ( strcmp(field,"not_equal") == 0 ) { else if ( strcmp(field,"not_equal") == 0 ) {
not_equal = interface_field_parse(); not_equal = interface_field_parse(&not_equal_format);
} }
else if ( strcmp(field,"less") == 0 ) { else if ( strcmp(field,"less") == 0 ) {
less = interface_field_parse(); less = interface_field_parse(&less_format);
} }
else if ( strcmp(field,"greater_equal") == 0 ) { else if ( strcmp(field,"greater_equal") == 0 ) {
greater_equal = interface_field_parse(); greater_equal = interface_field_parse(&greater_equal_format);
} }
else if ( strcmp(field,"less_equal") == 0 ) { else if ( strcmp(field,"less_equal") == 0 ) {
less_equal = interface_field_parse(); less_equal = interface_field_parse(&less_equal_format);
} }
else if ( strcmp(field,"greater") == 0 ) { else if ( strcmp(field,"greater") == 0 ) {
greater = interface_field_parse(); greater = interface_field_parse(&greater_format);
} }
else { else {
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n"); parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
...@@ -3252,14 +3257,18 @@ Interface *ADLParser::cond_interface_parse(void) { ...@@ -3252,14 +3257,18 @@ Interface *ADLParser::cond_interface_parse(void) {
next_char(); // Skip '}' next_char(); // Skip '}'
// Construct desired object and return // Construct desired object and return
Interface *inter = new CondInterface(equal, not_equal, less, greater_equal, Interface *inter = new CondInterface(equal, equal_format,
less_equal, greater); not_equal, not_equal_format,
less, less_format,
greater_equal, greater_equal_format,
less_equal, less_equal_format,
greater, greater_format);
return inter; return inter;
} }
//------------------------------interface_field_parse-------------------------- //------------------------------interface_field_parse--------------------------
char *ADLParser::interface_field_parse(void) { char *ADLParser::interface_field_parse(const char ** format) {
char *iface_field = NULL; char *iface_field = NULL;
// Get interface field // Get interface field
...@@ -3280,6 +3289,32 @@ char *ADLParser::interface_field_parse(void) { ...@@ -3280,6 +3289,32 @@ char *ADLParser::interface_field_parse(void) {
return NULL; return NULL;
} }
skipws(); skipws();
if (format != NULL && _curchar == ',') {
next_char();
skipws();
if (_curchar != '"') {
parse_err(SYNERR, "Missing '\"' in field format .\n");
return NULL;
}
next_char();
char *start = _ptr; // Record start of the next string
while ((_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
if (_curchar == '\\') next_char(); // superquote
if (_curchar == '\n') parse_err(SYNERR, "newline in string"); // unimplemented!
next_char();
}
if (_curchar != '"') {
parse_err(SYNERR, "Missing '\"' at end of field format .\n");
return NULL;
}
// If a string was found, terminate it and record in FormatRule
if ( start != _ptr ) {
*_ptr = '\0'; // Terminate the string
*format = start;
}
next_char();
skipws();
}
if (_curchar != ')') { if (_curchar != ')') {
parse_err(SYNERR, "Missing ')' after interface field.\n"); parse_err(SYNERR, "Missing ')' after interface field.\n");
return NULL; return NULL;
...@@ -3342,6 +3377,12 @@ FormatRule* ADLParser::format_parse(void) { ...@@ -3342,6 +3377,12 @@ FormatRule* ADLParser::format_parse(void) {
next_char(); // Move past the '{' next_char(); // Move past the '{'
skipws(); skipws();
if (_curchar == '$') {
char* ident = get_rep_var_ident();
if (strcmp(ident, "$$template") == 0) return template_parse();
parse_err(SYNERR, "Unknown \"%s\" directive in format", ident);
return NULL;
}
// Check for the opening '"' inside the format description // Check for the opening '"' inside the format description
if ( _curchar == '"' ) { if ( _curchar == '"' ) {
next_char(); // Move past the initial '"' next_char(); // Move past the initial '"'
...@@ -3433,6 +3474,131 @@ FormatRule* ADLParser::format_parse(void) { ...@@ -3433,6 +3474,131 @@ FormatRule* ADLParser::format_parse(void) {
} }
//------------------------------template_parse-----------------------------------
FormatRule* ADLParser::template_parse(void) {
char *desc = NULL;
FormatRule *format = (new FormatRule(desc));
skipws();
while ( (_curchar != '%') && (*(_ptr+1) != '}') ) {
// (1)
// Check if there is a string to pass through to output
char *start = _ptr; // Record start of the next string
while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) {
// If at the start of a comment, skip past it
if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) {
skipws_no_preproc();
} else {
// ELSE advance to the next character, or start of the next line
next_char_or_line();
}
}
// If a string was found, terminate it and record in EncClass
if ( start != _ptr ) {
*_ptr = '\0'; // Terminate the string
// Add flag to _strings list indicating we should check _rep_vars
format->_strings.addName(NameList::_signal2);
format->_strings.addName(start);
}
// (2)
// If we are at a replacement variable,
// copy it and record in EncClass
if ( _curchar == '$' ) {
// Found replacement Variable
char *rep_var = get_rep_var_ident_dup();
if (strcmp(rep_var, "$emit") == 0) {
// switch to normal format parsing
next_char();
next_char();
skipws();
// Check for the opening '"' inside the format description
if ( _curchar == '"' ) {
next_char(); // Move past the initial '"'
if( _curchar == '"' ) { // Handle empty format string case
*_ptr = '\0'; // Terminate empty string
format->_strings.addName(_ptr);
}
// Collect the parts of the format description
// (1) strings that are passed through to tty->print
// (2) replacement/substitution variable, preceeded by a '$'
// (3) multi-token ANSIY C style strings
while ( true ) {
if ( _curchar == '%' || _curchar == '\n' ) {
parse_err(SYNERR, "missing '\"' at end of format block");
return NULL;
}
// (1)
// Check if there is a string to pass through to output
char *start = _ptr; // Record start of the next string
while ((_curchar != '$') && (_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
if (_curchar == '\\') next_char(); // superquote
if (_curchar == '\n') parse_err(SYNERR, "newline in string"); // unimplemented!
next_char();
}
// If a string was found, terminate it and record in FormatRule
if ( start != _ptr ) {
*_ptr = '\0'; // Terminate the string
format->_strings.addName(start);
}
// (2)
// If we are at a replacement variable,
// copy it and record in FormatRule
if ( _curchar == '$' ) {
next_char(); // Move past the '$'
char* rep_var = get_ident(); // Nil terminate the variable name
rep_var = strdup(rep_var);// Copy the string
*_ptr = _curchar; // and replace Nil with original character
format->_rep_vars.addName(rep_var);
// Add flag to _strings list indicating we should check _rep_vars
format->_strings.addName(NameList::_signal);
}
// (3)
// Allow very long strings to be broken up,
// using the ANSI C syntax "foo\n" <newline> "bar"
if ( _curchar == '"') {
next_char(); // Move past the '"'
skipws(); // Skip white space before next string token
if ( _curchar != '"') {
break;
} else {
// Found one. Skip both " and the whitespace in between.
next_char();
}
}
} // end while part of format description
}
} else {
// Add flag to _strings list indicating we should check _rep_vars
format->_rep_vars.addName(rep_var);
// Add flag to _strings list indicating we should check _rep_vars
format->_strings.addName(NameList::_signal3);
}
} // end while part of format description
}
skipws();
// Past format description, at '%'
if ( _curchar != '%' || *(_ptr+1) != '}' ) {
parse_err(SYNERR, "missing '%}' at end of format block");
return NULL;
}
next_char(); // Move past the '%'
next_char(); // Move past the '}'
// Debug Stuff
if (_AD._adl_debug > 1) fprintf(stderr,"Format Rule: %s\n", desc);
skipws();
return format;
}
//------------------------------effect_parse----------------------------------- //------------------------------effect_parse-----------------------------------
void ADLParser::effect_parse(InstructForm *instr) { void ADLParser::effect_parse(InstructForm *instr) {
char* desc = NULL; char* desc = NULL;
...@@ -3777,7 +3943,7 @@ char* ADLParser::find_cpp_block(const char* description) { ...@@ -3777,7 +3943,7 @@ char* ADLParser::find_cpp_block(const char* description) {
skipws_no_preproc(); // Skip leading whitespace skipws_no_preproc(); // Skip leading whitespace
cppBlock = _ptr; // Point to start of expression cppBlock = _ptr; // Point to start of expression
const char* file = _AD._ADL_file._name; const char* file = _AD._ADL_file._name;
int line = _linenum; int line = linenum();
next = _ptr + 1; next = _ptr + 1;
while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) { while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) {
next_char_or_line(); next_char_or_line();
...@@ -4297,11 +4463,11 @@ void ADLParser::parse_err(int flag, const char *fmt, ...) { ...@@ -4297,11 +4463,11 @@ void ADLParser::parse_err(int flag, const char *fmt, ...) {
va_start(args, fmt); va_start(args, fmt);
if (flag == 1) if (flag == 1)
_AD._syntax_errs += _AD.emit_msg(0, flag, _linenum, fmt, args); _AD._syntax_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
else if (flag == 2) else if (flag == 2)
_AD._semantic_errs += _AD.emit_msg(0, flag, _linenum, fmt, args); _AD._semantic_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
else else
_AD._warnings += _AD.emit_msg(0, flag, _linenum, fmt, args); _AD._warnings += _AD.emit_msg(0, flag, linenum(), fmt, args);
int error_char = _curchar; int error_char = _curchar;
char* error_ptr = _ptr+1; char* error_ptr = _ptr+1;
...@@ -4515,7 +4681,7 @@ void ADLParser::next_char_or_line() { ...@@ -4515,7 +4681,7 @@ void ADLParser::next_char_or_line() {
//---------------------------next_line----------------------------------------- //---------------------------next_line-----------------------------------------
void ADLParser::next_line() { void ADLParser::next_line() {
_curline = _buf.get_line(); _linenum++; _curline = _buf.get_line();
} }
//-------------------------is_literal_constant--------------------------------- //-------------------------is_literal_constant---------------------------------
......
...@@ -70,7 +70,6 @@ class ADLParser { ...@@ -70,7 +70,6 @@ class ADLParser {
protected: protected:
char *_curline; // Start of current line char *_curline; // Start of current line
char *_ptr; // Pointer into current location in File Buffer char *_ptr; // Pointer into current location in File Buffer
int _linenum; // Count of line numbers seen so far
char _curchar; // Current character from buffer char _curchar; // Current character from buffer
FormDict &_globalNames; // Global names FormDict &_globalNames; // Global names
...@@ -160,9 +159,10 @@ protected: ...@@ -160,9 +159,10 @@ protected:
Interface *interface_parse(); // Parse operand interface rule Interface *interface_parse(); // Parse operand interface rule
Interface *mem_interface_parse(); // Parse memory interface rule Interface *mem_interface_parse(); // Parse memory interface rule
Interface *cond_interface_parse(); // Parse conditional interface rule Interface *cond_interface_parse(); // Parse conditional interface rule
char *interface_field_parse();// Parse field contents char *interface_field_parse(const char** format = NULL);// Parse field contents
FormatRule *format_parse(void); // Parse format rule FormatRule *format_parse(void); // Parse format rule
FormatRule *template_parse(void); // Parse format rule
void effect_parse(InstructForm *instr); // Parse effect rule void effect_parse(InstructForm *instr); // Parse effect rule
ExpandRule *expand_parse(InstructForm *instr); // Parse expand rule ExpandRule *expand_parse(InstructForm *instr); // Parse expand rule
RewriteRule *rewrite_parse(void); // Parse rewrite rule RewriteRule *rewrite_parse(void); // Parse rewrite rule
...@@ -263,7 +263,7 @@ public: ...@@ -263,7 +263,7 @@ public:
void parse(void); // Do the parsing & build forms lists void parse(void); // Do the parsing & build forms lists
int getlines( ) { return _linenum; } int linenum() { return _buf.linenum(); }
static bool is_literal_constant(const char *hex_string); static bool is_literal_constant(const char *hex_string);
static bool is_hex_digit(char digit); static bool is_hex_digit(char digit);
......
...@@ -41,6 +41,7 @@ FileBuff::FileBuff( BufferedFile *fptr, ArchDesc& archDesc) : _fp(fptr), _AD(arc ...@@ -41,6 +41,7 @@ FileBuff::FileBuff( BufferedFile *fptr, ArchDesc& archDesc) : _fp(fptr), _AD(arc
exit(1); // Exit on seek error exit(1); // Exit on seek error
} }
_filepos = ftell(_fp->_fp); // Reset current file position _filepos = ftell(_fp->_fp); // Reset current file position
_linenum = 0;
_bigbuf = new char[_bufferSize]; // Create buffer to hold text for parser _bigbuf = new char[_bufferSize]; // Create buffer to hold text for parser
if( !_bigbuf ) { if( !_bigbuf ) {
...@@ -76,6 +77,7 @@ char *FileBuff::get_line(void) { ...@@ -76,6 +77,7 @@ char *FileBuff::get_line(void) {
// Check for end of file & return NULL // Check for end of file & return NULL
if (_bufeol >= _bufmax) return NULL; if (_bufeol >= _bufmax) return NULL;
_linenum++;
retval = ++_bufeol; // return character following end of previous line retval = ++_bufeol; // return character following end of previous line
if (*retval == '\0') return NULL; // Check for EOF sentinal if (*retval == '\0') return NULL; // Check for EOF sentinal
// Search for newline character which must end each line // Search for newline character which must end each line
......
...@@ -51,6 +51,7 @@ class FileBuff { ...@@ -51,6 +51,7 @@ class FileBuff {
int _err; // Error flag for file seek/read operations int _err; // Error flag for file seek/read operations
long _filepos; // Current offset from start of file long _filepos; // Current offset from start of file
int _linenum;
ArchDesc& _AD; // Reference to Architecture Description ArchDesc& _AD; // Reference to Architecture Description
...@@ -66,6 +67,7 @@ class FileBuff { ...@@ -66,6 +67,7 @@ class FileBuff {
// This returns a pointer to the start of the current line in the buffer, // This returns a pointer to the start of the current line in the buffer,
// and increments bufeol and filepos to point at the end of that line. // and increments bufeol and filepos to point at the end of that line.
char *get_line(void); char *get_line(void);
int linenum() const { return _linenum; }
// This converts a pointer into the buffer to a file offset. It only works // This converts a pointer into the buffer to a file offset. It only works
// when the pointer is valid (i.e. just obtained from getline()). // when the pointer is valid (i.e. just obtained from getline()).
......
...@@ -35,6 +35,8 @@ Arena *Form::generate_arena() { ...@@ -35,6 +35,8 @@ Arena *Form::generate_arena() {
//------------------------------NameList--------------------------------------- //------------------------------NameList---------------------------------------
// reserved user-defined string // reserved user-defined string
const char *NameList::_signal = "$$SIGNAL$$"; const char *NameList::_signal = "$$SIGNAL$$";
const char *NameList::_signal2 = "$$SIGNAL2$$";
const char *NameList::_signal3 = "$$SIGNAL3$$";
// Constructor and Destructor // Constructor and Destructor
NameList::NameList() : _cur(0), _max(4), _iter(0), _justReset(true) { NameList::NameList() : _cur(0), _max(4), _iter(0), _justReset(true) {
......
...@@ -329,6 +329,8 @@ protected: ...@@ -329,6 +329,8 @@ protected:
public: public:
static const char *_signal; // reserved user-defined string static const char *_signal; // reserved user-defined string
static const char *_signal2; // reserved user-defined string
static const char *_signal3; // reserved user-defined string
enum { Not_in_list = -1 }; enum { Not_in_list = -1 };
void addName(const char *name); void addName(const char *name);
......
...@@ -1574,10 +1574,10 @@ Opcode::opcode_type Opcode::as_opcode_type(const char *param) { ...@@ -1574,10 +1574,10 @@ Opcode::opcode_type Opcode::as_opcode_type(const char *param) {
return Opcode::NOT_AN_OPCODE; return Opcode::NOT_AN_OPCODE;
} }
void Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) { bool Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
// Default values previously provided by MachNode::primary()... // Default values previously provided by MachNode::primary()...
const char *description = "default_opcode()"; const char *description = NULL;
const char *value = "-1"; const char *value = NULL;
// Check if user provided any opcode definitions // Check if user provided any opcode definitions
if( this != NULL ) { if( this != NULL ) {
// Update 'value' if user provided a definition in the instruction // Update 'value' if user provided a definition in the instruction
...@@ -1599,7 +1599,10 @@ void Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) { ...@@ -1599,7 +1599,10 @@ void Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
break; break;
} }
} }
fprintf(fp, "(%s /*%s*/)", value, description); if (value != NULL) {
fprintf(fp, "(%s /*%s*/)", value, description);
}
return value != NULL;
} }
void Opcode::dump() { void Opcode::dump() {
...@@ -2610,14 +2613,19 @@ void MemInterface::output(FILE *fp) { ...@@ -2610,14 +2613,19 @@ void MemInterface::output(FILE *fp) {
} }
//------------------------------CondInterface---------------------------------- //------------------------------CondInterface----------------------------------
CondInterface::CondInterface(char *equal, char *not_equal, CondInterface::CondInterface(const char* equal, const char* equal_format,
char *less, char *greater_equal, const char* not_equal, const char* not_equal_format,
char *less_equal, char *greater) const char* less, const char* less_format,
const char* greater_equal, const char* greater_equal_format,
const char* less_equal, const char* less_equal_format,
const char* greater, const char* greater_format)
: Interface("COND_INTER"), : Interface("COND_INTER"),
_equal(equal), _not_equal(not_equal), _equal(equal), _equal_format(equal_format),
_less(less), _greater_equal(greater_equal), _not_equal(not_equal), _not_equal_format(not_equal_format),
_less_equal(less_equal), _greater(greater) { _less(less), _less_format(less_format),
// _greater_equal(greater_equal), _greater_equal_format(greater_equal_format),
_less_equal(less_equal), _less_equal_format(less_equal_format),
_greater(greater), _greater_format(greater_format) {
} }
CondInterface::~CondInterface() { CondInterface::~CondInterface() {
// not owner of any character arrays // not owner of any character arrays
...@@ -3316,7 +3324,7 @@ int MatchNode::needs_ideal_memory_edge(FormDict &globals) const { ...@@ -3316,7 +3324,7 @@ int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
"Load8B" ,"Load4B" ,"Load8C" ,"Load4C" ,"Load2C" ,"Load8S", "Load4S","Load2S", "Load8B" ,"Load4B" ,"Load8C" ,"Load4C" ,"Load2C" ,"Load8S", "Load4S","Load2S",
"LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned", "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
"LoadPLocked", "LoadLLocked", "LoadPLocked", "LoadLLocked",
"StorePConditional", "StoreLConditional", "StorePConditional", "StoreIConditional", "StoreLConditional",
"CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN", "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
"StoreCM", "StoreCM",
"ClearArray" "ClearArray"
......
...@@ -397,7 +397,7 @@ public: ...@@ -397,7 +397,7 @@ public:
void output(FILE *fp); void output(FILE *fp);
// --------------------------- FILE *output_routines // --------------------------- FILE *output_routines
void print_opcode(FILE *fp, Opcode::opcode_type desired_opcode); bool print_opcode(FILE *fp, Opcode::opcode_type desired_opcode);
}; };
//------------------------------InsEncode-------------------------------------- //------------------------------InsEncode--------------------------------------
...@@ -779,10 +779,20 @@ public: ...@@ -779,10 +779,20 @@ public:
const char *_greater_equal; const char *_greater_equal;
const char *_less_equal; const char *_less_equal;
const char *_greater; const char *_greater;
const char *_equal_format;
const char *_not_equal_format;
const char *_less_format;
const char *_greater_equal_format;
const char *_less_equal_format;
const char *_greater_format;
// Public Methods // Public Methods
CondInterface(char *equal, char *not_equal, char *less, char *greater_equal, CondInterface(const char* equal, const char* equal_format,
char *less_equal, char *greater); const char* not_equal, const char* not_equal_format,
const char* less, const char* less_format,
const char* greater_equal, const char* greater_equal_format,
const char* less_equal, const char* less_equal_format,
const char* greater, const char* greater_format);
~CondInterface(); ~CondInterface();
void dump(); void dump();
......
...@@ -1619,6 +1619,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) { ...@@ -1619,6 +1619,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
} }
// Iterate over the new instruction's operands // Iterate over the new instruction's operands
int prev_pos = -1;
for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) { for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) {
// Use 'parameter' at current position in list of new instruction's formals // Use 'parameter' at current position in list of new instruction's formals
// instead of 'opid' when looking up info internal to new_inst // instead of 'opid' when looking up info internal to new_inst
...@@ -1642,6 +1643,18 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) { ...@@ -1642,6 +1643,18 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
// ins = (InstructForm *) _globalNames[new_id]; // ins = (InstructForm *) _globalNames[new_id];
exp_pos = node->operand_position_format(opid); exp_pos = node->operand_position_format(opid);
assert(exp_pos != -1, "Bad expand rule"); assert(exp_pos != -1, "Bad expand rule");
if (prev_pos > exp_pos && expand_instruction->_matrule != NULL) {
// For the add_req calls below to work correctly they need
// to added in the same order that a match would add them.
// This means that they would need to be in the order of
// the components list instead of the formal parameters.
// This is a sort of hidden invariant that previously
// wasn't checked and could lead to incorrectly
// constructed nodes.
syntax_err(node->_linenum, "For expand in %s to work, parameter declaration order in %s must follow matchrule\n",
node->_ident, new_inst->_ident);
}
prev_pos = exp_pos;
new_pos = new_inst->operand_position(parameter,Component::USE); new_pos = new_inst->operand_position(parameter,Component::USE);
if (new_pos != -1) { if (new_pos != -1) {
...@@ -2306,7 +2319,12 @@ private: ...@@ -2306,7 +2319,12 @@ private:
_processing_noninput = false; _processing_noninput = false;
// A replacement variable, originally '$' // A replacement variable, originally '$'
if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) { if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) ); if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
// Missing opcode
_AD.syntax_err( _inst._linenum,
"Missing $%s opcode definition in %s, used by encoding %s\n",
rep_var, _inst._ident, _encoding._name);
}
} }
else { else {
// Lookup its position in parameter list // Lookup its position in parameter list
...@@ -2348,7 +2366,13 @@ private: ...@@ -2348,7 +2366,13 @@ private:
else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) { else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
// else check if "primary", "secondary", "tertiary" // else check if "primary", "secondary", "tertiary"
assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter"); assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) ); if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) )) {
// Missing opcode
_AD.syntax_err( _inst._linenum,
"Missing $%s opcode definition in %s\n",
rep_var, _inst._ident);
}
_constant_status = LITERAL_OUTPUT; _constant_status = LITERAL_OUTPUT;
} }
else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) { else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) {
......
...@@ -355,17 +355,19 @@ static void defineConstructor(FILE *fp, const char *name, uint num_consts, ...@@ -355,17 +355,19 @@ static void defineConstructor(FILE *fp, const char *name, uint num_consts,
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Generate the format rule for condition codes // Generate the format rule for condition codes
static void defineCCodeDump(FILE *fp, int i) { static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) {
fprintf(fp, " if( _c%d == BoolTest::eq ) st->print(\"eq\");\n",i); assert(oper != NULL, "what");
fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print(\"ne\");\n",i); CondInterface* cond = oper->_interface->is_CondInterface();
fprintf(fp, " else if( _c%d == BoolTest::le ) st->print(\"le\");\n",i); fprintf(fp, " if( _c%d == BoolTest::eq ) st->print(\"%s\");\n",i,cond->_equal_format);
fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"ge\");\n",i); fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print(\"%s\");\n",i,cond->_not_equal_format);
fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"lt\");\n",i); fprintf(fp, " else if( _c%d == BoolTest::le ) st->print(\"%s\");\n",i,cond->_less_equal_format);
fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"gt\");\n",i); fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format);
fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format);
fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format);
} }
// Output code that dumps constant values, increment "i" if type is constant // Output code that dumps constant values, increment "i" if type is constant
static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) { static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, OperandForm* oper) {
if (!strcmp(ideal_type, "ConI")) { if (!strcmp(ideal_type, "ConI")) {
fprintf(fp," st->print(\"#%%d\", _c%d);\n", i); fprintf(fp," st->print(\"#%%d\", _c%d);\n", i);
++i; ++i;
...@@ -375,7 +377,7 @@ static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) { ...@@ -375,7 +377,7 @@ static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) {
++i; ++i;
} }
else if (!strcmp(ideal_type, "ConN")) { else if (!strcmp(ideal_type, "ConN")) {
fprintf(fp," _c%d->dump();\n", i); fprintf(fp," _c%d->dump_on(st);\n", i);
++i; ++i;
} }
else if (!strcmp(ideal_type, "ConL")) { else if (!strcmp(ideal_type, "ConL")) {
...@@ -391,7 +393,7 @@ static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) { ...@@ -391,7 +393,7 @@ static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) {
++i; ++i;
} }
else if (!strcmp(ideal_type, "Bool")) { else if (!strcmp(ideal_type, "Bool")) {
defineCCodeDump(fp,i); defineCCodeDump(oper, fp,i);
++i; ++i;
} }
...@@ -476,7 +478,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_ ...@@ -476,7 +478,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_
} }
// ALWAYS! Provide a special case output for condition codes. // ALWAYS! Provide a special case output for condition codes.
if( oper.is_ideal_bool() ) { if( oper.is_ideal_bool() ) {
defineCCodeDump(fp,0); defineCCodeDump(&oper, fp,0);
} }
fprintf(fp,"}\n"); fprintf(fp,"}\n");
...@@ -549,7 +551,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_ ...@@ -549,7 +551,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_
} }
// ALWAYS! Provide a special case output for condition codes. // ALWAYS! Provide a special case output for condition codes.
if( oper.is_ideal_bool() ) { if( oper.is_ideal_bool() ) {
defineCCodeDump(fp,0); defineCCodeDump(&oper, fp,0);
} }
fprintf(fp, "}\n"); fprintf(fp, "}\n");
fprintf(fp, "#endif\n"); fprintf(fp, "#endif\n");
...@@ -583,10 +585,53 @@ void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &inst, bool for_c ...@@ -583,10 +585,53 @@ void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &inst, bool for_c
while( (string = inst._format->_strings.iter()) != NULL ) { while( (string = inst._format->_strings.iter()) != NULL ) {
fprintf(fp," "); fprintf(fp," ");
// Check if this is a standard string or a replacement variable // Check if this is a standard string or a replacement variable
if( string != NameList::_signal ) // Normal string. Pass through. if( string == NameList::_signal ) { // Replacement variable
const char* rep_var = inst._format->_rep_vars.iter();
inst.rep_var_format( fp, rep_var);
} else if( string == NameList::_signal3 ) { // Replacement variable in raw text
const char* rep_var = inst._format->_rep_vars.iter();
const Form *form = inst._localNames[rep_var];
if (form == NULL) {
fprintf(stderr, "unknown replacement variable in format statement: '%s'\n", rep_var);
assert(false, "ShouldNotReachHere()");
}
OpClassForm *opc = form->is_opclass();
assert( opc, "replacement variable was not found in local names");
// Lookup the index position of the replacement variable
int idx = inst.operand_position_format(rep_var);
if ( idx == -1 ) {
assert( strcmp(opc->_ident,"label")==0, "Unimplemented");
assert( false, "ShouldNotReachHere()");
}
if (inst.is_noninput_operand(idx)) {
assert( false, "ShouldNotReachHere()");
} else {
// Output the format call for this operand
fprintf(fp,"opnd_array(%d)",idx);
}
rep_var = inst._format->_rep_vars.iter();
inst._format->_strings.iter();
if ( strcmp(rep_var,"$constant") == 0 && opc->is_operand()) {
Form::DataType constant_type = form->is_operand()->is_base_constant(globals);
if ( constant_type == Form::idealD ) {
fprintf(fp,"->constantD()");
} else if ( constant_type == Form::idealF ) {
fprintf(fp,"->constantF()");
} else if ( constant_type == Form::idealL ) {
fprintf(fp,"->constantL()");
} else {
fprintf(fp,"->constant()");
}
} else if ( strcmp(rep_var,"$cmpcode") == 0) {
fprintf(fp,"->ccode()");
} else {
assert( false, "ShouldNotReachHere()");
}
} else if( string == NameList::_signal2 ) // Raw program text
fputs(inst._format->_strings.iter(), fp);
else
fprintf(fp,"st->print(\"%s\");\n", string); fprintf(fp,"st->print(\"%s\");\n", string);
else // Replacement variable
inst.rep_var_format( fp, inst._format->_rep_vars.iter() );
} // Done with all format strings } // Done with all format strings
} // Done generating the user-defined portion of the format } // Done generating the user-defined portion of the format
...@@ -1404,7 +1449,7 @@ void ArchDesc::declareClasses(FILE *fp) { ...@@ -1404,7 +1449,7 @@ void ArchDesc::declareClasses(FILE *fp) {
oper->_components.reset(); oper->_components.reset();
if ((comp = oper->_components.iter()) == NULL) { if ((comp = oper->_components.iter()) == NULL) {
assert(num_consts == 1, "Bad component list detected.\n"); assert(num_consts == 1, "Bad component list detected.\n");
i = dump_spec_constant( fp, type, i ); i = dump_spec_constant( fp, type, i, oper );
// Check that type actually matched // Check that type actually matched
assert( i != 0, "Non-constant operand lacks component list."); assert( i != 0, "Non-constant operand lacks component list.");
} // end if NULL } // end if NULL
...@@ -1414,7 +1459,7 @@ void ArchDesc::declareClasses(FILE *fp) { ...@@ -1414,7 +1459,7 @@ void ArchDesc::declareClasses(FILE *fp) {
oper->_components.reset(); oper->_components.reset();
while((comp = oper->_components.iter()) != NULL) { while((comp = oper->_components.iter()) != NULL) {
type = comp->base_type(_globalNames); type = comp->base_type(_globalNames);
i = dump_spec_constant( fp, type, i ); i = dump_spec_constant( fp, type, i, NULL );
} }
} }
// finish line (3) // finish line (3)
......
此差异已折叠。
...@@ -75,6 +75,7 @@ public: ...@@ -75,6 +75,7 @@ public:
void insert( uint i, Block *n ); void insert( uint i, Block *n );
uint size() const { return _cnt; } uint size() const { return _cnt; }
void reset() { _cnt = 0; } void reset() { _cnt = 0; }
void print();
}; };
...@@ -129,7 +130,11 @@ class Block : public CFGElement { ...@@ -129,7 +130,11 @@ class Block : public CFGElement {
uint _rpo; // Number in reverse post order walk uint _rpo; // Number in reverse post order walk
virtual bool is_block() { return true; } virtual bool is_block() { return true; }
float succ_prob(uint i); // return probability of i'th successor float succ_prob(uint i); // return probability of i'th successor
int num_fall_throughs(); // How many fall-through candidate this block has
void update_uncommon_branch(Block* un); // Lower branch prob to uncommon code
bool succ_fall_through(uint i); // Is successor "i" is a fall-through candidate
Block* lone_fall_through(); // Return lone fall-through Block or null
Block* dom_lca(Block* that); // Compute LCA in dominator tree. Block* dom_lca(Block* that); // Compute LCA in dominator tree.
#ifdef ASSERT #ifdef ASSERT
...@@ -144,6 +149,7 @@ class Block : public CFGElement { ...@@ -144,6 +149,7 @@ class Block : public CFGElement {
// Report the alignment required by this block. Must be a power of 2. // Report the alignment required by this block. Must be a power of 2.
// The previous block will insert nops to get this alignment. // The previous block will insert nops to get this alignment.
uint code_alignment(); uint code_alignment();
uint compute_loop_alignment();
// BLOCK_FREQUENCY is a sentinel to mark uses of constant block frequencies. // BLOCK_FREQUENCY is a sentinel to mark uses of constant block frequencies.
// It is currently also used to scale such frequencies relative to // It is currently also used to scale such frequencies relative to
...@@ -184,11 +190,12 @@ class Block : public CFGElement { ...@@ -184,11 +190,12 @@ class Block : public CFGElement {
int current_alignment = current_offset & max_pad; int current_alignment = current_offset & max_pad;
if( current_alignment != 0 ) { if( current_alignment != 0 ) {
uint padding = (block_alignment-current_alignment) & max_pad; uint padding = (block_alignment-current_alignment) & max_pad;
if( !head()->is_Loop() || if( has_loop_alignment() &&
padding <= (uint)MaxLoopPad || padding > (uint)MaxLoopPad &&
first_inst_size() > padding ) { first_inst_size() <= padding ) {
return padding; return 0;
} }
return padding;
} }
} }
return 0; return 0;
...@@ -202,6 +209,21 @@ class Block : public CFGElement { ...@@ -202,6 +209,21 @@ class Block : public CFGElement {
void set_connector() { _connector = true; } void set_connector() { _connector = true; }
bool is_connector() const { return _connector; }; bool is_connector() const { return _connector; };
// Loop_alignment will be set for blocks which are at the top of loops.
// The block layout pass may rotate loops such that the loop head may not
// be the sequentially first block of the loop encountered in the linear
// list of blocks. If the layout pass is not run, loop alignment is set
// for each block which is the head of a loop.
uint _loop_alignment;
void set_loop_alignment(Block *loop_top) {
uint new_alignment = loop_top->compute_loop_alignment();
if (new_alignment > _loop_alignment) {
_loop_alignment = new_alignment;
}
}
uint loop_alignment() const { return _loop_alignment; }
bool has_loop_alignment() const { return loop_alignment() > 0; }
// Create a new Block with given head Node. // Create a new Block with given head Node.
// Creates the (empty) predecessor arrays. // Creates the (empty) predecessor arrays.
Block( Arena *a, Node *headnode ) Block( Arena *a, Node *headnode )
...@@ -219,7 +241,8 @@ class Block : public CFGElement { ...@@ -219,7 +241,8 @@ class Block : public CFGElement {
_raise_LCA_mark(0), _raise_LCA_mark(0),
_raise_LCA_visited(0), _raise_LCA_visited(0),
_first_inst_size(999999), _first_inst_size(999999),
_connector(false) { _connector(false),
_loop_alignment(0) {
_nodes.push(headnode); _nodes.push(headnode);
} }
...@@ -275,6 +298,16 @@ class Block : public CFGElement { ...@@ -275,6 +298,16 @@ class Block : public CFGElement {
return s; return s;
} }
// Return true if b is a successor of this block
bool has_successor(Block* b) const {
for (uint i = 0; i < _num_succs; i++ ) {
if (non_connector_successor(i) == b) {
return true;
}
}
return false;
}
// Successor block, after forwarding through connectors // Successor block, after forwarding through connectors
Block* non_connector_successor(int i) const { Block* non_connector_successor(int i) const {
return _succs[i]->non_connector(); return _succs[i]->non_connector();
...@@ -319,7 +352,6 @@ class PhaseCFG : public Phase { ...@@ -319,7 +352,6 @@ class PhaseCFG : public Phase {
// I'll need a few machine-specific GotoNodes. Clone from this one. // I'll need a few machine-specific GotoNodes. Clone from this one.
MachNode *_goto; MachNode *_goto;
void insert_goto_at(uint block_no, uint succ_no);
Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false); Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
void verify_anti_dependences(Block* LCA, Node* load) { void verify_anti_dependences(Block* LCA, Node* load) {
...@@ -379,10 +411,15 @@ class PhaseCFG : public Phase { ...@@ -379,10 +411,15 @@ class PhaseCFG : public Phase {
// Compute the instruction global latency with a backwards walk // Compute the instruction global latency with a backwards walk
void ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack); void ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack);
// Set loop alignment
void set_loop_alignment();
// Remove empty basic blocks // Remove empty basic blocks
void RemoveEmpty(); void remove_empty();
bool MoveToNext(Block* bx, uint b_index); void fixup_flow();
void MoveToEnd(Block* bx, uint b_index); bool move_to_next(Block* bx, uint b_index);
void move_to_end(Block* bx, uint b_index);
void insert_goto_at(uint block_no, uint succ_no);
// Check for NeverBranch at block end. This needs to become a GOTO to the // Check for NeverBranch at block end. This needs to become a GOTO to the
// true target. NeverBranch are treated as a conditional branch that always // true target. NeverBranch are treated as a conditional branch that always
...@@ -413,7 +450,7 @@ class PhaseCFG : public Phase { ...@@ -413,7 +450,7 @@ class PhaseCFG : public Phase {
}; };
//------------------------------UnionFindInfo---------------------------------- //------------------------------UnionFind--------------------------------------
// Map Block indices to a block-index for a cfg-cover. // Map Block indices to a block-index for a cfg-cover.
// Array lookup in the optimized case. // Array lookup in the optimized case.
class UnionFind : public ResourceObj { class UnionFind : public ResourceObj {
...@@ -508,3 +545,166 @@ class CFGLoop : public CFGElement { ...@@ -508,3 +545,166 @@ class CFGLoop : public CFGElement {
void dump_tree() const; void dump_tree() const;
#endif #endif
}; };
//----------------------------------CFGEdge------------------------------------
// A edge between two basic blocks that will be embodied by a branch or a
// fall-through.
class CFGEdge : public ResourceObj {
private:
Block * _from; // Source basic block
Block * _to; // Destination basic block
float _freq; // Execution frequency (estimate)
int _state;
bool _infrequent;
int _from_pct;
int _to_pct;
// Private accessors
int from_pct() const { return _from_pct; }
int to_pct() const { return _to_pct; }
int from_infrequent() const { return from_pct() < BlockLayoutMinDiamondPercentage; }
int to_infrequent() const { return to_pct() < BlockLayoutMinDiamondPercentage; }
public:
enum {
open, // initial edge state; unprocessed
connected, // edge used to connect two traces together
interior // edge is interior to trace (could be backedge)
};
CFGEdge(Block *from, Block *to, float freq, int from_pct, int to_pct) :
_from(from), _to(to), _freq(freq),
_from_pct(from_pct), _to_pct(to_pct), _state(open) {
_infrequent = from_infrequent() || to_infrequent();
}
float freq() const { return _freq; }
Block* from() const { return _from; }
Block* to () const { return _to; }
int infrequent() const { return _infrequent; }
int state() const { return _state; }
void set_state(int state) { _state = state; }
#ifndef PRODUCT
void dump( ) const;
#endif
};
//-----------------------------------Trace-------------------------------------
// An ordered list of basic blocks.
class Trace : public ResourceObj {
private:
uint _id; // Unique Trace id (derived from initial block)
Block ** _next_list; // Array mapping index to next block
Block ** _prev_list; // Array mapping index to previous block
Block * _first; // First block in the trace
Block * _last; // Last block in the trace
// Return the block that follows "b" in the trace.
Block * next(Block *b) const { return _next_list[b->_pre_order]; }
void set_next(Block *b, Block *n) const { _next_list[b->_pre_order] = n; }
// Return the block that preceeds "b" in the trace.
Block * prev(Block *b) const { return _prev_list[b->_pre_order]; }
void set_prev(Block *b, Block *p) const { _prev_list[b->_pre_order] = p; }
// We've discovered a loop in this trace. Reset last to be "b", and first as
// the block following "b
void break_loop_after(Block *b) {
_last = b;
_first = next(b);
set_prev(_first, NULL);
set_next(_last, NULL);
}
public:
Trace(Block *b, Block **next_list, Block **prev_list) :
_first(b),
_last(b),
_next_list(next_list),
_prev_list(prev_list),
_id(b->_pre_order) {
set_next(b, NULL);
set_prev(b, NULL);
};
// Return the id number
uint id() const { return _id; }
void set_id(uint id) { _id = id; }
// Return the first block in the trace
Block * first_block() const { return _first; }
// Return the last block in the trace
Block * last_block() const { return _last; }
// Insert a trace in the middle of this one after b
void insert_after(Block *b, Trace *tr) {
set_next(tr->last_block(), next(b));
if (next(b) != NULL) {
set_prev(next(b), tr->last_block());
}
set_next(b, tr->first_block());
set_prev(tr->first_block(), b);
if (b == _last) {
_last = tr->last_block();
}
}
void insert_before(Block *b, Trace *tr) {
Block *p = prev(b);
assert(p != NULL, "use append instead");
insert_after(p, tr);
}
// Append another trace to this one.
void append(Trace *tr) {
insert_after(_last, tr);
}
// Append a block at the end of this trace
void append(Block *b) {
set_next(_last, b);
set_prev(b, _last);
_last = b;
}
// Adjust the the blocks in this trace
void fixup_blocks(PhaseCFG &cfg);
bool backedge(CFGEdge *e);
#ifndef PRODUCT
void dump( ) const;
#endif
};
//------------------------------PhaseBlockLayout-------------------------------
// Rearrange blocks into some canonical order, based on edges and their frequencies
class PhaseBlockLayout : public Phase {
PhaseCFG &_cfg; // Control flow graph
GrowableArray<CFGEdge *> *edges;
Trace **traces;
Block **next;
Block **prev;
UnionFind *uf;
// Given a block, find its encompassing Trace
Trace * trace(Block *b) {
return traces[uf->Find_compress(b->_pre_order)];
}
public:
PhaseBlockLayout(PhaseCFG &cfg);
void find_edges();
void grow_traces();
void merge_traces(bool loose_connections);
void reorder_traces(int count);
void union_traces(Trace* from, Trace* to);
};
...@@ -388,6 +388,9 @@ ...@@ -388,6 +388,9 @@
product(intx, EliminateAllocationArraySizeLimit, 64, \ product(intx, EliminateAllocationArraySizeLimit, 64, \
"Array size (number of elements) limit for scalar replacement") \ "Array size (number of elements) limit for scalar replacement") \
\ \
product(bool, UseOptoBiasInlining, true, \
"Generate biased locking code in C2 ideal graph") \
\
product(intx, ValueSearchLimit, 1000, \ product(intx, ValueSearchLimit, 1000, \
"Recursion limit in PhaseMacroExpand::value_from_mem_phi") \ "Recursion limit in PhaseMacroExpand::value_from_mem_phi") \
\ \
...@@ -396,5 +399,15 @@ ...@@ -396,5 +399,15 @@
\ \
diagnostic(intx, DominatorSearchLimit, 1000, \ diagnostic(intx, DominatorSearchLimit, 1000, \
"Iterations limit in Node::dominates") \ "Iterations limit in Node::dominates") \
\
product(bool, BlockLayoutByFrequency, true, \
"Use edge frequencies to drive block ordering") \
\
product(intx, BlockLayoutMinDiamondPercentage, 20, \
"Miniumum %% of a successor (predecessor) for which block layout "\
"a will allow a fork (join) in a single chain") \
\
product(bool, BlockLayoutRotateLoops, false, \
"Allow back branches to be fall throughs in the block layour") \
C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG) C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
...@@ -967,6 +967,7 @@ SafePointScalarObjectNode::SafePointScalarObjectNode(const TypeOopPtr* tp, ...@@ -967,6 +967,7 @@ SafePointScalarObjectNode::SafePointScalarObjectNode(const TypeOopPtr* tp,
init_class_id(Class_SafePointScalarObject); init_class_id(Class_SafePointScalarObject);
} }
bool SafePointScalarObjectNode::pinned() const { return true; }
uint SafePointScalarObjectNode::ideal_reg() const { uint SafePointScalarObjectNode::ideal_reg() const {
return 0; // No matching to machine instruction return 0; // No matching to machine instruction
......
...@@ -433,6 +433,10 @@ public: ...@@ -433,6 +433,10 @@ public:
uint n_fields() const { return _n_fields; } uint n_fields() const { return _n_fields; }
DEBUG_ONLY(AllocateNode* alloc() const { return _alloc; }) DEBUG_ONLY(AllocateNode* alloc() const { return _alloc; })
// SafePointScalarObject should be always pinned to the control edge
// of the SafePoint node for which it was generated.
virtual bool pinned() const; // { return true; }
virtual uint size_of() const { return sizeof(*this); } virtual uint size_of() const { return sizeof(*this); }
// Assumes that "this" is an argument to a safepoint node "s", and that // Assumes that "this" is an argument to a safepoint node "s", and that
......
...@@ -440,9 +440,7 @@ void PhaseChaitin::Register_Allocate() { ...@@ -440,9 +440,7 @@ void PhaseChaitin::Register_Allocate() {
assert((int)(_matcher._new_SP+_framesize) >= (int)_matcher._out_arg_limit, "framesize must be large enough"); assert((int)(_matcher._new_SP+_framesize) >= (int)_matcher._out_arg_limit, "framesize must be large enough");
// This frame must preserve the required fp alignment // This frame must preserve the required fp alignment
const int stack_alignment_in_words = Matcher::stack_alignment_in_slots(); _framesize = round_to(_framesize, Matcher::stack_alignment_in_slots());
if (stack_alignment_in_words > 0)
_framesize = round_to(_framesize, Matcher::stack_alignment_in_bytes());
assert( _framesize >= 0 && _framesize <= 1000000, "sanity check" ); assert( _framesize >= 0 && _framesize <= 1000000, "sanity check" );
#ifndef PRODUCT #ifndef PRODUCT
_total_framesize += _framesize; _total_framesize += _framesize;
......
...@@ -205,6 +205,7 @@ macro(StoreB) ...@@ -205,6 +205,7 @@ macro(StoreB)
macro(StoreC) macro(StoreC)
macro(StoreCM) macro(StoreCM)
macro(StorePConditional) macro(StorePConditional)
macro(StoreIConditional)
macro(StoreLConditional) macro(StoreLConditional)
macro(StoreD) macro(StoreD)
macro(StoreF) macro(StoreF)
......
...@@ -551,7 +551,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr ...@@ -551,7 +551,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
rethrow_exceptions(kit.transfer_exceptions_into_jvms()); rethrow_exceptions(kit.transfer_exceptions_into_jvms());
} }
print_method("Before RemoveUseless"); print_method("Before RemoveUseless", 3);
// Remove clutter produced by parsing. // Remove clutter produced by parsing.
if (!failing()) { if (!failing()) {
...@@ -822,6 +822,7 @@ void Compile::Init(int aliaslevel) { ...@@ -822,6 +822,7 @@ void Compile::Init(int aliaslevel) {
Copy::zero_to_bytes(_trap_hist, sizeof(_trap_hist)); Copy::zero_to_bytes(_trap_hist, sizeof(_trap_hist));
set_decompile_count(0); set_decompile_count(0);
set_do_freq_based_layout(BlockLayoutByFrequency || method_has_option("BlockLayoutByFrequency"));
// Compilation level related initialization // Compilation level related initialization
if (env()->comp_level() == CompLevel_fast_compile) { if (env()->comp_level() == CompLevel_fast_compile) {
set_num_loop_opts(Tier1LoopOptsCount); set_num_loop_opts(Tier1LoopOptsCount);
...@@ -1701,8 +1702,14 @@ void Compile::Code_Gen() { ...@@ -1701,8 +1702,14 @@ void Compile::Code_Gen() {
// are not adding any new instructions. If any basic block is empty, we // are not adding any new instructions. If any basic block is empty, we
// can now safely remove it. // can now safely remove it.
{ {
NOT_PRODUCT( TracePhase t2("removeEmpty", &_t_removeEmptyBlocks, TimeCompiler); ) NOT_PRODUCT( TracePhase t2("blockOrdering", &_t_blockOrdering, TimeCompiler); )
cfg.RemoveEmpty(); cfg.remove_empty();
if (do_freq_based_layout()) {
PhaseBlockLayout layout(cfg);
} else {
cfg.set_loop_alignment();
}
cfg.fixup_flow();
} }
// Perform any platform dependent postallocation verifications. // Perform any platform dependent postallocation verifications.
...@@ -1994,6 +2001,7 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) { ...@@ -1994,6 +2001,7 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
case Op_StorePConditional: case Op_StorePConditional:
case Op_StoreI: case Op_StoreI:
case Op_StoreL: case Op_StoreL:
case Op_StoreIConditional:
case Op_StoreLConditional: case Op_StoreLConditional:
case Op_CompareAndSwapI: case Op_CompareAndSwapI:
case Op_CompareAndSwapL: case Op_CompareAndSwapL:
......
...@@ -154,6 +154,7 @@ class Compile : public Phase { ...@@ -154,6 +154,7 @@ class Compile : public Phase {
uint _decompile_count; // Cumulative decompilation counts. uint _decompile_count; // Cumulative decompilation counts.
bool _do_inlining; // True if we intend to do inlining bool _do_inlining; // True if we intend to do inlining
bool _do_scheduling; // True if we intend to do scheduling bool _do_scheduling; // True if we intend to do scheduling
bool _do_freq_based_layout; // True if we intend to do frequency based block layout
bool _do_count_invocations; // True if we generate code to count invocations bool _do_count_invocations; // True if we generate code to count invocations
bool _do_method_data_update; // True if we generate code to update methodDataOops bool _do_method_data_update; // True if we generate code to update methodDataOops
int _AliasLevel; // Locally-adjusted version of AliasLevel flag. int _AliasLevel; // Locally-adjusted version of AliasLevel flag.
...@@ -307,6 +308,8 @@ class Compile : public Phase { ...@@ -307,6 +308,8 @@ class Compile : public Phase {
void set_do_inlining(bool z) { _do_inlining = z; } void set_do_inlining(bool z) { _do_inlining = z; }
bool do_scheduling() const { return _do_scheduling; } bool do_scheduling() const { return _do_scheduling; }
void set_do_scheduling(bool z) { _do_scheduling = z; } void set_do_scheduling(bool z) { _do_scheduling = z; }
bool do_freq_based_layout() const{ return _do_freq_based_layout; }
void set_do_freq_based_layout(bool z){ _do_freq_based_layout = z; }
bool do_count_invocations() const{ return _do_count_invocations; } bool do_count_invocations() const{ return _do_count_invocations; }
void set_do_count_invocations(bool z){ _do_count_invocations = z; } void set_do_count_invocations(bool z){ _do_count_invocations = z; }
bool do_method_data_update() const { return _do_method_data_update; } bool do_method_data_update() const { return _do_method_data_update; }
......
...@@ -1319,11 +1319,33 @@ void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_ ...@@ -1319,11 +1319,33 @@ void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_
//------------------------------Estimate_Block_Frequency----------------------- //------------------------------Estimate_Block_Frequency-----------------------
// Estimate block frequencies based on IfNode probabilities. // Estimate block frequencies based on IfNode probabilities.
void PhaseCFG::Estimate_Block_Frequency() { void PhaseCFG::Estimate_Block_Frequency() {
int cnts = C->method() ? C->method()->interpreter_invocation_count() : 1;
// Most of our algorithms will die horribly if frequency can become // Force conditional branches leading to uncommon traps to be unlikely,
// negative so make sure cnts is a sane value. // not because we get to the uncommon_trap with less relative frequency,
if( cnts <= 0 ) cnts = 1; // but because an uncommon_trap typically causes a deopt, so we only get
float f = (float)cnts/(float)FreqCountInvocations; // there once.
if (C->do_freq_based_layout()) {
Block_List worklist;
Block* root_blk = _blocks[0];
for (uint i = 1; i < root_blk->num_preds(); i++) {
Block *pb = _bbs[root_blk->pred(i)->_idx];
if (pb->has_uncommon_code()) {
worklist.push(pb);
}
}
while (worklist.size() > 0) {
Block* uct = worklist.pop();
if (uct == _broot) continue;
for (uint i = 1; i < uct->num_preds(); i++) {
Block *pb = _bbs[uct->pred(i)->_idx];
if (pb->_num_succs == 1) {
worklist.push(pb);
} else if (pb->num_fall_throughs() == 2) {
pb->update_uncommon_branch(uct);
}
}
}
}
// Create the loop tree and calculate loop depth. // Create the loop tree and calculate loop depth.
_root_loop = create_loop_tree(); _root_loop = create_loop_tree();
...@@ -1333,27 +1355,29 @@ void PhaseCFG::Estimate_Block_Frequency() { ...@@ -1333,27 +1355,29 @@ void PhaseCFG::Estimate_Block_Frequency() {
_root_loop->compute_freq(); _root_loop->compute_freq();
// Adjust all frequencies to be relative to a single method entry // Adjust all frequencies to be relative to a single method entry
_root_loop->_freq = f * 1.0; _root_loop->_freq = 1.0;
_root_loop->scale_freq(); _root_loop->scale_freq();
// force paths ending at uncommon traps to be infrequent // force paths ending at uncommon traps to be infrequent
Block_List worklist; if (!C->do_freq_based_layout()) {
Block* root_blk = _blocks[0]; Block_List worklist;
for (uint i = 0; i < root_blk->num_preds(); i++) { Block* root_blk = _blocks[0];
Block *pb = _bbs[root_blk->pred(i)->_idx]; for (uint i = 1; i < root_blk->num_preds(); i++) {
if (pb->has_uncommon_code()) { Block *pb = _bbs[root_blk->pred(i)->_idx];
worklist.push(pb); if (pb->has_uncommon_code()) {
}
}
while (worklist.size() > 0) {
Block* uct = worklist.pop();
uct->_freq = PROB_MIN;
for (uint i = 0; i < uct->num_preds(); i++) {
Block *pb = _bbs[uct->pred(i)->_idx];
if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) {
worklist.push(pb); worklist.push(pb);
} }
} }
while (worklist.size() > 0) {
Block* uct = worklist.pop();
uct->_freq = PROB_MIN;
for (uint i = 1; i < uct->num_preds(); i++) {
Block *pb = _bbs[uct->pred(i)->_idx];
if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) {
worklist.push(pb);
}
}
}
} }
#ifndef PRODUCT #ifndef PRODUCT
...@@ -1556,22 +1580,6 @@ void CFGLoop::compute_freq() { ...@@ -1556,22 +1580,6 @@ void CFGLoop::compute_freq() {
} }
} }
#if 0
// Raise frequency of the loop backedge block, in an effort
// to keep it empty. Skip the method level "loop".
if (_parent != NULL) {
CFGElement* s = _members.at(_members.length() - 1);
if (s->is_block()) {
Block* bk = s->as_Block();
if (bk->_num_succs == 1 && bk->_succs[0] == hd) {
// almost any value >= 1.0f works
// FIXME: raw constant
bk->_freq = 1.05f;
}
}
}
#endif
// For all loops other than the outer, "method" loop, // For all loops other than the outer, "method" loop,
// sum and normalize the exit probability. The "method" loop // sum and normalize the exit probability. The "method" loop
// should keep the initial exit probability of 1, so that // should keep the initial exit probability of 1, so that
...@@ -1589,12 +1597,15 @@ void CFGLoop::compute_freq() { ...@@ -1589,12 +1597,15 @@ void CFGLoop::compute_freq() {
// the probability of exit per loop entry. // the probability of exit per loop entry.
for (int i = 0; i < _exits.length(); i++) { for (int i = 0; i < _exits.length(); i++) {
Block* et = _exits.at(i).get_target(); Block* et = _exits.at(i).get_target();
float new_prob = _exits.at(i).get_prob() / exits_sum; float new_prob = 0.0f;
if (_exits.at(i).get_prob() > 0.0f) {
new_prob = _exits.at(i).get_prob() / exits_sum;
}
BlockProbPair bpp(et, new_prob); BlockProbPair bpp(et, new_prob);
_exits.at_put(i, bpp); _exits.at_put(i, bpp);
} }
// Save the total, but guard against unreasoable probability, // Save the total, but guard against unreasonable probability,
// as the value is used to estimate the loop trip count. // as the value is used to estimate the loop trip count.
// An infinite trip count would blur relative block // An infinite trip count would blur relative block
// frequencies. // frequencies.
...@@ -1688,6 +1699,137 @@ float Block::succ_prob(uint i) { ...@@ -1688,6 +1699,137 @@ float Block::succ_prob(uint i) {
return 0.0f; return 0.0f;
} }
//------------------------------num_fall_throughs-----------------------------
// Return the number of fall-through candidates for a block
int Block::num_fall_throughs() {
int eidx = end_idx();
Node *n = _nodes[eidx]; // Get ending Node
int op = n->Opcode();
if (n->is_Mach()) {
if (n->is_MachNullCheck()) {
// In theory, either side can fall-thru, for simplicity sake,
// let's say only the false branch can now.
return 1;
}
op = n->as_Mach()->ideal_Opcode();
}
// Switch on branch type
switch( op ) {
case Op_CountedLoopEnd:
case Op_If:
return 2;
case Op_Root:
case Op_Goto:
return 1;
case Op_Catch: {
for (uint i = 0; i < _num_succs; i++) {
const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
if (ci->_con == CatchProjNode::fall_through_index) {
return 1;
}
}
return 0;
}
case Op_Jump:
case Op_NeverBranch:
case Op_TailCall:
case Op_TailJump:
case Op_Return:
case Op_Halt:
case Op_Rethrow:
return 0;
default:
ShouldNotReachHere();
}
return 0;
}
//------------------------------succ_fall_through-----------------------------
// Return true if a specific successor could be fall-through target.
bool Block::succ_fall_through(uint i) {
int eidx = end_idx();
Node *n = _nodes[eidx]; // Get ending Node
int op = n->Opcode();
if (n->is_Mach()) {
if (n->is_MachNullCheck()) {
// In theory, either side can fall-thru, for simplicity sake,
// let's say only the false branch can now.
return _nodes[i + eidx + 1]->Opcode() == Op_IfFalse;
}
op = n->as_Mach()->ideal_Opcode();
}
// Switch on branch type
switch( op ) {
case Op_CountedLoopEnd:
case Op_If:
case Op_Root:
case Op_Goto:
return true;
case Op_Catch: {
const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
return ci->_con == CatchProjNode::fall_through_index;
}
case Op_Jump:
case Op_NeverBranch:
case Op_TailCall:
case Op_TailJump:
case Op_Return:
case Op_Halt:
case Op_Rethrow:
return false;
default:
ShouldNotReachHere();
}
return false;
}
//------------------------------update_uncommon_branch------------------------
// Update the probability of a two-branch to be uncommon
void Block::update_uncommon_branch(Block* ub) {
int eidx = end_idx();
Node *n = _nodes[eidx]; // Get ending Node
int op = n->as_Mach()->ideal_Opcode();
assert(op == Op_CountedLoopEnd || op == Op_If, "must be a If");
assert(num_fall_throughs() == 2, "must be a two way branch block");
// Which successor is ub?
uint s;
for (s = 0; s <_num_succs; s++) {
if (_succs[s] == ub) break;
}
assert(s < 2, "uncommon successor must be found");
// If ub is the true path, make the proability small, else
// ub is the false path, and make the probability large
bool invert = (_nodes[s + eidx + 1]->Opcode() == Op_IfFalse);
// Get existing probability
float p = n->as_MachIf()->_prob;
if (invert) p = 1.0 - p;
if (p > PROB_MIN) {
p = PROB_MIN;
}
if (invert) p = 1.0 - p;
n->as_MachIf()->_prob = p;
}
//------------------------------update_succ_freq------------------------------- //------------------------------update_succ_freq-------------------------------
// Update the appropriate frequency associated with block 'b', a succesor of // Update the appropriate frequency associated with block 'b', a succesor of
// a block in this loop. // a block in this loop.
......
...@@ -3485,11 +3485,32 @@ bool LibraryCallKit::inline_native_AtomicLong_attemptUpdate() { ...@@ -3485,11 +3485,32 @@ bool LibraryCallKit::inline_native_AtomicLong_attemptUpdate() {
const TypePtr *adr_type = _gvn.type(adr)->is_ptr(); const TypePtr *adr_type = _gvn.type(adr)->is_ptr();
int alias_idx = C->get_alias_index(adr_type); int alias_idx = C->get_alias_index(adr_type);
Node *result = _gvn.transform(new (C, 5) StoreLConditionalNode(control(), memory(alias_idx), adr, newVal, oldVal)); Node *cas = _gvn.transform(new (C, 5) StoreLConditionalNode(control(), memory(alias_idx), adr, newVal, oldVal));
Node *store_proj = _gvn.transform( new (C, 1) SCMemProjNode(result)); Node *store_proj = _gvn.transform( new (C, 1) SCMemProjNode(cas));
set_memory(store_proj, alias_idx); set_memory(store_proj, alias_idx);
Node *bol = _gvn.transform( new (C, 2) BoolNode( cas, BoolTest::eq ) );
push(result); Node *result;
// CMove node is not used to be able fold a possible check code
// after attemptUpdate() call. This code could be transformed
// into CMove node by loop optimizations.
{
RegionNode *r = new (C, 3) RegionNode(3);
result = new (C, 3) PhiNode(r, TypeInt::BOOL);
Node *iff = create_and_xform_if(control(), bol, PROB_FAIR, COUNT_UNKNOWN);
Node *iftrue = opt_iff(r, iff);
r->init_req(1, iftrue);
result->init_req(1, intcon(1));
result->init_req(2, intcon(0));
set_control(_gvn.transform(r));
record_for_igvn(r);
C->set_has_split_ifs(true); // Has chance for split-if optimization
}
push(_gvn.transform(result));
return true; return true;
} }
......
...@@ -1519,6 +1519,7 @@ void IdealLoopTree::adjust_loop_exit_prob( PhaseIdealLoop *phase ) { ...@@ -1519,6 +1519,7 @@ void IdealLoopTree::adjust_loop_exit_prob( PhaseIdealLoop *phase ) {
Node *bol = iff->in(1); Node *bol = iff->in(1);
if( bol && bol->req() > 1 && bol->in(1) && if( bol && bol->req() > 1 && bol->in(1) &&
((bol->in(1)->Opcode() == Op_StorePConditional ) || ((bol->in(1)->Opcode() == Op_StorePConditional ) ||
(bol->in(1)->Opcode() == Op_StoreIConditional ) ||
(bol->in(1)->Opcode() == Op_StoreLConditional ) || (bol->in(1)->Opcode() == Op_StoreLConditional ) ||
(bol->in(1)->Opcode() == Op_CompareAndSwapI ) || (bol->in(1)->Opcode() == Op_CompareAndSwapI ) ||
(bol->in(1)->Opcode() == Op_CompareAndSwapL ) || (bol->in(1)->Opcode() == Op_CompareAndSwapL ) ||
......
此差异已折叠。
...@@ -93,7 +93,7 @@ private: ...@@ -93,7 +93,7 @@ private:
int replace_input(Node *use, Node *oldref, Node *newref); int replace_input(Node *use, Node *oldref, Node *newref);
void copy_call_debug_info(CallNode *oldcall, CallNode * newcall); void copy_call_debug_info(CallNode *oldcall, CallNode * newcall);
Node* opt_iff(Node* region, Node* iff); Node* opt_bits_test(Node* ctrl, Node* region, int edge, Node* word, int mask, int bits, bool return_fast_path = false);
void copy_predefined_input_for_runtime_call(Node * ctrl, CallNode* oldcall, CallNode* call); void copy_predefined_input_for_runtime_call(Node * ctrl, CallNode* oldcall, CallNode* call);
CallNode* make_slow_call(CallNode *oldcall, const TypeFunc* slow_call_type, address slow_call, CallNode* make_slow_call(CallNode *oldcall, const TypeFunc* slow_call_type, address slow_call,
const char* leaf_name, Node* slow_path, Node* parm0, Node* parm1); const char* leaf_name, Node* slow_path, Node* parm0, Node* parm1);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册