--- a/.hgignore Mon Jun 30 17:04:59 2008 -0700
+++ b/.hgignore Tue Jul 01 11:59:44 2008 -0700
@@ -2,3 +2,6 @@
^dist/
^nbproject/private/
^src/share/tools/hsdis/bin/
+^src/share/tools/IdealGraphVisualizer/[a-zA-Z0-9]*/build/
+^src/share/tools/IdealGraphVisualizer/build/
+^src/share/tools/IdealGraphVisualizer/dist/
--- a/.hgtags Mon Jun 30 17:04:59 2008 -0700
+++ b/.hgtags Tue Jul 01 11:59:44 2008 -0700
@@ -3,3 +3,4 @@ ad0b851458ff9d1d490ed2d79bb84f75a9fdb753
ad0b851458ff9d1d490ed2d79bb84f75a9fdb753 jdk7-b26
e3d2692f8442e2d951166dc9bd9a330684754438 jdk7-b27
c14dab40ed9bf45ad21150bd70c9c80cdf655415 jdk7-b28
+4f91c08b3e4498213a9c5a24898f7d9c38cf86fb jdk7-b29
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Mon Jun 30 17:04:59 2008 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Tue Jul 01 11:59:44 2008 -0700
@@ -316,6 +316,14 @@ public class ObjectHeap {
iterateLiveRegions(liveRegions, visitor, null);
}
+ public boolean isValidMethod(OopHandle handle) {
+ OopHandle klass = Oop.getKlassForOopHandle(handle);
+ if (klass != null && klass.equals(methodKlassHandle)) {
+ return true;
+ }
+ return false;
+ }
+
// Creates an instance from the Oop hierarchy based based on the handle
public Oop newOop(OopHandle handle) {
// The only known way to detect the right type of an oop is
@@ -375,8 +383,10 @@ public class ObjectHeap {
}
}
- System.err.println("Unknown oop at " + handle);
- System.err.println("Oop's klass is " + klass);
+ if (DEBUG) {
+ System.err.println("Unknown oop at " + handle);
+ System.err.println("Oop's klass is " + klass);
+ }
throw new UnknownOopException();
}
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java Mon Jun 30 17:04:59 2008 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java Tue Jul 01 11:59:44 2008 -0700
@@ -215,11 +215,11 @@ public class JavaThread extends Thread {
if (f == null) return null;
boolean imprecise = true;
if (f.isInterpretedFrame() && !f.isInterpretedFrameValid()) {
- if (DEBUG) {
- System.out.println("Correcting for invalid interpreter frame");
- }
- f = f.sender(regMap);
- imprecise = false;
+ if (DEBUG) {
+ System.out.println("Correcting for invalid interpreter frame");
+ }
+ f = f.sender(regMap);
+ imprecise = false;
}
VFrame vf = VFrame.newVFrame(f, regMap, this, true, imprecise);
if (vf == null) {
@@ -228,10 +228,7 @@ public class JavaThread extends Thread {
}
return null;
}
- if (vf.isJavaFrame()) {
- return (JavaVFrame) vf;
- }
- return (JavaVFrame) vf.javaSender();
+ return vf.isJavaFrame() ? (JavaVFrame)vf : vf.javaSender();
}
/** In this system, a JavaThread is the top-level factory for a
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/solaris_sparc/SolarisSPARCJavaThreadPDAccess.java Mon Jun 30 17:04:59 2008 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/solaris_sparc/SolarisSPARCJavaThreadPDAccess.java Tue Jul 01 11:59:44 2008 -0700
@@ -121,6 +121,13 @@ public class SolarisSPARCJavaThreadPDAcc
}
public Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
+
+ // If java stack is walkable then both last_Java_sp and last_Java_pc are
+ // non null and we can start stack walk from this frame.
+ if (thread.getLastJavaSP() != null && thread.getLastJavaPC() != null) {
+ return new SPARCFrame(SPARCFrame.biasSP(thread.getLastJavaSP()), thread.getLastJavaPC());
+ }
+
ThreadProxy t = getThreadProxy(addr);
SPARCThreadContext context = (SPARCThreadContext) t.getContext();
// For now, let's see what happens if we do a similar thing to
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java Mon Jun 30 17:04:59 2008 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java Tue Jul 01 11:59:44 2008 -0700
@@ -422,6 +422,13 @@ public class SPARCFrame extends Frame {
if (getFP().addOffsetTo(INTERPRETER_FRAME_VM_LOCAL_WORDS * VM.getVM().getAddressSize()).lessThan(getSP())) {
return false;
}
+
+ OopHandle methodHandle = addressOfInterpreterFrameMethod().getOopHandleAt(0);
+
+ if (VM.getVM().getObjectHeap().isValidMethod(methodHandle) == false) {
+ return false;
+ }
+
// These are hacks to keep us out of trouble.
// The problem with these is that they mask other problems
if (getFP().lessThanOrEqual(getSP())) { // this attempts to deal with unsigned comparison above
@@ -433,9 +440,18 @@ public class SPARCFrame extends Frame {
// FIXME: this is not atomic with respect to GC and is unsuitable
// for use in a non-debugging, or reflective, system. Need to
// figure out how to express this.
- if (addressOfInterpreterFrameBCX().getAddressAt(0) == null) {
- return false; // BCP not yet set up
- }
+ Address bcx = addressOfInterpreterFrameBCX().getAddressAt(0);
+
+ Method method;
+ try {
+ method = (Method) VM.getVM().getObjectHeap().newOop(methodHandle);
+ } catch (UnknownOopException ex) {
+ return false;
+ }
+ int bci = bcpToBci(bcx, method);
+ //validate bci
+ if (bci < 0) return false;
+
return true;
}
@@ -471,7 +487,7 @@ public class SPARCFrame extends Frame {
// will update it accordingly
map.setIncludeArgumentOops(false);
- if (cb == null && isEntryFrame()) {
+ if (isEntryFrame()) {
return senderForEntryFrame(map);
}
@@ -539,7 +555,6 @@ public class SPARCFrame extends Frame {
int SP_OFFSET_IN_GREGSET = 17;
raw_sp = fp.getAddressAt(VM.getVM().getAddressSize() * SP_OFFSET_IN_GREGSET);
Address pc = fp.getAddressAt(VM.getVM().getAddressSize() * PC_OFFSET_IN_GREGSET);
- // System.out.println(" next frame's SP: " + sp + " PC: " + pc);
return new SPARCFrame(raw_sp, pc);
}
}
@@ -562,10 +577,8 @@ public class SPARCFrame extends Frame {
// sender's _interpreter_sp_adjustment field.
if (VM.getVM().getInterpreter().contains(pc)) {
isInterpreted = true;
- if (VM.getVM().isClientCompiler()) {
- map.makeIntegerRegsUnsaved();
- map.shiftWindow(sp, youngerSP);
- }
+ map.makeIntegerRegsUnsaved();
+ map.shiftWindow(sp, youngerSP);
} else {
// Find a CodeBlob containing this frame's pc or elide the lookup and use the
// supplied blob which is already known to be associated with this frame.
--- a/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java Mon Jun 30 17:04:59 2008 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java Tue Jul 01 11:59:44 2008 -0700
@@ -87,12 +87,13 @@ public class PStack extends Tool {
while (f != null) {
ClosestSymbol sym = f.closestSymbolToPC();
Address pc = f.pc();
+ out.print(pc + "\t");
if (sym != null) {
String name = sym.getName();
if (cdbgCanDemangle) {
name = cdbg.demangle(name);
}
- out.print(pc + "\t" + name);
+ out.print(name);
long diff = sym.getOffset();
if (diff != 0L) {
out.print(" + 0x" + Long.toHexString(diff));
@@ -120,7 +121,6 @@ public class PStack extends Tool {
// look for known code blobs
CodeCache c = VM.getVM().getCodeCache();
if (c.contains(pc)) {
- out.print(pc + "\t");
CodeBlob cb = c.findBlobUnsafe(pc);
if (cb.isNMethod()) {
names = getJavaNames(th, f.localVariableBase());
@@ -144,18 +144,18 @@ public class PStack extends Tool {
out.println("<Unknown code blob>");
}
} else {
- printUnknown(out,pc);
+ printUnknown(out);
}
}
// print java frames, if any
if (names != null && names.length != 0) {
// print java frame(s)
for (int i = 0; i < names.length; i++) {
- out.println(pc + "\t" + names[i]);
+ out.println(names[i]);
}
}
} else {
- printUnknown(out,pc);
+ printUnknown(out);
}
}
f = f.sender();
@@ -220,8 +220,8 @@ public class PStack extends Tool {
}
}
- private void printUnknown(PrintStream out, Address pc) {
- out.println(pc + "\t????????");
+ private void printUnknown(PrintStream out) {
+ out.println("\t????????");
}
private String[] getJavaNames(ThreadProxy th, Address fp) {
--- a/src/cpu/sparc/vm/sparc.ad Mon Jun 30 17:04:59 2008 -0700
+++ b/src/cpu/sparc/vm/sparc.ad Tue Jul 01 11:59:44 2008 -0700
@@ -5955,7 +5955,7 @@ instruct storeA8B(memory mem, regD src)
// Convert oop pointer into compressed form
instruct encodeHeapOop(iRegN dst, iRegP src) %{
- predicate(n->bottom_type()->is_narrowoop()->make_oopptr()->ptr() != TypePtr::NotNull);
+ predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
match(Set dst (EncodeP src));
format %{ "encode_heap_oop $src, $dst" %}
ins_encode %{
@@ -5965,7 +5965,7 @@ instruct encodeHeapOop(iRegN dst, iRegP
%}
instruct encodeHeapOop_not_null(iRegN dst, iRegP src) %{
- predicate(n->bottom_type()->is_narrowoop()->make_oopptr()->ptr() == TypePtr::NotNull);
+ predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
match(Set dst (EncodeP src));
format %{ "encode_heap_oop_not_null $src, $dst" %}
ins_encode %{
--- a/src/cpu/x86/vm/vm_version_x86_32.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/cpu/x86/vm/vm_version_x86_32.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -306,6 +306,10 @@ void VM_Version::get_processor_features(
if( supports_sse2() && FLAG_IS_DEFAULT(UseAddressNop) ) {
// Use it on new AMD cpus starting from Opteron.
UseAddressNop = true;
+ }
+ if( supports_sse2() && FLAG_IS_DEFAULT(UseNewLongLShift) ) {
+ // Use it on new AMD cpus starting from Opteron.
+ UseNewLongLShift = true;
}
if( FLAG_IS_DEFAULT(UseXmmLoadAndClearUpper) ) {
if( supports_sse4a() ) {
--- a/src/cpu/x86/vm/x86_32.ad Mon Jun 30 17:04:59 2008 -0700
+++ b/src/cpu/x86/vm/x86_32.ad Tue Jul 01 11:59:44 2008 -0700
@@ -4754,6 +4754,33 @@ operand immI_32_63() %{
interface(CONST_INTER);
%}
+operand immI_1() %{
+ predicate( n->get_int() == 1 );
+ match(ConI);
+
+ op_cost(0);
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
+operand immI_2() %{
+ predicate( n->get_int() == 2 );
+ match(ConI);
+
+ op_cost(0);
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
+operand immI_3() %{
+ predicate( n->get_int() == 3 );
+ match(ConI);
+
+ op_cost(0);
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
// Pointer Immediate
operand immP() %{
match(ConP);
@@ -8941,6 +8968,63 @@ instruct xorl_eReg_mem(eRegL dst, load_l
opcode(0x33,0x33);
ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) );
ins_pipe( ialu_reg_long_mem );
+%}
+
+// Shift Left Long by 1
+instruct shlL_eReg_1(eRegL dst, immI_1 cnt, eFlagsReg cr) %{
+ predicate(UseNewLongLShift);
+ match(Set dst (LShiftL dst cnt));
+ effect(KILL cr);
+ ins_cost(100);
+ format %{ "ADD $dst.lo,$dst.lo\n\t"
+ "ADC $dst.hi,$dst.hi" %}
+ ins_encode %{
+ __ addl($dst$$Register,$dst$$Register);
+ __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
+ %}
+ ins_pipe( ialu_reg_long );
+%}
+
+// Shift Left Long by 2
+instruct shlL_eReg_2(eRegL dst, immI_2 cnt, eFlagsReg cr) %{
+ predicate(UseNewLongLShift);
+ match(Set dst (LShiftL dst cnt));
+ effect(KILL cr);
+ ins_cost(100);
+ format %{ "ADD $dst.lo,$dst.lo\n\t"
+ "ADC $dst.hi,$dst.hi\n\t"
+ "ADD $dst.lo,$dst.lo\n\t"
+ "ADC $dst.hi,$dst.hi" %}
+ ins_encode %{
+ __ addl($dst$$Register,$dst$$Register);
+ __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
+ __ addl($dst$$Register,$dst$$Register);
+ __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
+ %}
+ ins_pipe( ialu_reg_long );
+%}
+
+// Shift Left Long by 3
+instruct shlL_eReg_3(eRegL dst, immI_3 cnt, eFlagsReg cr) %{
+ predicate(UseNewLongLShift);
+ match(Set dst (LShiftL dst cnt));
+ effect(KILL cr);
+ ins_cost(100);
+ format %{ "ADD $dst.lo,$dst.lo\n\t"
+ "ADC $dst.hi,$dst.hi\n\t"
+ "ADD $dst.lo,$dst.lo\n\t"
+ "ADC $dst.hi,$dst.hi\n\t"
+ "ADD $dst.lo,$dst.lo\n\t"
+ "ADC $dst.hi,$dst.hi" %}
+ ins_encode %{
+ __ addl($dst$$Register,$dst$$Register);
+ __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
+ __ addl($dst$$Register,$dst$$Register);
+ __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
+ __ addl($dst$$Register,$dst$$Register);
+ __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
+ %}
+ ins_pipe( ialu_reg_long );
%}
// Shift Left Long by 1-31
--- a/src/cpu/x86/vm/x86_64.ad Mon Jun 30 17:04:59 2008 -0700
+++ b/src/cpu/x86/vm/x86_64.ad Tue Jul 01 11:59:44 2008 -0700
@@ -7060,7 +7060,7 @@ instruct castP2X(rRegL dst, rRegP src)
// Convert oop pointer into compressed form
instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
- predicate(n->bottom_type()->is_narrowoop()->make_oopptr()->ptr() != TypePtr::NotNull);
+ predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
match(Set dst (EncodeP src));
effect(KILL cr);
format %{ "encode_heap_oop $dst,$src" %}
@@ -7076,7 +7076,7 @@ instruct encodeHeapOop(rRegN dst, rRegP
%}
instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
- predicate(n->bottom_type()->is_narrowoop()->make_oopptr()->ptr() == TypePtr::NotNull);
+ predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
match(Set dst (EncodeP src));
effect(KILL cr);
format %{ "encode_heap_oop_not_null $dst,$src" %}
--- a/src/os/linux/vm/hpi_linux.hpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/os/linux/vm/hpi_linux.hpp Tue Jul 01 11:59:44 2008 -0700
@@ -68,6 +68,10 @@ inline int hpi::recv(int fd, char *buf,
inline int hpi::send(int fd, char *buf, int nBytes, int flags) {
RESTARTABLE_RETURN_INT(::send(fd, buf, nBytes, (unsigned int) flags));
+}
+
+inline int hpi::raw_send(int fd, char *buf, int nBytes, int flags) {
+ return send(fd, buf, nBytes, flags);
}
inline int hpi::timeout(int fd, long timeout) {
--- a/src/os/solaris/vm/hpi_solaris.hpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/os/solaris/vm/hpi_solaris.hpp Tue Jul 01 11:59:44 2008 -0700
@@ -69,6 +69,10 @@ inline int hpi::recv(int fd, char *bu
inline int hpi::send(int fd, char *buf, int nBytes, int flags) {
INTERRUPTIBLE_RETURN_INT(::send(fd, buf, nBytes, flags), os::Solaris::clear_interrupted);
+}
+
+inline int hpi::raw_send(int fd, char *buf, int nBytes, int flags) {
+ RESTARTABLE_RETURN_INT(::send(fd, buf, nBytes, flags));
}
// As both poll and select can be interrupted by signals, we have to be
--- a/src/os/windows/vm/hpi_windows.hpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/os/windows/vm/hpi_windows.hpp Tue Jul 01 11:59:44 2008 -0700
@@ -101,6 +101,10 @@ HPIDECL(send, "send", _socket, Send, int
("fd = %d, buf = %p, nBytes = %d, flags = %d",
fd, buf, nBytes, flags),
(fd, buf, nBytes, flags));
+
+inline int hpi::raw_send(int fd, char *buf, int nBytes, int flags) {
+ return send(fd, buf, nBytes, flags);
+}
HPIDECL(timeout, "timeout", _socket, Timeout, int, "%d",
(int fd, long timeout),
--- a/src/share/tools/MakeDeps/Database.java Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/tools/MakeDeps/Database.java Tue Jul 01 11:59:44 2008 -0700
@@ -36,6 +36,7 @@ public class Database {
private FileList outerFiles;
private FileList indivIncludes;
private FileList grandInclude; // the results for the grand include file
+ private HashMap<String,String> platformDepFiles;
private long threshold;
private int nOuterFiles;
private int nPrecompiledFiles;
@@ -57,6 +58,7 @@ public class Database {
outerFiles = new FileList("outerFiles", plat);
indivIncludes = new FileList("IndivIncludes", plat);
grandInclude = new FileList(plat.getGIFileTemplate().nameOfList(), plat);
+ platformDepFiles = new HashMap<String,String>();
threshold = t;
nOuterFiles = 0;
@@ -209,6 +211,10 @@ public class Database {
FileList p = allFiles.listForFile(includer);
p.setPlatformDependentInclude(pdName.dirPreStemSuff());
+ // Record the implicit include of this file so that the
+ // dependencies for precompiled headers can mention it.
+ platformDepFiles.put(newIncluder, includer);
+
// Add an implicit dependency on platform
// specific file for the generic file
@@ -408,6 +414,12 @@ public class Database {
for (Iterator iter = grandInclude.iterator(); iter.hasNext(); ) {
FileList list = (FileList) iter.next();
gd.println(list.getName() + " \\");
+ String platformDep = platformDepFiles.get(list.getName());
+ if (platformDep != null) {
+ // make sure changes to the platform dependent file will
+ // cause regeneration of the pch file.
+ gd.println(platformDep + " \\");
+ }
}
gd.println();
gd.println();
--- a/src/share/vm/adlc/formssel.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/adlc/formssel.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -729,6 +729,7 @@ bool InstructForm::captures_bottom_type(
!strcmp(_matrule->_rChild->_opType,"DecodeN") ||
!strcmp(_matrule->_rChild->_opType,"EncodeP") ||
!strcmp(_matrule->_rChild->_opType,"LoadN") ||
+ !strcmp(_matrule->_rChild->_opType,"LoadNKlass") ||
!strcmp(_matrule->_rChild->_opType,"CreateEx") || // type of exception
!strcmp(_matrule->_rChild->_opType,"CheckCastPP")) ) return true;
else if ( is_ideal_load() == Form::idealP ) return true;
--- a/src/share/vm/includeDB_compiler2 Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/includeDB_compiler2 Tue Jul 01 11:59:44 2008 -0700
@@ -1090,6 +1090,7 @@ idealGraphPrinter.hpp
idealGraphPrinter.hpp vectset.hpp
idealGraphPrinter.hpp growableArray.hpp
idealGraphPrinter.hpp ostream.hpp
+idealGraphPrinter.hpp xmlstream.hpp
idealGraphPrinter.cpp idealGraphPrinter.hpp
idealGraphPrinter.cpp chaitin.hpp
--- a/src/share/vm/oops/symbolKlass.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/oops/symbolKlass.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -209,22 +209,19 @@ int symbolKlass::oop_update_pointers(Par
void symbolKlass::oop_print_on(oop obj, outputStream* st) {
st->print("Symbol: '");
+ symbolOop(obj)->print_symbol_on(st);
+ st->print("'");
+}
+
+void symbolKlass::oop_print_value_on(oop obj, outputStream* st) {
symbolOop sym = symbolOop(obj);
+ st->print("'");
for (int i = 0; i < sym->utf8_length(); i++) {
st->print("%c", sym->byte_at(i));
}
st->print("'");
}
-void symbolKlass::oop_print_value_on(oop obj, outputStream* st) {
- symbolOop sym = symbolOop(obj);
- st->print("'");
- for (int i = 0; i < sym->utf8_length(); i++) {
- st->print("%c", sym->byte_at(i));
- }
- st->print("'");
-}
-
#endif //PRODUCT
const char* symbolKlass::internal_name() const {
--- a/src/share/vm/oops/symbolOop.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/oops/symbolOop.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -68,8 +68,17 @@ char* symbolOopDesc::as_C_string_flexibl
void symbolOopDesc::print_symbol_on(outputStream* st) {
st = st ? st : tty;
- for (int index = 0; index < utf8_length(); index++)
- st->put((char)byte_at(index));
+ int length = UTF8::unicode_length((const char*)bytes(), utf8_length());
+ const char *ptr = (const char *)bytes();
+ jchar value;
+ for (int index = 0; index < length; index++) {
+ ptr = UTF8::next(ptr, &value);
+ if (value >= 32 && value < 127 || value == '\'' || value == '\\') {
+ st->put(value);
+ } else {
+ st->print("\\u%04x", value);
+ }
+ }
}
jchar* symbolOopDesc::as_unicode(int& length) const {
--- a/src/share/vm/opto/callnode.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/callnode.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -632,7 +632,7 @@ bool CallNode::may_modify(const TypePtr
const TypeOopPtr *adrInst_t = addr_t->isa_oopptr();
// if not an InstPtr or not an instance type, assume the worst
- if (adrInst_t == NULL || !adrInst_t->is_instance_field()) {
+ if (adrInst_t == NULL || !adrInst_t->is_known_instance_field()) {
return true;
}
Compile *C = phase->C;
--- a/src/share/vm/opto/cfgnode.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/cfgnode.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -708,12 +708,12 @@ PhiNode* PhiNode::slice_memory(const Typ
// Split out an instance type from a bottom phi.
PhiNode* PhiNode::split_out_instance(const TypePtr* at, PhaseIterGVN *igvn) const {
const TypeOopPtr *t_oop = at->isa_oopptr();
- assert(t_oop != NULL && t_oop->is_instance(), "expecting instance oopptr");
+ assert(t_oop != NULL && t_oop->is_known_instance(), "expecting instance oopptr");
const TypePtr *t = adr_type();
assert(type() == Type::MEMORY &&
(t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM ||
- t->isa_oopptr() && !t->is_oopptr()->is_instance() &&
- t->is_oopptr()->cast_to_instance(t_oop->instance_id()) == t_oop),
+ t->isa_oopptr() && !t->is_oopptr()->is_known_instance() &&
+ t->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop),
"bottom or raw memory required");
// Check if an appropriate node already exists.
@@ -854,7 +854,8 @@ const Type *PhiNode::Value( PhaseTransfo
// Until we have harmony between classes and interfaces in the type
// lattice, we must tread carefully around phis which implicitly
// convert the one to the other.
- const TypeInstPtr* ttip = _type->isa_narrowoop() ? _type->isa_narrowoop()->make_oopptr()->isa_instptr() :_type->isa_instptr();
+ const TypePtr* ttp = _type->make_ptr();
+ const TypeInstPtr* ttip = (ttp != NULL) ? ttp->isa_instptr() : NULL;
bool is_intf = false;
if (ttip != NULL) {
ciKlass* k = ttip->klass();
@@ -873,7 +874,8 @@ const Type *PhiNode::Value( PhaseTransfo
// of all the input types. The lattice is not distributive in
// such cases. Ward off asserts in type.cpp by refusing to do
// meets between interfaces and proper classes.
- const TypeInstPtr* tiip = ti->isa_narrowoop() ? ti->is_narrowoop()->make_oopptr()->isa_instptr() : ti->isa_instptr();
+ const TypePtr* tip = ti->make_ptr();
+ const TypeInstPtr* tiip = (tip != NULL) ? tip->isa_instptr() : NULL;
if (tiip) {
bool ti_is_intf = false;
ciKlass* k = tiip->klass();
@@ -930,13 +932,14 @@ const Type *PhiNode::Value( PhaseTransfo
// class-typed Phi and an interface flows in, it's possible that the meet &
// join report an interface back out. This isn't possible but happens
// because the type system doesn't interact well with interfaces.
- const TypeInstPtr *jtip = jt->isa_narrowoop() ? jt->isa_narrowoop()->make_oopptr()->isa_instptr() : jt->isa_instptr();
+ const TypePtr *jtp = jt->make_ptr();
+ const TypeInstPtr *jtip = (jtp != NULL) ? jtp->isa_instptr() : NULL;
if( jtip && ttip ) {
if( jtip->is_loaded() && jtip->klass()->is_interface() &&
ttip->is_loaded() && !ttip->klass()->is_interface() ) {
// Happens in a CTW of rt.jar, 320-341, no extra flags
assert(ft == ttip->cast_to_ptr_type(jtip->ptr()) ||
- ft->isa_narrowoop() && ft->isa_narrowoop()->make_oopptr() == ttip->cast_to_ptr_type(jtip->ptr()), "");
+ ft->isa_narrowoop() && ft->make_ptr() == ttip->cast_to_ptr_type(jtip->ptr()), "");
jt = ft;
}
}
--- a/src/share/vm/opto/cfgnode.hpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/cfgnode.hpp Tue Jul 01 11:59:44 2008 -0700
@@ -129,7 +129,7 @@ public:
};
PhiNode( Node *r, const Type *t, const TypePtr* at = NULL,
- const int iid = TypeOopPtr::UNKNOWN_INSTANCE,
+ const int iid = TypeOopPtr::InstanceTop,
const int iidx = Compile::AliasIdxTop,
const int ioffs = Type::OffsetTop )
: TypeNode(t,r->req()),
--- a/src/share/vm/opto/compile.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/compile.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -313,9 +313,6 @@ CompileWrapper::CompileWrapper(Compile*
_compile->begin_method();
}
CompileWrapper::~CompileWrapper() {
- if (_compile->failing()) {
- _compile->print_method("Failed");
- }
_compile->end_method();
if (_compile->scratch_buffer_blob() != NULL)
BufferBlob::free(_compile->scratch_buffer_blob());
@@ -603,6 +600,8 @@ Compile::Compile( ciEnv* ci_env, C2Compi
Optimize();
if (failing()) return;
NOT_PRODUCT( verify_graph_edges(); )
+
+ print_method("Before Matching");
#ifndef PRODUCT
if (PrintIdeal) {
@@ -1070,7 +1069,7 @@ const TypePtr *Compile::flatten_alias_ty
// No constant oop pointers (such as Strings); they alias with
// unknown strings.
tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
- } else if( to->is_instance_field() ) {
+ } else if( to->is_known_instance_field() ) {
tj = to; // Keep NotNull and klass_is_exact for instance type
} else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) {
// During the 2nd round of IterGVN, NotNull castings are removed.
@@ -1191,8 +1190,8 @@ void Compile::AliasType::Init(int i, con
_field = NULL;
_is_rewritable = true; // default
const TypeOopPtr *atoop = (at != NULL) ? at->isa_oopptr() : NULL;
- if (atoop != NULL && atoop->is_instance()) {
- const TypeOopPtr *gt = atoop->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE);
+ if (atoop != NULL && atoop->is_known_instance()) {
+ const TypeOopPtr *gt = atoop->cast_to_instance_id(TypeOopPtr::InstanceBot);
_general_index = Compile::current()->get_alias_index(gt);
} else {
_general_index = 0;
@@ -1481,7 +1480,7 @@ void Compile::Optimize() {
NOT_PRODUCT( verify_graph_edges(); )
- print_method("Start");
+ print_method("After Parsing");
{
// Iterative Global Value Numbering, including ideal transforms
@@ -1688,7 +1687,7 @@ void Compile::Code_Gen() {
Output();
}
- print_method("End");
+ print_method("Final Code");
// He's dead, Jim.
_cfg = (PhaseCFG*)0xdeadbeef;
@@ -2017,7 +2016,7 @@ static void final_graph_reshaping_impl(
for (uint i = 0; i < cnt; i++) {
Node* m = r->raw_out(i);
if (m!= NULL && m->Opcode() == Op_ConN &&
- m->bottom_type()->is_narrowoop()->make_oopptr() == t) {
+ m->bottom_type()->make_ptr() == t) {
nn = m;
break;
}
@@ -2070,7 +2069,7 @@ static void final_graph_reshaping_impl(
}
}
} else if (t->isa_oopptr()) {
- in2 = ConNode::make(C, t->is_oopptr()->make_narrowoop());
+ in2 = ConNode::make(C, t->make_narrowoop());
}
}
if( in2 != NULL ) {
@@ -2466,6 +2465,9 @@ void Compile::record_failure(const char*
// Record the first failure reason.
_failure_reason = reason;
}
+ if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) {
+ C->print_method(_failure_reason);
+ }
_root = NULL; // flush the graph, too
}
--- a/src/share/vm/opto/connode.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/connode.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -565,26 +565,12 @@ Node* DecodeNNode::Identity(PhaseTransfo
}
const Type *DecodeNNode::Value( PhaseTransform *phase ) const {
- if (phase->type( in(1) ) == TypeNarrowOop::NULL_PTR) {
- return TypePtr::NULL_PTR;
- }
- return bottom_type();
-}
-
-Node* DecodeNNode::decode(PhaseTransform* phase, Node* value) {
- if (value->is_EncodeP()) {
- // (DecodeN (EncodeP p)) -> p
- return value->in(1);
- }
- const Type* newtype = value->bottom_type();
- if (newtype == TypeNarrowOop::NULL_PTR) {
- return phase->transform(new (phase->C, 1) ConPNode(TypePtr::NULL_PTR));
- } else if (newtype->isa_narrowoop()) {
- return phase->transform(new (phase->C, 2) DecodeNNode(value, newtype->is_narrowoop()->make_oopptr()));
- } else {
- ShouldNotReachHere();
- return NULL; // to make C++ compiler happy.
- }
+ const Type *t = phase->type( in(1) );
+ if (t == Type::TOP) return Type::TOP;
+ if (t == TypeNarrowOop::NULL_PTR) return TypePtr::NULL_PTR;
+
+ assert(t->isa_narrowoop(), "only narrowoop here");
+ return t->make_ptr();
}
Node* EncodePNode::Identity(PhaseTransform* phase) {
@@ -599,27 +585,14 @@ Node* EncodePNode::Identity(PhaseTransfo
}
const Type *EncodePNode::Value( PhaseTransform *phase ) const {
- if (phase->type( in(1) ) == TypePtr::NULL_PTR) {
- return TypeNarrowOop::NULL_PTR;
- }
- return bottom_type();
-}
-
-Node* EncodePNode::encode(PhaseTransform* phase, Node* value) {
- if (value->is_DecodeN()) {
- // (EncodeP (DecodeN p)) -> p
- return value->in(1);
- }
- const Type* newtype = value->bottom_type();
- if (newtype == TypePtr::NULL_PTR) {
- return phase->transform(new (phase->C, 1) ConNNode(TypeNarrowOop::NULL_PTR));
- } else if (newtype->isa_oopptr()) {
- return phase->transform(new (phase->C, 2) EncodePNode(value, newtype->is_oopptr()->make_narrowoop()));
- } else {
- ShouldNotReachHere();
- return NULL; // to make C++ compiler happy.
- }
-}
+ const Type *t = phase->type( in(1) );
+ if (t == Type::TOP) return Type::TOP;
+ if (t == TypePtr::NULL_PTR) return TypeNarrowOop::NULL_PTR;
+
+ assert(t->isa_oopptr(), "only oopptr here");
+ return t->make_narrowoop();
+}
+
Node *EncodePNode::Ideal_DU_postCCP( PhaseCCP *ccp ) {
return MemNode::Ideal_common_DU_postCCP(ccp, this, in(1));
--- a/src/share/vm/opto/connode.hpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/connode.hpp Tue Jul 01 11:59:44 2008 -0700
@@ -280,7 +280,6 @@ class EncodePNode : public TypeNode {
virtual const Type *Value( PhaseTransform *phase ) const;
virtual uint ideal_reg() const { return Op_RegN; }
- static Node* encode(PhaseTransform* phase, Node* value);
virtual Node *Ideal_DU_postCCP( PhaseCCP *ccp );
};
@@ -300,8 +299,6 @@ class DecodeNNode : public TypeNode {
virtual Node *Identity( PhaseTransform *phase );
virtual const Type *Value( PhaseTransform *phase ) const;
virtual uint ideal_reg() const { return Op_RegP; }
-
- static Node* decode(PhaseTransform* phase, Node* value);
};
//------------------------------Conv2BNode-------------------------------------
@@ -549,10 +546,18 @@ class Opaque1Node : public Node {
virtual uint hash() const ; // { return NO_HASH; }
virtual uint cmp( const Node &n ) const;
public:
- Opaque1Node( Node *n ) : Node(0,n) {}
+ Opaque1Node( Compile* C, Node *n ) : Node(0,n) {
+ // Put it on the Macro nodes list to removed during macro nodes expansion.
+ init_flags(Flag_is_macro);
+ C->add_macro_node(this);
+ }
// Special version for the pre-loop to hold the original loop limit
// which is consumed by range check elimination.
- Opaque1Node( Node *n, Node* orig_limit ) : Node(0,n,orig_limit) {}
+ Opaque1Node( Compile* C, Node *n, Node* orig_limit ) : Node(0,n,orig_limit) {
+ // Put it on the Macro nodes list to removed during macro nodes expansion.
+ init_flags(Flag_is_macro);
+ C->add_macro_node(this);
+ }
Node* original_loop_limit() { return req()==3 ? in(2) : NULL; }
virtual int Opcode() const;
virtual const Type *bottom_type() const { return TypeInt::INT; }
@@ -572,7 +577,11 @@ class Opaque2Node : public Node {
virtual uint hash() const ; // { return NO_HASH; }
virtual uint cmp( const Node &n ) const;
public:
- Opaque2Node( Node *n ) : Node(0,n) {}
+ Opaque2Node( Compile* C, Node *n ) : Node(0,n) {
+ // Put it on the Macro nodes list to removed during macro nodes expansion.
+ init_flags(Flag_is_macro);
+ C->add_macro_node(this);
+ }
virtual int Opcode() const;
virtual const Type *bottom_type() const { return TypeInt::INT; }
};
--- a/src/share/vm/opto/escape.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/escape.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -483,7 +483,7 @@ static Node* find_second_addp(Node* addp
//
void ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) {
const TypeOopPtr *base_t = igvn->type(base)->isa_oopptr();
- assert(base_t != NULL && base_t->is_instance(), "expecting instance oopptr");
+ assert(base_t != NULL && base_t->is_known_instance(), "expecting instance oopptr");
const TypeOopPtr *t = igvn->type(addp)->isa_oopptr();
if (t == NULL) {
// We are computing a raw address for a store captured by an Initialize
@@ -494,8 +494,8 @@ void ConnectionGraph::split_AddP(Node *a
assert(offs != Type::OffsetBot, "offset must be a constant");
t = base_t->add_offset(offs)->is_oopptr();
}
- uint inst_id = base_t->instance_id();
- assert(!t->is_instance() || t->instance_id() == inst_id,
+ int inst_id = base_t->instance_id();
+ assert(!t->is_known_instance() || t->instance_id() == inst_id,
"old type must be non-instance or match new type");
const TypeOopPtr *tinst = base_t->add_offset(t->offset())->is_oopptr();
// Do NOT remove the next call: ensure an new alias index is allocated
@@ -509,7 +509,7 @@ void ConnectionGraph::split_AddP(Node *a
Node *adr = addp->in(AddPNode::Address);
const TypeOopPtr *atype = igvn->type(adr)->isa_oopptr();
if (atype != NULL && atype->instance_id() != inst_id) {
- assert(!atype->is_instance(), "no conflicting instances");
+ assert(!atype->is_known_instance(), "no conflicting instances");
const TypeOopPtr *new_atype = base_t->add_offset(atype->offset())->isa_oopptr();
Node *acast = new (_compile, 2) CastPPNode(adr, new_atype);
acast->set_req(0, adr->in(0));
@@ -663,7 +663,7 @@ Node* ConnectionGraph::find_inst_mem(Nod
return orig_mem;
Compile* C = phase->C;
const TypeOopPtr *tinst = C->get_adr_type(alias_idx)->isa_oopptr();
- bool is_instance = (tinst != NULL) && tinst->is_instance();
+ bool is_instance = (tinst != NULL) && tinst->is_known_instance();
Node *prev = NULL;
Node *result = orig_mem;
while (prev != result) {
@@ -693,7 +693,7 @@ Node* ConnectionGraph::find_inst_mem(Nod
AllocateNode* alloc = proj_in->as_Initialize()->allocation();
// Stop if this is the initialization for the object instance which
// which contains this memory slice, otherwise skip over it.
- if (alloc == NULL || alloc->_idx != tinst->instance_id()) {
+ if (alloc == NULL || alloc->_idx != (uint)tinst->instance_id()) {
result = proj_in->in(TypeFunc::Memory);
}
} else if (proj_in->is_MemBar()) {
@@ -887,7 +887,7 @@ void ConnectionGraph::split_unique_types
const TypeOopPtr *t = igvn->type(n)->isa_oopptr();
if (t == NULL)
continue; // not a TypeInstPtr
- tinst = t->cast_to_instance(ni);
+ tinst = t->cast_to_instance_id(ni);
igvn->hash_delete(n);
igvn->set_type(n, tinst);
n->raise_bottom_type(tinst);
@@ -959,19 +959,19 @@ void ConnectionGraph::split_unique_types
Node *val = get_map(elem); // CheckCastPP node
TypeNode *tn = n->as_Type();
tinst = igvn->type(val)->isa_oopptr();
- assert(tinst != NULL && tinst->is_instance() &&
- tinst->instance_id() == elem , "instance type expected.");
-
- const TypeOopPtr *tn_t = NULL;
+ assert(tinst != NULL && tinst->is_known_instance() &&
+ (uint)tinst->instance_id() == elem , "instance type expected.");
+
const Type *tn_type = igvn->type(tn);
+ const TypeOopPtr *tn_t;
if (tn_type->isa_narrowoop()) {
- tn_t = tn_type->is_narrowoop()->make_oopptr()->isa_oopptr();
+ tn_t = tn_type->make_ptr()->isa_oopptr();
} else {
tn_t = tn_type->isa_oopptr();
}
if (tn_t != NULL &&
- tinst->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE)->higher_equal(tn_t)) {
+ tinst->cast_to_instance_id(TypeOopPtr::InstanceBot)->higher_equal(tn_t)) {
if (tn_type->isa_narrowoop()) {
tn_type = tinst->make_narrowoop();
} else {
@@ -1921,9 +1921,7 @@ void ConnectionGraph::record_for_escape_
case Op_StoreN:
{
const Type *adr_type = phase->type(n->in(MemNode::Address));
- if (adr_type->isa_narrowoop()) {
- adr_type = adr_type->is_narrowoop()->make_oopptr();
- }
+ adr_type = adr_type->make_ptr();
if (adr_type->isa_oopptr()) {
add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false);
} else {
@@ -1948,9 +1946,7 @@ void ConnectionGraph::record_for_escape_
case Op_CompareAndSwapN:
{
const Type *adr_type = phase->type(n->in(MemNode::Address));
- if (adr_type->isa_narrowoop()) {
- adr_type = adr_type->is_narrowoop()->make_oopptr();
- }
+ adr_type = adr_type->make_ptr();
if (adr_type->isa_oopptr()) {
add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false);
} else {
@@ -2131,10 +2127,7 @@ void ConnectionGraph::build_connection_g
case Op_CompareAndSwapN:
{
Node *adr = n->in(MemNode::Address);
- const Type *adr_type = phase->type(adr);
- if (adr_type->isa_narrowoop()) {
- adr_type = adr_type->is_narrowoop()->make_oopptr();
- }
+ const Type *adr_type = phase->type(adr)->make_ptr();
#ifdef ASSERT
if (!adr_type->isa_oopptr())
assert(phase->type(adr) == TypeRawPtr::NOTNULL, "Op_StoreP");
--- a/src/share/vm/opto/gcm.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/gcm.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -307,7 +307,6 @@ static Block* raise_LCA_above_marks(Bloc
// Test and set the visited bit.
if (mid->raise_LCA_visited() == mark) continue; // already visited
- mid->set_raise_LCA_visited(mark);
// Don't process the current LCA, otherwise the search may terminate early
if (mid != LCA && mid->raise_LCA_mark() == mark) {
@@ -317,6 +316,8 @@ static Block* raise_LCA_above_marks(Bloc
assert(early->dominates(LCA), "early is high enough");
// Resume searching at that point, skipping intermediate levels.
worklist.push(LCA);
+ if (LCA == mid)
+ continue; // Don't mark as visited to avoid early termination.
} else {
// Keep searching through this block's predecessors.
for (uint j = 1, jmax = mid->num_preds(); j < jmax; j++) {
@@ -324,6 +325,7 @@ static Block* raise_LCA_above_marks(Bloc
worklist.push(mid_parent);
}
}
+ mid->set_raise_LCA_visited(mark);
}
return LCA;
}
--- a/src/share/vm/opto/idealGraphPrinter.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/idealGraphPrinter.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -100,16 +100,18 @@ void IdealGraphPrinter::clean_up() {
// Constructor, either file or network output
IdealGraphPrinter::IdealGraphPrinter() {
- _traverse_outs = false;
+ // By default dump both ins and outs since dead or unreachable code
+ // needs to appear in the graph. There are also some special cases
+ // in the mach where kill projections have no users but should
+ // appear in the dump.
+ _traverse_outs = true;
_should_send_method = true;
_output = NULL;
buffer[0] = 0;
_depth = 0;
_current_method = NULL;
assert(!_current_method, "current method must be initialized to NULL");
- _arena = new Arena();
-
- _stream = new (ResourceObj::C_HEAP) networkStream();
+ _stream = NULL;
if (PrintIdealGraphFile != NULL) {
ThreadCritical tc;
@@ -124,12 +126,16 @@ IdealGraphPrinter::IdealGraphPrinter() {
} else {
st.print("%s%d", PrintIdealGraphFile, _file_count);
}
- _output = new (ResourceObj::C_HEAP) fileStream(st.as_string());
+ fileStream *stream = new (ResourceObj::C_HEAP) fileStream(st.as_string());
+ _output = stream;
} else {
- _output = new (ResourceObj::C_HEAP) fileStream(PrintIdealGraphFile);
+ fileStream *stream = new (ResourceObj::C_HEAP) fileStream(PrintIdealGraphFile);
+ _output = stream;
}
_file_count++;
} else {
+ _stream = new (ResourceObj::C_HEAP) networkStream();
+
// Try to connect to visualizer
if (_stream->connect(PrintIdealGraphAddress, PrintIdealGraphPort)) {
char c = 0;
@@ -149,13 +155,24 @@ IdealGraphPrinter::IdealGraphPrinter() {
}
}
- start_element(TOP_ELEMENT);
+ _xml = new (ResourceObj::C_HEAP) xmlStream(_output);
+
+ head(TOP_ELEMENT);
}
// Destructor, close file or network stream
IdealGraphPrinter::~IdealGraphPrinter() {
- end_element(TOP_ELEMENT);
+ tail(TOP_ELEMENT);
+
+ // tty->print_cr("Walk time: %d", (int)_walk_time.milliseconds());
+ // tty->print_cr("Output time: %d", (int)_output_time.milliseconds());
+ // tty->print_cr("Build blocks time: %d", (int)_build_blocks_time.milliseconds());
+
+ if(_xml) {
+ delete _xml;
+ _xml = NULL;
+ }
if (_stream) {
delete _stream;
@@ -171,94 +188,93 @@ IdealGraphPrinter::~IdealGraphPrinter()
}
}
-void IdealGraphPrinter::print_ifg(PhaseIFG* ifg) {
-
- // Code to print an interference graph to tty, currently not used
-
- /*
- if (!_current_method) return;
- // Remove neighbor colors
-
- for (uint i = 0; i < ifg._maxlrg; i++) {
-
- IndexSet *s = ifg.neighbors(i);
- IndexSetIterator elements(s);
- uint neighbor;
- while ((neighbor = elements.next()) != 0) {
- tty->print_cr("Edge between %d and %d\n", i, neighbor);
- }
- }
-
-
- for (uint i = 0; i < ifg._maxlrg; i++) {
- LRG &l = ifg.lrgs(i);
- if (l._def) {
- OptoReg::Name name = l.reg();
- tty->print("OptoReg::dump: ");
- OptoReg::dump(name);
- tty->print_cr("");
- tty->print_cr("name=%d\n", name);
- if (name) {
- if (OptoReg::is_stack(name)) {
- tty->print_cr("Stack number %d\n", OptoReg::reg2stack(name));
-
- } else if (!OptoReg::is_valid(name)) {
- tty->print_cr("BAD!!!");
- } else {
-
- if (OptoReg::is_reg(name)) {
- tty->print_cr(OptoReg::regname(name));
- } else {
- int x = 0;
- }
- }
- int x = 0;
- }
-
- if (l._def == NodeSentinel) {
- tty->print("multiple mapping from %d: ", i);
- for (int j=0; j<l._defs->length(); j++) {
- tty->print("%d ", l._defs->at(j)->_idx);
- }
- tty->print_cr("");
- } else {
- tty->print_cr("mapping between %d and %d\n", i, l._def->_idx);
- }
- }
- }*/
+
+void IdealGraphPrinter::begin_elem(const char *s) {
+ _xml->begin_elem(s);
+}
+
+void IdealGraphPrinter::end_elem() {
+ _xml->end_elem();
+}
+
+void IdealGraphPrinter::begin_head(const char *s) {
+ _xml->begin_head(s);
+}
+
+void IdealGraphPrinter::end_head() {
+ _xml->end_head();
+}
+
+void IdealGraphPrinter::print_attr(const char *name, intptr_t val) {
+ stringStream stream;
+ stream.print(INTX_FORMAT, val);
+ print_attr(name, stream.as_string());
+}
+
+void IdealGraphPrinter::print_attr(const char *name, const char *val) {
+ _xml->print(" %s='", name);
+ text(val);
+ _xml->print("'");
+}
+
+void IdealGraphPrinter::head(const char *name) {
+ _xml->head(name);
+}
+
+void IdealGraphPrinter::tail(const char *name) {
+ _xml->tail(name);
+}
+
+void IdealGraphPrinter::text(const char *s) {
+ _xml->text(s);
+}
+
+void IdealGraphPrinter::print_prop(const char *name, int val) {
+
+ stringStream stream;
+ stream.print("%d", val);
+ print_prop(name, stream.as_string());
+}
+
+void IdealGraphPrinter::print_prop(const char *name, const char *val) {
+ begin_head(PROPERTY_ELEMENT);
+ print_attr(PROPERTY_NAME_PROPERTY, name);
+ end_head();
+ text(val);
+ tail(PROPERTY_ELEMENT);
}
void IdealGraphPrinter::print_method(ciMethod *method, int bci, InlineTree *tree) {
-
- Properties properties;
+ begin_head(METHOD_ELEMENT);
+
stringStream str;
method->print_name(&str);
stringStream shortStr;
method->print_short_name(&shortStr);
-
- properties.add(new Property(METHOD_NAME_PROPERTY, str.as_string()));
- properties.add(new Property(METHOD_SHORT_NAME_PROPERTY, shortStr.as_string()));
- properties.add(new Property(METHOD_BCI_PROPERTY, bci));
- start_element(METHOD_ELEMENT, &properties);
-
- start_element(BYTECODES_ELEMENT);
+ print_attr(METHOD_NAME_PROPERTY, str.as_string());
+ print_attr(METHOD_SHORT_NAME_PROPERTY, shortStr.as_string());
+ print_attr(METHOD_BCI_PROPERTY, bci);
+
+ end_head();
+
+ head(BYTECODES_ELEMENT);
output()->print_cr("<![CDATA[");
method->print_codes_on(output());
output()->print_cr("]]>");
- end_element(BYTECODES_ELEMENT);
-
- start_element(INLINE_ELEMENT);
+ tail(BYTECODES_ELEMENT);
+
+ head(INLINE_ELEMENT);
if (tree != NULL) {
GrowableArray<InlineTree *> subtrees = tree->subtrees();
for (int i = 0; i < subtrees.length(); i++) {
print_inline_tree(subtrees.at(i));
}
}
- end_element(INLINE_ELEMENT);
-
- end_element(METHOD_ELEMENT);
+ tail(INLINE_ELEMENT);
+
+ tail(METHOD_ELEMENT);
output()->flush();
}
@@ -269,12 +285,6 @@ void IdealGraphPrinter::print_inline_tre
ciMethod *method = tree->method();
print_method(tree->method(), tree->caller_bci(), tree);
-}
-
-void IdealGraphPrinter::clear_nodes() {
- // for (int i = 0; i < _nodes.length(); i++) {
- // _nodes.at(i)->clear_node();
- // }
}
void IdealGraphPrinter::print_inlining(Compile* compile) {
@@ -298,141 +308,54 @@ void IdealGraphPrinter::begin_method(Com
assert(method, "null methods are not allowed!");
assert(!_current_method, "current method must be null!");
- _arena->destruct_contents();
-
- start_element(GROUP_ELEMENT);
+ head(GROUP_ELEMENT);
+
+ head(PROPERTIES_ELEMENT);
// Print properties
- Properties properties;
-
// Add method name
stringStream strStream;
method->print_name(&strStream);
- properties.add(new Property(METHOD_NAME_PROPERTY, strStream.as_string()));
+ print_prop(METHOD_NAME_PROPERTY, strStream.as_string());
if (method->flags().is_public()) {
- properties.add(new Property(METHOD_IS_PUBLIC_PROPERTY, TRUE_VALUE));
+ print_prop(METHOD_IS_PUBLIC_PROPERTY, TRUE_VALUE);
}
if (method->flags().is_static()) {
- properties.add(new Property(METHOD_IS_STATIC_PROPERTY, TRUE_VALUE));
- }
-
- properties.print(this);
+ print_prop(METHOD_IS_STATIC_PROPERTY, TRUE_VALUE);
+ }
+
+ tail(PROPERTIES_ELEMENT);
if (_stream) {
char answer = 0;
- _stream->flush();
+ _xml->flush();
int result = _stream->read(&answer, 1);
_should_send_method = (answer == 'y');
}
- this->_nodes = GrowableArray<NodeDescription *>(_arena, 2, 0, NULL);
- this->_edges = GrowableArray< EdgeDescription * >(_arena, 2, 0, NULL);
-
-
this->_current_method = method;
-
-
- _output->flush();
+ _xml->flush();
}
// Has to be called whenever a method has finished compilation
void IdealGraphPrinter::end_method() {
-// if (finish && !in_method) return;
-
nmethod* method = (nmethod*)this->_current_method->code();
- start_element(ASSEMBLY_ELEMENT);
- // Disassembler::decode(method, _output);
- end_element(ASSEMBLY_ELEMENT);
-
-
- end_element(GROUP_ELEMENT);
+ tail(GROUP_ELEMENT);
_current_method = NULL;
- _output->flush();
- for (int i = 0; i < _nodes.length(); i++) {
- NodeDescription *desc = _nodes.at(i);
- if (desc) {
- delete desc;
- _nodes.at_put(i, NULL);
- }
- }
- this->_nodes.clear();
-
-
- for (int i = 0; i < _edges.length(); i++) {
- // for (int j=0; j<_edges.at(i)->length(); j++) {
- EdgeDescription *conn = _edges.at(i);
- conn->print(this);
- if (conn) {
- delete conn;
- _edges.at_put(i, NULL);
- }
- //}
- //_edges.at(i)->clear();
- //delete _edges.at(i);
- //_edges.at_put(i, NULL);
- }
- this->_edges.clear();
-
-// in_method = false;
-}
-
-// Outputs an XML start element
-void IdealGraphPrinter::start_element(const char *s, Properties *properties /* = NULL */, bool print_indent /* = false */, bool print_return /* = true */) {
-
- start_element_helper(s, properties, false, print_indent, print_return);
- _depth++;
-
-}
-
-// Outputs an XML start element without body
-void IdealGraphPrinter::simple_element(const char *s, Properties *properties /* = NULL */, bool print_indent /* = false */) {
- start_element_helper(s, properties, true, print_indent, true);
-}
-
-// Outputs an XML start element. If outputEnd is true, the element has no body.
-void IdealGraphPrinter::start_element_helper(const char *s, Properties *properties, bool outputEnd, bool print_indent /* = false */, bool print_return /* = true */) {
-
- assert(_output, "output stream must exist!");
-
- if (print_indent) this->print_indent();
- _output->print("<");
- _output->print(s);
- if (properties) properties->print_as_attributes(this);
-
- if (outputEnd) {
- _output->print("/");
- }
-
- _output->print(">");
- if (print_return) _output->print_cr("");
-
+ _xml->flush();
}
// Print indent
void IdealGraphPrinter::print_indent() {
+ tty->print_cr("printing ident %d", _depth);
for (int i = 0; i < _depth; i++) {
- _output->print(INDENT);
- }
-}
-
-// Outputs an XML end element
-void IdealGraphPrinter::end_element(const char *s, bool print_indent /* = true */, bool print_return /* = true */) {
-
- assert(_output, "output stream must exist!");
-
- _depth--;
-
- if (print_indent) this->print_indent();
- _output->print("</");
- _output->print(s);
- _output->print(">");
- if (print_return) _output->print_cr("");
-
+ _xml->print(INDENT);
+ }
}
bool IdealGraphPrinter::traverse_outs() {
@@ -443,7 +366,255 @@ void IdealGraphPrinter::set_traverse_out
_traverse_outs = b;
}
-void IdealGraphPrinter::walk(Node *start) {
+intptr_t IdealGraphPrinter::get_node_id(Node *n) {
+ return (intptr_t)(n);
+}
+
+void IdealGraphPrinter::visit_node(Node *n, void *param) {
+
+ if(param) {
+
+ // Output edge
+ intptr_t dest_id = get_node_id(n);
+ for ( uint i = 0; i < n->len(); i++ ) {
+ if ( n->in(i) ) {
+ Node *source = n->in(i);
+ begin_elem(EDGE_ELEMENT);
+ intptr_t source_id = get_node_id(source);
+ print_attr(FROM_PROPERTY, source_id);
+ print_attr(TO_PROPERTY, dest_id);
+ print_attr(INDEX_PROPERTY, i);
+ end_elem();
+ }
+ }
+
+ } else {
+
+ // Output node
+ begin_head(NODE_ELEMENT);
+ print_attr(NODE_ID_PROPERTY, get_node_id(n));
+ end_head();
+
+ head(PROPERTIES_ELEMENT);
+
+ Node *node = n;
+#ifndef PRODUCT
+ node->_in_dump_cnt++;
+ print_prop(NODE_NAME_PROPERTY, (const char *)node->Name());
+ const Type *t = node->bottom_type();
+ print_prop("type", (const char *)Type::msg[t->base()]);
+ print_prop("idx", node->_idx);
+#ifdef ASSERT
+ print_prop("debug_idx", node->_debug_idx);
+#endif
+
+ if(C->cfg() != NULL) {
+ Block *block = C->cfg()->_bbs[node->_idx];
+ if(block == NULL) {
+ print_prop("block", C->cfg()->_blocks[0]->_pre_order);
+ } else {
+ print_prop("block", block->_pre_order);
+ }
+ }
+
+ const jushort flags = node->flags();
+ if (flags & Node::Flag_is_Copy) {
+ print_prop("is_copy", "true");
+ }
+ if (flags & Node::Flag_is_Call) {
+ print_prop("is_call", "true");
+ }
+ if (flags & Node::Flag_rematerialize) {
+ print_prop("rematerialize", "true");
+ }
+ if (flags & Node::Flag_needs_anti_dependence_check) {
+ print_prop("needs_anti_dependence_check", "true");
+ }
+ if (flags & Node::Flag_is_macro) {
+ print_prop("is_macro", "true");
+ }
+ if (flags & Node::Flag_is_Con) {
+ print_prop("is_con", "true");
+ }
+ if (flags & Node::Flag_is_cisc_alternate) {
+ print_prop("is_cisc_alternate", "true");
+ }
+ if (flags & Node::Flag_is_Branch) {
+ print_prop("is_branch", "true");
+ }
+ if (flags & Node::Flag_is_block_start) {
+ print_prop("is_block_start", "true");
+ }
+ if (flags & Node::Flag_is_Goto) {
+ print_prop("is_goto", "true");
+ }
+ if (flags & Node::Flag_is_dead_loop_safe) {
+ print_prop("is_dead_loop_safe", "true");
+ }
+ if (flags & Node::Flag_may_be_short_branch) {
+ print_prop("may_be_short_branch", "true");
+ }
+ if (flags & Node::Flag_is_safepoint_node) {
+ print_prop("is_safepoint_node", "true");
+ }
+ if (flags & Node::Flag_is_pc_relative) {
+ print_prop("is_pc_relative", "true");
+ }
+
+ if (C->matcher() != NULL) {
+ if (C->matcher()->is_shared(node)) {
+ print_prop("is_shared", "true");
+ } else {
+ print_prop("is_shared", "false");
+ }
+ if (C->matcher()->is_dontcare(node)) {
+ print_prop("is_dontcare", "true");
+ } else {
+ print_prop("is_dontcare", "false");
+ }
+
+ Node* old = C->matcher()->find_old_node(node);
+ if (old != NULL) {
+ print_prop("old_node_idx", old->_idx);
+ }
+ }
+
+ if (node->is_Proj()) {
+ print_prop("con", (int)node->as_Proj()->_con);
+ }
+
+ if (node->is_Mach()) {
+ print_prop("idealOpcode", (const char *)NodeClassNames[node->as_Mach()->ideal_Opcode()]);
+ }
+
+ buffer[0] = 0;
+ stringStream s2(buffer, sizeof(buffer) - 1);
+
+ node->dump_spec(&s2);
+ if (t != NULL && (t->isa_instptr() || t->isa_klassptr())) {
+ const TypeInstPtr *toop = t->isa_instptr();
+ const TypeKlassPtr *tkls = t->isa_klassptr();
+ ciKlass* klass = toop ? toop->klass() : (tkls ? tkls->klass() : NULL );
+ if( klass && klass->is_loaded() && klass->is_interface() ) {
+ s2.print(" Interface:");
+ } else if( toop ) {
+ s2.print(" Oop:");
+ } else if( tkls ) {
+ s2.print(" Klass:");
+ }
+ t->dump_on(&s2);
+ } else if( t == Type::MEMORY ) {
+ s2.print(" Memory:");
+ MemNode::dump_adr_type(node, node->adr_type(), &s2);
+ }
+
+ assert(s2.size() < sizeof(buffer), "size in range");
+ print_prop("dump_spec", buffer);
+
+ if (node->is_block_proj()) {
+ print_prop("is_block_proj", "true");
+ }
+
+ if (node->is_block_start()) {
+ print_prop("is_block_start", "true");
+ }
+
+ const char *short_name = "short_name";
+ if (strcmp(node->Name(), "Parm") == 0 && node->as_Proj()->_con >= TypeFunc::Parms) {
+ int index = node->as_Proj()->_con - TypeFunc::Parms;
+ if (index >= 10) {
+ print_prop(short_name, "PA");
+ } else {
+ sprintf(buffer, "P%d", index);
+ print_prop(short_name, buffer);
+ }
+ } else if (strcmp(node->Name(), "IfTrue") == 0) {
+ print_prop(short_name, "T");
+ } else if (strcmp(node->Name(), "IfFalse") == 0) {
+ print_prop(short_name, "F");
+ } else if ((node->is_Con() && node->is_Type()) || node->is_Proj()) {
+
+ if (t->base() == Type::Int && t->is_int()->is_con()) {
+ const TypeInt *typeInt = t->is_int();
+ assert(typeInt->is_con(), "must be constant");
+ jint value = typeInt->get_con();
+
+ // max. 2 chars allowed
+ if (value >= -9 && value <= 99) {
+ sprintf(buffer, "%d", value);
+ print_prop(short_name, buffer);
+ } else {
+ print_prop(short_name, "I");
+ }
+ } else if (t == Type::TOP) {
+ print_prop(short_name, "^");
+ } else if (t->base() == Type::Long && t->is_long()->is_con()) {
+ const TypeLong *typeLong = t->is_long();
+ assert(typeLong->is_con(), "must be constant");
+ jlong value = typeLong->get_con();
+
+ // max. 2 chars allowed
+ if (value >= -9 && value <= 99) {
+ sprintf(buffer, "%d", value);
+ print_prop(short_name, buffer);
+ } else {
+ print_prop(short_name, "L");
+ }
+ } else if (t->base() == Type::KlassPtr) {
+ const TypeKlassPtr *typeKlass = t->is_klassptr();
+ print_prop(short_name, "CP");
+ } else if (t->base() == Type::Control) {
+ print_prop(short_name, "C");
+ } else if (t->base() == Type::Memory) {
+ print_prop(short_name, "M");
+ } else if (t->base() == Type::Abio) {
+ print_prop(short_name, "IO");
+ } else if (t->base() == Type::Return_Address) {
+ print_prop(short_name, "RA");
+ } else if (t->base() == Type::AnyPtr) {
+ print_prop(short_name, "P");
+ } else if (t->base() == Type::RawPtr) {
+ print_prop(short_name, "RP");
+ } else if (t->base() == Type::AryPtr) {
+ print_prop(short_name, "AP");
+ }
+ }
+
+ JVMState* caller = NULL;
+ if (node->is_SafePoint()) {
+ caller = node->as_SafePoint()->jvms();
+ } else {
+ Node_Notes* notes = C->node_notes_at(node->_idx);
+ if (notes != NULL) {
+ caller = notes->jvms();
+ }
+ }
+
+ if (caller != NULL) {
+ stringStream bciStream;
+ while(caller) {
+ bciStream.print("%d ", caller->bci());
+ caller = caller->caller();
+ }
+ print_prop("bci", bciStream.as_string());
+ }
+
+ if (_chaitin && _chaitin != (PhaseChaitin *)0xdeadbeef) {
+ buffer[0] = 0;
+ _chaitin->dump_register(node, buffer);
+ print_prop("reg", buffer);
+ print_prop("lrg", _chaitin->n2lidx(node));
+ }
+
+ node->_in_dump_cnt--;
+#endif
+
+ tail(PROPERTIES_ELEMENT);
+ tail(NODE_ELEMENT);
+ }
+}
+
+void IdealGraphPrinter::walk_nodes(Node *start, void *param) {
VectorSet visited(Thread::current()->resource_area());
@@ -453,7 +624,7 @@ void IdealGraphPrinter::walk(Node *start
while(nodeStack.length() > 0) {
Node *n = nodeStack.pop();
- IdealGraphPrinter::pre_node(n, this);
+ visit_node(n, param);
if (_traverse_outs) {
for (DUIterator i = n->outs(); n->has_out(i); i++) {
@@ -474,573 +645,6 @@ void IdealGraphPrinter::walk(Node *start
}
}
-void IdealGraphPrinter::compress(int index, GrowableArray<Block>* blocks) {
- Block *block = blocks->adr_at(index);
-
- int ancestor = block->ancestor();
- assert(ancestor != -1, "");
-
- Block *ancestor_block = blocks->adr_at(ancestor);
- if (ancestor_block->ancestor() != -1) {
- compress(ancestor, blocks);
-
- int label = block->label();
- Block *label_block = blocks->adr_at(label);
-
- int ancestor_label = ancestor_block->label();
- Block *ancestor_label_block = blocks->adr_at(label);
- if (ancestor_label_block->semi() < label_block->semi()) {
- block->set_label(ancestor_label);
- }
-
- block->set_ancestor(ancestor_block->ancestor());
- }
-}
-
-int IdealGraphPrinter::eval(int index, GrowableArray<Block>* blocks) {
- Block *block = blocks->adr_at(index);
- if (block->ancestor() == -1) {
- return index;
- } else {
- compress(index, blocks);
- return block->label();
- }
-}
-
-void IdealGraphPrinter::link(int index1, int index2, GrowableArray<Block>* blocks) {
- Block *block2 = blocks->adr_at(index2);
- block2->set_ancestor(index1);
-}
-
-void IdealGraphPrinter::build_dominators(GrowableArray<Block>* blocks) {
-
- if (blocks->length() == 0) return;
-
- GrowableArray<int> stack;
- stack.append(0);
-
- GrowableArray<Block *> array;
-
- assert(blocks->length() > 0, "");
- blocks->adr_at(0)->set_dominator(0);
-
- int n = 0;
- while(!stack.is_empty()) {
- int index = stack.pop();
- Block *block = blocks->adr_at(index);
- block->set_semi(n);
- array.append(block);
- n = n + 1;
- for (int i = 0; i < block->succs()->length(); i++) {
- int succ_index = block->succs()->at(i);
- Block *succ = blocks->adr_at(succ_index);
- if (succ->semi() == -1) {
- succ->set_parent(index);
- stack.push(succ_index);
- }
- succ->add_pred(index);
- }
- }
-
- for (int i=n-1; i>0; i--) {
- Block *block = array.at(i);
- int block_index = block->index();
- for (int j=0; j<block->pred()->length(); j++) {
- int pred_index = block->pred()->at(j);
- int cur_index = eval(pred_index, blocks);
-
- Block *cur_block = blocks->adr_at(cur_index);
- if (cur_block->semi() < block->semi()) {
- block->set_semi(cur_block->semi());
- }
- }
-
- int semi_index = block->semi();
- Block *semi_block = array.at(semi_index);
- semi_block->add_to_bucket(block_index);
-
- link(block->parent(), block_index, blocks);
- Block *parent_block = blocks->adr_at(block->parent());
-
- for (int j=0; j<parent_block->bucket()->length(); j++) {
- int cur_index = parent_block->bucket()->at(j);
- int new_index = eval(cur_index, blocks);
- Block *cur_block = blocks->adr_at(cur_index);
- Block *new_block = blocks->adr_at(new_index);
- int dom = block->parent();
-
- if (new_block->semi() < cur_block->semi()) {
- dom = new_index;
- }
-
- cur_block->set_dominator(dom);
- }
-
- parent_block->clear_bucket();
- }
-
- for (int i=1; i < n; i++) {
-
- Block *block = array.at(i);
- int block_index = block->index();
-
- int semi_index = block->semi();
- Block *semi_block = array.at(semi_index);
-
- if (block->dominator() != semi_block->index()) {
- int new_dom = blocks->adr_at(block->dominator())->dominator();
- block->set_dominator(new_dom);
- }
- }
-
- for (int i = 0; i < blocks->length(); i++) {
- if (blocks->adr_at(i)->dominator() == -1) {
- blocks->adr_at(i)->set_dominator(0);
- }
- }
-
- // Build dominates array
- for (int i=1; i < blocks->length(); i++) {
- Block *block = blocks->adr_at(i);
- int dominator = block->dominator();
- Block *dom_block = blocks->adr_at(dominator);
- dom_block->add_dominates(i);
- dom_block->add_child(i);
-
- while(dominator != 0) {
- dominator = dom_block->dominator();
- dom_block = blocks->adr_at(dominator);
- dom_block->add_child(i);
- }
- }
-}
-
-void IdealGraphPrinter::build_common_dominator(int **common_dominator, int index, GrowableArray<Block>* blocks) {
-
- common_dominator[index][index] = index;
- Block *block = blocks->adr_at(index);
- for (int i = 0; i < block->dominates()->length(); i++) {
- Block *dominated = blocks->adr_at(block->dominates()->at(i));
-
- for (int j=0; j<dominated->children()->length(); j++) {
- Block *child = blocks->adr_at(dominated->children()->at(j));
- common_dominator[index][child->index()] = common_dominator[child->index()][index] = index;
-
- for (int k=0; k<i; k++) {
- Block *other_dominated = blocks->adr_at(block->dominates()->at(k));
- common_dominator[child->index()][other_dominated->index()] = common_dominator[other_dominated->index()][child->index()] = index;
-
- for (int l=0 ; l<other_dominated->children()->length(); l++) {
- Block *other_child = blocks->adr_at(other_dominated->children()->at(l));
- common_dominator[child->index()][other_child->index()] = common_dominator[other_child->index()][child->index()] = index;
- }
- }
- }
-
- build_common_dominator(common_dominator, dominated->index(), blocks);
- }
-}
-
-void IdealGraphPrinter::schedule_latest(int **common_dominator, GrowableArray<Block>* blocks) {
-
- int queue_size = _nodes.length() + 1;
- NodeDescription **queue = NEW_RESOURCE_ARRAY(NodeDescription *, queue_size);
- int queue_start = 0;
- int queue_end = 0;
- Arena *a = new Arena();
- VectorSet on_queue(a);
-
- for (int i = 0; i < _nodes.length(); i++) {
- NodeDescription *desc = _nodes.at(i);
- if (desc) {
- desc->init_succs();
- }
- }
-
- for (int i = 0; i < _nodes.length(); i++) {
- NodeDescription *desc = _nodes.at(i);
- if (desc) {
- for (uint j=0; j<desc->node()->len(); j++) {
- Node *n = desc->node()->in(j);
- if (n) {
- NodeDescription *other_desc = _nodes.at(n->_idx);
- other_desc->add_succ(desc);
- }
- }
- }
- }
-
- for (int i = 0; i < _nodes.length(); i++) {
- NodeDescription *desc = _nodes.at(i);
- if (desc && desc->block_index() == -1) {
-
- // Put Phi into same block as region
- if (desc->node()->is_Phi() && desc->node()->in(0) && _nodes.at(desc->node()->in(0)->_idx)->block_index() != -1) {
- int index = _nodes.at(desc->node()->in(0)->_idx)->block_index();
- desc->set_block_index(index);
- blocks->adr_at(index)->add_node(desc);
-
- // Put Projections to same block as parent
- } else if (desc->node()->is_block_proj() && _nodes.at(desc->node()->is_block_proj()->_idx)->block_index() != -1) {
- int index = _nodes.at(desc->node()->is_block_proj()->_idx)->block_index();
- desc->set_block_index(index);
- blocks->adr_at(index)->add_node(desc);
- } else {
- queue[queue_end] = desc;
- queue_end++;
- on_queue.set(desc->node()->_idx);
- }
- }
- }
-
-
- int z = 0;
- while(queue_start != queue_end && z < 10000) {
-
- NodeDescription *desc = queue[queue_start];
- queue_start = (queue_start + 1) % queue_size;
- on_queue >>= desc->node()->_idx;
-
- Node* node = desc->node();
-
- if (desc->succs()->length() == 0) {
- int x = 0;
- }
-
- int block_index = -1;
- if (desc->succs()->length() != 0) {
- for (int i = 0; i < desc->succs()->length(); i++) {
- NodeDescription *cur_desc = desc->succs()->at(i);
- if (cur_desc != desc) {
- if (cur_desc->succs()->length() == 0) {
-
- // Ignore nodes with 0 successors
-
- } else if (cur_desc->block_index() == -1) {
-
- // Let this node schedule first
- block_index = -1;
- break;
-
- } else if (cur_desc->node()->is_Phi()){
-
- // Special treatment for Phi functions
- PhiNode *phi = cur_desc->node()->as_Phi();
- assert(phi->in(0) && phi->in(0)->is_Region(), "Must have region node in first input");
- RegionNode *region = phi->in(0)->as_Region();
-
- for (uint j=1; j<phi->len(); j++) {
- Node *cur_phi_input = phi->in(j);
- if (cur_phi_input == desc->node() && region->in(j)) {
- NodeDescription *cur_region_input = _nodes.at(region->in(j)->_idx);
- if (cur_region_input->block_index() == -1) {
-
- // Let this node schedule first
- block_index = -1;
- break;
- } else {
- if (block_index == -1) {
- block_index = cur_region_input->block_index();
- } else {
- block_index = common_dominator[block_index][cur_region_input->block_index()];
- }
- }
- }
- }
-
- } else {
- if (block_index == -1) {
- block_index = cur_desc->block_index();
- } else {
- block_index = common_dominator[block_index][cur_desc->block_index()];
- }
- }
- }
- }
- }
-
- if (block_index == -1) {
- queue[queue_end] = desc;
- queue_end = (queue_end + 1) % queue_size;
- on_queue.set(desc->node()->_idx);
- z++;
- } else {
- assert(desc->block_index() == -1, "");
- desc->set_block_index(block_index);
- blocks->adr_at(block_index)->add_node(desc);
- z = 0;
- }
- }
-
- for (int i = 0; i < _nodes.length(); i++) {
- NodeDescription *desc = _nodes.at(i);
- if (desc && desc->block_index() == -1) {
-
- //if (desc->node()->is_Proj() || desc->node()->is_Con()) {
- Node *parent = desc->node()->in(0);
- uint cur = 1;
- while(!parent && cur < desc->node()->len()) {
- parent = desc->node()->in(cur);
- cur++;
- }
-
- if (parent && _nodes.at(parent->_idx)->block_index() != -1) {
- int index = _nodes.at(parent->_idx)->block_index();
- desc->set_block_index(index);
- blocks->adr_at(index)->add_node(desc);
- } else {
- desc->set_block_index(0);
- blocks->adr_at(0)->add_node(desc);
- //ShouldNotReachHere();
- }
- //}
- /*
- if (desc->node()->is_block_proj() && _nodes.at(desc->node()->is_block_proj()->_idx)->block_index() != -1) {
- int index = _nodes.at(desc->node()->is_block_proj()->_idx)->block_index();
- desc->set_block_index(index);
- blocks->adr_at(index)->add_node(desc);
- } */
- }
- }
-
- for (int i = 0; i < _nodes.length(); i++) {
- NodeDescription *desc = _nodes.at(i);
- if (desc) {
- desc->clear_succs();
- }
- }
-
- for (int i = 0; i < _nodes.length(); i++) {
- NodeDescription *desc = _nodes.at(i);
- if (desc) {
- int block_index = desc->block_index();
-
- assert(block_index >= 0 && block_index < blocks->length(), "Block index must be in range");
- assert(blocks->adr_at(block_index)->nodes()->contains(desc), "Node must be child of block");
- }
- }
- a->destruct_contents();
-}
-
-void IdealGraphPrinter::build_blocks(Node *root) {
-
- Arena *a = new Arena();
- Node_Stack stack(a, 100);
-
- VectorSet visited(a);
- stack.push(root, 0);
- GrowableArray<Block> blocks(a, 2, 0, Block(0));
-
- for (int i = 0; i < _nodes.length(); i++) {
- if (_nodes.at(i)) _nodes.at(i)->set_block_index(-1);
- }
-
-
- // Order nodes such that node index is equal to idx
- for (int i = 0; i < _nodes.length(); i++) {
-
- if (_nodes.at(i)) {
- NodeDescription *node = _nodes.at(i);
- int index = node->node()->_idx;
- if (index != i) {
- _nodes.at_grow(index);
- NodeDescription *tmp = _nodes.at(index);
- *(_nodes.adr_at(index)) = node;
- *(_nodes.adr_at(i)) = tmp;
- i--;
- }
- }
- }
-
- for (int i = 0; i < _nodes.length(); i++) {
- NodeDescription *node = _nodes.at(i);
- if (node) {
- assert(node->node()->_idx == (uint)i, "");
- }
- }
-
- while(stack.is_nonempty()) {
-
- //Node *n = stack.node();
- //int index = stack.index();
- Node *proj = stack.node();//n->in(index);
- const Node *parent = proj->is_block_proj();
- if (parent == NULL) {
- parent = proj;
- }
-
- if (!visited.test_set(parent->_idx)) {
-
- NodeDescription *end_desc = _nodes.at(parent->_idx);
- int block_index = blocks.length();
- Block block(block_index);
- blocks.append(block);
- Block *b = blocks.adr_at(block_index);
- b->set_start(end_desc);
- // assert(end_desc->block_index() == -1, "");
- end_desc->set_block_index(block_index);
- b->add_node(end_desc);
-
- // Skip any control-pinned middle'in stuff
- Node *p = proj;
- NodeDescription *start_desc = NULL;
- do {
- proj = p; // Update pointer to last Control
- if (p->in(0) == NULL) {
- start_desc = end_desc;
- break;
- }
- p = p->in(0); // Move control forward
- start_desc = _nodes.at(p->_idx);
- assert(start_desc, "");
-
- if (start_desc != end_desc && start_desc->block_index() == -1) {
- assert(start_desc->block_index() == -1, "");
- assert(block_index < blocks.length(), "");
- start_desc->set_block_index(block_index);
- b->add_node(start_desc);
- }
- } while( !p->is_block_proj() &&
- !p->is_block_start() );
-
- for (uint i = 0; i < start_desc->node()->len(); i++) {
-
- Node *pred_node = start_desc->node()->in(i);
-
-
- if (pred_node && pred_node != start_desc->node()) {
- const Node *cur_parent = pred_node->is_block_proj();
- if (cur_parent != NULL) {
- pred_node = (Node *)cur_parent;
- }
-
- NodeDescription *pred_node_desc = _nodes.at(pred_node->_idx);
- if (pred_node_desc->block_index() != -1) {
- blocks.adr_at(pred_node_desc->block_index())->add_succ(block_index);
- }
- }
- }
-
- for (DUIterator_Fast dmax, i = end_desc->node()->fast_outs(dmax); i < dmax; i++) {
- Node* cur_succ = end_desc->node()->fast_out(i);
- NodeDescription *cur_succ_desc = _nodes.at(cur_succ->_idx);
-
- DUIterator_Fast dmax2, i2 = cur_succ->fast_outs(dmax2);
- if (cur_succ->is_block_proj() && i2 < dmax2 && !cur_succ->is_Root()) {
-
- for (; i2<dmax2; i2++) {
- Node *cur_succ2 = cur_succ->fast_out(i2);
- if (cur_succ2) {
- cur_succ_desc = _nodes.at(cur_succ2->_idx);
- if (cur_succ_desc == NULL) {
- // dead node so skip it
- continue;
- }
- if (cur_succ2 != end_desc->node() && cur_succ_desc->block_index() != -1) {
- b->add_succ(cur_succ_desc->block_index());
- }
- }
- }
-
- } else {
-
- if (cur_succ != end_desc->node() && cur_succ_desc && cur_succ_desc->block_index() != -1) {
- b->add_succ(cur_succ_desc->block_index());
- }
- }
- }
-
-
- int num_preds = p->len();
- int bottom = -1;
- if (p->is_Region() || p->is_Phi()) {
- bottom = 0;
- }
-
- int pushed = 0;
- for (int i=num_preds - 1; i > bottom; i--) {
- if (p->in(i) != NULL && p->in(i) != p) {
- stack.push(p->in(i), 0);
- pushed++;
- }
- }
-
- if (pushed == 0 && p->is_Root() && !_matcher) {
- // Special case when backedges to root are not yet built
- for (int i = 0; i < _nodes.length(); i++) {
- if (_nodes.at(i) && _nodes.at(i)->node()->is_SafePoint() && _nodes.at(i)->node()->outcnt() == 0) {
- stack.push(_nodes.at(i)->node(), 0);
- }
- }
- }
-
- } else {
- stack.pop();
- }
- }
-
- build_dominators(&blocks);
-
- int **common_dominator = NEW_RESOURCE_ARRAY(int *, blocks.length());
- for (int i = 0; i < blocks.length(); i++) {
- int *cur = NEW_RESOURCE_ARRAY(int, blocks.length());
- common_dominator[i] = cur;
-
- for (int j=0; j<blocks.length(); j++) {
- cur[j] = 0;
- }
- }
-
- for (int i = 0; i < blocks.length(); i++) {
- blocks.adr_at(i)->add_child(blocks.adr_at(i)->index());
- }
- build_common_dominator(common_dominator, 0, &blocks);
-
- schedule_latest(common_dominator, &blocks);
-
- start_element(CONTROL_FLOW_ELEMENT);
-
- for (int i = 0; i < blocks.length(); i++) {
- Block *block = blocks.adr_at(i);
-
- Properties props;
- props.add(new Property(BLOCK_NAME_PROPERTY, i));
- props.add(new Property(BLOCK_DOMINATOR_PROPERTY, block->dominator()));
- start_element(BLOCK_ELEMENT, &props);
-
- if (block->succs()->length() > 0) {
- start_element(SUCCESSORS_ELEMENT);
- for (int j=0; j<block->succs()->length(); j++) {
- int cur_index = block->succs()->at(j);
- if (cur_index != 0 /* start_block has must not have inputs */) {
- Properties properties;
- properties.add(new Property(BLOCK_NAME_PROPERTY, cur_index));
- simple_element(SUCCESSOR_ELEMENT, &properties);
- }
- }
- end_element(SUCCESSORS_ELEMENT);
- }
-
- start_element(NODES_ELEMENT);
-
- for (int j=0; j<block->nodes()->length(); j++) {
- NodeDescription *n = block->nodes()->at(j);
- Properties properties;
- properties.add(new Property(NODE_ID_PROPERTY, n->id()));
- simple_element(NODE_ELEMENT, &properties);
- }
-
- end_element(NODES_ELEMENT);
-
- end_element(BLOCK_ELEMENT);
- }
-
-
- end_element(CONTROL_FLOW_ELEMENT);
-
- a->destruct_contents();
-}
-
void IdealGraphPrinter::print_method(Compile* compile, const char *name, int level, bool clear_nodes) {
print(compile, name, (Node *)compile->root(), level, clear_nodes);
}
@@ -1048,872 +652,53 @@ void IdealGraphPrinter::print_method(Com
// Print current ideal graph
void IdealGraphPrinter::print(Compile* compile, const char *name, Node *node, int level, bool clear_nodes) {
-// if (finish && !in_method) return;
if (!_current_method || !_should_send_method || level > PrintIdealGraphLevel) return;
- assert(_current_method, "newMethod has to be called first!");
-
- if (clear_nodes) {
- int x = 0;
- }
-
- _clear_nodes = clear_nodes;
+ this->C = compile;
// Warning, unsafe cast?
- _chaitin = (PhaseChaitin *)compile->regalloc();
- _matcher = compile->matcher();
-
-
- // Update nodes
- for (int i = 0; i < _nodes.length(); i++) {
- NodeDescription *desc = _nodes.at(i);
- if (desc) {
- desc->set_state(Invalid);
- }
- }
- Node *n = node;
- walk(n);
-
- // Update edges
- for (int i = 0; i < _edges.length(); i++) {
- _edges.at(i)->set_state(Invalid);
- }
-
- for (int i = 0; i < _nodes.length(); i++) {
- NodeDescription *desc = _nodes.at(i);
- if (desc && desc->state() != Invalid) {
-
- int to = desc->id();
- uint len = desc->node()->len();
- for (uint j=0; j<len; j++) {
- Node *n = desc->node()->in(j);
-
- if (n) {
-
-
- intptr_t from = (intptr_t)n;
-
- // Assert from node is valid
- /*
- bool ok = false;
- for (int k=0; k<_nodes.length(); k++) {
- NodeDescription *desc = _nodes.at(k);
- if (desc && desc->id() == from) {
- assert(desc->state() != Invalid, "");
- ok = true;
- }
- }
- assert(ok, "");*/
-
- uint index = j;
- if (index >= desc->node()->req()) {
- index = desc->node()->req();
- }
-
- print_edge(from, to, index);
- }
- }
- }
- }
-
- bool is_different = false;
-
- for (int i = 0; i < _nodes.length(); i++) {
- NodeDescription *desc = _nodes.at(i);
- if (desc && desc->state() != Valid) {
- is_different = true;
- break;
- }
- }
-
- if (!is_different) {
- for (int i = 0; i < _edges.length(); i++) {
- EdgeDescription *conn = _edges.at(i);
- if (conn && conn->state() != Valid) {
- is_different = true;
- break;
- }
- }
- }
-
- // No changes -> do not print graph
- if (!is_different) return;
-
- Properties properties;
- properties.add(new Property(GRAPH_NAME_PROPERTY, (const char *)name));
- start_element(GRAPH_ELEMENT, &properties);
-
- start_element(NODES_ELEMENT);
- for (int i = 0; i < _nodes.length(); i++) {
- NodeDescription *desc = _nodes.at(i);
- if (desc) {
- desc->print(this);
- if (desc->state() == Invalid) {
- delete desc;
- _nodes.at_put(i, NULL);
- } else {
- desc->set_state(Valid);
- }
- }
- }
- end_element(NODES_ELEMENT);
-
- build_blocks(node);
-
- start_element(EDGES_ELEMENT);
- for (int i = 0; i < _edges.length(); i++) {
- EdgeDescription *conn = _edges.at(i);
-
- // Assert from and to nodes are valid
- /*
- if (!conn->state() == Invalid) {
- bool ok1 = false;
- bool ok2 = false;
- for (int j=0; j<_nodes.length(); j++) {
- NodeDescription *desc = _nodes.at(j);
- if (desc && desc->id() == conn->from()) {
- ok1 = true;
- }
-
- if (desc && desc->id() == conn->to()) {
- ok2 = true;
- }
- }
-
- assert(ok1, "from node not found!");
- assert(ok2, "to node not found!");
- }*/
-
- conn->print(this);
- if (conn->state() == Invalid) {
- _edges.remove_at(i);
- delete conn;
- i--;
- }
- }
-
- end_element(EDGES_ELEMENT);
-
- end_element(GRAPH_ELEMENT);
-
- _output->flush();
-}
-
-// Print edge
-void IdealGraphPrinter::print_edge(int from, int to, int index) {
-
- EdgeDescription *conn = new EdgeDescription(from, to, index);
- for (int i = 0; i < _edges.length(); i++) {
- if (_edges.at(i)->equals(conn)) {
- conn->set_state(Valid);
- delete _edges.at(i);
- _edges.at_put(i, conn);
- return;
- }
- }
-
- _edges.append(conn);
+ _chaitin = (PhaseChaitin *)C->regalloc();
+
+ begin_head(GRAPH_ELEMENT);
+ print_attr(GRAPH_NAME_PROPERTY, (const char *)name);
+ end_head();
+
+ head(NODES_ELEMENT);
+ walk_nodes(node, NULL);
+ tail(NODES_ELEMENT);
+
+ head(EDGES_ELEMENT);
+ walk_nodes(node, (void *)1);
+ tail(EDGES_ELEMENT);
+ if (C->cfg() != NULL) {
+ head(CONTROL_FLOW_ELEMENT);
+ for (uint i = 0; i < C->cfg()->_blocks.size(); i++) {
+ Block *b = C->cfg()->_blocks[i];
+ begin_head(BLOCK_ELEMENT);
+ print_attr(BLOCK_NAME_PROPERTY, b->_pre_order);
+ end_head();
+
+ head(SUCCESSORS_ELEMENT);
+ for (uint s = 0; s < C->cfg()->_blocks[i]->_num_succs; s++) {
+ begin_elem(SUCCESSOR_ELEMENT);
+ print_attr(BLOCK_NAME_PROPERTY, b->_succs[s]->_pre_order);
+ end_elem();
+ }
+ tail(SUCCESSORS_ELEMENT);
+
+ tail(BLOCK_ELEMENT);
+ }
+
+ tail(CONTROL_FLOW_ELEMENT);
+ }
+ tail(GRAPH_ELEMENT);
+ output()->flush();
}
extern const char *NodeClassNames[];
-// Create node description
-IdealGraphPrinter::NodeDescription *IdealGraphPrinter::create_node_description(Node* node) {
-
-#ifndef PRODUCT
- node->_in_dump_cnt++;
- NodeDescription *desc = new NodeDescription(node);
- desc->properties()->add(new Property(NODE_NAME_PROPERTY, (const char *)node->Name()));
-
- const Type *t = node->bottom_type();
- desc->properties()->add(new Property("type", (const char *)Type::msg[t->base()]));
-
- desc->properties()->add(new Property("idx", node->_idx));
-#ifdef ASSERT
- desc->properties()->add(new Property("debug_idx", node->_debug_idx));
+outputStream *IdealGraphPrinter::output() {
+ return _xml;
+}
+
#endif
-
-
- const jushort flags = node->flags();
- if (flags & Node::Flag_is_Copy) {
- desc->properties()->add(new Property("is_copy", "true"));
- }
- if (flags & Node::Flag_is_Call) {
- desc->properties()->add(new Property("is_call", "true"));
- }
- if (flags & Node::Flag_rematerialize) {
- desc->properties()->add(new Property("rematerialize", "true"));
- }
- if (flags & Node::Flag_needs_anti_dependence_check) {
- desc->properties()->add(new Property("needs_anti_dependence_check", "true"));
- }
- if (flags & Node::Flag_is_macro) {
- desc->properties()->add(new Property("is_macro", "true"));
- }
- if (flags & Node::Flag_is_Con) {
- desc->properties()->add(new Property("is_con", "true"));
- }
- if (flags & Node::Flag_is_cisc_alternate) {
- desc->properties()->add(new Property("is_cisc_alternate", "true"));
- }
- if (flags & Node::Flag_is_Branch) {
- desc->properties()->add(new Property("is_branch", "true"));
- }
- if (flags & Node::Flag_is_block_start) {
- desc->properties()->add(new Property("is_block_start", "true"));
- }
- if (flags & Node::Flag_is_Goto) {
- desc->properties()->add(new Property("is_goto", "true"));
- }
- if (flags & Node::Flag_is_dead_loop_safe) {
- desc->properties()->add(new Property("is_dead_loop_safe", "true"));
- }
- if (flags & Node::Flag_may_be_short_branch) {
- desc->properties()->add(new Property("may_be_short_branch", "true"));
- }
- if (flags & Node::Flag_is_safepoint_node) {
- desc->properties()->add(new Property("is_safepoint_node", "true"));
- }
- if (flags & Node::Flag_is_pc_relative) {
- desc->properties()->add(new Property("is_pc_relative", "true"));
- }
-
- if (_matcher) {
- if (_matcher->is_shared(desc->node())) {
- desc->properties()->add(new Property("is_shared", "true"));
- } else {
- desc->properties()->add(new Property("is_shared", "false"));
- }
-
- if (_matcher->is_dontcare(desc->node())) {
- desc->properties()->add(new Property("is_dontcare", "true"));
- } else {
- desc->properties()->add(new Property("is_dontcare", "false"));
- }
- }
-
- if (node->is_Proj()) {
- desc->properties()->add(new Property("con", (int)node->as_Proj()->_con));
- }
-
- if (node->is_Mach()) {
- desc->properties()->add(new Property("idealOpcode", (const char *)NodeClassNames[node->as_Mach()->ideal_Opcode()]));
- }
-
-
-
-
-
- outputStream *oldTty = tty;
- buffer[0] = 0;
- stringStream s2(buffer, sizeof(buffer) - 1);
-
- node->dump_spec(&s2);
- assert(s2.size() < sizeof(buffer), "size in range");
- desc->properties()->add(new Property("dump_spec", buffer));
-
- if (node->is_block_proj()) {
- desc->properties()->add(new Property("is_block_proj", "true"));
- }
-
- if (node->is_block_start()) {
- desc->properties()->add(new Property("is_block_start", "true"));
- }
-
- const char *short_name = "short_name";
- if (strcmp(node->Name(), "Parm") == 0 && node->as_Proj()->_con >= TypeFunc::Parms) {
- int index = node->as_Proj()->_con - TypeFunc::Parms;
- if (index >= 10) {
- desc->properties()->add(new Property(short_name, "PA"));
- } else {
- sprintf(buffer, "P%d", index);
- desc->properties()->add(new Property(short_name, buffer));
- }
- } else if (strcmp(node->Name(), "IfTrue") == 0) {
- desc->properties()->add(new Property(short_name, "T"));
- } else if (strcmp(node->Name(), "IfFalse") == 0) {
- desc->properties()->add(new Property(short_name, "F"));
- } else if ((node->is_Con() && node->is_Type()) || node->is_Proj()) {
-
- if (t->base() == Type::Int && t->is_int()->is_con()) {
- const TypeInt *typeInt = t->is_int();
- assert(typeInt->is_con(), "must be constant");
- jint value = typeInt->get_con();
-
- // max. 2 chars allowed
- if (value >= -9 && value <= 99) {
- sprintf(buffer, "%d", value);
- desc->properties()->add(new Property(short_name, buffer));
- }
- else
- {
- desc->properties()->add(new Property(short_name, "I"));
- }
- } else if (t == Type::TOP) {
- desc->properties()->add(new Property(short_name, "^"));
- } else if (t->base() == Type::Long && t->is_long()->is_con()) {
- const TypeLong *typeLong = t->is_long();
- assert(typeLong->is_con(), "must be constant");
- jlong value = typeLong->get_con();
-
- // max. 2 chars allowed
- if (value >= -9 && value <= 99) {
- sprintf(buffer, "%d", value);
- desc->properties()->add(new Property(short_name, buffer));
- }
- else
- {
- desc->properties()->add(new Property(short_name, "L"));
- }
- } else if (t->base() == Type::KlassPtr) {
- const TypeKlassPtr *typeKlass = t->is_klassptr();
- desc->properties()->add(new Property(short_name, "CP"));
- } else if (t->base() == Type::Control) {
- desc->properties()->add(new Property(short_name, "C"));
- } else if (t->base() == Type::Memory) {
- desc->properties()->add(new Property(short_name, "M"));
- } else if (t->base() == Type::Abio) {
- desc->properties()->add(new Property(short_name, "IO"));
- } else if (t->base() == Type::Return_Address) {
- desc->properties()->add(new Property(short_name, "RA"));
- } else if (t->base() == Type::AnyPtr) {
- desc->properties()->add(new Property(short_name, "P"));
- } else if (t->base() == Type::RawPtr) {
- desc->properties()->add(new Property(short_name, "RP"));
- } else if (t->base() == Type::AryPtr) {
- desc->properties()->add(new Property(short_name, "AP"));
- }
- }
-
- if (node->is_SafePoint()) {
- SafePointNode *safePointNode = node->as_SafePoint();
- if (safePointNode->jvms()) {
- stringStream bciStream;
- bciStream.print("%d ", safePointNode->jvms()->bci());
- JVMState *caller = safePointNode->jvms()->caller();
- while(caller) {
- bciStream.print("%d ", caller->bci());
-
- caller = caller->caller();
- }
- desc->properties()->add(new Property("bci", bciStream.as_string()));
- }
- }
-
- if (_chaitin && _chaitin != (PhaseChaitin *)0xdeadbeef) {
- buffer[0] = 0;
- _chaitin->dump_register(node, buffer);
- desc->properties()->add(new Property("reg", buffer));
- desc->properties()->add(new Property("lrg", _chaitin->n2lidx(node)));
- }
-
-
- node->_in_dump_cnt--;
- return desc;
-#else
- return NULL;
-#endif
-}
-
-void IdealGraphPrinter::pre_node(Node* node, void *env) {
-
- IdealGraphPrinter *printer = (IdealGraphPrinter *)env;
-
- NodeDescription *newDesc = printer->create_node_description(node);
-
- if (printer->_clear_nodes) {
-
- printer->_nodes.append(newDesc);
- } else {
-
- NodeDescription *desc = printer->_nodes.at_grow(node->_idx, NULL);
-
- if (desc && desc->equals(newDesc)) {
- //desc->set_state(Valid);
- //desc->set_node(node);
- delete desc;
- printer->_nodes.at_put(node->_idx, NULL);
- newDesc->set_state(Valid);
- //printer->_nodes.at_put(node->_idx, newDesc);
- } else {
-
- if (desc && desc->id() == newDesc->id()) {
- delete desc;
- printer->_nodes.at_put(node->_idx, NULL);
- newDesc->set_state(New);
-
- }
-
- //if (desc) {
- // delete desc;
- //}
-
- //printer->_nodes.at_put(node->_idx, newDesc);
- }
-
- printer->_nodes.append(newDesc);
- }
-}
-
-void IdealGraphPrinter::post_node(Node* node, void *env) {
-}
-
-outputStream *IdealGraphPrinter::output() {
- return _output;
-}
-
-IdealGraphPrinter::Description::Description() {
- _state = New;
-}
-
-void IdealGraphPrinter::Description::print(IdealGraphPrinter *printer) {
- if (_state == Invalid) {
- print_removed(printer);
- } else if (_state == New) {
- print_changed(printer);
- }
-}
-
-void IdealGraphPrinter::Description::set_state(State s) {
- _state = s;
-}
-
-IdealGraphPrinter::State IdealGraphPrinter::Description::state() {
- return _state;
-}
-
-void IdealGraphPrinter::Block::set_proj(NodeDescription *n) {
- _proj = n;
-}
-
-void IdealGraphPrinter::Block::set_start(NodeDescription *n) {
- _start = n;
-}
-
-int IdealGraphPrinter::Block::semi() {
- return _semi;
-}
-
-int IdealGraphPrinter::Block::parent() {
- return _parent;
-}
-
-GrowableArray<int>* IdealGraphPrinter::Block::bucket() {
- return &_bucket;
-}
-
-GrowableArray<int>* IdealGraphPrinter::Block::children() {
- return &_children;
-}
-
-void IdealGraphPrinter::Block::add_child(int i) {
- _children.append(i);
-}
-
-GrowableArray<int>* IdealGraphPrinter::Block::dominates() {
- return &_dominates;
-}
-
-void IdealGraphPrinter::Block::add_dominates(int i) {
- _dominates.append(i);
-}
-
-void IdealGraphPrinter::Block::add_to_bucket(int i) {
- _bucket.append(i);
-}
-
-void IdealGraphPrinter::Block::clear_bucket() {
- _bucket.clear();
-}
-
-void IdealGraphPrinter::Block::set_dominator(int i) {
- _dominator = i;
-}
-
-void IdealGraphPrinter::Block::set_label(int i) {
- _label = i;
-}
-
-int IdealGraphPrinter::Block::label() {
- return _label;
-}
-
-int IdealGraphPrinter::Block::ancestor() {
- return _ancestor;
-}
-
-void IdealGraphPrinter::Block::set_ancestor(int i) {
- _ancestor = i;
-}
-
-int IdealGraphPrinter::Block::dominator() {
- return _dominator;
-}
-
-int IdealGraphPrinter::Block::index() {
- return _index;
-}
-
-void IdealGraphPrinter::Block::set_parent(int i) {
- _parent = i;
-}
-
-GrowableArray<int>* IdealGraphPrinter::Block::pred() {
- return &_pred;
-}
-
-void IdealGraphPrinter::Block::set_semi(int i) {
- _semi = i;
-}
-
-IdealGraphPrinter::Block::Block() {
-}
-
-IdealGraphPrinter::Block::Block(int index) {
- _index = index;
- _label = index;
- _semi = -1;
- _ancestor = -1;
- _dominator = -1;
-}
-
-void IdealGraphPrinter::Block::add_pred(int i) {
- _pred.append(i);
-}
-
-IdealGraphPrinter::NodeDescription *IdealGraphPrinter::Block::proj() {
- return _proj;
-}
-
-IdealGraphPrinter::NodeDescription *IdealGraphPrinter::Block::start() {
- return _start;
-}
-
-GrowableArray<int>* IdealGraphPrinter::Block::succs() {
- return &_succs;
-}
-
-void IdealGraphPrinter::Block::add_succ(int index) {
-
- if (this->_index == 16 && index == 15) {
- int x = 0;
- }
-
- if (!_succs.contains(index)) {
- _succs.append(index);
- }
-}
-
-
-void IdealGraphPrinter::Block::add_node(NodeDescription *n) {
- if (!_nodes.contains(n)) {
- _nodes.append(n);
- }
-}
-
-GrowableArray<IdealGraphPrinter::NodeDescription *>* IdealGraphPrinter::Block::nodes() {
- return &_nodes;
-}
-
-int IdealGraphPrinter::NodeDescription::count = 0;
-
-IdealGraphPrinter::NodeDescription::NodeDescription(Node* node) : _node(node) {
- _id = (intptr_t)(node);
- _block_index = -1;
-}
-
-IdealGraphPrinter::NodeDescription::~NodeDescription() {
- _properties.clean();
-}
-
-// void IdealGraphPrinter::NodeDescription::set_node(Node* node) {
-// //this->_node = node;
-// }
-
-int IdealGraphPrinter::NodeDescription::block_index() {
- return _block_index;
-}
-
-
-GrowableArray<IdealGraphPrinter::NodeDescription *>* IdealGraphPrinter::NodeDescription::succs() {
- return &_succs;
-}
-
-void IdealGraphPrinter::NodeDescription::clear_succs() {
- _succs.clear();
-}
-
-void IdealGraphPrinter::NodeDescription::init_succs() {
- _succs = GrowableArray<NodeDescription *>();
-}
-
-void IdealGraphPrinter::NodeDescription::add_succ(NodeDescription *desc) {
- _succs.append(desc);
-}
-
-void IdealGraphPrinter::NodeDescription::set_block_index(int i) {
- _block_index = i;
-}
-
-bool IdealGraphPrinter::NodeDescription::equals(NodeDescription *desc) {
- if (desc == NULL) return false;
- if (desc->id() != id()) return false;
- return properties()->equals(desc->properties());
-}
-
-Node* IdealGraphPrinter::NodeDescription::node() {
- return _node;
-}
-
-IdealGraphPrinter::Properties* IdealGraphPrinter::NodeDescription::properties() {
- return &_properties;
-}
-
-uint IdealGraphPrinter::NodeDescription::id() {
- return _id;
-}
-
-void IdealGraphPrinter::NodeDescription::print_changed(IdealGraphPrinter *printer) {
-
-
- Properties properties;
- properties.add(new Property(NODE_ID_PROPERTY, id()));
- printer->start_element(NODE_ELEMENT, &properties);
-
- this->properties()->print(printer);
-
-
- printer->end_element(NODE_ELEMENT);
-}
-
-void IdealGraphPrinter::NodeDescription::print_removed(IdealGraphPrinter *printer) {
-
- Properties properties;
- properties.add(new Property(NODE_ID_PROPERTY, id()));
- printer->simple_element(REMOVE_NODE_ELEMENT, &properties);
-}
-
-IdealGraphPrinter::EdgeDescription::EdgeDescription(int from, int to, int index) {
- this->_from = from;
- this->_to = to;
- this->_index = index;
-}
-
-IdealGraphPrinter::EdgeDescription::~EdgeDescription() {
-}
-
-int IdealGraphPrinter::EdgeDescription::from() {
- return _from;
-}
-
-int IdealGraphPrinter::EdgeDescription::to() {
- return _to;
-}
-
-void IdealGraphPrinter::EdgeDescription::print_changed(IdealGraphPrinter *printer) {
-
- Properties properties;
- properties.add(new Property(INDEX_PROPERTY, _index));
- properties.add(new Property(FROM_PROPERTY, _from));
- properties.add(new Property(TO_PROPERTY, _to));
- printer->simple_element(EDGE_ELEMENT, &properties);
-}
-
-void IdealGraphPrinter::EdgeDescription::print_removed(IdealGraphPrinter *printer) {
-
- Properties properties;
- properties.add(new Property(INDEX_PROPERTY, _index));
- properties.add(new Property(FROM_PROPERTY, _from));
- properties.add(new Property(TO_PROPERTY, _to));
- printer->simple_element(REMOVE_EDGE_ELEMENT, &properties);
-}
-
-bool IdealGraphPrinter::EdgeDescription::equals(IdealGraphPrinter::EdgeDescription *desc) {
- if (desc == NULL) return false;
- return (_from == desc->_from && _to == desc->_to && _index == desc->_index);
-}
-
-IdealGraphPrinter::Properties::Properties() : list(new (ResourceObj::C_HEAP) GrowableArray<Property *>(2, 0, NULL, true)) {
-}
-
-IdealGraphPrinter::Properties::~Properties() {
- clean();
- delete list;
-}
-
-void IdealGraphPrinter::Properties::add(Property *p) {
- assert(p != NULL, "Property not NULL");
- list->append(p);
-}
-
-void IdealGraphPrinter::Properties::print(IdealGraphPrinter *printer) {
- printer->start_element(PROPERTIES_ELEMENT);
-
- for (int i = 0; i < list->length(); i++) {
- list->at(i)->print(printer);
- }
-
- printer->end_element(PROPERTIES_ELEMENT);
-}
-
-void IdealGraphPrinter::Properties::clean() {
- for (int i = 0; i < list->length(); i++) {
- delete list->at(i);
- list->at_put(i, NULL);
- }
- list->clear();
- assert(list->length() == 0, "List cleared");
-}
-
-void IdealGraphPrinter::Properties::remove(const char *name) {
- for (int i = 0; i < list->length(); i++) {
- if (strcmp(list->at(i)->name(), name) == 0) {
- delete list->at(i);
- list->remove_at(i);
- i--;
- }
- }
-}
-
-void IdealGraphPrinter::Properties::print_as_attributes(IdealGraphPrinter *printer) {
-
- for (int i = 0; i < list->length(); i++) {
- assert(list->at(i) != NULL, "Property not null!");
- printer->output()->print(" ");
- list->at(i)->print_as_attribute(printer);
- }
-}
-
-bool IdealGraphPrinter::Properties::equals(Properties* p) {
- if (p->list->length() != this->list->length()) return false;
-
- for (int i = 0; i < list->length(); i++) {
- assert(list->at(i) != NULL, "Property not null!");
- if (!list->at(i)->equals(p->list->at(i))) return false;
- }
-
- return true;
-}
-
-IdealGraphPrinter::Property::Property() {
- _name = NULL;
- _value = NULL;
-}
-
-const char *IdealGraphPrinter::Property::name() {
- return _name;
-}
-
-IdealGraphPrinter::Property::Property(const Property* p) {
-
- this->_name = NULL;
- this->_value = NULL;
-
- if (p->_name != NULL) {
- _name = dup(p->_name);
- }
-
- if (p->_value) {
- _value = dup(p->_value);
- }
-}
-
-IdealGraphPrinter::Property::~Property() {
-
- clean();
-}
-
-IdealGraphPrinter::Property::Property(const char *name, const char *value) {
-
- assert(name, "Name must not be null!");
- assert(value, "Value must not be null!");
-
- _name = dup(name);
- _value = dup(value);
-}
-
-IdealGraphPrinter::Property::Property(const char *name, int intValue) {
- _name = dup(name);
-
- stringStream stream;
- stream.print("%d", intValue);
- _value = dup(stream.as_string());
-}
-
-void IdealGraphPrinter::Property::clean() {
- if (_name) {
- delete _name;
- _name = NULL;
- }
-
- if (_value) {
- delete _value;
- _value = NULL;
- }
-}
-
-
-bool IdealGraphPrinter::Property::is_null() {
- return _name == NULL;
-}
-
-void IdealGraphPrinter::Property::print(IdealGraphPrinter *printer) {
-
- assert(!is_null(), "null properties cannot be printed!");
- Properties properties;
- properties.add(new Property(PROPERTY_NAME_PROPERTY, _name));
- printer->start_element(PROPERTY_ELEMENT, &properties, false, false);
- printer->print_xml(_value);
- printer->end_element(PROPERTY_ELEMENT, false, true);
-}
-
-void IdealGraphPrinter::Property::print_as_attribute(IdealGraphPrinter *printer) {
-
- printer->output()->print(_name);
- printer->output()->print("=\"");
- printer->print_xml(_value);
- printer->output()->print("\"");
-}
-
-
-bool IdealGraphPrinter::Property::equals(Property* p) {
-
- if (is_null() && p->is_null()) return true;
- if (is_null()) return false;
- if (p->is_null()) return false;
-
- int cmp1 = strcmp(p->_name, _name);
- if (cmp1 != 0) return false;
-
- int cmp2 = strcmp(p->_value, _value);
- if (cmp2 != 0) return false;
-
- return true;
-}
-
-void IdealGraphPrinter::print_xml(const char *value) {
- size_t len = strlen(value);
-
- char buf[2];
- buf[1] = 0;
- for (size_t i = 0; i < len; i++) {
- char c = value[i];
-
- switch(c) {
- case '<':
- output()->print("<");
- break;
-
- case '>':
- output()->print(">");
- break;
-
- default:
- buf[0] = c;
- output()->print(buf);
- break;
- }
- }
-}
-
-#endif
--- a/src/share/vm/opto/idealGraphPrinter.hpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/idealGraphPrinter.hpp Tue Jul 01 11:59:44 2008 -0700
@@ -82,222 +82,42 @@ private:
static const char *METHOD_SHORT_NAME_PROPERTY;
static const char *ASSEMBLY_ELEMENT;
- class Property {
-
- private:
-
- const char *_name;
- const char *_value;
-
- public:
-
- Property();
- Property(const Property* p);
- ~Property();
- Property(const char *name, const char *value);
- Property(const char *name, int value);
- bool equals(Property* p);
- void print(IdealGraphPrinter *printer);
- void print_as_attribute(IdealGraphPrinter *printer);
- bool is_null();
- void clean();
- const char *name();
-
- static const char* dup(const char *str) {
- char * copy = new char[strlen(str)+1];
- strcpy(copy, str);
- return copy;
- }
-
- };
-
- class Properties {
-
- private:
-
- GrowableArray<Property *> *list;
-
- public:
-
- Properties();
- ~Properties();
- void add(Property *p);
- void remove(const char *name);
- bool equals(Properties* p);
- void print(IdealGraphPrinter *printer);
- void print_as_attributes(IdealGraphPrinter *printer);
- void clean();
-
- };
-
-
- class Description {
-
- private:
-
- State _state;
-
- public:
-
- Description();
-
- State state();
- void set_state(State s);
- void print(IdealGraphPrinter *printer);
- virtual void print_changed(IdealGraphPrinter *printer) = 0;
- virtual void print_removed(IdealGraphPrinter *printer) = 0;
-
- };
-
- class NodeDescription : public Description{
-
- public:
-
- static int count;
-
- private:
-
- GrowableArray<NodeDescription *> _succs;
- int _block_index;
- uintptr_t _id;
- Properties _properties;
- Node* _node;
-
- public:
-
- NodeDescription(Node* node);
- ~NodeDescription();
- Node* node();
-
- // void set_node(Node* node);
- GrowableArray<NodeDescription *>* succs();
- void init_succs();
- void clear_succs();
- void add_succ(NodeDescription *desc);
- int block_index();
- void set_block_index(int i);
- Properties* properties();
- virtual void print_changed(IdealGraphPrinter *printer);
- virtual void print_removed(IdealGraphPrinter *printer);
- bool equals(NodeDescription *desc);
- uint id();
-
- };
-
- class Block {
-
- private:
-
- NodeDescription *_start;
- NodeDescription *_proj;
- GrowableArray<int> _succs;
- GrowableArray<NodeDescription *> _nodes;
- GrowableArray<int> _dominates;
- GrowableArray<int> _children;
- int _semi;
- int _parent;
- GrowableArray<int> _pred;
- GrowableArray<int> _bucket;
- int _index;
- int _dominator;
- int _ancestor;
- int _label;
-
- public:
-
- Block();
- Block(int index);
-
- void add_node(NodeDescription *n);
- GrowableArray<NodeDescription *>* nodes();
- GrowableArray<int>* children();
- void add_child(int i);
- void add_succ(int index);
- GrowableArray<int>* succs();
- GrowableArray<int>* dominates();
- void add_dominates(int i);
- NodeDescription *start();
- NodeDescription *proj();
- void set_start(NodeDescription *n);
- void set_proj(NodeDescription *n);
-
- int label();
- void set_label(int i);
- int ancestor();
- void set_ancestor(int i);
- int index();
- int dominator();
- void set_dominator(int i);
- int parent();
- void set_parent(int i);
- int semi();
- GrowableArray<int>* bucket();
- void add_to_bucket(int i);
- void clear_bucket();
- GrowableArray<int>* pred();
- void set_semi(int i);
- void add_pred(int i);
-
- };
-
- class EdgeDescription : public Description {
-
- private:
-
- int _from;
- int _to;
- int _index;
- public:
-
- EdgeDescription(int from, int to, int index);
- ~EdgeDescription();
-
- virtual void print_changed(IdealGraphPrinter *printer);
- virtual void print_removed(IdealGraphPrinter *printer);
- bool equals(EdgeDescription *desc);
- int from();
- int to();
- };
-
+ elapsedTimer _walk_time;
+ elapsedTimer _output_time;
+ elapsedTimer _build_blocks_time;
static int _file_count;
networkStream *_stream;
+ xmlStream *_xml;
outputStream *_output;
ciMethod *_current_method;
- GrowableArray<NodeDescription *> _nodes;
- GrowableArray<EdgeDescription *> _edges;
int _depth;
- Arena *_arena;
char buffer[128];
bool _should_send_method;
PhaseChaitin* _chaitin;
- bool _clear_nodes;
- Matcher* _matcher;
bool _traverse_outs;
-
- void start_element_helper(const char *name, Properties *properties, bool endElement, bool print_indent = false, bool print_return = true);
- NodeDescription *create_node_description(Node* node);
+ Compile *C;
static void pre_node(Node* node, void *env);
static void post_node(Node* node, void *env);
- void schedule_latest(int **common_dominator, GrowableArray<Block>* blocks);
- void build_common_dominator(int **common_dominator, int index, GrowableArray<Block>* blocks);
- void compress(int index, GrowableArray<Block>* blocks);
- int eval(int index, GrowableArray<Block>* blocks);
- void link(int index1, int index2, GrowableArray<Block>* blocks);
- void build_dominators(GrowableArray<Block>* blocks);
- void build_blocks(Node *node);
- void walk(Node *n);
- void start_element(const char *name, Properties *properties = NULL, bool print_indent = false, bool print_return = true);
- void simple_element(const char *name, Properties *properties = NULL, bool print_indent = false);
- void end_element(const char *name, bool print_indent = false, bool print_return = true);
- void print_edge(int from, int to, int index);
void print_indent();
void print_method(ciMethod *method, int bci, InlineTree *tree);
void print_inline_tree(InlineTree *tree);
- void clear_nodes();
-
+ void visit_node(Node *n, void *param);
+ void walk_nodes(Node *start, void *param);
+ void begin_elem(const char *s);
+ void end_elem();
+ void begin_head(const char *s);
+ void end_head();
+ void print_attr(const char *name, const char *val);
+ void print_attr(const char *name, intptr_t val);
+ void print_prop(const char *name, const char *val);
+ void print_prop(const char *name, int val);
+ void tail(const char *name);
+ void head(const char *name);
+ void text(const char *s);
+ intptr_t get_node_id(Node *n);
IdealGraphPrinter();
~IdealGraphPrinter();
@@ -308,7 +128,6 @@ public:
bool traverse_outs();
void set_traverse_outs(bool b);
- void print_ifg(PhaseIFG* ifg);
outputStream *output();
void print_inlining(Compile* compile);
void begin_method(Compile* compile);
--- a/src/share/vm/opto/library_call.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/library_call.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -2194,14 +2194,15 @@ bool LibraryCallKit::inline_unsafe_CAS(B
pre_barrier(control(), base, adr, alias_idx, newval, value_type, T_OBJECT);
#ifdef _LP64
if (adr->bottom_type()->is_ptr_to_narrowoop()) {
+ Node *newval_enc = _gvn.transform(new (C, 2) EncodePNode(newval, newval->bottom_type()->make_narrowoop()));
+ Node *oldval_enc = _gvn.transform(new (C, 2) EncodePNode(oldval, oldval->bottom_type()->make_narrowoop()));
cas = _gvn.transform(new (C, 5) CompareAndSwapNNode(control(), mem, adr,
- EncodePNode::encode(&_gvn, newval),
- EncodePNode::encode(&_gvn, oldval)));
+ newval_enc, oldval_enc));
} else
#endif
- {
- cas = _gvn.transform(new (C, 5) CompareAndSwapPNode(control(), mem, adr, newval, oldval));
- }
+ {
+ cas = _gvn.transform(new (C, 5) CompareAndSwapPNode(control(), mem, adr, newval, oldval));
+ }
post_barrier(control(), cas, base, adr, alias_idx, newval, T_OBJECT, true);
break;
default:
--- a/src/share/vm/opto/loopTransform.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/loopTransform.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -690,7 +690,7 @@ void PhaseIdealLoop::insert_pre_post_loo
// (the main-loop trip-counter exit value) because we will be changing
// the exit value (via unrolling) so we cannot constant-fold away the zero
// trip guard until all unrolling is done.
- Node *zer_opaq = new (C, 2) Opaque1Node(incr);
+ Node *zer_opaq = new (C, 2) Opaque1Node(C, incr);
Node *zer_cmp = new (C, 3) CmpINode( zer_opaq, limit );
Node *zer_bol = new (C, 2) BoolNode( zer_cmp, b_test );
register_new_node( zer_opaq, new_main_exit );
@@ -760,7 +760,7 @@ void PhaseIdealLoop::insert_pre_post_loo
// pre-loop, the main-loop may not execute at all. Later in life this
// zero-trip guard will become the minimum-trip guard when we unroll
// the main-loop.
- Node *min_opaq = new (C, 2) Opaque1Node(limit);
+ Node *min_opaq = new (C, 2) Opaque1Node(C, limit);
Node *min_cmp = new (C, 3) CmpINode( pre_incr, min_opaq );
Node *min_bol = new (C, 2) BoolNode( min_cmp, b_test );
register_new_node( min_opaq, new_pre_exit );
@@ -810,7 +810,7 @@ void PhaseIdealLoop::insert_pre_post_loo
// Save the original loop limit in this Opaque1 node for
// use by range check elimination.
- Node *pre_opaq = new (C, 3) Opaque1Node(pre_limit, limit);
+ Node *pre_opaq = new (C, 3) Opaque1Node(C, pre_limit, limit);
register_new_node( pre_limit, pre_head->in(0) );
register_new_node( pre_opaq , pre_head->in(0) );
--- a/src/share/vm/opto/loopUnswitch.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/loopUnswitch.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -205,7 +205,7 @@ ProjNode* PhaseIdealLoop::create_slow_ve
Node *cont = _igvn.intcon(1);
set_ctrl(cont, C->root());
- Node* opq = new (C, 2) Opaque1Node(cont);
+ Node* opq = new (C, 2) Opaque1Node(C, cont);
register_node(opq, outer_loop, entry, dom_depth(entry));
Node *bol = new (C, 2) Conv2BNode(opq);
register_node(bol, outer_loop, entry, dom_depth(entry));
--- a/src/share/vm/opto/loopnode.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/loopnode.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -1071,8 +1071,6 @@ bool IdealLoopTree::beautify_loops( Phas
for (DUIterator_Fast imax, i = l->fast_outs(imax); i < imax; i++)
phase->_igvn.add_users_to_worklist(l->fast_out(i));
}
-
- phase->C->print_method("After beautify loops", 3);
// Now recursively beautify nested loops
if( _child ) result |= _child->beautify_loops( phase );
@@ -1470,6 +1468,8 @@ PhaseIdealLoop::PhaseIdealLoop( PhaseIte
}
// Reset loop nesting depth
_ltree_root->set_nest( 0 );
+
+ C->print_method("After beautify loops", 3);
}
}
--- a/src/share/vm/opto/loopopts.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/loopopts.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -41,7 +41,7 @@ Node *PhaseIdealLoop::split_thru_phi( No
const Type* type = n->bottom_type();
const TypeOopPtr *t_oop = _igvn.type(n)->isa_oopptr();
Node *phi;
- if( t_oop != NULL && t_oop->is_instance_field() ) {
+ if( t_oop != NULL && t_oop->is_known_instance_field() ) {
int iid = t_oop->instance_id();
int index = C->get_alias_index(t_oop);
int offset = t_oop->offset();
@@ -2685,7 +2685,7 @@ void PhaseIdealLoop::reorg_offsets( Idea
if( !cle->stride_is_con() ) continue;
// Hit! Refactor use to use the post-incremented tripcounter.
// Compute a post-increment tripcounter.
- Node *opaq = new (C, 2) Opaque2Node( cle->incr() );
+ Node *opaq = new (C, 2) Opaque2Node( C, cle->incr() );
register_new_node( opaq, u_ctrl );
Node *neg_stride = _igvn.intcon(-cle->stride_con());
set_ctrl(neg_stride, C->root());
--- a/src/share/vm/opto/machnode.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/machnode.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -262,17 +262,19 @@ const Node* MachNode::get_base_and_disp(
// Now we have collected every part of the ADLC MEMORY_INTER.
// See if it adds up to a base + offset.
if (index != NULL) {
- if (!index->is_Con()) {
- const TypeNarrowOop* narrowoop = index->bottom_type()->isa_narrowoop();
- if (narrowoop != NULL) {
- // Memory references through narrow oops have a
- // funny base so grab the type from the index.
- adr_type = narrowoop->make_oopptr();
- return NULL;
- }
+ const Type* t_index = index->bottom_type();
+ if (t_index->isa_narrowoop()) { // EncodeN, LoadN, LoadConN, LoadNKlass.
+ // Memory references through narrow oops have a
+ // funny base so grab the type from the index:
+ // [R12 + narrow_oop_reg<<3 + offset]
+ assert(base == NULL, "Memory references through narrow oops have no base");
+ offset = disp;
+ adr_type = t_index->make_ptr()->add_offset(offset);
+ return NULL;
+ } else if (!index->is_Con()) {
disp = Type::OffsetBot;
} else if (disp != Type::OffsetBot) {
- const TypeX* ti = index->bottom_type()->isa_intptr_t();
+ const TypeX* ti = t_index->isa_intptr_t();
if (ti == NULL) {
disp = Type::OffsetBot; // a random constant??
} else {
--- a/src/share/vm/opto/macro.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/macro.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -320,9 +320,9 @@ Node *PhaseMacroExpand::value_from_mem_p
// Search the last value stored into the object's field.
Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc) {
- assert(adr_t->is_instance_field(), "instance required");
- uint instance_id = adr_t->instance_id();
- assert(instance_id == alloc->_idx, "wrong allocation");
+ assert(adr_t->is_known_instance_field(), "instance required");
+ int instance_id = adr_t->instance_id();
+ assert((uint)instance_id == alloc->_idx, "wrong allocation");
int alias_idx = C->get_alias_index(adr_t);
int offset = adr_t->offset();
@@ -354,7 +354,7 @@ Node *PhaseMacroExpand::value_from_mem(N
const TypeOopPtr* atype = mem->as_Store()->adr_type()->isa_oopptr();
assert(atype != NULL, "address type must be oopptr");
assert(C->get_alias_index(atype) == alias_idx &&
- atype->is_instance_field() && atype->offset() == offset &&
+ atype->is_known_instance_field() && atype->offset() == offset &&
atype->instance_id() == instance_id, "store is correct memory slice");
done = true;
} else if (mem->is_Phi()) {
@@ -598,7 +598,7 @@ bool PhaseMacroExpand::scalar_replacemen
field_type = TypeOopPtr::make_from_klass(elem_type->as_klass());
}
if (UseCompressedOops) {
- field_type = field_type->is_oopptr()->make_narrowoop();
+ field_type = field_type->make_narrowoop();
basic_elem_type = T_NARROWOOP;
}
} else {
@@ -666,9 +666,11 @@ bool PhaseMacroExpand::scalar_replacemen
if (UseCompressedOops && field_type->isa_narrowoop()) {
// Enable "DecodeN(EncodeP(Allocate)) --> Allocate" transformation
// to be able scalar replace the allocation.
- _igvn.set_delay_transform(false);
- field_val = DecodeNNode::decode(&_igvn, field_val);
- _igvn.set_delay_transform(true);
+ if (field_val->is_EncodeP()) {
+ field_val = field_val->in(1);
+ } else {
+ field_val = transform_later(new (C, 2) DecodeNNode(field_val, field_val->bottom_type()->make_ptr()));
+ }
}
sfpt->add_req(field_val);
}
@@ -1676,7 +1678,14 @@ bool PhaseMacroExpand::expand_macro_node
success = eliminate_locking_node(n->as_AbstractLock());
break;
default:
- assert(false, "unknown node type in macro list");
+ if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
+ _igvn.add_users_to_worklist(n);
+ _igvn.hash_delete(n);
+ _igvn.subsume_node(n, n->in(1));
+ success = true;
+ } else {
+ assert(false, "unknown node type in macro list");
+ }
}
assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
progress = progress || success;
--- a/src/share/vm/opto/matcher.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/matcher.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -51,6 +51,7 @@ Matcher::Matcher( Node_List &proj_list )
PhaseTransform( Phase::Ins_Select ),
#ifdef ASSERT
_old2new_map(C->comp_arena()),
+ _new2old_map(C->comp_arena()),
#endif
_shared_nodes(C->comp_arena()),
_reduceOp(reduceOp), _leftOp(leftOp), _rightOp(rightOp),
@@ -82,6 +83,7 @@ Matcher::Matcher( Node_List &proj_list )
idealreg2debugmask[Op_RegF] = NULL;
idealreg2debugmask[Op_RegD] = NULL;
idealreg2debugmask[Op_RegP] = NULL;
+ debug_only(_mem_node = NULL;) // Ideal memory node consumed by mach node
}
//------------------------------warp_incoming_stk_arg------------------------
@@ -834,10 +836,16 @@ Node *Matcher::xform( Node *n, int max_s
if( n->is_Proj() && n->in(0)->is_Multi()) { // Projections?
// Convert to machine-dependent projection
m = n->in(0)->as_Multi()->match( n->as_Proj(), this );
+#ifdef ASSERT
+ _new2old_map.map(m->_idx, n);
+#endif
if (m->in(0) != NULL) // m might be top
collect_null_checks(m);
} else { // Else just a regular 'ol guy
m = n->clone(); // So just clone into new-space
+#ifdef ASSERT
+ _new2old_map.map(m->_idx, n);
+#endif
// Def-Use edges will be added incrementally as Uses
// of this node are matched.
assert(m->outcnt() == 0, "no Uses of this clone yet");
@@ -886,6 +894,9 @@ Node *Matcher::xform( Node *n, int max_s
// || op == Op_BoxLock // %%%% enable this and remove (+++) in chaitin.cpp
) {
m = m->clone();
+#ifdef ASSERT
+ _new2old_map.map(m->_idx, n);
+#endif
mstack.push(m, Post_Visit, n, i); // Don't neet to visit
mstack.push(m->in(0), Visit, m, 0);
} else {
@@ -1153,7 +1164,10 @@ MachNode *Matcher::match_tree( const Nod
// StoreNodes require their Memory input to match any LoadNodes
Node *mem = n->is_Store() ? n->in(MemNode::Memory) : (Node*)1 ;
-
+#ifdef ASSERT
+ Node* save_mem_node = _mem_node;
+ _mem_node = n->is_Store() ? (Node*)n : NULL;
+#endif
// State object for root node of match tree
// Allocate it on _states_arena - stack allocation can cause stack overflow.
State *s = new (&_states_arena) State;
@@ -1186,6 +1200,7 @@ MachNode *Matcher::match_tree( const Nod
MachNode *m = ReduceInst( s, s->_rule[mincost], mem );
#ifdef ASSERT
_old2new_map.map(n->_idx, m);
+ _new2old_map.map(m->_idx, (Node*)n);
#endif
// Add any Matcher-ignored edges
@@ -1205,6 +1220,7 @@ MachNode *Matcher::match_tree( const Nod
}
}
+ debug_only( _mem_node = save_mem_node; )
return m;
}
@@ -1445,8 +1461,30 @@ MachNode *Matcher::ReduceInst( State *s,
}
// If a Memory was used, insert a Memory edge
- if( mem != (Node*)1 )
+ if( mem != (Node*)1 ) {
mach->ins_req(MemNode::Memory,mem);
+#ifdef ASSERT
+ // Verify adr type after matching memory operation
+ const MachOper* oper = mach->memory_operand();
+ if (oper != NULL && oper != (MachOper*)-1 &&
+ mach->adr_type() != TypeRawPtr::BOTTOM) { // non-direct addressing mode
+ // It has a unique memory operand. Find corresponding ideal mem node.
+ Node* m = NULL;
+ if (leaf->is_Mem()) {
+ m = leaf;
+ } else {
+ m = _mem_node;
+ assert(m != NULL && m->is_Mem(), "expecting memory node");
+ }
+ if (m->adr_type() != mach->adr_type()) {
+ m->dump();
+ tty->print_cr("mach:");
+ mach->dump(1);
+ }
+ assert(m->adr_type() == mach->adr_type(), "matcher should not change adr type");
+ }
+#endif
+ }
// If the _leaf is an AddP, insert the base edge
if( leaf->is_AddP() )
@@ -1464,6 +1502,9 @@ MachNode *Matcher::ReduceInst( State *s,
for( uint i=0; i<mach->req(); i++ ) {
mach->set_req(i,NULL);
}
+#ifdef ASSERT
+ _new2old_map.map(ex->_idx, s->_leaf);
+#endif
}
// PhaseChaitin::fixup_spills will sometimes generate spill code
@@ -1510,7 +1551,9 @@ void Matcher::ReduceInst_Chain_Rule( Sta
assert( newrule >= _LAST_MACH_OPER, "Do NOT chain from internal operand");
mach->_opnds[1] = s->MachOperGenerator( _reduceOp[catch_op], C );
Node *mem1 = (Node*)1;
+ debug_only(Node *save_mem_node = _mem_node;)
mach->add_req( ReduceInst(s, newrule, mem1) );
+ debug_only(_mem_node = save_mem_node;)
}
return;
}
@@ -1520,6 +1563,7 @@ uint Matcher::ReduceInst_Interior( State
if( s->_leaf->is_Load() ) {
Node *mem2 = s->_leaf->in(MemNode::Memory);
assert( mem == (Node*)1 || mem == mem2, "multiple Memories being matched at once?" );
+ debug_only( if( mem == (Node*)1 ) _mem_node = s->_leaf;)
mem = mem2;
}
if( s->_leaf->in(0) != NULL && s->_leaf->req() > 1) {
@@ -1563,7 +1607,9 @@ uint Matcher::ReduceInst_Interior( State
// --> ReduceInst( newrule )
mach->_opnds[num_opnds++] = s->MachOperGenerator( _reduceOp[catch_op], C );
Node *mem1 = (Node*)1;
+ debug_only(Node *save_mem_node = _mem_node;)
mach->add_req( ReduceInst( newstate, newrule, mem1 ) );
+ debug_only(_mem_node = save_mem_node;)
}
}
assert( mach->_opnds[num_opnds-1], "" );
@@ -1594,6 +1640,7 @@ void Matcher::ReduceOper( State *s, int
if( s->_leaf->is_Load() ) {
assert( mem == (Node*)1, "multiple Memories being matched at once?" );
mem = s->_leaf->in(MemNode::Memory);
+ debug_only(_mem_node = s->_leaf;)
}
if( s->_leaf->in(0) && s->_leaf->req() > 1) {
if( !mach->in(0) )
@@ -1618,7 +1665,9 @@ void Matcher::ReduceOper( State *s, int
// Reduce the instruction, and add a direct pointer from this
// machine instruction to the newly reduced one.
Node *mem1 = (Node*)1;
+ debug_only(Node *save_mem_node = _mem_node;)
mach->add_req( ReduceInst( kid, newrule, mem1 ) );
+ debug_only(_mem_node = save_mem_node;)
}
}
}
@@ -1731,8 +1780,8 @@ void Matcher::find_shared( Node *n ) {
}
case Op_ConN: { // Convert narrow pointers above the centerline to NUL
TypeNode *tn = n->as_Type(); // Constants derive from type nodes
- const TypePtr* tp = tn->type()->is_narrowoop()->make_oopptr();
- if (tp->_ptr == TypePtr::AnyNull) {
+ const TypePtr* tp = tn->type()->make_ptr();
+ if (tp && tp->_ptr == TypePtr::AnyNull) {
tn->set_type(TypeNarrowOop::NULL_PTR);
}
break;
--- a/src/share/vm/opto/matcher.hpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/matcher.hpp Tue Jul 01 11:59:44 2008 -0700
@@ -84,6 +84,7 @@ class Matcher : public PhaseTransform {
Node_Array _shared_nodes;
debug_only(Node_Array _old2new_map;) // Map roots of ideal-trees to machine-roots
+ debug_only(Node_Array _new2old_map;) // Maps machine nodes back to ideal
// Accessors for the inherited field PhaseTransform::_nodes:
void grow_new_node_array(uint idx_limit) {
@@ -104,6 +105,8 @@ class Matcher : public PhaseTransform {
#ifdef ASSERT
// Make sure only new nodes are reachable from this node
void verify_new_nodes_only(Node* root);
+
+ Node* _mem_node; // Ideal memory node consumed by mach node
#endif
public:
@@ -388,5 +391,9 @@ public:
#ifdef ASSERT
void dump_old2new_map(); // machine-independent to machine-dependent
+
+ Node* find_old_node(Node* new_node) {
+ return _new2old_map[new_node->_idx];
+ }
#endif
};
--- a/src/share/vm/opto/memnode.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/memnode.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -91,7 +91,7 @@ extern void print_alias_types();
Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) {
const TypeOopPtr *tinst = t_adr->isa_oopptr();
- if (tinst == NULL || !tinst->is_instance_field())
+ if (tinst == NULL || !tinst->is_known_instance_field())
return mchain; // don't try to optimize non-instance types
uint instance_id = tinst->instance_id();
Node *prev = NULL;
@@ -125,7 +125,7 @@ Node *MemNode::optimize_simple_memory_ch
Node *MemNode::optimize_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) {
const TypeOopPtr *t_oop = t_adr->isa_oopptr();
- bool is_instance = (t_oop != NULL) && t_oop->is_instance_field();
+ bool is_instance = (t_oop != NULL) && t_oop->is_known_instance_field();
PhaseIterGVN *igvn = phase->is_IterGVN();
Node *result = mchain;
result = optimize_simple_memory_chain(result, t_adr, phase);
@@ -134,8 +134,8 @@ Node *MemNode::optimize_memory_chain(Nod
assert(mphi->bottom_type() == Type::MEMORY, "memory phi required");
const TypePtr *t = mphi->adr_type();
if (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM ||
- t->isa_oopptr() && !t->is_oopptr()->is_instance() &&
- t->is_oopptr()->cast_to_instance(t_oop->instance_id()) == t_oop) {
+ t->isa_oopptr() && !t->is_oopptr()->is_known_instance() &&
+ t->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop) {
// clone the Phi with our address type
result = mphi->split_out_instance(t_adr, igvn);
} else {
@@ -470,7 +470,7 @@ Node* MemNode::find_previous_store(Phase
return mem; // let caller handle steps (c), (d)
}
- } else if (addr_t != NULL && addr_t->is_instance_field()) {
+ } else if (addr_t != NULL && addr_t->is_known_instance_field()) {
// Can't use optimize_simple_memory_chain() since it needs PhaseGVN.
if (mem->is_Proj() && mem->in(0)->is_Call()) {
CallNode *call = mem->in(0)->as_Call();
@@ -769,15 +769,8 @@ Node *LoadNode::make( PhaseGVN& gvn, Nod
case T_OBJECT:
#ifdef _LP64
if (adr->bottom_type()->is_ptr_to_narrowoop()) {
- const TypeNarrowOop* narrowtype;
- if (rt->isa_narrowoop()) {
- narrowtype = rt->is_narrowoop();
- } else {
- narrowtype = rt->is_oopptr()->make_narrowoop();
- }
- Node* load = gvn.transform(new (C, 3) LoadNNode(ctl, mem, adr, adr_type, narrowtype));
-
- return DecodeNNode::decode(&gvn, load);
+ Node* load = gvn.transform(new (C, 3) LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop()));
+ return new (C, 2) DecodeNNode(load, load->bottom_type()->make_ptr());
} else
#endif
{
@@ -923,7 +916,7 @@ bool LoadNode::is_instance_field_load_wi
in(MemNode::Address)->is_AddP() ) {
const TypeOopPtr* t_oop = in(MemNode::Address)->bottom_type()->isa_oopptr();
// Only instances.
- if( t_oop != NULL && t_oop->is_instance_field() &&
+ if( t_oop != NULL && t_oop->is_known_instance_field() &&
t_oop->offset() != Type::OffsetBot &&
t_oop->offset() != Type::OffsetTop) {
return true;
@@ -1146,7 +1139,7 @@ Node *LoadNode::split_through_phi(PhaseG
const TypeOopPtr *t_oop = addr_t->isa_oopptr();
assert(mem->is_Phi() && (t_oop != NULL) &&
- t_oop->is_instance_field(), "invalide conditions");
+ t_oop->is_known_instance_field(), "invalide conditions");
Node *region = mem->in(0);
if (region == NULL) {
@@ -1314,7 +1307,7 @@ Node *LoadNode::Ideal(PhaseGVN *phase, b
}
const TypeOopPtr *t_oop = addr_t->isa_oopptr();
if (can_reshape && opt_mem->is_Phi() &&
- (t_oop != NULL) && t_oop->is_instance_field()) {
+ (t_oop != NULL) && t_oop->is_known_instance_field()) {
// Split instance field load through Phi.
Node* result = split_through_phi(phase);
if (result != NULL) return result;
@@ -1549,7 +1542,7 @@ const Type *LoadNode::Value( PhaseTransf
}
const TypeOopPtr *tinst = tp->isa_oopptr();
- if (tinst != NULL && tinst->is_instance_field()) {
+ if (tinst != NULL && tinst->is_known_instance_field()) {
// If we have an instance type and our memory input is the
// programs's initial memory state, there is no matching store,
// so just return a zero of the appropriate type
@@ -1631,9 +1624,8 @@ Node *LoadKlassNode::make( PhaseGVN& gvn
assert(adr_type != NULL, "expecting TypeOopPtr");
#ifdef _LP64
if (adr_type->is_ptr_to_narrowoop()) {
- const TypeNarrowOop* narrowtype = tk->is_oopptr()->make_narrowoop();
- Node* load_klass = gvn.transform(new (C, 3) LoadNKlassNode(ctl, mem, adr, at, narrowtype));
- return DecodeNNode::decode(&gvn, load_klass);
+ Node* load_klass = gvn.transform(new (C, 3) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowoop()));
+ return new (C, 2) DecodeNNode(load_klass, load_klass->bottom_type()->make_ptr());
}
#endif
assert(!adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop");
@@ -1843,15 +1835,10 @@ Node* LoadNode::klass_identity_common(Ph
//------------------------------Value------------------------------------------
const Type *LoadNKlassNode::Value( PhaseTransform *phase ) const {
const Type *t = klass_value_common(phase);
-
- if (t == TypePtr::NULL_PTR) {
- return TypeNarrowOop::NULL_PTR;
- }
- if (t != Type::TOP && !t->isa_narrowoop()) {
- assert(t->is_oopptr(), "sanity");
- t = t->is_oopptr()->make_narrowoop();
- }
- return t;
+ if (t == Type::TOP)
+ return t;
+
+ return t->make_narrowoop();
}
//------------------------------Identity---------------------------------------
@@ -1864,7 +1851,7 @@ Node* LoadNKlassNode::Identity( PhaseTra
if( t == Type::TOP ) return x;
if( t->isa_narrowoop()) return x;
- return EncodePNode::encode(phase, x);
+ return phase->transform(new (phase->C, 2) EncodePNode(x, t->make_narrowoop()));
}
//------------------------------Value-----------------------------------------
@@ -1930,14 +1917,13 @@ StoreNode* StoreNode::make( PhaseGVN& gv
if (adr->bottom_type()->is_ptr_to_narrowoop() ||
(UseCompressedOops && val->bottom_type()->isa_klassptr() &&
adr->bottom_type()->isa_rawptr())) {
- const TypePtr* type = val->bottom_type()->is_ptr();
- Node* cp = EncodePNode::encode(&gvn, val);
- return new (C, 4) StoreNNode(ctl, mem, adr, adr_type, cp);
+ val = gvn.transform(new (C, 2) EncodePNode(val, val->bottom_type()->make_narrowoop()));
+ return new (C, 4) StoreNNode(ctl, mem, adr, adr_type, val);
} else
#endif
- {
- return new (C, 4) StorePNode(ctl, mem, adr, adr_type, val);
- }
+ {
+ return new (C, 4) StorePNode(ctl, mem, adr, adr_type, val);
+ }
}
ShouldNotReachHere();
return (StoreNode*)NULL;
@@ -2151,7 +2137,7 @@ bool StoreNode::value_never_loaded( Phas
const TypeOopPtr *adr_oop = phase->type(adr)->isa_oopptr();
if (adr_oop == NULL)
return false;
- if (!adr_oop->is_instance_field())
+ if (!adr_oop->is_known_instance_field())
return false; // if not a distinct instance, there may be aliases of the address
for (DUIterator_Fast imax, i = adr->fast_outs(imax); i < imax; i++) {
Node *use = adr->fast_out(i);
--- a/src/share/vm/opto/node.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/node.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -1387,7 +1387,7 @@ static void find_recur( Node* &result, N
}
#ifdef ASSERT
// Search along debug_orig edges last:
- for (Node* orig = n->debug_orig(); orig != NULL; orig = orig->debug_orig()) {
+ for (Node* orig = n->debug_orig(); orig != NULL && n != orig; orig = orig->debug_orig()) {
if (NotANode(orig)) break;
find_recur( result, orig, idx, only_ctrl, old_space, new_space );
}
--- a/src/share/vm/opto/output.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/output.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -447,6 +447,7 @@ void Compile::Shorten_branches(Label *la
// We've got a winner. Replace this branch.
MachNode *replacement = mach->short_branch_version(this);
b->_nodes.map(j, replacement);
+ mach->subsume_by(replacement);
// Update the jmp_end size to save time in our
// next pass.
--- a/src/share/vm/opto/parse2.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/parse2.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -67,12 +67,9 @@ Node* Parse::array_addressing(BasicType
const Type* elemtype = arytype->elem();
if (UseUniqueSubclasses && result2 != NULL) {
- const Type* el = elemtype;
- if (elemtype->isa_narrowoop()) {
- el = elemtype->is_narrowoop()->make_oopptr();
- }
- const TypeInstPtr* toop = el->isa_instptr();
- if (toop) {
+ const Type* el = elemtype->make_ptr();
+ if (el && el->isa_instptr()) {
+ const TypeInstPtr* toop = el->is_instptr();
if (toop->klass()->as_instance_klass()->unique_concrete_subklass()) {
// If we load from "AbstractClass[]" we must see "ConcreteSubClass".
const Type* subklass = Type::get_const_type(toop->klass());
@@ -2223,7 +2220,7 @@ void Parse::do_one_bytecode() {
sprintf(buffer, "Bytecode %d: %s", bci(), Bytecodes::name(bc()));
bool old = printer->traverse_outs();
printer->set_traverse_outs(true);
- printer->print_method(C, buffer, 3);
+ printer->print_method(C, buffer, 4);
printer->set_traverse_outs(old);
}
#endif
--- a/src/share/vm/opto/subnode.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/subnode.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -45,10 +45,13 @@ Node *SubNode::Identity( PhaseTransform
return in(2)->in(2);
}
- // Convert "(X+Y) - Y" into X
+ // Convert "(X+Y) - Y" into X and "(X+Y) - X" into Y
if( in(1)->Opcode() == Op_AddI ) {
if( phase->eqv(in(1)->in(2),in(2)) )
return in(1)->in(1);
+ if (phase->eqv(in(1)->in(1),in(2)))
+ return in(1)->in(2);
+
// Also catch: "(X + Opaque2(Y)) - Y". In this case, 'Y' is a loop-varying
// trip counter and X is likely to be loop-invariant (that's how O2 Nodes
// are originally used, although the optimizer sometimes jiggers things).
@@ -740,8 +743,8 @@ Node *CmpPNode::Ideal( PhaseGVN *phase,
// Simplify an CmpN (compare 2 pointers) node, based on local information.
// If both inputs are constants, compare them.
const Type *CmpNNode::sub( const Type *t1, const Type *t2 ) const {
- const TypePtr *r0 = t1->is_narrowoop()->make_oopptr(); // Handy access
- const TypePtr *r1 = t2->is_narrowoop()->make_oopptr();
+ const TypePtr *r0 = t1->make_ptr(); // Handy access
+ const TypePtr *r1 = t2->make_ptr();
// Undefined inputs makes for an undefined result
if( TypePtr::above_centerline(r0->_ptr) ||
--- a/src/share/vm/opto/superword.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/superword.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -1424,9 +1424,9 @@ int SuperWord::memory_alignment(MemNode*
//---------------------------container_type---------------------------
// Smallest type containing range of values
const Type* SuperWord::container_type(const Type* t) {
- if (t->isa_narrowoop()) t = t->is_narrowoop()->make_oopptr();
- if (t->isa_aryptr()) {
- t = t->is_aryptr()->elem();
+ const Type* tp = t->make_ptr();
+ if (tp && tp->isa_aryptr()) {
+ t = tp->is_aryptr()->elem();
}
if (t->basic_type() == T_INT) {
if (t->higher_equal(TypeInt::BOOL)) return TypeInt::BOOL;
--- a/src/share/vm/opto/type.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/type.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -491,14 +491,8 @@ bool Type::is_nan() const {
// commutative and the lattice is symmetric.
const Type *Type::meet( const Type *t ) const {
if (isa_narrowoop() && t->isa_narrowoop()) {
- const Type* result = is_narrowoop()->make_oopptr()->meet(t->is_narrowoop()->make_oopptr());
- if (result->isa_oopptr()) {
- return result->isa_oopptr()->make_narrowoop();
- } else if (result == TypePtr::NULL_PTR) {
- return TypeNarrowOop::NULL_PTR;
- } else {
- return result;
- }
+ const Type* result = make_ptr()->meet(t->make_ptr());
+ return result->make_narrowoop();
}
const Type *mt = xmeet(t);
@@ -520,23 +514,8 @@ const Type *Type::meet( const Type *t )
bool t_interface = t_inst->klass()->is_interface();
interface_vs_oop = this_interface ^ t_interface;
}
- const Type *tdual = t->_dual;
- const Type *thisdual = _dual;
- // strip out instances
- if (t2t->isa_oopptr() != NULL) {
- t2t = t2t->isa_oopptr()->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE);
- }
- if (t2this->isa_oopptr() != NULL) {
- t2this = t2this->isa_oopptr()->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE);
- }
- if (tdual->isa_oopptr() != NULL) {
- tdual = tdual->isa_oopptr()->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE);
- }
- if (thisdual->isa_oopptr() != NULL) {
- thisdual = thisdual->isa_oopptr()->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE);
- }
-
- if( !interface_vs_oop && (t2t != tdual || t2this != thisdual) ) {
+
+ if( !interface_vs_oop && (t2t != t->_dual || t2this != _dual) ) {
tty->print_cr("=== Meet Not Symmetric ===");
tty->print("t = "); t->dump(); tty->cr();
tty->print("this= "); dump(); tty->cr();
@@ -1764,7 +1743,7 @@ inline const TypeInt* normalize_array_si
//------------------------------make-------------------------------------------
const TypeAry *TypeAry::make( const Type *elem, const TypeInt *size) {
if (UseCompressedOops && elem->isa_oopptr()) {
- elem = elem->is_oopptr()->make_narrowoop();
+ elem = elem->make_narrowoop();
}
size = normalize_array_size(size);
return (TypeAry*)(new TypeAry(elem,size))->hashcons();
@@ -1849,9 +1828,8 @@ bool TypeAry::ary_must_be_exact() const
if (_elem == BOTTOM) return false; // general array not exact
if (_elem == TOP ) return false; // inverted general array not exact
const TypeOopPtr* toop = NULL;
- if (UseCompressedOops) {
- const TypeNarrowOop* noop = _elem->isa_narrowoop();
- if (noop) toop = noop->make_oopptr()->isa_oopptr();
+ if (UseCompressedOops && _elem->isa_narrowoop()) {
+ toop = _elem->make_ptr()->isa_oopptr();
} else {
toop = _elem->isa_oopptr();
}
@@ -1861,16 +1839,18 @@ bool TypeAry::ary_must_be_exact() const
if (!tklass->is_loaded()) return false; // unloaded class
const TypeInstPtr* tinst;
if (_elem->isa_narrowoop())
- tinst = _elem->is_narrowoop()->make_oopptr()->isa_instptr();
+ tinst = _elem->make_ptr()->isa_instptr();
else
tinst = _elem->isa_instptr();
- if (tinst) return tklass->as_instance_klass()->is_final();
+ if (tinst)
+ return tklass->as_instance_klass()->is_final();
const TypeAryPtr* tap;
if (_elem->isa_narrowoop())
- tap = _elem->is_narrowoop()->make_oopptr()->isa_aryptr();
+ tap = _elem->make_ptr()->isa_aryptr();
else
tap = _elem->isa_aryptr();
- if (tap) return tap->ary()->ary_must_be_exact();
+ if (tap)
+ return tap->ary()->ary_must_be_exact();
return false;
}
@@ -2227,7 +2207,7 @@ const TypeOopPtr *TypeOopPtr::make(PTR p
ciKlass* k = ciKlassKlass::make();
bool xk = false;
ciObject* o = NULL;
- return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, UNKNOWN_INSTANCE))->hashcons();
+ return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, InstanceBot))->hashcons();
}
@@ -2239,7 +2219,7 @@ const Type *TypeOopPtr::cast_to_ptr_type
}
//-----------------------------cast_to_instance-------------------------------
-const TypeOopPtr *TypeOopPtr::cast_to_instance(int instance_id) const {
+const TypeOopPtr *TypeOopPtr::cast_to_instance_id(int instance_id) const {
// There are no instances of a general oop.
// Return self unchanged.
return this;
@@ -2333,7 +2313,7 @@ const Type *TypeOopPtr::xdual() const {
const Type *TypeOopPtr::xdual() const {
assert(klass() == ciKlassKlass::make(), "no klasses here");
assert(const_oop() == NULL, "no constants here");
- return new TypeOopPtr(_base, dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance() );
+ return new TypeOopPtr(_base, dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id() );
}
//--------------------------make_from_klass_common-----------------------------
@@ -2547,7 +2527,9 @@ void TypeOopPtr::dump2( Dict &d, uint de
case 0: break;
default: st->print("+%d",_offset); break;
}
- if (_instance_id != UNKNOWN_INSTANCE)
+ if (_instance_id == InstanceTop)
+ st->print(",iid=top");
+ else if (_instance_id != InstanceBot)
st->print(",iid=%d",_instance_id);
}
#endif
@@ -2579,19 +2561,23 @@ const TypePtr *TypeOopPtr::add_offset( i
return make( _ptr, xadd_offset(offset) );
}
-const TypeNarrowOop* TypeOopPtr::make_narrowoop() const {
- return TypeNarrowOop::make(this);
-}
-
-int TypeOopPtr::meet_instance(int iid) const {
- if (iid == 0) {
- return (_instance_id < 0) ? _instance_id : UNKNOWN_INSTANCE;
- } else if (_instance_id == UNKNOWN_INSTANCE) {
- return (iid < 0) ? iid : UNKNOWN_INSTANCE;
- } else {
- return (_instance_id == iid) ? iid : UNKNOWN_INSTANCE;
- }
-}
+//------------------------------meet_instance_id--------------------------------
+int TypeOopPtr::meet_instance_id( int instance_id ) const {
+ // Either is 'TOP' instance? Return the other instance!
+ if( _instance_id == InstanceTop ) return instance_id;
+ if( instance_id == InstanceTop ) return _instance_id;
+ // If either is different, return 'BOTTOM' instance
+ if( _instance_id != instance_id ) return InstanceBot;
+ return _instance_id;
+}
+
+//------------------------------dual_instance_id--------------------------------
+int TypeOopPtr::dual_instance_id( ) const {
+ if( _instance_id == InstanceTop ) return InstanceBot; // Map TOP into BOTTOM
+ if( _instance_id == InstanceBot ) return InstanceTop; // Map BOTTOM into TOP
+ return _instance_id; // Map everything else into self
+}
+
//=============================================================================
// Convenience common pre-built types.
@@ -2624,7 +2610,7 @@ const TypeInstPtr *TypeInstPtr::make(PTR
// Ptr is never Null
assert( ptr != Null, "NULL pointers are not typed" );
- if (instance_id != UNKNOWN_INSTANCE)
+ if ( instance_id > 0 )
xk = true; // instances are always exactly typed
if (!UseExactTypes) xk = false;
if (ptr == Constant) {
@@ -2649,7 +2635,7 @@ const Type *TypeInstPtr::cast_to_ptr_typ
if( ptr == _ptr ) return this;
// Reconstruct _sig info here since not a problem with later lazy
// construction, _sig will show up on demand.
- return make(ptr, klass(), klass_is_exact(), const_oop(), _offset);
+ return make(ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id);
}
@@ -2665,13 +2651,13 @@ const Type *TypeInstPtr::cast_to_exactne
}
//-----------------------------cast_to_instance-------------------------------
-const TypeOopPtr *TypeInstPtr::cast_to_instance(int instance_id) const {
- if( instance_id == _instance_id) return this;
- bool exact = true;
- PTR ptr_t = NotNull;
- if (instance_id == UNKNOWN_INSTANCE) {
- exact = _klass_is_exact;
- ptr_t = _ptr;
+const TypeOopPtr *TypeInstPtr::cast_to_instance_id(int instance_id) const {
+ if( instance_id == _instance_id ) return this;
+ bool exact = _klass_is_exact;
+ PTR ptr_t = _ptr;
+ if ( instance_id > 0 ) { // instances are always exactly typed
+ if (UseExactTypes) exact = true;
+ ptr_t = NotNull;
}
return make(ptr_t, klass(), exact, const_oop(), _offset, instance_id);
}
@@ -2754,16 +2740,17 @@ const Type *TypeInstPtr::xmeet( const Ty
const TypeAryPtr *tp = t->is_aryptr();
int offset = meet_offset(tp->offset());
PTR ptr = meet_ptr(tp->ptr());
- int iid = meet_instance(tp->instance_id());
+ int instance_id = meet_instance_id(tp->instance_id());
switch (ptr) {
case TopPTR:
case AnyNull: // Fall 'down' to dual of object klass
if (klass()->equals(ciEnv::current()->Object_klass())) {
- return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, iid);
+ return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id);
} else {
// cannot subclass, so the meet has to fall badly below the centerline
ptr = NotNull;
- return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, iid);
+ instance_id = InstanceBot;
+ return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id);
}
case Constant:
case NotNull:
@@ -2774,14 +2761,15 @@ const Type *TypeInstPtr::xmeet( const Ty
// then we can subclass in the Java class heirarchy.
if (klass()->equals(ciEnv::current()->Object_klass())) {
// that is, tp's array type is a subtype of my klass
- return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, iid);
+ return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id);
}
}
// The other case cannot happen, since I cannot be a subtype of an array.
// The meet falls down to Object class below centerline.
if( ptr == Constant )
ptr = NotNull;
- return make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, iid );
+ instance_id = InstanceBot;
+ return make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id );
default: typerr(t);
}
}
@@ -2793,9 +2781,11 @@ const Type *TypeInstPtr::xmeet( const Ty
PTR ptr = meet_ptr(tp->ptr());
switch (tp->ptr()) {
case TopPTR:
- case AnyNull:
+ case AnyNull: {
+ int instance_id = meet_instance_id(InstanceTop);
return make(ptr, klass(), klass_is_exact(),
- (ptr == Constant ? const_oop() : NULL), offset);
+ (ptr == Constant ? const_oop() : NULL), offset, instance_id);
+ }
case NotNull:
case BotPTR:
return TypeOopPtr::make(ptr, offset);
@@ -2811,10 +2801,13 @@ const Type *TypeInstPtr::xmeet( const Ty
switch (tp->ptr()) {
case Null:
if( ptr == Null ) return TypePtr::make( AnyPtr, ptr, offset );
+ // else fall through to AnyNull
case TopPTR:
- case AnyNull:
+ case AnyNull: {
+ int instance_id = meet_instance_id(InstanceTop);
return make( ptr, klass(), klass_is_exact(),
- (ptr == Constant ? const_oop() : NULL), offset );
+ (ptr == Constant ? const_oop() : NULL), offset, instance_id);
+ }
case NotNull:
case BotPTR:
return TypePtr::make( AnyPtr, ptr, offset );
@@ -2843,7 +2836,7 @@ const Type *TypeInstPtr::xmeet( const Ty
const TypeInstPtr *tinst = t->is_instptr();
int off = meet_offset( tinst->offset() );
PTR ptr = meet_ptr( tinst->ptr() );
- int instance_id = meet_instance(tinst->instance_id());
+ int instance_id = meet_instance_id(tinst->instance_id());
// Check for easy case; klasses are equal (and perhaps not loaded!)
// If we have constants, then we created oops so classes are loaded
@@ -2912,7 +2905,7 @@ const Type *TypeInstPtr::xmeet( const Ty
// Find out which constant.
o = (this_klass == klass()) ? const_oop() : tinst->const_oop();
}
- return make( ptr, k, xk, o, off );
+ return make( ptr, k, xk, o, off, instance_id );
}
// Either oop vs oop or interface vs interface or interface vs Object
@@ -2999,7 +2992,7 @@ const Type *TypeInstPtr::xmeet( const Ty
// Now we find the LCA of Java classes
ciKlass* k = this_klass->least_common_ancestor(tinst_klass);
- return make( ptr, k, false, NULL, off );
+ return make( ptr, k, false, NULL, off, instance_id );
} // End of case InstPtr
case KlassPtr:
@@ -3026,7 +3019,7 @@ ciType* TypeInstPtr::java_mirror_type()
// Dual: do NOT dual on klasses. This means I do NOT understand the Java
// inheritence mechanism.
const Type *TypeInstPtr::xdual() const {
- return new TypeInstPtr( dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance() );
+ return new TypeInstPtr( dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id() );
}
//------------------------------eq---------------------------------------------
@@ -3078,7 +3071,9 @@ void TypeInstPtr::dump2( Dict &d, uint d
}
st->print(" *");
- if (_instance_id != UNKNOWN_INSTANCE)
+ if (_instance_id == InstanceTop)
+ st->print(",iid=top");
+ else if (_instance_id != InstanceBot)
st->print(",iid=%d",_instance_id);
}
#endif
@@ -3106,7 +3101,7 @@ const TypeAryPtr *TypeAryPtr::make( PTR
assert(!(k == NULL && ary->_elem->isa_int()),
"integral arrays must be pre-equipped with a class");
if (!xk) xk = ary->ary_must_be_exact();
- if (instance_id != UNKNOWN_INSTANCE)
+ if ( instance_id > 0 )
xk = true; // instances are always exactly typed
if (!UseExactTypes) xk = (ptr == Constant);
return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id))->hashcons();
@@ -3118,7 +3113,7 @@ const TypeAryPtr *TypeAryPtr::make( PTR
"integral arrays must be pre-equipped with a class");
assert( (ptr==Constant && o) || (ptr!=Constant && !o), "" );
if (!xk) xk = (o != NULL) || ary->ary_must_be_exact();
- if (instance_id != UNKNOWN_INSTANCE)
+ if ( instance_id > 0 )
xk = true; // instances are always exactly typed
if (!UseExactTypes) xk = (ptr == Constant);
return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id))->hashcons();
@@ -3127,7 +3122,7 @@ const TypeAryPtr *TypeAryPtr::make( PTR
//------------------------------cast_to_ptr_type-------------------------------
const Type *TypeAryPtr::cast_to_ptr_type(PTR ptr) const {
if( ptr == _ptr ) return this;
- return make(ptr, const_oop(), _ary, klass(), klass_is_exact(), _offset);
+ return make(ptr, const_oop(), _ary, klass(), klass_is_exact(), _offset, _instance_id);
}
@@ -3140,13 +3135,13 @@ const Type *TypeAryPtr::cast_to_exactnes
}
//-----------------------------cast_to_instance-------------------------------
-const TypeOopPtr *TypeAryPtr::cast_to_instance(int instance_id) const {
- if( instance_id == _instance_id) return this;
- bool exact = true;
- PTR ptr_t = NotNull;
- if (instance_id == UNKNOWN_INSTANCE) {
- exact = _klass_is_exact;
- ptr_t = _ptr;
+const TypeOopPtr *TypeAryPtr::cast_to_instance_id(int instance_id) const {
+ if( instance_id == _instance_id ) return this;
+ bool exact = _klass_is_exact;
+ PTR ptr_t = _ptr;
+ if ( instance_id > 0 ) { // instances are always exactly typed
+ if (UseExactTypes) exact = true;
+ ptr_t = NotNull;
}
return make(ptr_t, const_oop(), _ary, klass(), exact, _offset, instance_id);
}
@@ -3199,7 +3194,7 @@ const TypeAryPtr* TypeAryPtr::cast_to_si
new_size = TypeInt::ZERO; // intermediate dead fast-path goo
if (new_size == size()) return this;
const TypeAry* new_ary = TypeAry::make(elem(), new_size);
- return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset);
+ return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id);
}
@@ -3251,8 +3246,11 @@ const Type *TypeAryPtr::xmeet( const Typ
PTR ptr = meet_ptr(tp->ptr());
switch (tp->ptr()) {
case TopPTR:
- case AnyNull:
- return make(ptr, (ptr == Constant ? const_oop() : NULL), _ary, _klass, _klass_is_exact, offset);
+ case AnyNull: {
+ int instance_id = meet_instance_id(InstanceTop);
+ return make(ptr, (ptr == Constant ? const_oop() : NULL),
+ _ary, _klass, _klass_is_exact, offset, instance_id);
+ }
case BotPTR:
case NotNull:
return TypeOopPtr::make(ptr, offset);
@@ -3273,8 +3271,12 @@ const Type *TypeAryPtr::xmeet( const Typ
return TypePtr::make(AnyPtr, ptr, offset);
case Null:
if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset);
- case AnyNull:
- return make( ptr, (ptr == Constant ? const_oop() : NULL), _ary, _klass, _klass_is_exact, offset );
+ // else fall through to AnyNull
+ case AnyNull: {
+ int instance_id = meet_instance_id(InstanceTop);
+ return make( ptr, (ptr == Constant ? const_oop() : NULL),
+ _ary, _klass, _klass_is_exact, offset, instance_id);
+ }
default: ShouldNotReachHere();
}
}
@@ -3286,7 +3288,7 @@ const Type *TypeAryPtr::xmeet( const Typ
int off = meet_offset(tap->offset());
const TypeAry *tary = _ary->meet(tap->_ary)->is_ary();
PTR ptr = meet_ptr(tap->ptr());
- int iid = meet_instance(tap->instance_id());
+ int instance_id = meet_instance_id(tap->instance_id());
ciKlass* lazy_klass = NULL;
if (tary->_elem->isa_int()) {
// Integral array element types have irrelevant lattice relations.
@@ -3307,7 +3309,7 @@ const Type *TypeAryPtr::xmeet( const Typ
case TopPTR:
// Compute new klass on demand, do not use tap->_klass
xk = (tap->_klass_is_exact | this->_klass_is_exact);
- return make( ptr, const_oop(), tary, lazy_klass, xk, off, iid );
+ return make( ptr, const_oop(), tary, lazy_klass, xk, off, instance_id );
case Constant: {
ciObject* o = const_oop();
if( _ptr == Constant ) {
@@ -3319,7 +3321,7 @@ const Type *TypeAryPtr::xmeet( const Typ
o = tap->const_oop();
}
xk = true;
- return TypeAryPtr::make( ptr, o, tary, tap->_klass, xk, off, iid );
+ return TypeAryPtr::make( ptr, o, tary, tap->_klass, xk, off, instance_id );
}
case NotNull:
case BotPTR:
@@ -3330,7 +3332,7 @@ const Type *TypeAryPtr::xmeet( const Typ
xk = this->_klass_is_exact;
else xk = (tap->_klass_is_exact & this->_klass_is_exact) &&
(klass() == tap->klass()); // Only precise for identical arrays
- return TypeAryPtr::make( ptr, NULL, tary, lazy_klass, xk, off, iid );
+ return TypeAryPtr::make( ptr, NULL, tary, lazy_klass, xk, off, instance_id );
default: ShouldNotReachHere();
}
}
@@ -3340,16 +3342,17 @@ const Type *TypeAryPtr::xmeet( const Typ
const TypeInstPtr *tp = t->is_instptr();
int offset = meet_offset(tp->offset());
PTR ptr = meet_ptr(tp->ptr());
- int iid = meet_instance(tp->instance_id());
+ int instance_id = meet_instance_id(tp->instance_id());
switch (ptr) {
case TopPTR:
case AnyNull: // Fall 'down' to dual of object klass
if( tp->klass()->equals(ciEnv::current()->Object_klass()) ) {
- return TypeAryPtr::make( ptr, _ary, _klass, _klass_is_exact, offset, iid );
+ return TypeAryPtr::make( ptr, _ary, _klass, _klass_is_exact, offset, instance_id );
} else {
// cannot subclass, so the meet has to fall badly below the centerline
ptr = NotNull;
- return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL,offset, iid);
+ instance_id = InstanceBot;
+ return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id);
}
case Constant:
case NotNull:
@@ -3360,14 +3363,15 @@ const Type *TypeAryPtr::xmeet( const Typ
// then we can subclass in the Java class heirarchy.
if( tp->klass()->equals(ciEnv::current()->Object_klass()) ) {
// that is, my array type is a subtype of 'tp' klass
- return make( ptr, _ary, _klass, _klass_is_exact, offset, iid );
+ return make( ptr, _ary, _klass, _klass_is_exact, offset, instance_id );
}
}
// The other case cannot happen, since t cannot be a subtype of an array.
// The meet falls down to Object class below centerline.
if( ptr == Constant )
ptr = NotNull;
- return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL,offset, iid);
+ instance_id = InstanceBot;
+ return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id);
default: typerr(t);
}
}
@@ -3382,7 +3386,7 @@ const Type *TypeAryPtr::xmeet( const Typ
//------------------------------xdual------------------------------------------
// Dual: compute field-by-field dual
const Type *TypeAryPtr::xdual() const {
- return new TypeAryPtr( dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance() );
+ return new TypeAryPtr( dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance_id() );
}
//------------------------------dump2------------------------------------------
@@ -3419,7 +3423,9 @@ void TypeAryPtr::dump2( Dict &d, uint de
}
}
st->print(" *");
- if (_instance_id != UNKNOWN_INSTANCE)
+ if (_instance_id == InstanceTop)
+ st->print(",iid=top");
+ else if (_instance_id != InstanceBot)
st->print(",iid=%d",_instance_id);
}
#endif
@@ -3494,7 +3500,7 @@ const Type *TypeNarrowOop::xmeet( const
return this;
case NarrowOop: {
- const Type* result = _ooptype->xmeet(t->is_narrowoop()->make_oopptr());
+ const Type* result = _ooptype->xmeet(t->make_ptr());
if (result->isa_ptr()) {
return TypeNarrowOop::make(result->is_ptr());
}
@@ -3604,7 +3610,7 @@ ciKlass* TypeAryPtr::klass() const {
const TypeAryPtr *tary;
const Type* el = elem();
if (el->isa_narrowoop()) {
- el = el->is_narrowoop()->make_oopptr();
+ el = el->make_ptr();
}
// Get element klass
--- a/src/share/vm/opto/type.hpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/opto/type.hpp Tue Jul 01 11:59:44 2008 -0700
@@ -225,6 +225,12 @@ public:
virtual bool is_finite() const; // Has a finite value
virtual bool is_nan() const; // Is not a number (NaN)
+ // Returns this ptr type or the equivalent ptr type for this compressed pointer.
+ const TypePtr* make_ptr() const;
+ // Returns this compressed pointer or the equivalent compressed version
+ // of this pointer type.
+ const TypeNarrowOop* make_narrowoop() const;
+
// Special test for register pressure heuristic
bool is_floatingpoint() const; // True if Float or Double base type
@@ -648,7 +654,8 @@ public:
virtual int hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
enum {
- UNKNOWN_INSTANCE = 0
+ InstanceTop = -1, // undefined instance
+ InstanceBot = 0 // any possible instance
};
protected:
@@ -661,14 +668,15 @@ protected:
bool _klass_is_exact;
bool _is_ptr_to_narrowoop;
- int _instance_id; // if not UNKNOWN_INSTANCE, indicates that this is a particular instance
- // of this type which is distinct. This is the the node index of the
- // node creating this instance
+ // If not InstanceTop or InstanceBot, indicates that this is
+ // a particular instance of this type which is distinct.
+ // This is the the node index of the allocation node creating this instance.
+ int _instance_id;
static const TypeOopPtr* make_from_klass_common(ciKlass* klass, bool klass_change, bool try_for_exact);
- int dual_instance() const { return -_instance_id; }
- int meet_instance(int uid) const;
+ int dual_instance_id() const;
+ int meet_instance_id(int uid) const;
public:
// Creates a type given a klass. Correctly handles multi-dimensional arrays
@@ -701,9 +709,9 @@ public:
// compressed oop references.
bool is_ptr_to_narrowoop_nv() const { return _is_ptr_to_narrowoop; }
- bool is_instance() const { return _instance_id != UNKNOWN_INSTANCE; }
- uint instance_id() const { return _instance_id; }
- bool is_instance_field() const { return _instance_id != UNKNOWN_INSTANCE && _offset >= 0; }
+ bool is_known_instance() const { return _instance_id > 0; }
+ int instance_id() const { return _instance_id; }
+ bool is_known_instance_field() const { return is_known_instance() && _offset >= 0; }
virtual intptr_t get_con() const;
@@ -711,15 +719,12 @@ public:
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
- virtual const TypeOopPtr *cast_to_instance(int instance_id) const;
+ virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const;
// corresponding pointer to klass, for a given instance
const TypeKlassPtr* as_klass_type() const;
virtual const TypePtr *add_offset( int offset ) const;
-
- // returns the equivalent compressed version of this pointer type
- virtual const TypeNarrowOop* make_narrowoop() const;
virtual const Type *xmeet( const Type *t ) const;
virtual const Type *xdual() const; // Compute dual right now.
@@ -775,7 +780,7 @@ class TypeInstPtr : public TypeOopPtr {
}
// Make a pointer to an oop.
- static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = 0 );
+ static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = InstanceBot );
// If this is a java.lang.Class constant, return the type for it or NULL.
// Pass to Type::get_const_type to turn it to a type, which will usually
@@ -786,7 +791,7 @@ class TypeInstPtr : public TypeOopPtr {
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
- virtual const TypeOopPtr *cast_to_instance(int instance_id) const;
+ virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const;
virtual const TypePtr *add_offset( int offset ) const;
@@ -820,9 +825,9 @@ public:
const Type* elem() const { return _ary->_elem; }
const TypeInt* size() const { return _ary->_size; }
- static const TypeAryPtr *make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = 0);
+ static const TypeAryPtr *make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot);
// Constant pointer to array
- static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = 0);
+ static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot);
// Convenience
static const TypeAryPtr *make(ciObject* o);
@@ -832,7 +837,7 @@ public:
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
- virtual const TypeOopPtr *cast_to_instance(int instance_id) const;
+ virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const;
virtual const TypeAryPtr* cast_to_size(const TypeInt* size) const;
@@ -911,7 +916,7 @@ public:
// between the normal and the compressed form.
class TypeNarrowOop : public Type {
protected:
- const TypePtr* _ooptype;
+ const TypePtr* _ooptype; // Could be TypePtr::NULL_PTR
TypeNarrowOop( const TypePtr* ooptype): Type(NarrowOop),
_ooptype(ooptype) {
@@ -940,8 +945,8 @@ public:
return make(TypeOopPtr::make_from_constant(con));
}
- // returns the equivalent oopptr type for this compressed pointer
- virtual const TypePtr *make_oopptr() const {
+ // returns the equivalent ptr type for this compressed pointer
+ const TypePtr *make_oopptr() const {
return _ooptype;
}
@@ -1126,6 +1131,16 @@ inline const TypeKlassPtr *Type::is_klas
inline const TypeKlassPtr *Type::is_klassptr() const {
assert( _base == KlassPtr, "Not a klass pointer" );
return (TypeKlassPtr*)this;
+}
+
+inline const TypePtr* Type::make_ptr() const {
+ return (_base == NarrowOop) ? is_narrowoop()->make_oopptr() :
+ (isa_ptr() ? is_ptr() : NULL);
+}
+
+inline const TypeNarrowOop* Type::make_narrowoop() const {
+ return (_base == NarrowOop) ? is_narrowoop() :
+ (isa_ptr() ? TypeNarrowOop::make(is_ptr()) : NULL);
}
inline bool Type::is_floatingpoint() const {
--- a/src/share/vm/runtime/globals.hpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/runtime/globals.hpp Tue Jul 01 11:59:44 2008 -0700
@@ -961,6 +961,9 @@ class CommandLineFlags {
diagnostic(bool, UseIncDec, true, \
"Use INC, DEC instructions on x86") \
\
+ product(bool, UseNewLongLShift, false, \
+ "Use optimized bitwise shift left") \
+ \
product(bool, UseStoreImmI16, true, \
"Use store immediate 16-bits value instruction on x86") \
\
--- a/src/share/vm/runtime/hpi.hpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/runtime/hpi.hpp Tue Jul 01 11:59:44 2008 -0700
@@ -66,6 +66,8 @@ public:
static inline int socket_shutdown(int fd, int howto);
static inline int recv(int fd, char *buf, int nBytes, int flags);
static inline int send(int fd, char *buf, int nBytes, int flags);
+ // Variant of send that doesn't support interruptible I/O
+ static inline int raw_send(int fd, char *buf, int nBytes, int flags);
static inline int timeout(int fd, long timeout);
static inline int listen(int fd, int count);
static inline int connect(int fd, struct sockaddr *him, int len);
--- a/src/share/vm/utilities/ostream.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/utilities/ostream.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -764,21 +764,28 @@ void staticBufferStream::vprint_cr(const
write(str, len);
}
-bufferedStream::bufferedStream(size_t initial_size) : outputStream() {
+bufferedStream::bufferedStream(size_t initial_size, size_t bufmax) : outputStream() {
buffer_length = initial_size;
buffer = NEW_C_HEAP_ARRAY(char, buffer_length);
buffer_pos = 0;
buffer_fixed = false;
-}
-
-bufferedStream::bufferedStream(char* fixed_buffer, size_t fixed_buffer_size) : outputStream() {
+ buffer_max = bufmax;
+}
+
+bufferedStream::bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax) : outputStream() {
buffer_length = fixed_buffer_size;
buffer = fixed_buffer;
buffer_pos = 0;
buffer_fixed = true;
+ buffer_max = bufmax;
}
void bufferedStream::write(const char* s, size_t len) {
+
+ if(buffer_pos + len > buffer_max) {
+ flush();
+ }
+
size_t end = buffer_pos + len;
if (end >= buffer_length) {
if (buffer_fixed) {
@@ -822,7 +829,7 @@ bufferedStream::~bufferedStream() {
#endif
// Network access
-networkStream::networkStream() {
+networkStream::networkStream() : bufferedStream(1024*10, 1024*10) {
_socket = -1;
@@ -842,7 +849,9 @@ int networkStream::read(char *buf, size_
void networkStream::flush() {
if (size() != 0) {
- hpi::send(_socket, (char *)base(), (int)size(), 0);
+ int result = hpi::raw_send(_socket, (char *)base(), (int)size(), 0);
+ assert(result != -1, "connection error");
+ assert(result == (int)size(), "didn't send enough data");
}
reset();
}
--- a/src/share/vm/utilities/ostream.hpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/utilities/ostream.hpp Tue Jul 01 11:59:44 2008 -0700
@@ -210,11 +210,12 @@ class bufferedStream : public outputStre
protected:
char* buffer;
size_t buffer_pos;
+ size_t buffer_max;
size_t buffer_length;
bool buffer_fixed;
public:
- bufferedStream(size_t initial_bufsize = 256);
- bufferedStream(char* fixed_buffer, size_t fixed_buffer_size);
+ bufferedStream(size_t initial_bufsize = 256, size_t bufmax = 1024*1024*10);
+ bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax = 1024*1024*10);
~bufferedStream();
virtual void write(const char* c, size_t len);
size_t size() { return buffer_pos; }
--- a/src/share/vm/utilities/xmlstream.cpp Mon Jun 30 17:04:59 2008 -0700
+++ b/src/share/vm/utilities/xmlstream.cpp Tue Jul 01 11:59:44 2008 -0700
@@ -59,6 +59,7 @@ void xmlStream::write(const char* s, siz
if (!is_open()) return;
out()->write(s, len);
+ update_position(s, len);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/build.xml Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.svg" default="netbeans" basedir=".">
+ <description>Builds, tests, and runs the project com.sun.hotspot.igv.svg.</description>
+ <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/manifest.mf Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.svg
+OpenIDE-Module-Layer: com/sun/hotspot/igv/svg/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/svg/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/build-impl.xml Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT ***
+*** EDIT ../build.xml INSTEAD ***
+-->
+<project name="com.sun.hotspot.igv.svg-impl" basedir="..">
+ <property file="nbproject/private/suite-private.properties"/>
+ <property file="nbproject/suite.properties"/>
+ <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+ <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+ <property file="${suite.dir}/nbproject/platform.properties"/>
+ <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+ <attribute name="name"/>
+ <attribute name="value"/>
+ <sequential>
+ <property name="@{name}" value="${@{value}}"/>
+ </sequential>
+ </macrodef>
+ <property file="${user.properties.file}"/>
+ <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+ <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+ <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+ <condition>
+ <not>
+ <available file="${harness.dir}" type="dir"/>
+ </not>
+ </condition>
+ </fail>
+ <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/genfiles.properties Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=ebcf0422
+build.xml.script.CRC32=d7a2678d
+build.xml.stylesheet.CRC32=79c3b980
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=ebcf0422
+nbproject/build-impl.xml.script.CRC32=57997f94
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/project.properties Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/project.xml Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.apisupport.project</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+ <code-name-base>com.sun.hotspot.igv.svg</code-name-base>
+ <suite-component/>
+ <module-dependencies/>
+ <public-packages>
+ <package>com.sun.hotspot.igv.svg</package>
+ </public-packages>
+ </data>
+ </configuration>
+</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/suite.properties Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/BatikSVG.java Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.svg;
+
+import java.awt.Graphics2D;
+import java.io.Writer;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import org.w3c.dom.DOMImplementation;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class BatikSVG {
+
+ private static Constructor SVGGraphics2DConstructor;
+ private static Method Method_stream;
+ private static Method Method_createDefault;
+ private static Method Method_getDOMImplementation;
+ private static Method Method_setEmbeddedFontsOn;
+
+ public static Graphics2D createGraphicsObject() {
+ try {
+ if (SVGGraphics2DConstructor == null) {
+ ClassLoader cl = BatikSVG.class.getClassLoader();
+ Class Class_GenericDOMImplementation = cl.loadClass("org.apache.batik.dom.GenericDOMImplementation");
+ Class Class_SVGGeneratorContext = cl.loadClass("org.apache.batik.svggen.SVGGeneratorContext");
+ Class Class_SVGGraphics2D = cl.loadClass("org.apache.batik.svggen.SVGGraphics2D");
+ Method_getDOMImplementation = Class_GenericDOMImplementation.getDeclaredMethod("getDOMImplementation", new Class[0]);
+ Method_createDefault = Class_SVGGeneratorContext.getDeclaredMethod("createDefault", new Class[]{org.w3c.dom.Document.class});
+ Method_setEmbeddedFontsOn = Class_SVGGeneratorContext.getDeclaredMethod("setEmbeddedFontsOn", new Class[]{boolean.class});
+ Method_stream = Class_SVGGraphics2D.getDeclaredMethod("stream", Writer.class, boolean.class);
+ SVGGraphics2DConstructor = Class_SVGGraphics2D.getConstructor(Class_SVGGeneratorContext, boolean.class);
+ }
+ DOMImplementation dom = (DOMImplementation) Method_getDOMImplementation.invoke(null);
+ org.w3c.dom.Document document = dom.createDocument("http://www.w3.org/2000/svg", "svg", null);
+ Object ctx = Method_createDefault.invoke(null, document);
+ Method_setEmbeddedFontsOn.invoke(ctx, true);
+ Graphics2D svgGenerator = (Graphics2D) SVGGraphics2DConstructor.newInstance(ctx, true);
+ return svgGenerator;
+ } catch (ClassNotFoundException e) {
+ return null;
+ } catch (NoSuchMethodException e) {
+ return null;
+ } catch (IllegalAccessException e) {
+ return null;
+ } catch (InvocationTargetException e) {
+ return null;
+ } catch (InstantiationException e) {
+ return null;
+ }
+ }
+
+ public static void printToStream(Graphics2D svgGenerator, Writer stream, boolean useCSS) {
+ try {
+ Method_stream.invoke(svgGenerator, stream, useCSS);
+ } catch (IllegalAccessException e) {
+ assert false;
+ } catch (InvocationTargetException e) {
+ assert false;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/Bundle.properties Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=BatikSVGProxy
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/layer.xml Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+</filesystem>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/build.xml Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.bytecodes" default="netbeans" basedir=".">
+ <description>Builds, tests, and runs the project com.sun.hotspot.igv.bytecodes.</description>
+ <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/manifest.mf Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.bytecodes
+OpenIDE-Module-Layer: com/sun/hotspot/igv/bytecodes/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/bytecodes/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/build-impl.xml Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT ***
+*** EDIT ../build.xml INSTEAD ***
+-->
+<project name="com.sun.hotspot.igv.bytecodes-impl" basedir="..">
+ <property file="nbproject/private/suite-private.properties"/>
+ <property file="nbproject/suite.properties"/>
+ <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+ <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+ <property file="${suite.dir}/nbproject/platform.properties"/>
+ <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+ <attribute name="name"/>
+ <attribute name="value"/>
+ <sequential>
+ <property name="@{name}" value="${@{value}}"/>
+ </sequential>
+ </macrodef>
+ <property file="${user.properties.file}"/>
+ <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+ <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+ <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+ <condition>
+ <not>
+ <available file="${harness.dir}" type="dir"/>
+ </not>
+ </condition>
+ </fail>
+ <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/genfiles.properties Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=1dee290d
+build.xml.script.CRC32=d594034f
+build.xml.stylesheet.CRC32=79c3b980
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=1dee290d
+nbproject/build-impl.xml.script.CRC32=b4dab126
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/platform.properties Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+ apisupport1,\
+ harness,\
+ ide8,\
+ java1,\
+ nb6.0,\
+ profiler2
+disabled.modules=\
+ org.netbeans.core.execution,\
+ org.netbeans.core.multiview,\
+ org.netbeans.core.output2,\
+ org.netbeans.modules.applemenu,\
+ org.netbeans.modules.autoupdate.services,\
+ org.netbeans.modules.autoupdate.ui,\
+ org.netbeans.modules.core.kit,\
+ org.netbeans.modules.favorites,\
+ org.netbeans.modules.javahelp,\
+ org.netbeans.modules.masterfs,\
+ org.netbeans.modules.options.keymap,\
+ org.netbeans.modules.sendopts,\
+ org.netbeans.modules.templates,\
+ org.openide.compat,\
+ org.openide.execution,\
+ org.openide.util.enumerations
+enabled.clusters=\
+ platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.properties Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.xml Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.apisupport.project</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+ <code-name-base>com.sun.hotspot.igv.bytecodes</code-name-base>
+ <suite-component/>
+ <module-dependencies>
+ <dependency>
+ <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>1.0</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.jdesktop.layout</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>1</release-version>
+ <specification-version>1.4</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.explorer</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>6.11</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.nodes</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.2.0.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.util</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.9.0.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.windows</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>6.16</specification-version>
+ </run-dependency>
+ </dependency>
+ </module-dependencies>
+ <public-packages/>
+ </data>
+ </configuration>
+</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/suite.properties Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/Bundle.properties Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,5 @@
+CTL_BytecodeViewAction=Open BytecodeView Window
+CTL_BytecodeViewTopComponent=BytecodeView Window
+CTL_SelectBytecodesAction=Select nodes
+HINT_BytecodeViewTopComponent=This is a BytecodeView window
+OpenIDE-Module-Name=Bytecodes
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.bytecodes;
+
+import com.sun.hotspot.igv.data.InputBytecode;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
+import java.awt.Image;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.swing.Action;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.util.Utilities;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class BytecodeNode extends AbstractNode {
+
+ private Set<InputNode> nodes;
+
+ public BytecodeNode(InputBytecode bytecode, InputGraph graph, String bciValue) {
+
+ super(Children.LEAF);
+ this.setDisplayName(bytecode.getBci() + " " + bytecode.getName());
+
+ bciValue = bytecode.getBci() + " " + bciValue;
+ bciValue = bciValue.trim();
+
+ Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<InputNode>(graph.getNodes());
+ StringPropertyMatcher matcher = new StringPropertyMatcher("bci", bciValue);
+ List<InputNode> nodeList = selector.selectMultiple(matcher);
+ if (nodeList.size() > 0) {
+ nodes = new HashSet<InputNode>();
+ for (InputNode n : nodeList) {
+ nodes.add(n);
+ }
+ this.setDisplayName(this.getDisplayName() + " (" + nodes.size() + " nodes)");
+ }
+ }
+
+ @Override
+ public Image getIcon(int i) {
+ if (nodes != null) {
+ return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/link.gif");
+ } else {
+ return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/bytecode.gif");
+ }
+ }
+
+ @Override
+ public Image getOpenedIcon(int i) {
+ return getIcon(i);
+ }
+
+ @Override
+ public Action[] getActions(boolean b) {
+ return new Action[]{(Action) SelectBytecodesAction.findObject(SelectBytecodesAction.class, true)};
+ }
+
+ @Override
+ public Action getPreferredAction() {
+ return (Action) SelectBytecodesAction.findObject(SelectBytecodesAction.class, true);
+ }
+
+ @Override
+ public <T extends Node.Cookie> T getCookie(Class<T> aClass) {
+ if (aClass == SelectBytecodesCookie.class && nodes != null) {
+ return (T) (new SelectBytecodesCookie(nodes));
+ }
+ return super.getCookie(aClass);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewAction.java Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.bytecodes;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.util.NbBundle;
+import org.openide.windows.TopComponent;
+
+/**
+ * @author Thomas Wuerthinger
+ */
+public class BytecodeViewAction extends AbstractAction {
+
+ public BytecodeViewAction() {
+ super(NbBundle.getMessage(BytecodeViewAction.class, "CTL_BytecodeViewAction"));
+ }
+
+ public void actionPerformed(ActionEvent evt) {
+ TopComponent win = BytecodeViewTopComponent.findInstance();
+ win.open();
+ win.requestActive();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.form Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.3" maxVersion="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+ <AuxValues>
+ <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+ <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
+ <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+ <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+ </AuxValues>
+
+ <Layout>
+ <DimensionLayout dim="0">
+ <Group type="103" groupAlignment="0" attributes="0">
+ <EmptySpace min="0" pref="400" max="32767" attributes="0"/>
+ </Group>
+ </DimensionLayout>
+ <DimensionLayout dim="1">
+ <Group type="103" groupAlignment="0" attributes="0">
+ <EmptySpace min="0" pref="300" max="32767" attributes="0"/>
+ </Group>
+ </DimensionLayout>
+ </Layout>
+</Form>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.bytecodes;
+
+import com.sun.hotspot.igv.data.Group;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import java.awt.BorderLayout;
+import java.io.Serializable;
+import org.openide.ErrorManager;
+import org.openide.explorer.ExplorerManager;
+import org.openide.explorer.ExplorerUtils;
+import org.openide.explorer.view.BeanTreeView;
+import org.openide.util.Lookup;
+import org.openide.util.LookupEvent;
+import org.openide.util.LookupListener;
+import org.openide.util.NbBundle;
+import org.openide.util.Utilities;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+
+/**
+ * @author Thomas Wuerthinger
+ */
+final class BytecodeViewTopComponent extends TopComponent implements ExplorerManager.Provider, LookupListener {
+
+ private static BytecodeViewTopComponent instance;
+ private static final String PREFERRED_ID = "BytecodeViewTopComponent";
+ private ExplorerManager manager;
+ private BeanTreeView treeView;
+ private Lookup.Result result = null;
+ private MethodNode rootNode;
+
+ private BytecodeViewTopComponent() {
+ initComponents();
+ setName(NbBundle.getMessage(BytecodeViewTopComponent.class, "CTL_BytecodeViewTopComponent"));
+ setToolTipText(NbBundle.getMessage(BytecodeViewTopComponent.class, "HINT_BytecodeViewTopComponent"));
+
+ manager = new ExplorerManager();
+ rootNode = new MethodNode(null, null, "");
+ manager.setRootContext(rootNode);
+
+ setLayout(new BorderLayout());
+
+ treeView = new BeanTreeView();
+ treeView.setRootVisible(false);
+ this.add(BorderLayout.CENTER, treeView);
+ associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+ .add(0, 400, Short.MAX_VALUE)
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+ .add(0, 300, Short.MAX_VALUE)
+ );
+ }// </editor-fold>//GEN-END:initComponents
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ // End of variables declaration//GEN-END:variables
+ /**
+ * Gets default instance. Do not use directly: reserved for *.settings files only,
+ * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
+ * To obtain the singleton instance, use {@link findInstance}.
+ */
+ public static synchronized BytecodeViewTopComponent getDefault() {
+ if (instance == null) {
+ instance = new BytecodeViewTopComponent();
+ }
+ return instance;
+ }
+
+ /**
+ * Obtain the BytecodeViewTopComponent instance. Never call {@link #getDefault} directly!
+ */
+ public static synchronized BytecodeViewTopComponent findInstance() {
+ TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+ if (win == null) {
+ ErrorManager.getDefault().log(ErrorManager.WARNING, "Cannot find BytecodeView component. It will not be located properly in the window system.");
+ return getDefault();
+ }
+ if (win instanceof BytecodeViewTopComponent) {
+ return (BytecodeViewTopComponent) win;
+ }
+ ErrorManager.getDefault().log(ErrorManager.WARNING, "There seem to be multiple components with the '" + PREFERRED_ID + "' ID. That is a potential source of errors and unexpected behavior.");
+ return getDefault();
+ }
+
+ @Override
+ public int getPersistenceType() {
+ return TopComponent.PERSISTENCE_ALWAYS;
+ }
+
+ @Override
+ public void componentOpened() {
+ Lookup.Template tpl = new Lookup.Template(Object.class);
+ result = Utilities.actionsGlobalContext().lookup(tpl);
+ result.addLookupListener(this);
+ }
+
+ @Override
+ public void componentClosed() {
+ result.removeLookupListener(this);
+ result = null;
+ }
+
+ @Override
+ public Object writeReplace() {
+ return new ResolvableHelper();
+ }
+
+ @Override
+ protected String preferredID() {
+ return PREFERRED_ID;
+ }
+
+ public ExplorerManager getExplorerManager() {
+ return manager;
+ }
+
+ public void resultChanged(LookupEvent lookupEvent) {
+ InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+ if (p != null) {
+ InputGraph graph = p.getGraph();
+ if (graph != null) {
+ Group g = graph.getGroup();
+ rootNode.update(graph, g.getMethod());
+ }
+ }
+ }
+
+ final static class ResolvableHelper implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ public Object readResolve() {
+ return BytecodeViewTopComponent.getDefault();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponentSettings.xml Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">
+<settings version="1.0">
+ <module name="com.sun.hotspot.igv.bytecodes" spec="1.0"/>
+ <instanceof class="org.openide.windows.TopComponent"/>
+ <instanceof class="com.sun.hotspot.igv.bytecodes.BytecodeViewTopComponent"/>
+ <instance class="com.sun.hotspot.igv.bytecodes.BytecodeViewTopComponent" method="getDefault"/>
+</settings>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponentWstcref.xml Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE tc-ref PUBLIC "-//NetBeans//DTD Top Component in Mode Properties 2.0//EN" "http://www.netbeans.org/dtds/tc-ref2_0.dtd">
+<tc-ref version="2.0" >
+ <module name="com.sun.hotspot.igv.bytecodes" spec="1.0"/>
+ <tc-id id="BytecodeViewTopComponent"/>
+ <state opened="true"/>
+</tc-ref>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/MethodNode.java Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.bytecodes;
+
+import com.sun.hotspot.igv.data.InputBytecode;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputMethod;
+import java.awt.Image;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.util.Utilities;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class MethodNode extends AbstractNode {
+
+ private static class MethodNodeChildren extends Children.Keys {
+
+ private InputMethod method;
+ private InputGraph graph;
+ private String bciString;
+
+ public MethodNodeChildren(InputMethod method, InputGraph graph, String bciString) {
+ this.method = method;
+ this.bciString = bciString;
+ this.graph = graph;
+ }
+
+ protected Node[] createNodes(Object object) {
+ assert object instanceof InputBytecode;
+ InputBytecode bc = (InputBytecode) object;
+ if (bc.getInlined() == null) {
+ return new Node[]{new BytecodeNode(bc, graph, bciString)};
+ } else {
+ return new Node[]{new BytecodeNode(bc, graph, bciString), new MethodNode(bc.getInlined(), graph, bc.getBci() + " " + bciString)};
+ }
+ }
+
+ @Override
+ public void addNotify() {
+ if (method != null) {
+ setKeys(method.getBytecodes());
+ }
+ }
+
+ public void setMethod(InputMethod method, InputGraph graph) {
+ this.method = method;
+ this.graph = graph;
+ addNotify();
+ }
+ }
+
+ /** Creates a new instance of MethodNode */
+ public MethodNode(InputMethod method, InputGraph graph, String bciString) {
+ super((method != null && method.getBytecodes().size() == 0) ? Children.LEAF : new MethodNodeChildren(method, graph, bciString));
+ if (method != null) {
+ this.setDisplayName(method.getName());
+ }
+ }
+
+ @Override
+ public Image getIcon(int i) {
+ return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/method.gif");
+ }
+
+ @Override
+ public Image getOpenedIcon(int i) {
+ return getIcon(i);
+ }
+
+ public void update(InputGraph graph, InputMethod method) {
+ ((MethodNodeChildren) this.getChildren()).setMethod(method, graph);
+ if (method != null) {
+ this.setDisplayName(method.getName());
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.bytecodes;
+
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import org.openide.nodes.Node;
+import org.openide.util.HelpCtx;
+import org.openide.util.Lookup;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CookieAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class SelectBytecodesAction extends CookieAction {
+
+ protected void performAction(Node[] activatedNodes) {
+ SelectBytecodesCookie c = activatedNodes[0].getCookie(SelectBytecodesCookie.class);
+ InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+ if (p != null) {
+ p.setSelectedNodes(c.getNodes());
+ }
+ }
+
+ protected int mode() {
+ return CookieAction.MODE_EXACTLY_ONE;
+ }
+
+ public String getName() {
+ return NbBundle.getMessage(SelectBytecodesAction.class, "CTL_SelectBytecodesAction");
+ }
+
+ protected Class[] cookieClasses() {
+ return new Class[]{
+ SelectBytecodesCookie.class
+ };
+ }
+
+ @Override
+ protected void initialize() {
+ super.initialize();
+ putValue("noIconInMenu", Boolean.TRUE);
+ }
+
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+ @Override
+ protected boolean asynchronous() {
+ return false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesCookie.java Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.bytecodes;
+
+import com.sun.hotspot.igv.data.InputNode;
+import java.util.Collections;
+import java.util.Set;
+import org.openide.nodes.Node;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class SelectBytecodesCookie implements Node.Cookie {
+
+ private Set<InputNode> nodes;
+
+ /** Creates a new instance of SelectBytecodesCookie */
+ public SelectBytecodesCookie(Set<InputNode> nodes) {
+ this.nodes = nodes;
+ }
+
+ public Set<InputNode> getNodes() {
+ return Collections.unmodifiableSet(nodes);
+ }
+}
Binary file src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/bytecode.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/link.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/method.gif has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/layer.xml Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+ <folder name="Actions">
+ <folder name="Edit">
+ <file name="com-sun-hotspot-igv-bytecodes-SelectBytecodesAction.instance"/>
+ </folder>
+ <folder name="Window">
+ <file name="com-sun-hotspot-igv-bytecodes-BytecodeViewAction.instance"/>
+ </folder>
+ </folder>
+ <folder name="Menu">
+ <folder name="Window">
+ <file name="BytecodeViewAction.shadow">
+ <attr name="originalFile" stringvalue="Actions/Window/com-sun-hotspot-igv-bytecodes-BytecodeViewAction.instance"/>
+ </file>
+ </folder>
+ </folder>
+ <folder name="Windows2">
+ <folder name="Components">
+ <file name="BytecodeViewTopComponent.settings" url="BytecodeViewTopComponentSettings.xml"/>
+ </folder>
+ <folder name="Modes">
+ <folder name="customRightTopMode">
+ <file name="BytecodeViewTopComponent.wstcref" url="BytecodeViewTopComponentWstcref.xml"/>
+ </folder>
+ </folder>
+ </folder>
+</filesystem>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/build.xml Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.controlflow" default="netbeans" basedir=".">
+ <description>Builds, tests, and runs the project com.sun.hotspot.igv.controlflow.</description>
+ <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/manifest.mf Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.controlflow
+OpenIDE-Module-Layer: com/sun/hotspot/igv/controlflow/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/controlflow/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/build-impl.xml Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT ***
+*** EDIT ../build.xml INSTEAD ***
+-->
+<project name="com.sun.hotspot.igv.controlflow-impl" basedir="..">
+ <property file="nbproject/private/suite-private.properties"/>
+ <property file="nbproject/suite.properties"/>
+ <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+ <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+ <property file="${suite.dir}/nbproject/platform.properties"/>
+ <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+ <attribute name="name"/>
+ <attribute name="value"/>
+ <sequential>
+ <property name="@{name}" value="${@{value}}"/>
+ </sequential>
+ </macrodef>
+ <property file="${user.properties.file}"/>
+ <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+ <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+ <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+ <condition>
+ <not>
+ <available file="${harness.dir}" type="dir"/>
+ </not>
+ </condition>
+ </fail>
+ <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/genfiles.properties Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=b524efb3
+build.xml.script.CRC32=79a27be9
+build.xml.stylesheet.CRC32=79c3b980
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=b524efb3
+nbproject/build-impl.xml.script.CRC32=582bdab7
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/platform.properties Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+ apisupport1,\
+ harness,\
+ ide8,\
+ java1,\
+ nb6.0,\
+ profiler2
+disabled.modules=\
+ org.netbeans.core.execution,\
+ org.netbeans.core.multiview,\
+ org.netbeans.core.output2,\
+ org.netbeans.modules.applemenu,\
+ org.netbeans.modules.autoupdate.services,\
+ org.netbeans.modules.autoupdate.ui,\
+ org.netbeans.modules.core.kit,\
+ org.netbeans.modules.favorites,\
+ org.netbeans.modules.javahelp,\
+ org.netbeans.modules.masterfs,\
+ org.netbeans.modules.options.keymap,\
+ org.netbeans.modules.sendopts,\
+ org.netbeans.modules.templates,\
+ org.openide.compat,\
+ org.openide.execution,\
+ org.openide.util.enumerations
+enabled.clusters=\
+ platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/project.properties Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/project.xml Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.apisupport.project</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+ <code-name-base>com.sun.hotspot.igv.controlflow</code-name-base>
+ <suite-component/>
+ <module-dependencies>
+ <dependency>
+ <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>1.0</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>com.sun.hotspot.igv.hierarchicallayout</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>1.0</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>com.sun.hotspot.igv.layout</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>1.0</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.jdesktop.layout</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>1</release-version>
+ <specification-version>1.4</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.netbeans.api.visual</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>2.9</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.util</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.9.0.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.windows</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>6.16</specification-version>
+ </run-dependency>
+ </dependency>
+ </module-dependencies>
+ <public-packages/>
+ </data>
+ </configuration>
+</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/suite.properties Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockConnectionWidget.java Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.controlflow;
+
+import com.sun.hotspot.igv.data.InputBlockEdge;
+import com.sun.hotspot.igv.layout.Link;
+import com.sun.hotspot.igv.layout.Port;
+import java.awt.Point;
+import java.util.ArrayList;
+import java.util.List;
+import org.netbeans.api.visual.widget.ConnectionWidget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class BlockConnectionWidget extends ConnectionWidget implements Link {
+
+ private BlockWidget from;
+ private BlockWidget to;
+ private Port inputSlot;
+ private Port outputSlot;
+ private List<Point> points;
+ private InputBlockEdge edge;
+
+ public BlockConnectionWidget(ControlFlowScene scene, InputBlockEdge edge) {
+ super(scene);
+
+ this.edge = edge;
+ this.from = (BlockWidget) scene.findWidget(edge.getFrom());
+ this.to = (BlockWidget) scene.findWidget(edge.getTo());
+ inputSlot = to.getInputSlot();
+ outputSlot = from.getOutputSlot();
+ points = new ArrayList<Point>();
+ }
+
+ public InputBlockEdge getEdge() {
+ return edge;
+ }
+
+ public Port getTo() {
+ return inputSlot;
+ }
+
+ public Port getFrom() {
+ return outputSlot;
+ }
+
+ public void setControlPoints(List<Point> p) {
+ this.points = p;
+ }
+
+ @Override
+ public List<Point> getControlPoints() {
+ return points;
+ }
+
+ @Override
+ public String toString() {
+ return "Connection[ " + from.toString() + " - " + to.toString() + "]";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockWidget.java Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.controlflow;
+
+import com.sun.hotspot.igv.data.InputBlock;
+import com.sun.hotspot.igv.layout.Cluster;
+import com.sun.hotspot.igv.layout.Port;
+import com.sun.hotspot.igv.layout.Vertex;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Point;
+import org.netbeans.api.visual.border.BorderFactory;
+import org.netbeans.api.visual.model.ObjectState;
+import org.netbeans.api.visual.widget.LabelWidget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class BlockWidget extends LabelWidget implements Vertex {
+
+ public static final Dimension SIZE = new Dimension(20, 20);
+ private InputBlock block;
+ private Port inputSlot;
+ private Port outputSlot;
+ private Cluster cluster;
+ private boolean root;
+ private static final Font font = new Font(Font.SERIF, Font.PLAIN, 12);
+ private static final Font boldFont = font.deriveFont(Font.BOLD);
+ public static final Color NORMAL_FOREGROUND_COLOR = Color.BLACK;
+ public static final Color HOVER_FOREGROUND_COLOR = Color.BLUE;
+
+ /** Creates a new instance of BlockWidget */
+ public BlockWidget(ControlFlowScene scene, InputBlock block) {
+ super(scene);
+ this.block = block;
+ this.setLabel(block.getName());
+ this.setForeground(NORMAL_FOREGROUND_COLOR);
+ this.setBorder(BorderFactory.createLineBorder(1, NORMAL_FOREGROUND_COLOR));
+ this.setMinimumSize(SIZE);
+ this.setMaximumSize(SIZE);
+
+ this.setFont(font);
+
+ final BlockWidget widget = this;
+ inputSlot = new Port() {
+
+ public Point getRelativePosition() {
+ return new Point((int) (SIZE.getWidth() / 2), (int) (SIZE.getHeight() / 2));
+ }
+
+ public Vertex getVertex() {
+ return widget;
+ }
+ };
+
+ outputSlot = new Port() {
+
+ public Point getRelativePosition() {
+ return new Point((int) (SIZE.getWidth() / 2), (int) (SIZE.getHeight() / 2));
+ }
+
+ public Vertex getVertex() {
+ return widget;
+ }
+ };
+ }
+
+ public Port getInputSlot() {
+ return inputSlot;
+ }
+
+ public Port getOutputSlot() {
+ return outputSlot;
+ }
+
+ public InputBlock getBlock() {
+ return block;
+ }
+
+ public Dimension getSize() {
+ return SIZE;
+ }
+
+ public void setPosition(Point p) {
+ this.setPreferredLocation(p);
+ }
+
+ @Override
+ public String toString() {
+ return block.getName();
+ }
+
+ public Point getPosition() {
+ return this.getPreferredLocation();
+ }
+
+ public Cluster getCluster() {
+ return cluster;
+ }
+
+ public boolean isRoot() {
+ return root;
+ }
+
+ public void setCluster(Cluster c) {
+ cluster = c;
+ }
+
+ public void setRoot(boolean b) {
+ root = b;
+ }
+
+ public int compareTo(Vertex o) {
+ return toString().compareTo(o.toString());
+ }
+
+ @Override
+ protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
+ super.notifyStateChanged(previousState, state);
+
+ if (previousState.isHovered() != state.isHovered()) {
+ if (state.isHovered()) {
+ this.setBorder(BorderFactory.createLineBorder(1, HOVER_FOREGROUND_COLOR));
+ } else {
+ this.setBorder(BorderFactory.createLineBorder(1, NORMAL_FOREGROUND_COLOR));
+ }
+ }
+
+ if (previousState.isSelected() != state.isSelected()) {
+ if (state.isSelected()) {
+ this.setFont(boldFont);
+ } else {
+ this.setFont(font);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/Bundle.properties Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,4 @@
+CTL_ControlFlowAction=Open ControlFlow Window
+CTL_ControlFlowTopComponent=ControlFlow Window
+HINT_ControlFlowTopComponent=This is a ControlFlow window
+OpenIDE-Module-Name=ControlFlow
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowAction.java Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.controlflow;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.util.NbBundle;
+import org.openide.windows.TopComponent;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ControlFlowAction extends AbstractAction {
+
+ public ControlFlowAction() {
+ super(NbBundle.getMessage(ControlFlowAction.class, "CTL_ControlFlowAction"));
+ }
+
+ public void actionPerformed(ActionEvent evt) {
+ TopComponent win = ControlFlowTopComponent.findInstance();
+ win.open();
+ win.requestActive();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowScene.java Tue Jul 01 11:59:44 2008 -0700
@@ -0,0 +1,296 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.controlflow;
+
+import com.sun.hotspot.igv.data.InputBlock;
+import com.sun.hotspot.igv.data.InputBlockEdge;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import com.sun.hotspot.igv.data.InputNode;
+import java.awt.Color;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+import javax.swing.BorderFactory;
+import org.netbeans.api.visual.action.ActionFactory;
+import org.netbeans.api.visual.action.MoveProvider;
+import org.netbeans.api.visual.action.RectangularSelectDecorator;
+import org.netbeans.api.visual.action.RectangularSelectProvider;
+import org.netbeans.api.visual.action.SelectProvider;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.anchor.AnchorFactory;
+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.router.RouterFactory;
+import org.netbeans.api.visual.widget.LayerWidget;
+import org.netbeans.api.visual.widget.Widget;
+import org.netbeans.api.visual.graph.GraphScene;
+import org.netbeans.api.visual.graph.layout.GraphLayout;
+import org.netbeans.api.visual.layout.SceneLayout;
+import org.netbeans.api.visual.widget.ConnectionWidget;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> implements SelectProvider, MoveProvider, RectangularSelectDecorator, RectangularSelectProvider {
+
+ private Set<BlockWidget> selection;
+ private Hashtable<InputBlock, BlockWidget> blockMap;
+ private InputGraph oldGraph;
+ private LayerWidget edgeLayer;
+ private LayerWidget mainLayer;
+ private LayerWidget selectLayer;
+ private WidgetAction hoverAction = this.createWidgetHoverAction();
+ private WidgetAction selectAction = ActionFactory.createSelectAction(this);
+ private WidgetAction moveAction = ActionFactory.createMoveAction(null, this);
+
+ public ControlFlowScene() {
+ selection = new HashSet<BlockWidget>();
+
+ this.getInputBindings().setZoomActionModifiers(0);
+ this.setLayout(LayoutFactory.createAbsoluteLayout());
+
+ mainLayer = new LayerWidget(this);
+ this.addChild(mainLayer);
+
+ edgeLayer = new LayerWidget(this);
+ this.addChild(edgeLayer);
+
+ selectLayer = new LayerWidget(this);
+ this.addChild(selectLayer);
+
+ this.getActions().addAction(hoverAction);
+ this.getActions().addAction(selectAction);
+ this.getActions().addAction(ActionFactory.createRectangularSelectAction(this, selectLayer, this));
+ this.getActions().addAction(ActionFactory.createMouseCenteredZoomAction(1.1));
+ }
+
+ public void setGraph(InputGraph g) {
+ if (g == oldGraph) {
+ return;
+ }
+ oldGraph = g;
+
+ ArrayList<InputBlock> blocks = new ArrayList<InputBlock>(this.getNodes());
+ for (InputBlock b : blocks) {
+ removeNode(b);
+ }
+
+ ArrayList<InputBlockEdge> edges = new ArrayList<InputBlockEdge>(this.getEdges());
+ for (InputBlockEdge e : edges) {
+ removeEdge(e);
+ }
+
+ for (InputBlock b : g.getBlocks()) {
+ addNode(b);
+ }
+
+ for (InputBlock b : g.getBlocks()) {
+ for (InputBlockEdge e : b.getOutputs()) {
+ addEdge(e);
+ assert g.getBlocks().contains(e.getFrom());
+ assert g.getBlocks().contains(e.getTo());
+ this.setEdgeSource(e, e.getFrom());
+ this.setEdgeTarget(e, e.getTo());
+ }
+ }
+
+ GraphLayout layout = new HierarchicalGraphLayout();//GridGraphLayout();
+ SceneLayout sceneLayout = LayoutFactory.createSceneGraphLayout(this, layout);
+ sceneLayout.invokeLayout();
+
+ this.validate();
+ }
+
+ public BlockWidget getBlockWidget(InputBlock b) {
+ return blockMap.get(b);
+ }
+
+ public void clearSelection() {
+ for (BlockWidget w : selection) {
+ w.setState(w.getState().deriveSelected(false));
+ }
+ selection.clear();
+ selectionChanged();
+ }
+
+ public void selectionChanged() {
+ InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+ if (p != null) {
+ Set<InputNode> inputNodes = new HashSet<InputNode>();
+ for (BlockWidget w : selection) {
+ inputNodes.addAll(w.getBlock().getNodes());
+ }
+ p.setSelectedNodes(inputNodes);
+ }
+ }
+
+ public void addToSelection(BlockWidget widget) {
+ widget.setState(widget.getState().deriveSelected(true));
+ selection.add(widget);
+ selectionChanged();
+ }
+
+ public void removeFromSelection(BlockWidget widget) {
+ widget.setState(widget.getState().deriveSelected(false));
+ selection.remove(widget);
+ selectionChanged();
+ }
+
+ public boolean isAimingAllowed(Widget widget, Point point, boolean b) {
+ return false;
+ }
+
+ public boolean isSelectionAllowed(Widget widget, Point point, boolean b) {
+ return true;
+ }
+
+ public void select(Widget widget, Point point, boolean change) {
+ if (widget == this) {
+ clearSelection();
+ } else {
+
+ assert widget instanceof BlockWidget;
+ BlockWidget bw = (BlockWidget) widget;
+ if (change) {
+ if (selection.contains(bw)) {
+ removeFromSelection(bw);
+ } else {
+ addToSelection(bw);
+ }
+ } else {
+ if (!selection.contains(bw)) {
+ clearSelection();
+ addToSelection(bw);
+ }
+ }
+ }
+ }
+
+ public void movementStarted(Widget widget) {
+ }
+
+ public void movementFinished(Widget widget) {
+ }
+
+ public Point getOriginalLocation(Widget widget) {
+ return widget.getPreferredLocation();
+ }
+
+ public void setNewLocation(Widget widget, Point location) {
+ Point originalLocation = getOriginalLocation(widget);
+ int xOffset = location.x - originalLocation.x;
+ int yOffset = location.y - originalLocation.y;
+ for (Widget w : this.selection) {
+ Point p = new Point(w.getPreferredLocation());
+ p.translate(xOffset, yOffset);
+ w.setPreferredLocation(p);
+ }
+
+ }
+
+ public Widget createSelectionWidget() {
+ Widget widget = new Widget(this);
+ widget.setOpaque(false);
+ widget.setBorder(BorderFactory.createLineBorder(Color.black, 2));
+ widget.setForeground(Color.red);
+ return widget;
+ }
+
+ public void performSelection(Rectangle rectangle) {
+
+ if (rectangle.width < 0) {
+ rectangle.x += rectangle.width;
+ rectangle.width *= -1;
+ }
+
+ if (rectangle.height < 0) {
+ rectangle.y += rectangle.height;
+ rectangle.height *= -1;
+ }
+
+ boolean changed = false;
+ for (InputBlock b : this.getNodes()) {
+ BlockWidget w = (BlockWidget) findWidget(b);
+ Rectangle r = new Rectangle(w.getBounds());
+ r.setLocation(w.getLocation());
+ if (r.intersects(rectangle)) {
+ if (!selection.contains(w)) {
+ changed = true;
+ selection.add(w);
+ w.setState(w.getState().deriveSelected(true));
+ }
+ } else {
+ if (selection.contains(w)) {
+ changed = true;
+ selection.remove(w);