# HG changeset patch
# User dcubed
# Date 1269561299 25200
# Node ID 84043c7507b9b464b0c52056ddd98929ac759872
# Parent 5d393243d487fecfe968b00ce86b5fc3fe109223# Parent 39e409a664b340ca0eaaa5a4e55dddfa99c82bdd
Merge
diff -r 39e409a664b3 -r 84043c7507b9 .hgignore
--- a/.hgignore Thu Mar 25 16:27:12 2010 -0700
+++ b/.hgignore Thu Mar 25 16:54:59 2010 -0700
@@ -1,6 +1,6 @@
^build/
^dist/
-^nbproject/private/
+/nbproject/private/
^src/share/tools/hsdis/build/
^src/share/tools/IdealGraphVisualizer/[a-zA-Z0-9]*/build/
^src/share/tools/IdealGraphVisualizer/build/
diff -r 39e409a664b3 -r 84043c7507b9 .hgtags
--- a/.hgtags Thu Mar 25 16:27:12 2010 -0700
+++ b/.hgtags Thu Mar 25 16:54:59 2010 -0700
@@ -45,3 +45,39 @@
d07e68298d4e17ebf93d8299e43fcc3ded26472a jdk7-b68
54fd4d9232969ea6cd3d236e5ad276183bb0d423 jdk7-b69
0632c3e615a315ff11e2ab1d64f4d82ff9853461 jdk7-b70
+50a95aa4a247f0cbbf66df285a8b1d78ffb153d9 jdk7-b71
+a94714c550658fd6741793ef036cb9625dc2ab1a jdk7-b72
+faf94d94786b621f8e13cbcc941ca69c6d967c3f jdk7-b73
+f4b900403d6e4b0af51447bd13bbe23fe3a1dac7 jdk7-b74
+d8dd291a362acb656026a9c0a9da48501505a1e7 jdk7-b75
+9174bb32e934965288121f75394874eeb1fcb649 jdk7-b76
+455105fc81d941482f8f8056afaa7aa0949c9300 jdk7-b77
+e703499b4b51e3af756ae77c3d5e8b3058a14e4e jdk7-b78
+a5a6adfca6ecefb5894a848debabfe442ff50e25 jdk7-b79
+3003ddd1d4330b06cb4691ae74d600d3685899eb jdk7-b80
+1f9b07674480c224828852ffe137beea36b3cab5 jdk7-b81
+1999f5b12482d66c8b0daf6709daea4f51893a04 jdk7-b82
+a94714c550658fd6741793ef036cb9625dc2ab1a hs17-b01
+faf94d94786b621f8e13cbcc941ca69c6d967c3f hs17-b02
+f4b900403d6e4b0af51447bd13bbe23fe3a1dac7 hs17-b03
+d8dd291a362acb656026a9c0a9da48501505a1e7 hs17-b04
+9174bb32e934965288121f75394874eeb1fcb649 hs17-b05
+a5a6adfca6ecefb5894a848debabfe442ff50e25 hs17-b06
+3003ddd1d4330b06cb4691ae74d600d3685899eb hs17-b07
+1f9b07674480c224828852ffe137beea36b3cab5 hs17-b08
+ff3232b68fbb35185b338d7ff4695b52460243f3 hs17-b09
+981375ca07b7f0605f92f57aad95122e8c385a4d hs16-b01
+f4cbf78110c726919f46b59a3b054c54c7e889b4 hs16-b02
+07c1c01e031513bfe6a7d17c6cf30d2752824ae9 hs16-b03
+08f86fa55a31113df626a75c8a626e66a543a1bd hs16-b04
+32c83fb84370a35344676991a48440378e6b6c8a hs16-b05
+ba313800759b678979434d6da8ed3bf49eb8bea4 hs16-b06
+3c0f729815607e1678bd0c41ae68494c700dcc71 hs16-b07
+ac59d4e6dae51ac5fc31a9a4940d1857f91161b1 hs16-b08
+3f844a28c5f4912bd04043b44f21b25b0805ffc2 hs15-b01
+1605bb4eb5a7a1703b13d5b077a22cc665fe45f7 hs15-b02
+2581d90c6c9b2012da930eb4742add94a03069a0 hs15-b03
+9ab385cb0c42997e16a7761ebcd25c90560a2714 hs15-b04
+fafab5d5349c7c066d677538db67a1ee0fb33bd2 hs15-b05
+3f370a32906eb5ba993fabd7b4279be7f31052b9 jdk7-b83
+ffc8d176b84bcfb5ac21302b4feb3b0c0d69b97c jdk7-b84
diff -r 39e409a664b3 -r 84043c7507b9 agent/make/saenv.sh
--- a/agent/make/saenv.sh Thu Mar 25 16:27:12 2010 -0700
+++ b/agent/make/saenv.sh Thu Mar 25 16:54:59 2010 -0700
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2003-2009 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
@@ -48,8 +48,16 @@
CPU=i386
fi
else
- LD_AUDIT_32=$STARTDIR/../src/os/solaris/proc/`uname -p`/libsaproc_audit.so
- export LD_AUDIT_32
+ # configure audit helper library if SA_ALTROOT is set
+ if [ -n "$SA_ALTROOT" ]; then
+ LD_AUDIT_32=$STARTDIR/../src/os/solaris/proc/`uname -p`/libsaproc_audit.so
+ export LD_AUDIT_32
+ if [ ! -f $LD_AUDIT_32 ]; then
+ echo "SA_ALTROOT is set and can't find libsaproc_audit.so."
+ echo "Make sure to build it with 'make natives'."
+ exit 1
+ fi
+ fi
SA_LIBPATH=$STARTDIR/../src/os/solaris/proc/`uname -p`:$STARTDIR/solaris/`uname -p`
OPTIONS="-Dsa.library.path=$SA_LIBPATH -Dsun.jvm.hotspot.debugger.useProcDebugger"
CPU=sparc
diff -r 39e409a664b3 -r 84043c7507b9 agent/make/saenv64.sh
--- a/agent/make/saenv64.sh Thu Mar 25 16:27:12 2010 -0700
+++ b/agent/make/saenv64.sh Thu Mar 25 16:54:59 2010 -0700
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2003-2009 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
@@ -43,8 +43,16 @@
fi
fi
-LD_AUDIT_64=$STARTDIR/../src/os/solaris/proc/$CPU/libsaproc_audit.so
-export LD_AUDIT_64
+# configure audit helper library if SA_ALTROOT is set
+if [ -n "$SA_ALTROOT" ]; then
+ LD_AUDIT_64=$STARTDIR/../src/os/solaris/proc/$CPU/libsaproc_audit.so
+ export LD_AUDIT_64
+ if [ ! -f $LD_AUDIT_64 ]; then
+ echo "SA_ALTROOT is set and can't find libsaproc_audit.so."
+ echo "Make sure to build it with 'make natives'."
+ exit 1
+ fi
+fi
SA_LIBPATH=$STARTDIR/../src/os/solaris/proc/$CPU:$STARTDIR/solaris/$CPU
OPTIONS="-Dsa.library.path=$SA_LIBPATH -Dsun.jvm.hotspot.debugger.useProcDebugger"
diff -r 39e409a664b3 -r 84043c7507b9 agent/src/os/solaris/proc/Makefile
--- a/agent/src/os/solaris/proc/Makefile Thu Mar 25 16:27:12 2010 -0700
+++ b/agent/src/os/solaris/proc/Makefile Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
#
-# Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2002-2009 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
diff -r 39e409a664b3 -r 84043c7507b9 agent/src/os/solaris/proc/mapfile
--- a/agent/src/os/solaris/proc/mapfile Thu Mar 25 16:27:12 2010 -0700
+++ b/agent/src/os/solaris/proc/mapfile Thu Mar 25 16:54:59 2010 -0700
@@ -1,7 +1,7 @@
#
#
-# Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2003-2009 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
diff -r 39e409a664b3 -r 84043c7507b9 agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
--- a/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Thu Mar 25 16:27:12 2010 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Thu Mar 25 16:54:59 2010 -0700
@@ -926,6 +926,28 @@
}
}
},
+ new Command("dumpcodecache", "dumpcodecache", false) {
+ public void doit(Tokens t) {
+ if (t.countTokens() != 0) {
+ usage();
+ } else {
+ final PrintStream fout = out;
+ final HTMLGenerator gen = new HTMLGenerator(false);
+ CodeCacheVisitor v = new CodeCacheVisitor() {
+ public void prologue(Address start, Address end) {
+ }
+ public void visit(CodeBlob blob) {
+ fout.println(gen.genHTML(blob.instructionsBegin()));
+ }
+ public void epilogue() {
+ }
+
+
+ };
+ VM.getVM().getCodeCache().iterate(v);
+ }
+ }
+ },
new Command("where", "where { -a | id }", false) {
public void doit(Tokens t) {
if (t.countTokens() != 1) {
diff -r 39e409a664b3 -r 84043c7507b9 agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java
--- a/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java Thu Mar 25 16:27:12 2010 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java Thu Mar 25 16:54:59 2010 -0700
@@ -33,6 +33,7 @@
public class CodeCache {
private static AddressField heapField;
+ private static AddressField scavengeRootNMethodsField;
private static VirtualConstructor virtualConstructor;
private CodeHeap heap;
@@ -49,6 +50,7 @@
Type type = db.lookupType("CodeCache");
heapField = type.getAddressField("_heap");
+ scavengeRootNMethodsField = type.getAddressField("_scavenge_root_nmethods");
virtualConstructor = new VirtualConstructor(db);
// Add mappings for all possible CodeBlob subclasses
@@ -67,6 +69,10 @@
heap = (CodeHeap) VMObjectFactory.newObject(CodeHeap.class, heapField.getValue());
}
+ public NMethod scavengeRootMethods() {
+ return (NMethod) VMObjectFactory.newObject(NMethod.class, scavengeRootNMethodsField.getValue());
+ }
+
public boolean contains(Address p) {
return getHeap().contains(p);
}
@@ -167,7 +173,8 @@
CodeBlob lastBlob = null;
while (ptr != null && ptr.lessThan(end)) {
try {
- CodeBlob blob = findBlobUnsafe(ptr);
+ // Use findStart to get a pointer inside blob other findBlob asserts
+ CodeBlob blob = findBlobUnsafe(heap.findStart(ptr));
if (blob != null) {
visitor.visit(blob);
if (blob == lastBlob) {
diff -r 39e409a664b3 -r 84043c7507b9 agent/src/share/classes/sun/jvm/hotspot/code/DebugInfoReadStream.java
--- a/agent/src/share/classes/sun/jvm/hotspot/code/DebugInfoReadStream.java Thu Mar 25 16:27:12 2010 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/DebugInfoReadStream.java Thu Mar 25 16:54:59 2010 -0700
@@ -81,4 +81,8 @@
Assert.that(false, "should not reach here");
return null;
}
+
+ public int readBCI() {
+ return readInt() + InvocationEntryBCI;
+ }
}
diff -r 39e409a664b3 -r 84043c7507b9 agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java
--- a/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java Thu Mar 25 16:27:12 2010 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2009 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
@@ -40,7 +40,10 @@
/** != InvocationEntryBci if this nmethod is an on-stack replacement method */
private static CIntegerField entryBCIField;
/** To support simple linked-list chaining of nmethods */
- private static AddressField linkField;
+ private static AddressField osrLinkField;
+ private static AddressField scavengeRootLinkField;
+ private static JByteField scavengeRootStateField;
+
/** Offsets for different nmethod parts */
private static CIntegerField exceptionOffsetField;
private static CIntegerField deoptOffsetField;
@@ -87,7 +90,10 @@
zombieInstructionSizeField = type.getCIntegerField("_zombie_instruction_size");
methodField = type.getOopField("_method");
entryBCIField = type.getCIntegerField("_entry_bci");
- linkField = type.getAddressField("_link");
+ osrLinkField = type.getAddressField("_osr_link");
+ scavengeRootLinkField = type.getAddressField("_scavenge_root_link");
+ scavengeRootStateField = type.getJByteField("_scavenge_root_state");
+
exceptionOffsetField = type.getCIntegerField("_exception_offset");
deoptOffsetField = type.getCIntegerField("_deoptimize_offset");
origPCOffsetField = type.getCIntegerField("_orig_pc_offset");
@@ -219,10 +225,19 @@
return getEntryBCI();
}
- public NMethod getLink() {
- return (NMethod) VMObjectFactory.newObject(NMethod.class, linkField.getValue(addr));
+ public NMethod getOSRLink() {
+ return (NMethod) VMObjectFactory.newObject(NMethod.class, osrLinkField.getValue(addr));
}
+ public NMethod getScavengeRootLink() {
+ return (NMethod) VMObjectFactory.newObject(NMethod.class, scavengeRootLinkField.getValue(addr));
+ }
+
+ public int getScavengeRootState() {
+ return (int) scavengeRootStateField.getValue(addr);
+ }
+
+
/** Tells whether frames described by this nmethod can be
deoptimized. Note: native wrappers cannot be deoptimized. */
public boolean canBeDeoptimized() { return isJavaMethod(); }
@@ -259,7 +274,7 @@
if (Assert.ASSERTS_ENABLED) {
Assert.that(pd != null, "scope must be present");
}
- return new ScopeDesc(this, pd.getScopeDecodeOffset());
+ return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getObjDecodeOffset(), pd.getReexecute());
}
/** This is only for use by the debugging system, and is only
@@ -291,11 +306,11 @@
public ScopeDesc getScopeDescNearDbg(Address pc) {
PCDesc pd = getPCDescNearDbg(pc);
if (pd == null) return null;
- return new ScopeDesc(this, pd.getScopeDecodeOffset());
+ return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getObjDecodeOffset(), pd.getReexecute());
}
- public Map/*
*/ getSafepoints() {
- Map safepoints = new HashMap(); // Map
+ public Map/**/ getSafepoints() {
+ Map safepoints = new HashMap(); // Map
sun.jvm.hotspot.debugger.Address p = null;
for (p = scopesPCsBegin(); p.lessThan(scopesPCsEnd());
p = p.addOffsetTo(pcDescSize)) {
diff -r 39e409a664b3 -r 84043c7507b9 agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java
--- a/agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java Thu Mar 25 16:27:12 2010 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2009 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
@@ -36,6 +36,8 @@
public class PCDesc extends VMObject {
private static CIntegerField pcOffsetField;
private static CIntegerField scopeDecodeOffsetField;
+ private static CIntegerField objDecodeOffsetField;
+ private static CIntegerField pcFlagsField;
static {
VM.registerVMInitializedObserver(new Observer() {
@@ -50,6 +52,8 @@
pcOffsetField = type.getCIntegerField("_pc_offset");
scopeDecodeOffsetField = type.getCIntegerField("_scope_decode_offset");
+ objDecodeOffsetField = type.getCIntegerField("_obj_decode_offset");
+ pcFlagsField = type.getCIntegerField("_flags");
}
public PCDesc(Address addr) {
@@ -66,10 +70,20 @@
return ((int) scopeDecodeOffsetField.getValue(addr));
}
+ public int getObjDecodeOffset() {
+ return ((int) objDecodeOffsetField.getValue(addr));
+ }
+
public Address getRealPC(NMethod code) {
return code.instructionsBegin().addOffsetTo(getPCOffset());
}
+
+ public boolean getReexecute() {
+ int flags = (int)pcFlagsField.getValue(addr);
+ return ((flags & 0x1)== 1); //first is the reexecute bit
+ }
+
public void print(NMethod code) {
printOn(System.out, code);
}
diff -r 39e409a664b3 -r 84043c7507b9 agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java
--- a/agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java Thu Mar 25 16:27:12 2010 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java Thu Mar 25 16:54:59 2010 -0700
@@ -51,45 +51,46 @@
/** Scalar replaced bjects pool */
private List objects; // ArrayList
-
- public ScopeDesc(NMethod code, int decodeOffset) {
+ private ScopeDesc(NMethod code, int decodeOffset, List objects, boolean reexecute) {
this.code = code;
this.decodeOffset = decodeOffset;
- this.objects = decodeObjectValues(DebugInformationRecorder.SERIALIZED_NULL);
+ this.objects = objects;
+ this.reexecute = reexecute;
// Decode header
DebugInfoReadStream stream = streamAt(decodeOffset);
senderDecodeOffset = stream.readInt();
method = (Method) VM.getVM().getObjectHeap().newOop(stream.readOopHandle());
- setBCIAndReexecute(stream.readInt());
+ bci = stream.readBCI();
// Decode offsets for body and sender
localsDecodeOffset = stream.readInt();
expressionsDecodeOffset = stream.readInt();
monitorsDecodeOffset = stream.readInt();
}
- public ScopeDesc(NMethod code, int decodeOffset, int objectDecodeOffset) {
+ public ScopeDesc(NMethod code, int decodeOffset, int objectDecodeOffset, boolean reexecute) {
this.code = code;
this.decodeOffset = decodeOffset;
this.objects = decodeObjectValues(objectDecodeOffset);
+ this.reexecute = reexecute;
// Decode header
DebugInfoReadStream stream = streamAt(decodeOffset);
senderDecodeOffset = stream.readInt();
method = (Method) VM.getVM().getObjectHeap().newOop(stream.readOopHandle());
- setBCIAndReexecute(stream.readInt());
+ bci = stream.readBCI();
// Decode offsets for body and sender
localsDecodeOffset = stream.readInt();
expressionsDecodeOffset = stream.readInt();
monitorsDecodeOffset = stream.readInt();
}
- public NMethod getNMethod() { return code; }
- public Method getMethod() { return method; }
- public int getBCI() { return bci; }
- public boolean getReexecute() {return reexecute;}
+ public NMethod getNMethod() { return code; }
+ public Method getMethod() { return method; }
+ public int getBCI() { return bci; }
+ public boolean getReexecute() { return reexecute;}
/** Returns a List<ScopeValue> */
public List getLocals() {
@@ -106,7 +107,7 @@
return decodeMonitorValues(monitorsDecodeOffset);
}
- /** Returns a List<MonitorValue> */
+ /** Returns a List<ObjectValue> */
public List getObjects() {
return objects;
}
@@ -117,7 +118,7 @@
return null;
}
- return new ScopeDesc(code, senderDecodeOffset);
+ return new ScopeDesc(code, senderDecodeOffset, objects, false);
}
/** Returns where the scope was decoded */
@@ -151,8 +152,8 @@
public void printValueOn(PrintStream tty) {
tty.print("ScopeDesc for ");
method.printValueOn(tty);
- tty.println(" @bci " + bci);
- tty.println(" reexecute: " + reexecute);
+ tty.print(" @bci " + bci);
+ tty.println(" reexecute=" + reexecute);
}
// FIXME: add more accessors
@@ -160,12 +161,6 @@
//--------------------------------------------------------------------------------
// Internals only below this point
//
- private void setBCIAndReexecute(int combination) {
- int InvocationEntryBci = VM.getVM().getInvocationEntryBCI();
- bci = (combination >> 1) + InvocationEntryBci;
- reexecute = (combination & 1)==1 ? true : false;
- }
-
private DebugInfoReadStream streamAt(int decodeOffset) {
return new DebugInfoReadStream(code, decodeOffset, objects);
}
diff -r 39e409a664b3 -r 84043c7507b9 agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java Thu Mar 25 16:27:12 2010 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2009 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
diff -r 39e409a664b3 -r 84043c7507b9 agent/src/share/classes/sun/jvm/hotspot/memory/FreeChunk.java
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/FreeChunk.java Thu Mar 25 16:27:12 2010 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/FreeChunk.java Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2009 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
diff -r 39e409a664b3 -r 84043c7507b9 agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java Thu Mar 25 16:27:12 2010 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java Thu Mar 25 16:54:59 2010 -0700
@@ -63,12 +63,12 @@
javaSystemLoaderField = type.getOopField("_java_system_loader");
nofBuckets = db.lookupIntConstant("SystemDictionary::_nof_buckets").intValue();
- objectKlassField = type.getOopField(WK_KLASS("object_klass"));
- classLoaderKlassField = type.getOopField(WK_KLASS("classloader_klass"));
- stringKlassField = type.getOopField(WK_KLASS("string_klass"));
- systemKlassField = type.getOopField(WK_KLASS("system_klass"));
- threadKlassField = type.getOopField(WK_KLASS("thread_klass"));
- threadGroupKlassField = type.getOopField(WK_KLASS("threadGroup_klass"));
+ objectKlassField = type.getOopField(WK_KLASS("Object_klass"));
+ classLoaderKlassField = type.getOopField(WK_KLASS("ClassLoader_klass"));
+ stringKlassField = type.getOopField(WK_KLASS("String_klass"));
+ systemKlassField = type.getOopField(WK_KLASS("System_klass"));
+ threadKlassField = type.getOopField(WK_KLASS("Thread_klass"));
+ threadGroupKlassField = type.getOopField(WK_KLASS("ThreadGroup_klass"));
}
// This WK functions must follow the definitions in systemDictionary.hpp:
diff -r 39e409a664b3 -r 84043c7507b9 agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
--- a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Thu Mar 25 16:27:12 2010 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Thu Mar 25 16:54:59 2010 -0700
@@ -807,6 +807,9 @@
Interpreter interp = VM.getVM().getInterpreter();
if (interp.contains(pc)) {
InterpreterCodelet codelet = interp.getCodeletContaining(pc);
+ if (codelet == null) {
+ return "Unknown location in the Interpreter: " + pc;
+ }
return genHTML(codelet);
}
return genHTML(blob);
@@ -969,16 +972,24 @@
}
protected String genSafepointInfo(NMethod nm, PCDesc pcDesc) {
- ScopeDesc sd = nm.getScopeDescAt(pcDesc.getRealPC(nm));
- Formatter buf = new Formatter(genHTML);
- Formatter tabs = new Formatter(genHTML);
+ ScopeDesc sd = nm.getScopeDescAt(pcDesc.getRealPC(nm));
+ Formatter buf = new Formatter(genHTML);
+ Formatter tabs = new Formatter(genHTML);
+ tabs.append(tab + tab + tab); // Initial indent for debug info
+
+ buf.beginTag("pre");
+ genScope(buf, tabs, sd);
- buf.beginTag("pre");
- genScope(buf, tabs, sd);
- buf.endTag("pre");
- buf.append(genOopMapInfo(nm, pcDesc));
+ // Reset indent for scalar replaced objects
+ tabs = new Formatter(genHTML);
+ tabs.append(tab + tab + tab); // Initial indent for debug info
- return buf.toString();
+ genScObjInfo(buf, tabs, sd);
+ buf.endTag("pre");
+
+ buf.append(genOopMapInfo(nm, pcDesc));
+
+ return buf.toString();
}
protected void genScope(Formatter buf, Formatter tabs, ScopeDesc sd) {
@@ -1022,8 +1033,95 @@
buf.append(genHTMLForMonitors(sd, monitors));
}
+ buf.br();
tabs.append(tab);
- buf.br();
+ }
+
+ protected void genScObjInfo(Formatter buf, Formatter tabs, ScopeDesc sd) {
+ if (sd == null) {
+ return;
+ }
+
+ List objects = sd.getObjects();
+ if (objects == null) {
+ return;
+ }
+ int length = objects.size();
+ for (int i = 0; i < length; i++) {
+ buf.append(tabs);
+ ObjectValue ov = (ObjectValue)objects.get(i);
+ buf.append("ScObj" + i);
+ ScopeValue sv = ov.getKlass();
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(sv.isConstantOop(), "scalar replaced object klass must be constant oop");
+ }
+ ConstantOopReadValue klv = (ConstantOopReadValue)sv;
+ OopHandle klHandle = klv.getValue();
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(klHandle != null, "scalar replaced object klass must be not NULL");
+ }
+ Oop obj = VM.getVM().getObjectHeap().newOop(klHandle);
+ if (obj instanceof InstanceKlass) {
+ InstanceKlass kls = (InstanceKlass) obj;
+ buf.append(" " + kls.getName().asString() + "={");
+ int flen = ov.fieldsSize();
+
+ TypeArray klfields = kls.getFields();
+ int klen = (int) klfields.getLength();
+
+ ConstantPool cp = kls.getConstants();
+ int findex = 0;
+ for (int index = 0; index < klen; index += kls.NEXT_OFFSET) {
+ int accsFlags = klfields.getShortAt(index + kls.ACCESS_FLAGS_OFFSET);
+ int nameIndex = klfields.getShortAt(index + kls.NAME_INDEX_OFFSET);
+ AccessFlags access = new AccessFlags(accsFlags);
+ if (!access.isStatic()) {
+ ScopeValue svf = ov.getFieldAt(findex++);
+ String fstr = scopeValueAsString(sd, svf);
+ Symbol f_name = cp.getSymbolAt(nameIndex);
+ buf.append(" [" + f_name.asString() + " :"+ index + "]=(#" + fstr + ")");
+ }
+ }
+ buf.append(" }");
+ } else {
+ buf.append(" ");
+ int flen = ov.fieldsSize();
+ if (obj instanceof TypeArrayKlass) {
+ TypeArrayKlass kls = (TypeArrayKlass) obj;
+ buf.append(kls.getElementTypeName() + "[" + flen + "]");
+ } else if (obj instanceof ObjArrayKlass) {
+ ObjArrayKlass kls = (ObjArrayKlass) obj;
+ Klass elobj = kls.getBottomKlass();
+ if (elobj instanceof InstanceKlass) {
+ buf.append(elobj.getName().asString());
+ } else if (elobj instanceof TypeArrayKlass) {
+ TypeArrayKlass elkls = (TypeArrayKlass) elobj;
+ buf.append(elkls.getElementTypeName());
+ } else {
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(false, "unknown scalar replaced object klass!");
+ }
+ }
+ buf.append("[" + flen + "]");
+ int ndim = (int) kls.getDimension();
+ while (--ndim > 0) {
+ buf.append("[]");
+ }
+ } else {
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(false, "unknown scalar replaced object klass!");
+ }
+ }
+ buf.append("={");
+ for (int findex = 0; findex < flen; findex++) {
+ ScopeValue svf = ov.getFieldAt(findex);
+ String fstr = scopeValueAsString(sd, svf);
+ buf.append(" [" + findex + "]=(#" + fstr + ")");
+ }
+ buf.append(" }");
+ }
+ buf.br();
+ }
}
protected String genHTMLForOopMap(OopMap map) {
@@ -1037,8 +1135,6 @@
tmpBuf.beginTag("tr");
tmpBuf.beginTag("td");
tmpBuf.append(type);
- tmpBuf.endTag("td");
- tmpBuf.endTag("tr");
for (; ! oms.isDone(); oms.next()) {
OopMapValue omv = oms.getCurrent();
if (omv == null) {
@@ -1048,7 +1144,7 @@
VMReg vmReg = omv.getReg();
int reg = vmReg.getValue();
if (reg < stack0) {
- tmpBuf.append(VMRegImpl.getRegisterName(vmReg.getValue()));
+ tmpBuf.append(VMRegImpl.getRegisterName(reg));
} else {
tmpBuf.append('[');
tmpBuf.append(Integer.toString((reg - stack0) * 4));
@@ -1058,7 +1154,13 @@
tmpBuf.append(" = ");
VMReg vmContentReg = omv.getContentReg();
int contentReg = vmContentReg.getValue();
- tmpBuf.append(VMRegImpl.getRegisterName(vmContentReg.getValue()));
+ if (contentReg < stack0) {
+ tmpBuf.append(VMRegImpl.getRegisterName(contentReg));
+ } else {
+ tmpBuf.append('[');
+ tmpBuf.append(Integer.toString((contentReg - stack0) * 4));
+ tmpBuf.append(']');
+ }
}
tmpBuf.append(spaces);
}
@@ -1072,19 +1174,19 @@
OopMapValueIterator omvIterator = new OopMapValueIterator();
OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.OOP_VALUE);
- buf.append(omvIterator.iterate(oms, "Oop:", false));
+ buf.append(omvIterator.iterate(oms, "Oops:", false));
+
+ oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE);
+ buf.append(omvIterator.iterate(oms, "narrowOops:", false));
oms = new OopMapStream(map, OopMapValue.OopTypes.VALUE_VALUE);
- buf.append(omvIterator.iterate(oms, "Value:", false));
-
- oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE);
- buf.append(omvIterator.iterate(oms, "Oop:", false));
+ buf.append(omvIterator.iterate(oms, "Values:", false));
oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE);
buf.append(omvIterator.iterate(oms, "Callee saved:", true));
oms = new OopMapStream(map, OopMapValue.OopTypes.DERIVED_OOP_VALUE);
- buf.append(omvIterator.iterate(oms, "Derived oop:", true));
+ buf.append(omvIterator.iterate(oms, "Derived oops:", true));
buf.endTag("table");
return buf.toString();
@@ -1093,6 +1195,8 @@
protected String genOopMapInfo(NMethod nmethod, PCDesc pcDesc) {
OopMapSet mapSet = nmethod.getOopMaps();
+ if (mapSet == null || (mapSet.getSize() <= 0))
+ return "";
int pcOffset = pcDesc.getPCOffset();
OopMap map = mapSet.findMapAtOffset(pcOffset, VM.getVM().isDebugging());
if (map == null) {
@@ -1106,6 +1210,7 @@
Formatter buf = new Formatter(genHTML);
buf.beginTag("pre");
buf.append("OopMap: ");
+ buf.br();
buf.append(genHTMLForOopMap(map));
buf.endTag("pre");
@@ -1154,7 +1259,7 @@
return buf.toString();
}
- private String scopeValueAsString(ScopeValue sv) {
+ private String scopeValueAsString(ScopeDesc sd, ScopeValue sv) {
Formatter buf = new Formatter(genHTML);
if (sv.isConstantInt()) {
buf.append("int ");
@@ -1187,6 +1292,11 @@
} else {
buf.append("null");
}
+ } else if (sv.isObject()) {
+ ObjectValue ov = (ObjectValue)sv;
+ buf.append("#ScObj" + sd.getObjects().indexOf(ov));
+ } else {
+ buf.append("unknown scope value " + sv);
}
return buf.toString();
}
@@ -1219,7 +1329,7 @@
}
buf.append(", ");
- buf.append(scopeValueAsString(sv));
+ buf.append(scopeValueAsString(sd, sv));
buf.append(") ");
}
@@ -1246,7 +1356,7 @@
buf.append("(owner = ");
ScopeValue owner = mv.owner();
if (owner != null) {
- buf.append(scopeValueAsString(owner));
+ buf.append(scopeValueAsString(sd, owner));
} else {
buf.append("null");
}
@@ -1324,11 +1434,11 @@
buf.append(instr.asString(currentPc, symFinder));
}
+ buf.br();
if (isSafepoint && !prevWasCall) {
- buf.append(genSafepointInfo(nmethod, pcDesc));
+ buf.append(genSafepointInfo(nmethod, pcDesc));
}
- buf.br();
prevWasCall = instr.isCall();
}
diff -r 39e409a664b3 -r 84043c7507b9 agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Thu Mar 25 16:27:12 2010 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Thu Mar 25 16:54:59 2010 -0700
@@ -1047,7 +1047,7 @@
} else {
// some type names have ':'. replace to make it as a
// JavaScript identifier
- tmp.name = tmp.name.replace(':', '_');
+ tmp.name = tmp.name.replace(':', '_').replace('<', '_').replace('>', '_').replace('*', '_').replace(' ', '_');
eval("function read" + tmp.name + "(addr) {" +
" return readVMType('" + tmp.name + "', addr);}");
eval("function print" + tmp.name + "(addr) {" +
diff -r 39e409a664b3 -r 84043c7507b9 make/Makefile
--- a/make/Makefile Thu Mar 25 16:27:12 2010 -0700
+++ b/make/Makefile Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
#
-# Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2005-2010 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
@@ -84,6 +84,7 @@
C1_VM_TARGETS=product1 fastdebug1 optimized1 jvmg1
C2_VM_TARGETS=product fastdebug optimized jvmg
KERNEL_VM_TARGETS=productkernel fastdebugkernel optimizedkernel jvmgkernel
+ZERO_VM_TARGETS=productzero fastdebugzero optimizedzero jvmgzero
# JDK directory list
JDK_DIRS=bin include jre lib demo
@@ -94,6 +95,12 @@
all_debug: jvmg jvmg1 jvmgkernel docs export_debug
all_optimized: optimized optimized1 optimizedkernel docs export_optimized
+allzero: all_productzero all_fastdebugzero
+all_productzero: productzero docs export_product
+all_fastdebugzero: fastdebugzero docs export_fastdebug
+all_debugzero: jvmgzero docs export_debug
+all_optimizedzero: optimizedzero docs export_optimized
+
# Do everything
world: all create_jdk
@@ -120,6 +127,10 @@
$(CD) $(GAMMADIR)/make; \
$(MAKE) VM_TARGET=$@ generic_buildkernel $(ALT_OUT)
+$(ZERO_VM_TARGETS):
+ $(CD) $(GAMMADIR)/make; \
+ $(MAKE) VM_TARGET=$@ generic_buildzero $(ALT_OUT)
+
# Build compiler1 (client) rule, different for platforms
generic_build1:
$(MKDIR) -p $(OUTPUTDIR)
@@ -180,6 +191,12 @@
@$(ECHO) "No kernel ($(VM_TARGET)) for OS_NAME=$(OSNAME)"
endif
+generic_buildzero:
+ $(MKDIR) -p $(OUTPUTDIR)
+ $(CD) $(OUTPUTDIR); \
+ $(MAKE) -f $(ABS_OS_MAKEFILE) \
+ $(MAKE_ARGS) $(VM_TARGET)
+
# Export file rule
generic_export: $(EXPORT_LIST)
export_product:
@@ -210,11 +227,17 @@
C1_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler1
C2_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler2
KERNEL_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_kernel
+ZERO_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_zero
C1_DIR=$(C1_BASE_DIR)/$(VM_SUBDIR)
C2_DIR=$(C2_BASE_DIR)/$(VM_SUBDIR)
KERNEL_DIR=$(KERNEL_BASE_DIR)/$(VM_SUBDIR)
+ZERO_DIR=$(ZERO_BASE_DIR)/$(VM_SUBDIR)
# Misc files and generated files need to come from C1 or C2 area
+ifeq ($(ZERO_BUILD), true)
+ MISC_DIR=$(ZERO_DIR)
+ GEN_DIR=$(ZERO_BASE_DIR)/generated
+else
ifeq ($(ARCH_DATA_MODEL), 32)
MISC_DIR=$(C1_DIR)
GEN_DIR=$(C1_BASE_DIR)/generated
@@ -222,6 +245,7 @@
MISC_DIR=$(C2_DIR)
GEN_DIR=$(C2_BASE_DIR)/generated
endif
+endif
# Bin files (windows)
ifeq ($(OSNAME),windows)
@@ -265,6 +289,12 @@
# Shared Library
ifneq ($(OSNAME),windows)
+ ifeq ($(ZERO_BUILD), true)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(ZERO_DIR)/%.so
+ $(install-file)
+$(EXPORT_SERVER_DIR)/%.so: $(ZERO_DIR)/%.so
+ $(install-file)
+ else
$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(C2_DIR)/%.so
$(install-file)
$(EXPORT_CLIENT_DIR)/%.so: $(C1_DIR)/%.so
@@ -275,16 +305,20 @@
$(install-file)
$(EXPORT_SERVER_DIR)/64/%.so: $(C2_DIR)/%.so
$(install-file)
+ endif
endif
# Jar file (sa-jdi.jar)
$(EXPORT_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
$(install-file)
-# Include files (jvmti.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h)
+# Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h)
$(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/%
$(install-file)
+$(EXPORT_INCLUDE_DIR)/%: $(HS_SRC_DIR)/share/vm/code/%
+ $(install-file)
+
$(EXPORT_INCLUDE_DIR)/%: $(HS_SRC_DIR)/share/vm/prims/%
$(install-file)
@@ -313,6 +347,7 @@
$(RM) -r $(C1_DIR)
$(RM) -r $(C2_DIR)
$(RM) -r $(KERNEL_DIR)
+ $(RM) -r $(ZERO_DIR)
clean_export:
$(RM) -r $(EXPORT_PATH)
clean_jdk:
@@ -335,8 +370,10 @@
($(CD) $(JDK_IMAGE_DIR) && $(TAR) -xf -)
test_jdk:
- ifeq ($(ARCH_DATA_MODEL), 32)
+ ifneq ($(ZERO_BUILD), true)
+ ifeq ($(ARCH_DATA_MODEL), 32)
$(JDK_IMAGE_DIR)/bin/java -client -version
+ endif
endif
$(JDK_IMAGE_DIR)/bin/java -server -version
diff -r 39e409a664b3 -r 84043c7507b9 make/defs.make
--- a/make/defs.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/defs.make Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
#
-# Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2006-2010 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
@@ -192,13 +192,14 @@
# Use uname output for SRCARCH, but deal with platform differences. If ARCH
# is not explicitly listed below, it is treated as x86.
- SRCARCH = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64,$(ARCH)))
+ SRCARCH = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 zero,$(ARCH)))
ARCH/ = x86
ARCH/sparc = sparc
ARCH/sparc64= sparc
ARCH/ia64 = ia64
ARCH/amd64 = x86
ARCH/x86_64 = x86
+ ARCH/zero = zero
# BUILDARCH is usually the same as SRCARCH, except for sparcv9
BUILDARCH = $(SRCARCH)
@@ -222,8 +223,9 @@
LIBARCH/sparc = sparc
LIBARCH/sparcv9 = sparcv9
LIBARCH/ia64 = ia64
+ LIBARCH/zero = $(ZERO_LIBARCH)
- LP64_ARCH = sparcv9 amd64 ia64
+ LP64_ARCH = sparcv9 amd64 ia64 zero
endif
# Required make macro settings for all platforms
@@ -259,6 +261,7 @@
# Common export list of files
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jvmti.h
+EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jvmticmlr.h
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jni.h
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/$(JDK_INCLUDE_SUBDIR)/jni_md.h
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jmm.h
diff -r 39e409a664b3 -r 84043c7507b9 make/hotspot_version
--- a/make/hotspot_version Thu Mar 25 16:27:12 2010 -0700
+++ b/make/hotspot_version Thu Mar 25 16:54:59 2010 -0700
@@ -33,9 +33,9 @@
# Don't put quotes (fail windows build).
HOTSPOT_VM_COPYRIGHT=Copyright 2009
-HS_MAJOR_VER=16
+HS_MAJOR_VER=17
HS_MINOR_VER=0
-HS_BUILD_NUMBER=08
+HS_BUILD_NUMBER=10
JDK_MAJOR_VER=1
JDK_MINOR_VER=7
diff -r 39e409a664b3 -r 84043c7507b9 make/jprt.gmk
--- a/make/jprt.gmk Thu Mar 25 16:27:12 2010 -0700
+++ b/make/jprt.gmk Thu Mar 25 16:54:59 2010 -0700
@@ -29,17 +29,24 @@
MILESTONE=$(JPRT_BUILD_VERSION)
endif
+ifeq ($(OSNAME),windows)
+ ZIPFLAGS=-q
+else
+ # store symbolic links as the link
+ ZIPFLAGS=-q -y
+endif
+
jprt_build_product: all_product copy_product_jdk export_product_jdk
( $(CD) $(JDK_IMAGE_DIR) && \
- $(ZIPEXE) -q -r $(JPRT_ARCHIVE_BUNDLE) . )
+ $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
jprt_build_fastdebug: all_fastdebug copy_fastdebug_jdk export_fastdebug_jdk
( $(CD) $(JDK_IMAGE_DIR)/fastdebug && \
- $(ZIPEXE) -q -r $(JPRT_ARCHIVE_BUNDLE) . )
+ $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
jprt_build_debug: all_debug copy_debug_jdk export_debug_jdk
( $(CD) $(JDK_IMAGE_DIR)/debug && \
- $(ZIPEXE) -q -r $(JPRT_ARCHIVE_BUNDLE) . )
+ $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
.PHONY: jprt_build_product jprt_build_fastdebug jprt_build_debug
diff -r 39e409a664b3 -r 84043c7507b9 make/jprt.properties
--- a/make/jprt.properties Thu Mar 25 16:27:12 2010 -0700
+++ b/make/jprt.properties Thu Mar 25 16:54:59 2010 -0700
@@ -40,6 +40,10 @@
jprt.tools.default.release=${jprt.submit.release}
+# Disable syncing the source after builds and tests are done.
+
+jprt.sync.push=false
+
# Define the Solaris platforms we want for the various releases
jprt.my.solaris.sparc.jdk7=solaris_sparc_5.10
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/Makefile
--- a/make/linux/Makefile Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/Makefile Thu Mar 25 16:54:59 2010 -0700
@@ -132,6 +132,9 @@
endif
+# BUILDARCH is set to "zero" for Zero builds. VARIANTARCH
+# is used to give the build directories meaningful names.
+VARIANTARCH = $(subst i386,i486,$(ZERO_LIBARCH))
# There is a (semi-) regular correspondence between make targets and actions:
#
@@ -158,6 +161,13 @@
# profiledcore core __core/profiled
# productcore core __core/product
#
+# debugzero zero __zero/debug
+# fastdebugzero zero __zero/fastdebug
+# jvmgzero zero __zero/jvmg
+# optimizedzero zero __zero/optimized
+# profiledzero zero __zero/profiled
+# productzero zero __zero/product
+#
# What you get with each target:
#
# debug* - "thin" libjvm_g - debug info linked into the gamma_g launcher
@@ -171,16 +181,22 @@
# in the build.sh script:
TARGETS = debug jvmg fastdebug optimized profiled product
-SUBDIR_DOCS = $(OSNAME)_$(BUILDARCH)_docs
+ifeq ($(ZERO_BUILD), true)
+ SUBDIR_DOCS = $(OSNAME)_$(VARIANTARCH)_docs
+else
+ SUBDIR_DOCS = $(OSNAME)_$(BUILDARCH)_docs
+endif
SUBDIRS_C1 = $(addprefix $(OSNAME)_$(BUILDARCH)_compiler1/,$(TARGETS))
SUBDIRS_C2 = $(addprefix $(OSNAME)_$(BUILDARCH)_compiler2/,$(TARGETS))
SUBDIRS_TIERED = $(addprefix $(OSNAME)_$(BUILDARCH)_tiered/,$(TARGETS))
SUBDIRS_CORE = $(addprefix $(OSNAME)_$(BUILDARCH)_core/,$(TARGETS))
+SUBDIRS_ZERO = $(addprefix $(OSNAME)_$(VARIANTARCH)_zero/,$(TARGETS))
TARGETS_C2 = $(TARGETS)
TARGETS_C1 = $(addsuffix 1,$(TARGETS))
TARGETS_TIERED = $(addsuffix tiered,$(TARGETS))
TARGETS_CORE = $(addsuffix core,$(TARGETS))
+TARGETS_ZERO = $(addsuffix zero,$(TARGETS))
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OSNAME)/makefiles/buildtree.make
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) ARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH)
@@ -196,6 +212,7 @@
@echo " $(TARGETS_C2)"
@echo " $(TARGETS_C1)"
@echo " $(TARGETS_CORE)"
+ @echo " $(TARGETS_ZERO)"
checks: check_os_version check_j2se_version
@@ -245,6 +262,13 @@
$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
$(BUILDTREE) VARIANT=core
+$(SUBDIRS_ZERO): $(BUILDTREE_MAKE) platform_zero
+ $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
+ $(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH)
+
+platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in
+ $(SED) 's/@ZERO_ARCHDEF@/$(ZERO_ARCHDEF)/g;s/@ZERO_LIBARCH@/$(ZERO_LIBARCH)/g;' < $< > $@
+
# Define INSTALL=y at command line to automatically copy JVM into JAVA_HOME
$(TARGETS_C2): $(SUBDIRS_C2)
@@ -275,10 +299,18 @@
cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS) install
endif
+$(TARGETS_ZERO): $(SUBDIRS_ZERO)
+ cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS)
+ cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && ./test_gamma
+ifdef INSTALL
+ cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS) install
+endif
+
# Just build the tree, and nothing else:
tree: $(SUBDIRS_C2)
tree1: $(SUBDIRS_C1)
treecore: $(SUBDIRS_CORE)
+treezero: $(SUBDIRS_ZERO)
# Doc target. This is the same for all build options.
# Hence create a docs directory beside ...$(ARCH)_[...]
@@ -293,20 +325,22 @@
core: jvmgcore productcore
+zero: jvmgzero productzero
+
clean_docs:
rm -rf $(SUBDIR_DOCS)
-clean_compiler1 clean_compiler2 clean_core:
+clean_compiler1 clean_compiler2 clean_core clean_zero:
rm -rf $(OSNAME)_$(BUILDARCH)_$(subst clean_,,$@)
-clean: clean_compiler2 clean_compiler1 clean_core clean_docs
+clean: clean_compiler2 clean_compiler1 clean_core clean_zero clean_docs
include $(GAMMADIR)/make/$(OSNAME)/makefiles/cscope.make
#-------------------------------------------------------------------------------
-.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE)
-.PHONY: tree tree1 treecore
-.PHONY: all compiler1 compiler2 core
-.PHONY: clean clean_compiler1 clean_compiler2 clean_core docs clean_docs
+.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE) $(TARGETS_ZERO)
+.PHONY: tree tree1 treecore treezero
+.PHONY: all compiler1 compiler2 core zero
+.PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero docs clean_docs
.PHONY: checks check_os_version check_j2se_version
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/buildtree.make
--- a/make/linux/makefiles/buildtree.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/buildtree.make Thu Mar 25 16:54:59 2010 -0700
@@ -63,20 +63,30 @@
# For now, until the compiler is less wobbly:
TESTFLAGS = -Xbatch -showversion
-ifdef USE_SUNCC
-PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH).suncc
+ifeq ($(ZERO_BUILD), true)
+ PLATFORM_FILE = $(shell dirname $(shell dirname $(shell pwd)))/platform_zero
else
-PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH)
+ ifdef USE_SUNCC
+ PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH).suncc
+ else
+ PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH)
+ endif
+endif
+
+# Allow overriding of the arch part of the directory but default
+# to BUILDARCH if nothing is specified
+ifeq ($(VARIANTARCH),)
+ VARIANTARCH=$(BUILDARCH)
endif
ifdef FORCE_TIERED
ifeq ($(VARIANT),tiered)
-PLATFORM_DIR = $(OS_FAMILY)_$(BUILDARCH)_compiler2
+PLATFORM_DIR = $(OS_FAMILY)_$(VARIANTARCH)_compiler2
else
-PLATFORM_DIR = $(OS_FAMILY)_$(BUILDARCH)_$(VARIANT)
+PLATFORM_DIR = $(OS_FAMILY)_$(VARIANTARCH)_$(VARIANT)
endif
else
-PLATFORM_DIR = $(OS_FAMILY)_$(BUILDARCH)_$(VARIANT)
+PLATFORM_DIR = $(OS_FAMILY)_$(VARIANTARCH)_$(VARIANT)
endif
#
@@ -321,6 +331,7 @@
DATA_MODE/sparcv9 = 64
DATA_MODE/amd64 = 64
DATA_MODE/ia64 = 64
+DATA_MODE/zero = $(ARCH_DATA_MODEL)
JAVA_FLAG/32 = -d32
JAVA_FLAG/64 = -d64
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/debug.make
--- a/make/linux/makefiles/debug.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/debug.make Thu Mar 25 16:54:59 2010 -0700
@@ -38,7 +38,7 @@
"Please use 'make jvmg' to build debug JVM. \n" \
"----------------------------------------------------------------------\n")
-G_SUFFIX =
+G_SUFFIX = _g
VERSION = debug
SYSDEFS += -DASSERT -DDEBUG
PICFLAGS = DEFAULT
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/defs.make
--- a/make/linux/makefiles/defs.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/defs.make Thu Mar 25 16:54:59 2010 -0700
@@ -37,6 +37,17 @@
ARCH_DATA_MODEL ?= 32
endif
+# zero
+ifeq ($(ZERO_BUILD), true)
+ ifeq ($(ARCH_DATA_MODEL), 64)
+ MAKE_ARGS += LP64=1
+ endif
+ PLATFORM = linux-zero
+ VM_PLATFORM = linux_$(subst i386,i486,$(ZERO_LIBARCH))
+ HS_ARCH = zero
+ ARCH = zero
+endif
+
# ia64
ifeq ($(ARCH), ia64)
ARCH_DATA_MODEL = 64
@@ -93,21 +104,25 @@
VM_DEBUG=jvmg
EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
+
+# client and server subdirectories have symbolic links to ../libjsig.so
+EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so
+
EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjsig.so
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so
-ifeq ($(ARCH_DATA_MODEL), 32)
- EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjsig.so
- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so
- EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so
- EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
-else
- ifeq ($(ARCH),ia64)
- else
- EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so
- EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
+ifneq ($(ZERO_BUILD), true)
+ ifeq ($(ARCH_DATA_MODEL), 32)
+ EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so
+ EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so
+ EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
+ else
+ ifeq ($(ARCH),ia64)
+ else
+ EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so
+ EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
endif
+ endif
endif
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/fastdebug.make
--- a/make/linux/makefiles/fastdebug.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/fastdebug.make Thu Mar 25 16:54:59 2010 -0700
@@ -58,7 +58,7 @@
# Linker mapfile
MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug
-G_SUFFIX =
+G_SUFFIX = _g
VERSION = optimized
SYSDEFS += -DASSERT -DFASTDEBUG
PICFLAGS = DEFAULT
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/gcc.make
--- a/make/linux/makefiles/gcc.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/gcc.make Thu Mar 25 16:54:59 2010 -0700
@@ -52,6 +52,9 @@
VM_PICFLAG/AOUT =
VM_PICFLAG = $(VM_PICFLAG/$(LINK_INTO))
+ifeq ($(ZERO_BUILD), true)
+CFLAGS += $(LIBFFI_CFLAGS)
+endif
CFLAGS += $(VM_PICFLAG)
CFLAGS += -fno-rtti
CFLAGS += -fno-exceptions
@@ -64,6 +67,7 @@
ARCHFLAG/ia64 =
ARCHFLAG/sparc = -m32 -mcpu=v9
ARCHFLAG/sparcv9 = -m64 -mcpu=v9
+ARCHFLAG/zero = $(ZERO_ARCHFLAG)
CFLAGS += $(ARCHFLAG)
AOUT_FLAGS += $(ARCHFLAG)
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/jsig.make
--- a/make/linux/makefiles/jsig.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/jsig.make Thu Mar 25 16:54:59 2010 -0700
@@ -25,9 +25,12 @@
# Rules to build signal interposition library, used by vm.make
# libjsig[_g].so: signal interposition library
-JSIG = jsig$(G_SUFFIX)
+JSIG = jsig
LIBJSIG = lib$(JSIG).so
+JSIG_G = $(JSIG)$(G_SUFFIX)
+LIBJSIG_G = lib$(JSIG_G).so
+
JSIGSRCDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/vm
DEST_JSIG = $(JDK_LIBDIR)/$(LIBJSIG)
@@ -50,6 +53,7 @@
@echo Making signal interposition lib...
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
$(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) -o $@ $< -ldl
+ $(QUIETLY) [ -f $(LIBJSIG_G) ] || { ln -s $@ $(LIBJSIG_G); }
install_jsig: $(LIBJSIG)
@echo "Copying $(LIBJSIG) to $(DEST_JSIG)"
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/jvmg.make
--- a/make/linux/makefiles/jvmg.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/jvmg.make Thu Mar 25 16:54:59 2010 -0700
@@ -35,7 +35,7 @@
# Linker mapfile
MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug
-G_SUFFIX =
+G_SUFFIX = _g
VERSION = debug
SYSDEFS += -DASSERT -DDEBUG
PICFLAGS = DEFAULT
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/jvmti.make
--- a/make/linux/makefiles/jvmti.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/jvmti.make Thu Mar 25 16:54:59 2010 -0700
@@ -70,10 +70,10 @@
both = $(JvmtiGenClass) $(JvmtiSrcDir)/jvmti.xml $(JvmtiSrcDir)/jvmtiLib.xsl
$(JvmtiGenClass): $(JvmtiGenSource)
- $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiGenSource)
+ $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiGenSource)
$(JvmtiEnvFillClass): $(JvmtiEnvFillSource)
- $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
+ $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
$(JvmtiOutDir)/jvmtiEnter.cpp: $(both) $(JvmtiSrcDir)/jvmtiEnter.xsl
@echo Generating $@
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/launcher.make
--- a/make/linux/makefiles/launcher.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/launcher.make Thu Mar 25 16:54:59 2010 -0700
@@ -25,7 +25,9 @@
# Rules to build gamma launcher, used by vm.make
# gamma[_g]: launcher
-LAUNCHER = gamma$(G_SUFFIX)
+
+LAUNCHER = gamma
+LAUNCHER_G = $(LAUNCHER)$(G_SUFFIX)
LAUNCHERDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/launcher
LAUNCHERFLAGS = $(ARCHFLAG) \
@@ -70,4 +72,5 @@
$(LINK_LAUNCHER/PRE_HOOK) \
$(LINK_LAUNCHER) $(LFLAGS_LAUNCHER) -o $@ $(LAUNCHER.o) $(LIBS_LAUNCHER); \
$(LINK_LAUNCHER/POST_HOOK) \
+ [ -f $(LAUNCHER_G) ] || { ln -s $@ $(LAUNCHER_G); }; \
}
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/mapfile-vers-debug
--- a/make/linux/makefiles/mapfile-vers-debug Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/mapfile-vers-debug Thu Mar 25 16:54:59 2010 -0700
@@ -74,6 +74,7 @@
JVM_CurrentTimeMillis;
JVM_DefineClass;
JVM_DefineClassWithSource;
+ JVM_DefineClassWithSourceCond;
JVM_DesiredAssertionStatus;
JVM_DisableCompiler;
JVM_DoPrivileged;
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/mapfile-vers-product
--- a/make/linux/makefiles/mapfile-vers-product Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/mapfile-vers-product Thu Mar 25 16:54:59 2010 -0700
@@ -74,6 +74,7 @@
JVM_CurrentTimeMillis;
JVM_DefineClass;
JVM_DefineClassWithSource;
+ JVM_DefineClassWithSourceCond;
JVM_DesiredAssertionStatus;
JVM_DisableCompiler;
JVM_DoPrivileged;
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/rules.make
--- a/make/linux/makefiles/rules.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/rules.make Thu Mar 25 16:54:59 2010 -0700
@@ -122,12 +122,20 @@
endif
endif
+COMPILE.JAVAC += $(BOOTSTRAP_JAVAC_FLAGS)
+
SUM = /usr/bin/sum
# 'gmake MAKE_VERBOSE=y' gives all the gory details.
QUIETLY$(MAKE_VERBOSE) = @
RUN.JAR$(MAKE_VERBOSE) += >/dev/null
+# Settings for javac
+BOOT_SOURCE_LANGUAGE_VERSION = 6
+BOOT_TARGET_CLASS_VERSION = 6
+JAVAC_FLAGS = -g -encoding ascii
+BOOTSTRAP_JAVAC_FLAGS = $(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
+
# With parallel makes, print a message at the end of compilation.
ifeq ($(findstring j,$(MFLAGS)),j)
COMPILE_DONE = && { echo Done with $<; }
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/sa.make
--- a/make/linux/makefiles/sa.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/sa.make Thu Mar 25 16:54:59 2010 -0700
@@ -52,10 +52,10 @@
SA_PROPERTIES = $(SA_CLASSDIR)/sa.properties
# if $(AGENT_DIR) does not exist, we don't build SA
-# also, we don't build SA on Itanium.
+# also, we don't build SA on Itanium or zero.
all:
- if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" ] ; then \
+ if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" -a "$(SRCARCH)" != "zero" ] ; then \
$(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \
fi
@@ -74,8 +74,8 @@
mkdir -p $(SA_CLASSDIR); \
fi
- $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1)
- $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2)
+ $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1)
+ $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2)
$(QUIETLY) $(REMOTE) $(COMPILE.RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/saproc.make
--- a/make/linux/makefiles/saproc.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/saproc.make Thu Mar 25 16:54:59 2010 -0700
@@ -25,9 +25,13 @@
# Rules to build serviceability agent library, used by vm.make
# libsaproc[_g].so: serviceability agent
-SAPROC = saproc$(G_SUFFIX)
+
+SAPROC = saproc
LIBSAPROC = lib$(SAPROC).so
+SAPROC_G = $(SAPROC)$(G_SUFFIX)
+LIBSAPROC_G = lib$(SAPROC_G).so
+
AGENT_DIR = $(GAMMADIR)/agent
SASRCDIR = $(AGENT_DIR)/src/os/$(Platform_os_family)
@@ -49,10 +53,10 @@
endif
# if $(AGENT_DIR) does not exist, we don't build SA
-# also, we don't build SA on Itanium.
+# also, we don't build SA on Itanium or zero.
checkAndBuildSA:
- $(QUIETLY) if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" ] ; then \
+ $(QUIETLY) if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" -a "$(SRCARCH)" != "zero" ] ; then \
$(MAKE) -f vm.make $(LIBSAPROC); \
fi
@@ -75,6 +79,7 @@
$(SA_DEBUG_CFLAGS) \
-o $@ \
-lthread_db
+ $(QUIETLY) [ -f $(LIBSAPROC_G) ] || { ln -s $@ $(LIBSAPROC_G); }
install_saproc: checkAndBuildSA
$(QUIETLY) if [ -e $(LIBSAPROC) ] ; then \
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/top.make
--- a/make/linux/makefiles/top.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/top.make Thu Mar 25 16:54:59 2010 -0700
@@ -24,7 +24,7 @@
# top.make is included in the Makefile in the build directories.
# It DOES NOT include the vm dependency info in order to be faster.
-# It's main job is to implement the incremental form of make lists.
+# Its main job is to implement the incremental form of make lists.
# It also:
# -builds and runs adlc via adlc.make
# -generates JVMTI source and docs via jvmti.make (JSR-163)
@@ -74,6 +74,7 @@
Include_DBs/COMPILER1 = $(Include_DBs/CORE) $(VM)/includeDB_compiler1
Include_DBs/COMPILER2 = $(Include_DBs/CORE) $(VM)/includeDB_compiler2
Include_DBs/TIERED = $(Include_DBs/CORE) $(VM)/includeDB_compiler1 $(VM)/includeDB_compiler2
+Include_DBs/ZERO = $(Include_DBs/CORE) $(VM)/includeDB_zero
Include_DBs = $(Include_DBs/$(TYPE))
Cached_plat = $(GENERATED)/platform.current
@@ -114,7 +115,7 @@
# make makeDeps: (and zap the cached db files to force a nonincremental run)
$(GENERATED)/$(MakeDepsClass): $(MakeDepsSources)
- @$(REMOTE) $(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -g -d $(GENERATED) $(MakeDepsSources)
+ @$(REMOTE) $(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -d $(GENERATED) $(MakeDepsSources)
@echo Removing $(Incremental_Lists) to force regeneration.
@rm -f $(Incremental_Lists)
@$(CDG) echo >$(Cached_plat)
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/vm.make
--- a/make/linux/makefiles/vm.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/linux/makefiles/vm.make Thu Mar 25 16:54:59 2010 -0700
@@ -40,7 +40,11 @@
include $(GENERATED)/Dependencies
# read machine-specific adjustments (%%% should do this via buildtree.make?)
-include $(MAKEFILES_DIR)/$(BUILDARCH).make
+ifeq ($(ZERO_BUILD), true)
+ include $(MAKEFILES_DIR)/zeroshark.make
+else
+ include $(MAKEFILES_DIR)/$(BUILDARCH).make
+endif
# set VPATH so make knows where to look for source files
# Src_Dirs is everything in src/share/vm/*, plus the right os/*/vm and cpu/*/vm
@@ -109,8 +113,9 @@
#----------------------------------------------------------------------
# JVM
-JVM = jvm$(G_SUFFIX)
-LIBJVM = lib$(JVM).so
+JVM = jvm
+LIBJVM = lib$(JVM).so
+LIBJVM_G = lib$(JVM)$(G_SUFFIX).so
JVM_OBJ_FILES = $(Obj_Files)
@@ -124,7 +129,11 @@
rm -f $@
cat $^ > $@
-STATIC_CXX = true
+ifeq ($(ZERO_LIBARCH), ppc64)
+ STATIC_CXX = false
+else
+ STATIC_CXX = true
+endif
ifeq ($(LINK_INTO),AOUT)
LIBJVM.o =
@@ -148,6 +157,9 @@
LIBS_VM += $(LIBS)
endif
+ifeq ($(ZERO_BUILD), true)
+ LIBS_VM += $(LIBFFI_LIBS)
+endif
LINK_VM = $(LINK_LIB.c)
@@ -190,6 +202,7 @@
$(LFLAGS_VM) -o $@ $(LIBJVM.o) $(LIBS_VM); \
$(LINK_LIB.CC/POST_HOOK) \
rm -f $@.1; ln -s $@ $@.1; \
+ [ -f $(LIBJVM_G) ] || { ln -s $@ $(LIBJVM_G); ln -s $@.1 $(LIBJVM_G).1; }; \
if [ -x /usr/sbin/selinuxenabled ] ; then \
/usr/sbin/selinuxenabled; \
if [ $$? = 0 ] ; then \
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/zero.make
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/make/linux/makefiles/zero.make Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,32 @@
+#
+# Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2009 Red Hat, Inc.
+# 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.
+#
+#
+
+# Setup for Zero (non-Shark) version of VM
+
+# Select which includeDB files to use (in top.make)
+TYPE = ZERO
+
+# Install libjvm.so, etc in in server directory.
+VM_SUBDIR = server
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/makefiles/zeroshark.make
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/make/linux/makefiles/zeroshark.make Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,43 @@
+#
+# Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2007, 2008 Red Hat, Inc.
+# 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.
+#
+#
+
+# Setup common to Zero (non-Shark) and Shark versions of VM
+
+# The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized
+OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT)
+# The copied fdlibm routines in sharedRuntimeTrans.o must not be optimized
+OPT_CFLAGS/sharedRuntimeTrans.o = $(OPT_CFLAGS/NOOPT)
+
+# Specify that the CPU is little endian, if necessary
+ifeq ($(ZERO_ENDIANNESS), little)
+ CFLAGS += -DVM_LITTLE_ENDIAN
+endif
+
+# Specify that the CPU is 64 bit, if necessary
+ifeq ($(ARCH_DATA_MODEL), 64)
+ CFLAGS += -D_LP64=1
+endif
+
+OPT_CFLAGS/compactingPermGenGen.o = -O1
diff -r 39e409a664b3 -r 84043c7507b9 make/linux/platform_zero.in
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/make/linux/platform_zero.in Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,17 @@
+os_family = linux
+
+arch = zero
+
+arch_model = zero
+
+os_arch = linux_zero
+
+os_arch_model = linux_zero
+
+lib_arch = zero
+
+compiler = gcc
+
+gnu_dis_arch = zero
+
+sysdefs = -DLINUX -D_GNU_SOURCE -DCC_INTERP -DZERO -D@ZERO_ARCHDEF@ -DZERO_LIBARCH=\"@ZERO_LIBARCH@\"
diff -r 39e409a664b3 -r 84043c7507b9 make/solaris/makefiles/debug.make
--- a/make/solaris/makefiles/debug.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/solaris/makefiles/debug.make Thu Mar 25 16:54:59 2010 -0700
@@ -54,7 +54,7 @@
"Please use 'gnumake jvmg' to build debug JVM. \n" \
"-------------------------------------------------------------------------\n")
-G_SUFFIX =
+G_SUFFIX = _g
VERSION = debug
SYSDEFS += -DASSERT -DDEBUG
PICFLAGS = DEFAULT
diff -r 39e409a664b3 -r 84043c7507b9 make/solaris/makefiles/defs.make
--- a/make/solaris/makefiles/defs.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/solaris/makefiles/defs.make Thu Mar 25 16:54:59 2010 -0700
@@ -65,16 +65,18 @@
VM_DEBUG=jvmg
EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
+
+# client and server subdirectories have symbolic links to ../libjsig.so
+EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so
+
EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjsig.so
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.so
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.so
ifeq ($(ARCH_DATA_MODEL), 32)
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjsig.so
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.so
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.so
diff -r 39e409a664b3 -r 84043c7507b9 make/solaris/makefiles/dtrace.make
--- a/make/solaris/makefiles/dtrace.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/solaris/makefiles/dtrace.make Thu Mar 25 16:54:59 2010 -0700
@@ -24,8 +24,8 @@
# Rules to build jvm_db/dtrace, used by vm.make
-# we build libjvm_dtrace/libjvm_db/dtrace for COMPILER1 and COMPILER2
-# but not for CORE configuration
+# We build libjvm_dtrace/libjvm_db/dtrace for COMPILER1 and COMPILER2
+# but not for CORE or KERNEL configurations.
ifneq ("${TYPE}", "CORE")
ifneq ("${TYPE}", "KERNEL")
@@ -37,12 +37,13 @@
else
-
JVM_DB = libjvm_db
-LIBJVM_DB = libjvm$(G_SUFFIX)_db.so
+LIBJVM_DB = libjvm_db.so
+LIBJVM_DB_G = libjvm$(G_SUFFIX)_db.so
JVM_DTRACE = jvm_dtrace
-LIBJVM_DTRACE = libjvm$(G_SUFFIX)_dtrace.so
+LIBJVM_DTRACE = libjvm_dtrace.so
+LIBJVM_DTRACE_G = libjvm$(G_SUFFIX)_dtrace.so
JVMOFFS = JvmOffsets
JVMOFFS.o = $(JVMOFFS).o
@@ -77,7 +78,7 @@
LFLAGS_JVM_DTRACE += -D_REENTRANT $(PICFLAG)
else
LFLAGS_JVM_DB += -mt $(PICFLAG) -xnolib
-LFLAGS_JVM_DTRACE += -mt $(PICFLAG) -xnolib
+LFLAGS_JVM_DTRACE += -mt $(PICFLAG) -xnolib -ldl
endif
ISA = $(subst i386,i486,$(shell isainfo -n))
@@ -86,18 +87,24 @@
ifneq ("${ISA}","${BUILDARCH}")
XLIBJVM_DB = 64/$(LIBJVM_DB)
+XLIBJVM_DB_G = 64/$(LIBJVM_DB_G)
XLIBJVM_DTRACE = 64/$(LIBJVM_DTRACE)
+XLIBJVM_DTRACE_G = 64/$(LIBJVM_DTRACE_G)
$(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
@echo Making $@
$(QUIETLY) mkdir -p 64/ ; \
$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. -I$(GENERATED) \
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
+ [ -f $(XLIBJVM_DB_G) ] || { ln -s $(LIBJVM_DB) $(XLIBJVM_DB_G); }
+
$(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
@echo Making $@
$(QUIETLY) mkdir -p 64/ ; \
$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
+ [ -f $(XLIBJVM_DTRACE_G) ] || { ln -s $(LIBJVM_DTRACE) $(XLIBJVM_DTRACE_G); }
+
endif # ifneq ("${ISA}","${BUILDARCH}")
ifdef USE_GCC
@@ -142,11 +149,13 @@
@echo Making $@
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. -I$(GENERATED) \
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
+ [ -f $(LIBJVM_DB_G) ] || { ln -s $@ $(LIBJVM_DB_G); }
$(LIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
@echo Making $@
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. \
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
+ [ -f $(LIBJVM_DTRACE_G) ] || { ln -s $@ $(LIBJVM_DTRACE_G); }
$(DTRACE).d: $(DTRACE_SRCDIR)/hotspot.d $(DTRACE_SRCDIR)/hotspot_jni.d \
$(DTRACE_SRCDIR)/hs_private.d $(DTRACE_SRCDIR)/jhelper.d
diff -r 39e409a664b3 -r 84043c7507b9 make/solaris/makefiles/fastdebug.make
--- a/make/solaris/makefiles/fastdebug.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/solaris/makefiles/fastdebug.make Thu Mar 25 16:54:59 2010 -0700
@@ -90,7 +90,6 @@
# for this method for now. (fix this when dtrace bug 6258412 is fixed)
OPT_CFLAGS/ciEnv.o = $(OPT_CFLAGS) -xinline=no%__1cFciEnvbFpost_compiled_method_load_event6MpnHnmethod__v_
-
# (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
# If you set HOTSPARC_GENERIC=yes, you disable all OPT_CFLAGS settings
@@ -115,8 +114,7 @@
# and mustn't be otherwise.
MAPFILE_DTRACE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-$(TYPE)
-
-G_SUFFIX =
+G_SUFFIX = _g
VERSION = optimized
SYSDEFS += -DASSERT -DFASTDEBUG -DCHECK_UNHANDLED_OOPS
PICFLAGS = DEFAULT
diff -r 39e409a664b3 -r 84043c7507b9 make/solaris/makefiles/jsig.make
--- a/make/solaris/makefiles/jsig.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/solaris/makefiles/jsig.make Thu Mar 25 16:54:59 2010 -0700
@@ -25,8 +25,11 @@
# Rules to build signal interposition library, used by vm.make
# libjsig[_g].so: signal interposition library
-JSIG = jsig$(G_SUFFIX)
-LIBJSIG = lib$(JSIG).so
+JSIG = jsig
+LIBJSIG = lib$(JSIG).so
+
+JSIG_G = $(JSIG)$(G_SUFFIX)
+LIBJSIG_G = lib$(JSIG_G).so
JSIGSRCDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/vm
@@ -46,6 +49,7 @@
@echo Making signal interposition lib...
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
$(LFLAGS_JSIG) -o $@ $< -ldl
+ [ -f $(LIBJSIG_G) ] || { ln -s $@ $(LIBJSIG_G); }
install_jsig: $(LIBJSIG)
@echo "Copying $(LIBJSIG) to $(DEST_JSIG)"
diff -r 39e409a664b3 -r 84043c7507b9 make/solaris/makefiles/jvmg.make
--- a/make/solaris/makefiles/jvmg.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/solaris/makefiles/jvmg.make Thu Mar 25 16:54:59 2010 -0700
@@ -51,7 +51,7 @@
# and mustn't be otherwise.
MAPFILE_DTRACE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-$(TYPE)
-G_SUFFIX =
+G_SUFFIX = _g
VERSION = debug
SYSDEFS += -DASSERT -DDEBUG
PICFLAGS = DEFAULT
diff -r 39e409a664b3 -r 84043c7507b9 make/solaris/makefiles/jvmti.make
--- a/make/solaris/makefiles/jvmti.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/solaris/makefiles/jvmti.make Thu Mar 25 16:54:59 2010 -0700
@@ -69,10 +69,10 @@
both = $(JvmtiGenClass) $(JvmtiSrcDir)/jvmti.xml $(JvmtiSrcDir)/jvmtiLib.xsl
$(JvmtiGenClass): $(JvmtiGenSource)
- $(QUIETLY) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiGenSource)
+ $(QUIETLY) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiGenSource)
$(JvmtiEnvFillClass): $(JvmtiEnvFillSource)
- $(QUIETLY) $(COMPILE.JAVAC) -g -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
+ $(QUIETLY) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
$(JvmtiOutDir)/jvmtiEnter.cpp: $(both) $(JvmtiSrcDir)/jvmtiEnter.xsl
@echo Generating $@
diff -r 39e409a664b3 -r 84043c7507b9 make/solaris/makefiles/launcher.make
--- a/make/solaris/makefiles/launcher.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/solaris/makefiles/launcher.make Thu Mar 25 16:54:59 2010 -0700
@@ -25,7 +25,8 @@
# Rules to build gamma launcher, used by vm.make
# gamma[_g]: launcher
-LAUNCHER = gamma$(G_SUFFIX)
+LAUNCHER = gamma
+LAUNCHER_G = $(LAUNCHER)$(G_SUFFIX)
LAUNCHERDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/launcher
LAUNCHERFLAGS = $(ARCHFLAG) \
@@ -88,5 +89,6 @@
$(LINK_LAUNCHER/PRE_HOOK) \
$(LINK_LAUNCHER) $(LFLAGS_LAUNCHER) -o $@ $(LAUNCHER.o) $(LIBS_LAUNCHER); \
$(LINK_LAUNCHER/POST_HOOK) \
+ [ -f $(LAUNCHER_G) ] || { ln -s $@ $(LAUNCHER_G); }; \
;; \
esac
diff -r 39e409a664b3 -r 84043c7507b9 make/solaris/makefiles/mapfile-vers
--- a/make/solaris/makefiles/mapfile-vers Thu Mar 25 16:27:12 2010 -0700
+++ b/make/solaris/makefiles/mapfile-vers Thu Mar 25 16:54:59 2010 -0700
@@ -74,6 +74,7 @@
JVM_CurrentTimeMillis;
JVM_DefineClass;
JVM_DefineClassWithSource;
+ JVM_DefineClassWithSourceCond;
JVM_DesiredAssertionStatus;
JVM_DisableCompiler;
JVM_DoPrivileged;
diff -r 39e409a664b3 -r 84043c7507b9 make/solaris/makefiles/rules.make
--- a/make/solaris/makefiles/rules.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/solaris/makefiles/rules.make Thu Mar 25 16:54:59 2010 -0700
@@ -122,12 +122,20 @@
endif
endif
+COMPILE.JAVAC += $(BOOTSTRAP_JAVAC_FLAGS)
+
SUM = /usr/bin/sum
# 'gmake MAKE_VERBOSE=y' gives all the gory details.
QUIETLY$(MAKE_VERBOSE) = @
RUN.JAR$(MAKE_VERBOSE) += >/dev/null
+# Settings for javac
+BOOT_SOURCE_LANGUAGE_VERSION = 6
+BOOT_TARGET_CLASS_VERSION = 6
+JAVAC_FLAGS = -g -encoding ascii
+BOOTSTRAP_JAVAC_FLAGS = $(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
+
# With parallel makes, print a message at the end of compilation.
ifeq ($(findstring j,$(MFLAGS)),j)
COMPILE_DONE = && { echo Done with $<; }
diff -r 39e409a664b3 -r 84043c7507b9 make/solaris/makefiles/sa.make
--- a/make/solaris/makefiles/sa.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/solaris/makefiles/sa.make Thu Mar 25 16:54:59 2010 -0700
@@ -67,8 +67,8 @@
$(QUIETLY) if [ ! -d $(SA_CLASSDIR) ] ; then \
mkdir -p $(SA_CLASSDIR); \
fi
- $(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1)
- $(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2)
+ $(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1)
+ $(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2)
$(QUIETLY) $(COMPILE.RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
diff -r 39e409a664b3 -r 84043c7507b9 make/solaris/makefiles/saproc.make
--- a/make/solaris/makefiles/saproc.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/solaris/makefiles/saproc.make Thu Mar 25 16:54:59 2010 -0700
@@ -25,9 +25,13 @@
# Rules to build serviceability agent library, used by vm.make
# libsaproc[_g].so: serviceability agent
-SAPROC = saproc$(G_SUFFIX)
+
+SAPROC = saproc
LIBSAPROC = lib$(SAPROC).so
+SAPROC_G = $(SAPROC)$(G_SUFFIX)
+LIBSAPROC_G = lib$(SAPROC_G).so
+
AGENT_DIR = $(GAMMADIR)/agent
SASRCDIR = $(AGENT_DIR)/src/os/$(Platform_os_family)/proc
@@ -69,6 +73,7 @@
$(SA_LFLAGS) \
-o $@ \
-ldl -ldemangle -lthread -lc
+ [ -f $(LIBSAPROC_G) ] || { ln -s $@ $(LIBSAPROC_G); }
install_saproc: checkAndBuildSA
$(QUIETLY) if [ -f $(LIBSAPROC) ] ; then \
diff -r 39e409a664b3 -r 84043c7507b9 make/solaris/makefiles/sparcWorks.make
--- a/make/solaris/makefiles/sparcWorks.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/solaris/makefiles/sparcWorks.make Thu Mar 25 16:54:59 2010 -0700
@@ -281,8 +281,6 @@
OPT_CFLAGS=-xO4 $(EXTRA_OPT_CFLAGS)
endif
-CFLAGS += $(GAMMADIR)/src/os_cpu/solaris_sparc/vm/solaris_sparc.il
-
endif # sparc
ifeq ("${Platform_arch_model}", "x86_32")
@@ -293,13 +291,14 @@
# [phh] Is this still true for 6.1?
OPT_CFLAGS+=-xO3
-CFLAGS += $(GAMMADIR)/src/os_cpu/solaris_x86/vm/solaris_x86_32.il
-
endif # 32bit x86
# no more exceptions
CFLAGS/NOEX=-noex
+# Inline functions
+CFLAGS += $(GAMMADIR)/src/os_cpu/solaris_${Platform_arch}/vm/solaris_${Platform_arch_model}.il
+
# Reduce code bloat by reverting back to 5.0 behavior for static initializers
CFLAGS += -Qoption ccfe -one_static_init
@@ -312,6 +311,15 @@
PICFLAG/BETTER = $(PICFLAG/DEFAULT)
PICFLAG/BYFILE = $(PICFLAG/$@)$(PICFLAG/DEFAULT$(PICFLAG/$@))
+# Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file.
+MAPFLAG = -M FILENAME
+
+# Use $(SONAMEFLAG:SONAME=soname) to specify the intrinsic name of a shared obj
+SONAMEFLAG = -h SONAME
+
+# Build shared library
+SHARED_FLAG = -G
+
# Would be better if these weren't needed, since we link with CC, but
# at present removing them causes run-time errors
LFLAGS += -library=Crun
diff -r 39e409a664b3 -r 84043c7507b9 make/solaris/makefiles/top.make
--- a/make/solaris/makefiles/top.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/solaris/makefiles/top.make Thu Mar 25 16:54:59 2010 -0700
@@ -24,7 +24,7 @@
# top.make is included in the Makefile in the build directories.
# It DOES NOT include the vm dependency info in order to be faster.
-# It's main job is to implement the incremental form of make lists.
+# Its main job is to implement the incremental form of make lists.
# It also:
# -builds and runs adlc via adlc.make
# -generates JVMTI source and docs via jvmti.make (JSR-163)
@@ -112,7 +112,7 @@
# make makeDeps: (and zap the cached db files to force a nonincremental run)
$(GENERATED)/$(MakeDepsClass): $(MakeDepsSources)
- @$(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -g -d $(GENERATED) $(MakeDepsSources)
+ @$(COMPILE.JAVAC) -classpath $(GAMMADIR)/src/share/tools/MakeDeps -d $(GENERATED) $(MakeDepsSources)
@echo Removing $(Incremental_Lists) to force regeneration.
@rm -f $(Incremental_Lists)
@$(CDG) echo >$(Cached_plat)
diff -r 39e409a664b3 -r 84043c7507b9 make/solaris/makefiles/vm.make
--- a/make/solaris/makefiles/vm.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/solaris/makefiles/vm.make Thu Mar 25 16:54:59 2010 -0700
@@ -108,11 +108,16 @@
# older libm before libCrun, just to make sure it's found and used first.
LIBS += -lsocket -lsched -ldl $(LIBM) -lCrun -lthread -ldoor -lc
else
+ifeq ($(COMPILER_REV_NUMERIC), 502)
+# SC6.1 has it's own libm.so: specifying anything else provokes a name conflict.
+LIBS += -ldl -lthread -lsocket -lm -lsched -ldoor
+else
LIBS += -ldl -lthread -lsocket $(LIBM) -lsched -ldoor
-endif
+endif # 502
+endif # 505
else
LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc
-endif
+endif # sparcWorks
# By default, link the *.o into the library, not the executable.
LINK_INTO$(LINK_INTO) = LIBJVM
@@ -126,8 +131,9 @@
#----------------------------------------------------------------------
# JVM
-JVM = jvm$(G_SUFFIX)
-LIBJVM = lib$(JVM).so
+JVM = jvm
+LIBJVM = lib$(JVM).so
+LIBJVM_G = lib$(JVM)$(G_SUFFIX).so
JVM_OBJ_FILES = $(Obj_Files) $(DTRACE_OBJS)
@@ -173,11 +179,12 @@
-sbfast|-xsbfast) \
;; \
*) \
- echo Linking vm...; \
- $(LINK_LIB.CC/PRE_HOOK) \
- $(LINK_VM) $(LFLAGS_VM) -o $@ $(LIBJVM.o) $(LIBS_VM); \
- $(LINK_LIB.CC/POST_HOOK) \
- rm -f $@.1; ln -s $@ $@.1; \
+ echo Linking vm...; \
+ $(LINK_LIB.CC/PRE_HOOK) \
+ $(LINK_VM) $(LFLAGS_VM) -o $@ $(LIBJVM.o) $(LIBS_VM); \
+ $(LINK_LIB.CC/POST_HOOK) \
+ rm -f $@.1; ln -s $@ $@.1; \
+ [ -f $(LIBJVM_G) ] || { ln -s $@ $(LIBJVM_G); ln -s $@.1 $(LIBJVM_G).1; }; \
;; \
esac
diff -r 39e409a664b3 -r 84043c7507b9 make/windows/makefiles/generated.make
--- a/make/windows/makefiles/generated.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/windows/makefiles/generated.make Thu Mar 25 16:54:59 2010 -0700
@@ -91,7 +91,7 @@
classes/MakeDeps.class: $(MakeDepsSources)
if exist classes rmdir /s /q classes
mkdir classes
- $(COMPILE_JAVAC) -classpath $(WorkSpace)\src\share\tools\MakeDeps -g -d classes $(MakeDepsSources)
+ $(COMPILE_JAVAC) -classpath $(WorkSpace)\src\share\tools\MakeDeps -d classes $(MakeDepsSources)
!if ("$(Variant)" == "compiler2") || ("$(Variant)" == "tiered")
diff -r 39e409a664b3 -r 84043c7507b9 make/windows/makefiles/jvmti.make
--- a/make/windows/makefiles/jvmti.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/windows/makefiles/jvmti.make Thu Mar 25 16:54:59 2010 -0700
@@ -68,10 +68,10 @@
@if not exist $(JvmtiOutDir) mkdir $(JvmtiOutDir)
$(JvmtiGenClass): $(JvmtiGenSource)
- $(COMPILE_JAVAC) -g -d $(JvmtiOutDir) $(JvmtiGenSource)
+ $(COMPILE_JAVAC) -d $(JvmtiOutDir) $(JvmtiGenSource)
$(JvmtiEnvFillClass): $(JvmtiEnvFillSource)
- @$(COMPILE_JAVAC) -g -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
+ @$(COMPILE_JAVAC) -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
$(JvmtiOutDir)/jvmtiEnter.cpp: $(both) $(JvmtiSrcDir)/jvmtiEnter.xsl
@echo Generating $@
diff -r 39e409a664b3 -r 84043c7507b9 make/windows/makefiles/rules.make
--- a/make/windows/makefiles/rules.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/windows/makefiles/rules.make Thu Mar 25 16:54:59 2010 -0700
@@ -29,7 +29,7 @@
RUN_JAVAP=$(BootStrapDir)\bin\javap
RUN_JAVAH=$(BootStrapDir)\bin\javah
RUN_JAR=$(BootStrapDir)\bin\jar
-COMPILE_JAVAC=$(BootStrapDir)\bin\javac
+COMPILE_JAVAC=$(BootStrapDir)\bin\javac $(BOOTSTRAP_JAVAC_FLAGS)
COMPILE_RMIC=$(BootStrapDir)\bin\rmic
BOOT_JAVA_HOME=$(BootStrapDir)
!else
@@ -37,11 +37,17 @@
RUN_JAVAP=javap
RUN_JAVAH=javah
RUN_JAR=jar
-COMPILE_JAVAC=javac
+COMPILE_JAVAC=javac $(BOOTSTRAP_JAVAC_FLAGS)
COMPILE_RMIC=rmic
BOOT_JAVA_HOME=
!endif
+# Settings for javac
+BOOT_SOURCE_LANGUAGE_VERSION=6
+BOOT_TARGET_CLASS_VERSION=6
+JAVAC_FLAGS=-g -encoding ascii
+BOOTSTRAP_JAVAC_FLAGS=$(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
+
ProjectFile=vm.vcproj
!if "$(MSC_VER)" == "1200"
diff -r 39e409a664b3 -r 84043c7507b9 make/windows/makefiles/sa.make
--- a/make/windows/makefiles/sa.make Thu Mar 25 16:27:12 2010 -0700
+++ b/make/windows/makefiles/sa.make Thu Mar 25 16:54:59 2010 -0700
@@ -55,9 +55,9 @@
$(GENERATED)\sa-jdi.jar: $(AGENT_FILES1:/=\) $(AGENT_FILES2:/=\)
@if not exist $(SA_CLASSDIR) mkdir $(SA_CLASSDIR)
@echo ...Building sa-jdi.jar
- @echo ...$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -g -d $(SA_CLASSDIR) ....
- @$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1:/=\)
- @$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2:/=\)
+ @echo ...$(COMPILE_JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -d $(SA_CLASSDIR) ....
+ @$(COMPILE_JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1:/=\)
+ @$(COMPILE_JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2:/=\)
$(COMPILE_RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
$(QUIETLY) echo $(SA_BUILD_VERSION_PROP)> $(SA_PROPERTIES)
$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
diff -r 39e409a664b3 -r 84043c7507b9 make/windows/projectfiles/common/Makefile
--- a/make/windows/projectfiles/common/Makefile Thu Mar 25 16:27:12 2010 -0700
+++ b/make/windows/projectfiles/common/Makefile Thu Mar 25 16:54:59 2010 -0700
@@ -179,6 +179,6 @@
$(HOTSPOTBUILDSPACE)/classes/MakeDeps.class: $(MakeDepsSources)
@if exist $(HOTSPOTBUILDSPACE)\classes rmdir /s /q $(HOTSPOTBUILDSPACE)\classes
@mkdir $(HOTSPOTBUILDSPACE)\classes
- @$(COMPILE_JAVAC) -classpath $(HOTSPOTWORKSPACE)\src\share\tools\MakeDeps -g -d $(HOTSPOTBUILDSPACE)/classes $(MakeDepsSources)
+ @$(COMPILE_JAVAC) -classpath $(HOTSPOTWORKSPACE)\src\share\tools\MakeDeps -d $(HOTSPOTBUILDSPACE)/classes $(MakeDepsSources)
FORCE:
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/assembler_sparc.cpp
--- a/src/cpu/sparc/vm/assembler_sparc.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/assembler_sparc.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -2631,13 +2631,13 @@
(src.is_register() && src.as_register() == G0)) {
// do nothing
} else if (dest.is_register()) {
- add(dest.as_register(), ensure_rs2(src, temp), dest.as_register());
+ add(dest.as_register(), ensure_simm13_or_reg(src, temp), dest.as_register());
} else if (src.is_constant()) {
intptr_t res = dest.as_constant() + src.as_constant();
dest = RegisterOrConstant(res); // side effect seen by caller
} else {
assert(temp != noreg, "cannot handle constant += register");
- add(src.as_register(), ensure_rs2(dest, temp), temp);
+ add(src.as_register(), ensure_simm13_or_reg(dest, temp), temp);
dest = RegisterOrConstant(temp); // side effect seen by caller
}
}
@@ -2710,7 +2710,7 @@
RegisterOrConstant itable_offset = itable_index;
regcon_sll_ptr(itable_offset, exact_log2(itableMethodEntry::size() * wordSize));
regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes());
- add(recv_klass, ensure_rs2(itable_offset, sethi_temp), recv_klass);
+ add(recv_klass, ensure_simm13_or_reg(itable_offset, sethi_temp), recv_klass);
// for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
// if (scan->interface() == intf) {
@@ -4676,3 +4676,50 @@
load_ptr_contents(base, G6_heapbase);
}
}
+
+// Compare char[] arrays aligned to 4 bytes.
+void MacroAssembler::char_arrays_equals(Register ary1, Register ary2,
+ Register limit, Register result,
+ Register chr1, Register chr2, Label& Ldone) {
+ Label Lvector, Lloop;
+ assert(chr1 == result, "should be the same");
+
+ // Note: limit contains number of bytes (2*char_elements) != 0.
+ andcc(limit, 0x2, chr1); // trailing character ?
+ br(Assembler::zero, false, Assembler::pt, Lvector);
+ delayed()->nop();
+
+ // compare the trailing char
+ sub(limit, sizeof(jchar), limit);
+ lduh(ary1, limit, chr1);
+ lduh(ary2, limit, chr2);
+ cmp(chr1, chr2);
+ br(Assembler::notEqual, true, Assembler::pt, Ldone);
+ delayed()->mov(G0, result); // not equal
+
+ // only one char ?
+ br_on_reg_cond(rc_z, true, Assembler::pn, limit, Ldone);
+ delayed()->add(G0, 1, result); // zero-length arrays are equal
+
+ // word by word compare, dont't need alignment check
+ bind(Lvector);
+ // Shift ary1 and ary2 to the end of the arrays, negate limit
+ add(ary1, limit, ary1);
+ add(ary2, limit, ary2);
+ neg(limit, limit);
+
+ lduw(ary1, limit, chr1);
+ bind(Lloop);
+ lduw(ary2, limit, chr2);
+ cmp(chr1, chr2);
+ br(Assembler::notEqual, true, Assembler::pt, Ldone);
+ delayed()->mov(G0, result); // not equal
+ inccc(limit, 2*sizeof(jchar));
+ // annul LDUW if branch is not taken to prevent access past end of array
+ br(Assembler::notZero, true, Assembler::pt, Lloop);
+ delayed()->lduw(ary1, limit, chr1); // hoisted
+
+ // Caller should set it:
+ // add(G0, 1, result); // equals
+}
+
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/assembler_sparc.hpp
--- a/src/cpu/sparc/vm/assembler_sparc.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/assembler_sparc.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -1279,6 +1279,7 @@
// 171
+ inline void ldf(FloatRegisterImpl::Width w, Register s1, RegisterOrConstant s2, FloatRegister d);
inline void ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d);
inline void ldf(FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d, RelocationHolder const& rspec = RelocationHolder());
@@ -1535,7 +1536,8 @@
// pp 222
- inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2 );
+ inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, RegisterOrConstant s2);
+ inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2);
inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a);
inline void stf( FloatRegisterImpl::Width w, FloatRegister d, const Address& a, int offset = 0);
@@ -2049,12 +2051,13 @@
Register temp = noreg );
void regcon_sll_ptr( RegisterOrConstant& dest, RegisterOrConstant src,
Register temp = noreg );
- RegisterOrConstant ensure_rs2(RegisterOrConstant rs2, Register sethi_temp) {
- guarantee(sethi_temp != noreg, "constant offset overflow");
- if (is_simm13(rs2.constant_or_zero()))
- return rs2; // register or short constant
- set(rs2.as_constant(), sethi_temp);
- return sethi_temp;
+
+ RegisterOrConstant ensure_simm13_or_reg(RegisterOrConstant roc, Register Rtemp) {
+ guarantee(Rtemp != noreg, "constant offset overflow");
+ if (is_simm13(roc.constant_or_zero()))
+ return roc; // register or short constant
+ set(roc.as_constant(), Rtemp);
+ return RegisterOrConstant(Rtemp);
}
// --------------------------------------------------
@@ -2455,6 +2458,11 @@
void inc_counter(address counter_addr, Register Rtmp1, Register Rtmp2);
void inc_counter(int* counter_addr, Register Rtmp1, Register Rtmp2);
+ // Compare char[] arrays aligned to 4 bytes.
+ void char_arrays_equals(Register ary1, Register ary2,
+ Register limit, Register result,
+ Register chr1, Register chr2, Label& Ldone);
+
#undef VIRTUAL
};
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/assembler_sparc.inline.hpp
--- a/src/cpu/sparc/vm/assembler_sparc.inline.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/assembler_sparc.inline.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -99,6 +99,11 @@
inline void Assembler::jmpl( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); }
inline void Assembler::jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { emit_data( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); has_delay_slot(); }
+inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, RegisterOrConstant s2, FloatRegister d) {
+ if (s2.is_register()) ldf(w, s1, s2.as_register(), d);
+ else ldf(w, s1, s2.as_constant(), d);
+}
+
inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d) { emit_long( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | rs2(s2) ); }
inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d, RelocationHolder const& rspec) { emit_data( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); }
@@ -224,6 +229,11 @@
// pp 222
+inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, RegisterOrConstant s2) {
+ if (s2.is_register()) stf(w, d, s1, s2.as_register());
+ else stf(w, d, s1, s2.as_constant());
+}
+
inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2) { emit_long( op(ldst_op) | fd(d, w) | alt_op3(stf_op3, w) | rs1(s1) | rs2(s2) ); }
inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a) { emit_data( op(ldst_op) | fd(d, w) | alt_op3(stf_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
@@ -284,6 +294,7 @@
inline void Assembler::stb(Register d, Register s1, RegisterOrConstant s2) { stb(d, Address(s1, s2)); }
inline void Assembler::sth(Register d, Register s1, RegisterOrConstant s2) { sth(d, Address(s1, s2)); }
+inline void Assembler::stw(Register d, Register s1, RegisterOrConstant s2) { stw(d, Address(s1, s2)); }
inline void Assembler::stx(Register d, Register s1, RegisterOrConstant s2) { stx(d, Address(s1, s2)); }
inline void Assembler::std(Register d, Register s1, RegisterOrConstant s2) { std(d, Address(s1, s2)); }
inline void Assembler::st( Register d, Register s1, RegisterOrConstant s2) { st( d, Address(s1, s2)); }
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/c1_Defs_sparc.hpp
--- a/src/cpu/sparc/vm/c1_Defs_sparc.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/c1_Defs_sparc.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2009 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
@@ -38,7 +38,7 @@
// registers
enum {
pd_nof_cpu_regs_frame_map = 32, // number of registers used during code emission
- pd_nof_caller_save_cpu_regs_frame_map = 6, // number of cpu registers killed by calls
+ pd_nof_caller_save_cpu_regs_frame_map = 10, // number of cpu registers killed by calls
pd_nof_cpu_regs_reg_alloc = 20, // number of registers that are visible to register allocator
pd_nof_cpu_regs_linearscan = 32,// number of registers visible linear scan
pd_first_cpu_reg = 0,
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/c1_FrameMap_sparc.cpp
--- a/src/cpu/sparc/vm/c1_FrameMap_sparc.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/c1_FrameMap_sparc.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -320,6 +320,10 @@
_caller_save_cpu_regs[3] = FrameMap::O3_opr;
_caller_save_cpu_regs[4] = FrameMap::O4_opr;
_caller_save_cpu_regs[5] = FrameMap::O5_opr;
+ _caller_save_cpu_regs[6] = FrameMap::G1_opr;
+ _caller_save_cpu_regs[7] = FrameMap::G3_opr;
+ _caller_save_cpu_regs[8] = FrameMap::G4_opr;
+ _caller_save_cpu_regs[9] = FrameMap::G5_opr;
for (int i = 0; i < nof_caller_save_fpu_regs; i++) {
_caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i);
}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
--- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2010 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
@@ -189,14 +189,17 @@
Register OSR_buf = osrBufferPointer()->as_register();
{ assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
int monitor_offset = BytesPerWord * method()->max_locals() +
- (BasicObjectLock::size() * BytesPerWord) * (number_of_locks - 1);
+ (2 * BytesPerWord) * (number_of_locks - 1);
+ // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in
+ // the OSR buffer using 2 word entries: first the lock and then
+ // the oop.
for (int i = 0; i < number_of_locks; i++) {
- int slot_offset = monitor_offset - ((i * BasicObjectLock::size()) * BytesPerWord);
+ int slot_offset = monitor_offset - ((i * 2) * BytesPerWord);
#ifdef ASSERT
// verify the interpreter's monitor has a non-null object
{
Label L;
- __ ld_ptr(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes(), O7);
+ __ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7);
__ cmp(G0, O7);
__ br(Assembler::notEqual, false, Assembler::pt, L);
__ delayed()->nop();
@@ -205,9 +208,9 @@
}
#endif // ASSERT
// Copy the lock field into the compiled activation.
- __ ld_ptr(OSR_buf, slot_offset + BasicObjectLock::lock_offset_in_bytes(), O7);
+ __ ld_ptr(OSR_buf, slot_offset + 0, O7);
__ st_ptr(O7, frame_map()->address_for_monitor_lock(i));
- __ ld_ptr(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes(), O7);
+ __ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7);
__ st_ptr(O7, frame_map()->address_for_monitor_object(i));
}
}
@@ -354,7 +357,7 @@
}
-void LIR_Assembler::emit_exception_handler() {
+int LIR_Assembler::emit_exception_handler() {
// if the last instruction is a call (typically to do a throw which
// is coming at the end after block reordering) the return address
// must still point into the code area in order to avoid assertion
@@ -370,15 +373,12 @@
if (handler_base == NULL) {
// not enough space left for the handler
bailout("exception handler overflow");
- return;
+ return -1;
}
-#ifdef ASSERT
+
int offset = code_offset();
-#endif // ASSERT
- compilation()->offsets()->set_value(CodeOffsets::Exceptions, code_offset());
-
-
- if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_exceptions()) {
+
+ if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_on_exceptions()) {
__ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type);
__ delayed()->nop();
}
@@ -387,11 +387,13 @@
__ delayed()->nop();
debug_only(__ stop("should have gone to the caller");)
assert(code_offset() - offset <= exception_handler_size, "overflow");
-
__ end_a_stub();
+
+ return offset;
}
-void LIR_Assembler::emit_deopt_handler() {
+
+int LIR_Assembler::emit_deopt_handler() {
// if the last instruction is a call (typically to do a throw which
// is coming at the end after block reordering) the return address
// must still point into the code area in order to avoid assertion
@@ -405,23 +407,18 @@
if (handler_base == NULL) {
// not enough space left for the handler
bailout("deopt handler overflow");
- return;
+ return -1;
}
-#ifdef ASSERT
+
int offset = code_offset();
-#endif // ASSERT
- compilation()->offsets()->set_value(CodeOffsets::Deopt, code_offset());
-
AddressLiteral deopt_blob(SharedRuntime::deopt_blob()->unpack());
-
__ JUMP(deopt_blob, G3_scratch, 0); // sethi;jmp
__ delayed()->nop();
-
assert(code_offset() - offset <= deopt_handler_size, "overflow");
-
debug_only(__ stop("should have gone to the caller");)
-
__ end_a_stub();
+
+ return offset;
}
@@ -953,9 +950,11 @@
} else {
#ifdef _LP64
assert(base != to_reg->as_register_lo(), "can't handle this");
+ assert(O7 != to_reg->as_register_lo(), "can't handle this");
__ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_lo());
+ __ lduw(base, offset + lo_word_offset_in_bytes, O7); // in case O7 is base or offset, use it last
__ sllx(to_reg->as_register_lo(), 32, to_reg->as_register_lo());
- __ ld(base, offset + lo_word_offset_in_bytes, to_reg->as_register_lo());
+ __ or3(to_reg->as_register_lo(), O7, to_reg->as_register_lo());
#else
if (base == to_reg->as_register_lo()) {
__ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_hi());
@@ -976,8 +975,8 @@
FloatRegister reg = to_reg->as_double_reg();
// split unaligned loads
if (unaligned || PatchALot) {
- __ ldf(FloatRegisterImpl::S, base, offset + BytesPerWord, reg->successor());
- __ ldf(FloatRegisterImpl::S, base, offset, reg);
+ __ ldf(FloatRegisterImpl::S, base, offset + 4, reg->successor());
+ __ ldf(FloatRegisterImpl::S, base, offset, reg);
} else {
__ ldf(FloatRegisterImpl::D, base, offset, to_reg->as_double_reg());
}
@@ -2171,7 +2170,7 @@
// subtype which we can't check or src is the same array as dst
// but not necessarily exactly of type default_type.
Label known_ok, halt;
- jobject2reg(op->expected_type()->encoding(), tmp);
+ jobject2reg(op->expected_type()->constant_encoding(), tmp);
__ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
if (basic_type != T_OBJECT) {
__ cmp(tmp, tmp2);
@@ -2200,6 +2199,7 @@
Register len = O2;
__ add(src, arrayOopDesc::base_offset_in_bytes(basic_type), src_ptr);
+ LP64_ONLY(__ sra(src_pos, 0, src_pos);) //higher 32bits must be null
if (shift == 0) {
__ add(src_ptr, src_pos, src_ptr);
} else {
@@ -2208,6 +2208,7 @@
}
__ add(dst, arrayOopDesc::base_offset_in_bytes(basic_type), dst_ptr);
+ LP64_ONLY(__ sra(dst_pos, 0, dst_pos);) //higher 32bits must be null
if (shift == 0) {
__ add(dst_ptr, dst_pos, dst_ptr);
} else {
@@ -2429,7 +2430,7 @@
assert(data->is_BitData(), "need BitData for checkcast");
Register mdo = k_RInfo;
Register data_val = Rtmp1;
- jobject2reg(md->encoding(), mdo);
+ jobject2reg(md->constant_encoding(), mdo);
int mdo_offset_bias = 0;
if (!Assembler::is_simm13(md->byte_offset_of_slot(data, DataLayout::header_offset()) + data->size_in_bytes())) {
@@ -2452,7 +2453,7 @@
// patching may screw with our temporaries on sparc,
// so let's do it before loading the class
if (k->is_loaded()) {
- jobject2reg(k->encoding(), k_RInfo);
+ jobject2reg(k->constant_encoding(), k_RInfo);
} else {
jobject2reg_with_patching(k_RInfo, op->info_for_patch());
}
@@ -2513,7 +2514,7 @@
// patching may screw with our temporaries on sparc,
// so let's do it before loading the class
if (k->is_loaded()) {
- jobject2reg(k->encoding(), k_RInfo);
+ jobject2reg(k->constant_encoding(), k_RInfo);
} else {
jobject2reg_with_patching(k_RInfo, op->info_for_patch());
}
@@ -2717,7 +2718,7 @@
assert(op->tmp1()->is_single_cpu(), "tmp1 must be allocated");
Register mdo = op->mdo()->as_register();
Register tmp1 = op->tmp1()->as_register();
- jobject2reg(md->encoding(), mdo);
+ jobject2reg(md->constant_encoding(), mdo);
int mdo_offset_bias = 0;
if (!Assembler::is_simm13(md->byte_offset_of_slot(data, CounterData::count_offset()) +
data->size_in_bytes())) {
@@ -2729,9 +2730,6 @@
}
Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias);
- __ lduw(counter_addr, tmp1);
- __ add(tmp1, DataLayout::counter_increment, tmp1);
- __ stw(tmp1, counter_addr);
Bytecodes::Code bc = method->java_code_at_bci(bci);
// Perform additional virtual call profiling for invokevirtual and
// invokeinterface bytecodes
@@ -2774,7 +2772,7 @@
if (receiver == NULL) {
Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)) -
mdo_offset_bias);
- jobject2reg(known_klass->encoding(), tmp1);
+ jobject2reg(known_klass->constant_encoding(), tmp1);
__ st_ptr(tmp1, recv_addr);
Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)) -
mdo_offset_bias);
@@ -2821,15 +2819,23 @@
__ set(DataLayout::counter_increment, tmp1);
__ st_ptr(tmp1, mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)) -
mdo_offset_bias);
- if (i < (VirtualCallData::row_limit() - 1)) {
- __ br(Assembler::always, false, Assembler::pt, update_done);
- __ delayed()->nop();
- }
+ __ br(Assembler::always, false, Assembler::pt, update_done);
+ __ delayed()->nop();
__ bind(next_test);
}
+ // Receiver did not match any saved receiver and there is no empty row for it.
+ // Increment total counter to indicate polymorphic case.
+ __ lduw(counter_addr, tmp1);
+ __ add(tmp1, DataLayout::counter_increment, tmp1);
+ __ stw(tmp1, counter_addr);
__ bind(update_done);
}
+ } else {
+ // Static call
+ __ lduw(counter_addr, tmp1);
+ __ add(tmp1, DataLayout::counter_increment, tmp1);
+ __ stw(tmp1, counter_addr);
}
}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp
--- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -144,17 +144,17 @@
if (index->is_register()) {
// apply the shift and accumulate the displacement
if (shift > 0) {
- LIR_Opr tmp = new_register(T_INT);
+ LIR_Opr tmp = new_pointer_register();
__ shift_left(index, shift, tmp);
index = tmp;
}
if (disp != 0) {
- LIR_Opr tmp = new_register(T_INT);
+ LIR_Opr tmp = new_pointer_register();
if (Assembler::is_simm13(disp)) {
- __ add(tmp, LIR_OprFact::intConst(disp), tmp);
+ __ add(tmp, LIR_OprFact::intptrConst(disp), tmp);
index = tmp;
} else {
- __ move(LIR_OprFact::intConst(disp), tmp);
+ __ move(LIR_OprFact::intptrConst(disp), tmp);
__ add(tmp, index, tmp);
index = tmp;
}
@@ -162,8 +162,8 @@
}
} else if (disp != 0 && !Assembler::is_simm13(disp)) {
// index is illegal so replace it with the displacement loaded into a register
- index = new_register(T_INT);
- __ move(LIR_OprFact::intConst(disp), index);
+ index = new_pointer_register();
+ __ move(LIR_OprFact::intptrConst(disp), index);
disp = 0;
}
@@ -668,7 +668,7 @@
__ add(obj.result(), offset.result(), addr);
if (type == objectType) { // Write-barrier needed for Object fields.
- pre_barrier(obj.result(), false, NULL);
+ pre_barrier(addr, false, NULL);
}
if (type == objectType)
@@ -749,6 +749,10 @@
void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
assert(x->number_of_arguments() == 5, "wrong type");
+
+ // Make all state_for calls early since they can emit code
+ CodeEmitInfo* info = state_for(x, x->state());
+
// Note: spill caller save before setting the item
LIRItem src (x->argument_at(0), this);
LIRItem src_pos (x->argument_at(1), this);
@@ -767,7 +771,6 @@
ciArrayKlass* expected_type;
arraycopy_helper(x, &flags, &expected_type);
- CodeEmitInfo* info = state_for(x, x->state());
__ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(),
length.result(), rlock_callee_saved(T_INT),
expected_type, flags, info);
@@ -878,6 +881,9 @@
void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {
+ // Evaluate state_for early since it may emit code
+ CodeEmitInfo* info = state_for(x, x->state());
+
LIRItem length(x->length(), this);
length.load_item();
@@ -890,9 +896,8 @@
LIR_Opr len = length.result();
BasicType elem_type = x->elt_type();
- __ oop2reg(ciTypeArrayKlass::make(elem_type)->encoding(), klass_reg);
+ __ oop2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg);
- CodeEmitInfo* info = state_for(x, x->state());
CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);
__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);
@@ -902,7 +907,8 @@
void LIRGenerator::do_NewObjectArray(NewObjectArray* x) {
- LIRItem length(x->length(), this);
+ // Evaluate state_for early since it may emit code.
+ CodeEmitInfo* info = state_for(x, x->state());
// in case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction
// and therefore provide the state before the parameters have been consumed
CodeEmitInfo* patching_info = NULL;
@@ -910,6 +916,7 @@
patching_info = state_for(x, x->state_before());
}
+ LIRItem length(x->length(), this);
length.load_item();
const LIR_Opr reg = result_register_for(x->type());
@@ -919,7 +926,6 @@
LIR_Opr tmp4 = FrameMap::O1_oop_opr;
LIR_Opr klass_reg = FrameMap::G5_oop_opr;
LIR_Opr len = length.result();
- CodeEmitInfo* info = state_for(x, x->state());
CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info);
ciObject* obj = (ciObject*) ciObjArrayKlass::make(x->klass());
@@ -943,25 +949,22 @@
items->at_put(i, size);
}
- // need to get the info before, as the items may become invalid through item_free
+ // Evaluate state_for early since it may emit code.
CodeEmitInfo* patching_info = NULL;
if (!x->klass()->is_loaded() || PatchALot) {
patching_info = state_for(x, x->state_before());
// cannot re-use same xhandlers for multiple CodeEmitInfos, so
- // clone all handlers
+ // clone all handlers. This is handled transparently in other
+ // places by the CodeEmitInfo cloning logic but is handled
+ // specially here because a stub isn't being used.
x->set_exception_handlers(new XHandlers(x->exception_handlers()));
}
+ CodeEmitInfo* info = state_for(x, x->state());
i = dims->length();
while (i-- > 0) {
LIRItem* size = items->at(i);
- // if a patching_info was generated above then debug information for the state before
- // the call is going to be emitted. The LIRGenerator calls above may have left some values
- // in registers and that's been recorded in the CodeEmitInfo. In that case the items
- // for those values can't simply be freed if they are registers because the values
- // might be destroyed by store_stack_parameter. So in the case of patching, delay the
- // freeing of the items that already were in registers
size->load_item();
store_stack_parameter (size->result(),
in_ByteSize(STACK_BIAS +
@@ -972,8 +975,6 @@
// This instruction can be deoptimized in the slow path : use
// O0 as result register.
const LIR_Opr reg = result_register_for(x->type());
- CodeEmitInfo* info = state_for(x, x->state());
-
jobject2reg_with_patching(reg, x->klass(), patching_info);
LIR_Opr rank = FrameMap::O1_opr;
__ move(LIR_OprFact::intConst(x->rank()), rank);
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/c1_globals_sparc.hpp
--- a/src/cpu/sparc/vm/c1_globals_sparc.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/c1_globals_sparc.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -22,10 +22,9 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the client compiler.
// (see c1_globals.hpp)
-//
+
#ifndef TIERED
define_pd_global(bool, BackgroundCompilation, true );
define_pd_global(bool, CICompileOSR, true );
@@ -48,27 +47,24 @@
define_pd_global(bool, UseTLAB, true );
define_pd_global(bool, ProfileInterpreter, false);
define_pd_global(intx, FreqInlineSize, 325 );
-define_pd_global(intx, NewRatio, 8 ); // Design center runs on 1.3.1
define_pd_global(bool, ResizeTLAB, true );
define_pd_global(intx, ReservedCodeCacheSize, 32*M );
define_pd_global(intx, CodeCacheExpansionSize, 32*K );
define_pd_global(uintx,CodeCacheMinBlockLength, 1);
-define_pd_global(uintx, PermSize, 12*M );
-define_pd_global(uintx, MaxPermSize, 64*M );
-define_pd_global(bool, NeverActAsServerClassMachine, true);
+define_pd_global(uintx,PermSize, 12*M );
+define_pd_global(uintx,MaxPermSize, 64*M );
+define_pd_global(bool, NeverActAsServerClassMachine, true );
define_pd_global(intx, NewSizeThreadIncrease, 16*K );
-define_pd_global(uintx, DefaultMaxRAM, 1*G);
+define_pd_global(uint64_t,MaxRAM, 1ULL*G);
define_pd_global(intx, InitialCodeCacheSize, 160*K);
-#endif // TIERED
+#endif // !TIERED
define_pd_global(bool, UseTypeProfile, false);
define_pd_global(bool, RoundFPResults, false);
-
-define_pd_global(bool, LIRFillDelaySlots, true);
+define_pd_global(bool, LIRFillDelaySlots, true );
define_pd_global(bool, OptimizeSinglePrecision, false);
-define_pd_global(bool, CSEArrayLength, true);
+define_pd_global(bool, CSEArrayLength, true );
define_pd_global(bool, TwoOperandLIRForm, false);
-
-define_pd_global(intx, SafepointPollOffset, 0);
+define_pd_global(intx, SafepointPollOffset, 0 );
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/c2_globals_sparc.hpp
--- a/src/cpu/sparc/vm/c2_globals_sparc.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/c2_globals_sparc.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -59,7 +59,6 @@
define_pd_global(intx, FreqInlineSize, 175);
define_pd_global(intx, INTPRESSURE, 48); // large register set
define_pd_global(intx, InteriorEntryAlignment, 16); // = CodeEntryAlignment
-define_pd_global(intx, NewRatio, 2);
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
// The default setting 16/16 seems to work best.
// (For _228_jack 16/16 is 2% better than 4/4, 16/4, 32/32, 32/16, or 16/32.)
@@ -83,25 +82,25 @@
// sequence of instructions to load a 64 bit pointer.
//
// InitialCodeCacheSize derived from specjbb2000 run.
-define_pd_global(intx, InitialCodeCacheSize, 2048*K); // Integral multiple of CodeCacheExpansionSize
-define_pd_global(intx, ReservedCodeCacheSize, 48*M);
-define_pd_global(intx, CodeCacheExpansionSize, 64*K);
+define_pd_global(intx, InitialCodeCacheSize, 2048*K); // Integral multiple of CodeCacheExpansionSize
+define_pd_global(intx, ReservedCodeCacheSize, 48*M);
+define_pd_global(intx, CodeCacheExpansionSize, 64*K);
// Ergonomics related flags
-define_pd_global(uintx, DefaultMaxRAM, 32*G);
+define_pd_global(uint64_t,MaxRAM, 128ULL*G);
#else
// InitialCodeCacheSize derived from specjbb2000 run.
-define_pd_global(intx, InitialCodeCacheSize, 1536*K); // Integral multiple of CodeCacheExpansionSize
-define_pd_global(intx, ReservedCodeCacheSize, 32*M);
-define_pd_global(intx, CodeCacheExpansionSize, 32*K);
+define_pd_global(intx, InitialCodeCacheSize, 1536*K); // Integral multiple of CodeCacheExpansionSize
+define_pd_global(intx, ReservedCodeCacheSize, 32*M);
+define_pd_global(intx, CodeCacheExpansionSize, 32*K);
// Ergonomics related flags
-define_pd_global(uintx, DefaultMaxRAM, 1*G);
+define_pd_global(uint64_t,MaxRAM, 4ULL*G);
#endif
-define_pd_global(uintx,CodeCacheMinBlockLength, 4);
+define_pd_global(uintx,CodeCacheMinBlockLength, 4);
// Heap related flags
-define_pd_global(uintx, PermSize, ScaleForWordSize(16*M));
-define_pd_global(uintx, MaxPermSize, ScaleForWordSize(64*M));
+define_pd_global(uintx,PermSize, ScaleForWordSize(16*M));
+define_pd_global(uintx,MaxPermSize, ScaleForWordSize(64*M));
// Ergonomics related flags
define_pd_global(bool, NeverActAsServerClassMachine, false);
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/frame_sparc.cpp
--- a/src/cpu/sparc/vm/frame_sparc.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/frame_sparc.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -366,8 +366,9 @@
// as get_original_pc() needs correct value for unextended_sp()
if (_pc != NULL) {
_cb = CodeCache::find_blob(_pc);
- if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) {
- _pc = ((nmethod*)_cb)->get_original_pc(this);
+ address original_pc = nmethod::get_deopt_original_pc(this);
+ if (original_pc != NULL) {
+ _pc = original_pc;
_deopt_state = is_deoptimized;
} else {
_deopt_state = not_deoptimized;
@@ -519,9 +520,9 @@
_cb = CodeCache::find_blob(pc);
*O7_addr() = pc - pc_return_offset;
_cb = CodeCache::find_blob(_pc);
- if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) {
- address orig = ((nmethod*)_cb)->get_original_pc(this);
- assert(orig == _pc, "expected original to be stored before patching");
+ address original_pc = nmethod::get_deopt_original_pc(this);
+ if (original_pc != NULL) {
+ assert(original_pc == _pc, "expected original to be stored before patching");
_deopt_state = is_deoptimized;
} else {
_deopt_state = not_deoptimized;
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/globals_sparc.hpp
--- a/src/cpu/sparc/vm/globals_sparc.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/globals_sparc.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -22,10 +22,8 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the runtime system.
// (see globals.hpp)
-//
// For sparc we do not do call backs when a thread is in the interpreter, because the
// interpreter dispatch needs at least two instructions - first to load the dispatch address
@@ -41,26 +39,23 @@
define_pd_global(bool, ImplicitNullChecks, true); // Generate code for implicit null checks
define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast
-define_pd_global(intx, CodeEntryAlignment, 32);
-define_pd_global(uintx, TLABSize, 0);
-define_pd_global(uintx, NewSize, ScaleForWordSize((2048 * K) + (2 * (64 * K))));
-define_pd_global(intx, SurvivorRatio, 8);
-define_pd_global(intx, InlineFrequencyCount, 50); // we can use more inlining on the SPARC
-define_pd_global(intx, InlineSmallCode, 1500);
+define_pd_global(intx, CodeEntryAlignment, 32);
+define_pd_global(intx, InlineFrequencyCount, 50); // we can use more inlining on the SPARC
+define_pd_global(intx, InlineSmallCode, 1500);
#ifdef _LP64
// Stack slots are 2X larger in LP64 than in the 32 bit VM.
-define_pd_global(intx, ThreadStackSize, 1024);
-define_pd_global(intx, VMThreadStackSize, 1024);
+define_pd_global(intx, ThreadStackSize, 1024);
+define_pd_global(intx, VMThreadStackSize, 1024);
#else
-define_pd_global(intx, ThreadStackSize, 512);
-define_pd_global(intx, VMThreadStackSize, 512);
+define_pd_global(intx, ThreadStackSize, 512);
+define_pd_global(intx, VMThreadStackSize, 512);
#endif
define_pd_global(intx, StackYellowPages, 2);
define_pd_global(intx, StackRedPages, 1);
define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+1));
-define_pd_global(intx, PreInflateSpin, 40); // Determined by running design center
+define_pd_global(intx, PreInflateSpin, 40); // Determined by running design center
define_pd_global(bool, RewriteBytecodes, true);
define_pd_global(bool, RewriteFrequentPairs, true);
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/interp_masm_sparc.cpp
--- a/src/cpu/sparc/vm/interp_masm_sparc.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -1681,11 +1681,8 @@
// If no method data exists, go to profile_continue.
test_method_data_pointer(profile_continue);
- // We are making a call. Increment the count.
- increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
-
// Record the receiver type.
- record_klass_in_profile(receiver, scratch);
+ record_klass_in_profile(receiver, scratch, true);
// The method data pointer needs to be updated to reflect the new target.
update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size()));
@@ -1695,7 +1692,14 @@
void InterpreterMacroAssembler::record_klass_in_profile_helper(
Register receiver, Register scratch,
- int start_row, Label& done) {
+ int start_row, Label& done, bool is_virtual_call) {
+ if (TypeProfileWidth == 0) {
+ if (is_virtual_call) {
+ increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
+ }
+ return;
+ }
+
int last_row = VirtualCallData::row_limit() - 1;
assert(start_row <= last_row, "must be work left to do");
// Test this row for both the receiver and for null.
@@ -1711,6 +1715,7 @@
// See if the receiver is receiver[n].
int recvr_offset = in_bytes(VirtualCallData::receiver_offset(row));
test_mdp_data_at(recvr_offset, receiver, next_test, scratch);
+ // delayed()->tst(scratch);
// The receiver is receiver[n]. Increment count[n].
int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row));
@@ -1720,20 +1725,31 @@
bind(next_test);
if (test_for_null_also) {
+ Label found_null;
// Failed the equality check on receiver[n]... Test for null.
if (start_row == last_row) {
// The only thing left to do is handle the null case.
- brx(Assembler::notZero, false, Assembler::pt, done);
- delayed()->nop();
+ if (is_virtual_call) {
+ brx(Assembler::zero, false, Assembler::pn, found_null);
+ delayed()->nop();
+ // Receiver did not match any saved receiver and there is no empty row for it.
+ // Increment total counter to indicate polymorphic case.
+ increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
+ ba(false, done);
+ delayed()->nop();
+ bind(found_null);
+ } else {
+ brx(Assembler::notZero, false, Assembler::pt, done);
+ delayed()->nop();
+ }
break;
}
// Since null is rare, make it be the branch-taken case.
- Label found_null;
brx(Assembler::zero, false, Assembler::pn, found_null);
delayed()->nop();
// Put all the "Case 3" tests here.
- record_klass_in_profile_helper(receiver, scratch, start_row + 1, done);
+ record_klass_in_profile_helper(receiver, scratch, start_row + 1, done, is_virtual_call);
// Found a null. Keep searching for a matching receiver,
// but remember that this is an empty (unused) slot.
@@ -1750,16 +1766,18 @@
int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row));
mov(DataLayout::counter_increment, scratch);
set_mdp_data_at(count_offset, scratch);
- ba(false, done);
- delayed()->nop();
+ if (start_row > 0) {
+ ba(false, done);
+ delayed()->nop();
+ }
}
void InterpreterMacroAssembler::record_klass_in_profile(Register receiver,
- Register scratch) {
+ Register scratch, bool is_virtual_call) {
assert(ProfileInterpreter, "must be profiling");
Label done;
- record_klass_in_profile_helper(receiver, scratch, 0, done);
+ record_klass_in_profile_helper(receiver, scratch, 0, done, is_virtual_call);
bind (done);
}
@@ -1837,7 +1855,7 @@
mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
// Record the object type.
- record_klass_in_profile(klass, scratch);
+ record_klass_in_profile(klass, scratch, false);
}
// The method data pointer needs to be updated.
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/interp_masm_sparc.hpp
--- a/src/cpu/sparc/vm/interp_masm_sparc.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/interp_masm_sparc.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -290,9 +290,9 @@
void test_mdp_data_at(int offset, Register value, Label& not_equal_continue,
Register scratch);
- void record_klass_in_profile(Register receiver, Register scratch);
+ void record_klass_in_profile(Register receiver, Register scratch, bool is_virtual_call);
void record_klass_in_profile_helper(Register receiver, Register scratch,
- int start_row, Label& done);
+ int start_row, Label& done, bool is_virtual_call);
void update_mdp_by_offset(int offset_of_disp, Register scratch);
void update_mdp_by_offset(Register reg, int offset_of_disp,
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/interpreter_sparc.cpp
--- a/src/cpu/sparc/vm/interpreter_sparc.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/interpreter_sparc.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -394,6 +394,11 @@
}
+bool AbstractInterpreter::can_be_compiled(methodHandle m) {
+ // No special entry points that preclude compilation
+ return true;
+}
+
// This method tells the deoptimizer how big an interpreted frame must be:
int AbstractInterpreter::size_activation(methodOop method,
int tempcount,
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/sharedRuntime_sparc.cpp
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 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
@@ -107,7 +107,7 @@
// are saved in register windows - I's and L's in the caller's frame and O's in the stub frame
// (as the stub's I's) when the runtime routine called by the stub creates its frame.
int i;
- // Always make the frame size 16 bytr aligned.
+ // Always make the frame size 16 byte aligned.
int frame_size = round_to(additional_frame_words + register_save_size, 16);
// OopMap frame size is in c2 stack slots (sizeof(jint)) not bytes or words
int frame_size_in_slots = frame_size / sizeof(jint);
@@ -201,15 +201,14 @@
__ stx(G5, SP, ccr_offset+STACK_BIAS);
__ stxfsr(SP, fsr_offset+STACK_BIAS);
- // Save all the FP registers
+ // Save all the FP registers: 32 doubles (32 floats correspond to the 2 halves of the first 16 doubles)
int offset = d00_offset;
- for( int i=0; i<64; i+=2 ) {
+ for( int i=0; iset_callee_saved(VMRegImpl::stack2reg(offset>>2), f->as_VMReg());
- if (true) {
- map->set_callee_saved(VMRegImpl::stack2reg((offset + sizeof(float))>>2), f->as_VMReg()->next());
- }
+ map->set_callee_saved(VMRegImpl::stack2reg((offset + sizeof(float))>>2), f->as_VMReg()->next());
offset += sizeof(double);
}
@@ -224,7 +223,7 @@
void RegisterSaver::restore_live_registers(MacroAssembler* masm) {
// Restore all the FP registers
- for( int i=0; i<64; i+=2 ) {
+ for( int i=0; ias_VMReg();// as part of the load/store shuffle
if (!r_2->is_valid()) __ ld (base, ld_off, G1_scratch);
else __ ldx(base, ld_off, G1_scratch);
@@ -867,9 +865,11 @@
if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ARRAY) {
store_c2i_object(r, base, st_off);
} else if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) {
+#ifndef _LP64
if (TieredCompilation) {
assert(G1_forced || sig_bt[i] != T_LONG, "should not use register args for longs");
}
+#endif // _LP64
store_c2i_long(r, base, st_off, r_2->is_stack());
} else {
store_c2i_int(r, base, st_off);
@@ -1052,9 +1052,7 @@
// Load in argument order going down.
const int ld_off = (total_args_passed-i)*Interpreter::stackElementSize();
-#ifdef _LP64
set_Rdisp(G1_scratch);
-#endif // _LP64
VMReg r_1 = regs[i].first();
VMReg r_2 = regs[i].second();
@@ -1074,7 +1072,7 @@
#ifdef _LP64
// In V9, longs are given 2 64-bit slots in the interpreter, but the
// data is passed in only 1 slot.
- Register slot = (sig_bt[i]==T_LONG) ?
+ RegisterOrConstant slot = (sig_bt[i] == T_LONG) ?
next_arg_slot(ld_off) : arg_slot(ld_off);
__ ldx(Gargs, slot, r);
#else
@@ -1092,7 +1090,7 @@
// data is passed in only 1 slot. This code also handles longs that
// are passed on the stack, but need a stack-to-stack move through a
// spare float register.
- Register slot = (sig_bt[i]==T_LONG || sig_bt[i] == T_DOUBLE) ?
+ RegisterOrConstant slot = (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) ?
next_arg_slot(ld_off) : arg_slot(ld_off);
__ ldf(FloatRegisterImpl::D, Gargs, slot, r_1->as_FloatRegister());
#else
@@ -1109,8 +1107,9 @@
// Convert stack slot to an SP offset
int st_off = reg2offset(regs[i].first()) + STACK_BIAS;
// Store down the shuffled stack word. Target address _is_ aligned.
- if (!r_2->is_valid()) __ stf(FloatRegisterImpl::S, r_1->as_FloatRegister(), SP, st_off);
- else __ stf(FloatRegisterImpl::D, r_1->as_FloatRegister(), SP, st_off);
+ RegisterOrConstant slot = __ ensure_simm13_or_reg(st_off, Rdisp);
+ if (!r_2->is_valid()) __ stf(FloatRegisterImpl::S, r_1->as_FloatRegister(), SP, slot);
+ else __ stf(FloatRegisterImpl::D, r_1->as_FloatRegister(), SP, slot);
}
}
bool made_space = false;
@@ -1192,7 +1191,8 @@
// VMReg max_arg,
int comp_args_on_stack, // VMRegStackSlots
const BasicType *sig_bt,
- const VMRegPair *regs) {
+ const VMRegPair *regs,
+ AdapterFingerPrint* fingerprint) {
address i2c_entry = __ pc();
AdapterGenerator agen(masm);
@@ -1261,7 +1261,7 @@
agen.gen_c2i_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
__ flush();
- return new AdapterHandlerEntry(i2c_entry, c2i_entry, c2i_unverified_entry);
+ return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
}
@@ -3216,9 +3216,8 @@
Register Oreturn0 = O0;
Register Oreturn1 = O1;
Register O2UnrollBlock = O2;
- Register O3tmp = O3;
- Register I5exception_tmp = I5;
- Register G4exception_tmp = G4_scratch;
+ Register L0deopt_mode = L0;
+ Register G4deopt_mode = G4_scratch;
int frame_size_words;
Address saved_Freturn0_addr(FP, -sizeof(double) + STACK_BIAS);
#if !defined(_LP64) && defined(COMPILER2)
@@ -3268,7 +3267,7 @@
map = RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
__ ba(false, cont);
- __ delayed()->mov(Deoptimization::Unpack_deopt, I5exception_tmp);
+ __ delayed()->mov(Deoptimization::Unpack_deopt, L0deopt_mode);
int exception_offset = __ offset() - start;
@@ -3319,7 +3318,7 @@
#endif
__ ba(false, cont);
- __ delayed()->mov(Deoptimization::Unpack_exception, I5exception_tmp);;
+ __ delayed()->mov(Deoptimization::Unpack_exception, L0deopt_mode);;
//
// Reexecute entry, similar to c2 uncommon trap
@@ -3329,7 +3328,7 @@
// No need to update oop_map as each call to save_live_registers will produce identical oopmap
(void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
- __ mov(Deoptimization::Unpack_reexecute, I5exception_tmp);
+ __ mov(Deoptimization::Unpack_reexecute, L0deopt_mode);
__ bind(cont);
@@ -3352,14 +3351,14 @@
// NOTE: we know that only O0/O1 will be reloaded by restore_result_registers
// so this move will survive
- __ mov(I5exception_tmp, G4exception_tmp);
+ __ mov(L0deopt_mode, G4deopt_mode);
__ mov(O0, O2UnrollBlock->after_save());
RegisterSaver::restore_result_registers(masm);
Label noException;
- __ cmp(G4exception_tmp, Deoptimization::Unpack_exception); // Was exception pending?
+ __ cmp(G4deopt_mode, Deoptimization::Unpack_exception); // Was exception pending?
__ br(Assembler::notEqual, false, Assembler::pt, noException);
__ delayed()->nop();
@@ -3393,10 +3392,10 @@
}
#endif
__ set_last_Java_frame(SP, noreg);
- __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames), G2_thread, G4exception_tmp);
+ __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames), G2_thread, G4deopt_mode);
#else
// LP64 uses g4 in set_last_Java_frame
- __ mov(G4exception_tmp, O1);
+ __ mov(G4deopt_mode, O1);
__ set_last_Java_frame(SP, G0);
__ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames), G2_thread, O1);
#endif
@@ -3449,7 +3448,6 @@
#endif
MacroAssembler* masm = new MacroAssembler(&buffer);
Register O2UnrollBlock = O2;
- Register O3tmp = O3;
Register O2klass_index = O2;
//
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/sparc.ad
--- a/src/cpu/sparc/vm/sparc.ad Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/sparc.ad Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
//
-// Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
+// Copyright 1998-2010 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
@@ -193,38 +193,38 @@
// I believe we can't handle callee-save doubles D32 and up until
// the place in the sparc stack crawler that asserts on the 255 is
// fixed up.
-reg_def R_D32x(SOC, SOC, Op_RegD,255, F32->as_VMReg());
-reg_def R_D32 (SOC, SOC, Op_RegD, 1, F32->as_VMReg()->next());
-reg_def R_D34x(SOC, SOC, Op_RegD,255, F34->as_VMReg());
-reg_def R_D34 (SOC, SOC, Op_RegD, 3, F34->as_VMReg()->next());
-reg_def R_D36x(SOC, SOC, Op_RegD,255, F36->as_VMReg());
-reg_def R_D36 (SOC, SOC, Op_RegD, 5, F36->as_VMReg()->next());
-reg_def R_D38x(SOC, SOC, Op_RegD,255, F38->as_VMReg());
-reg_def R_D38 (SOC, SOC, Op_RegD, 7, F38->as_VMReg()->next());
-reg_def R_D40x(SOC, SOC, Op_RegD,255, F40->as_VMReg());
-reg_def R_D40 (SOC, SOC, Op_RegD, 9, F40->as_VMReg()->next());
-reg_def R_D42x(SOC, SOC, Op_RegD,255, F42->as_VMReg());
-reg_def R_D42 (SOC, SOC, Op_RegD, 11, F42->as_VMReg()->next());
-reg_def R_D44x(SOC, SOC, Op_RegD,255, F44->as_VMReg());
-reg_def R_D44 (SOC, SOC, Op_RegD, 13, F44->as_VMReg()->next());
-reg_def R_D46x(SOC, SOC, Op_RegD,255, F46->as_VMReg());
-reg_def R_D46 (SOC, SOC, Op_RegD, 15, F46->as_VMReg()->next());
-reg_def R_D48x(SOC, SOC, Op_RegD,255, F48->as_VMReg());
-reg_def R_D48 (SOC, SOC, Op_RegD, 17, F48->as_VMReg()->next());
-reg_def R_D50x(SOC, SOC, Op_RegD,255, F50->as_VMReg());
-reg_def R_D50 (SOC, SOC, Op_RegD, 19, F50->as_VMReg()->next());
-reg_def R_D52x(SOC, SOC, Op_RegD,255, F52->as_VMReg());
-reg_def R_D52 (SOC, SOC, Op_RegD, 21, F52->as_VMReg()->next());
-reg_def R_D54x(SOC, SOC, Op_RegD,255, F54->as_VMReg());
-reg_def R_D54 (SOC, SOC, Op_RegD, 23, F54->as_VMReg()->next());
-reg_def R_D56x(SOC, SOC, Op_RegD,255, F56->as_VMReg());
-reg_def R_D56 (SOC, SOC, Op_RegD, 25, F56->as_VMReg()->next());
-reg_def R_D58x(SOC, SOC, Op_RegD,255, F58->as_VMReg());
-reg_def R_D58 (SOC, SOC, Op_RegD, 27, F58->as_VMReg()->next());
-reg_def R_D60x(SOC, SOC, Op_RegD,255, F60->as_VMReg());
-reg_def R_D60 (SOC, SOC, Op_RegD, 29, F60->as_VMReg()->next());
-reg_def R_D62x(SOC, SOC, Op_RegD,255, F62->as_VMReg());
-reg_def R_D62 (SOC, SOC, Op_RegD, 31, F62->as_VMReg()->next());
+reg_def R_D32 (SOC, SOC, Op_RegD, 1, F32->as_VMReg());
+reg_def R_D32x(SOC, SOC, Op_RegD,255, F32->as_VMReg()->next());
+reg_def R_D34 (SOC, SOC, Op_RegD, 3, F34->as_VMReg());
+reg_def R_D34x(SOC, SOC, Op_RegD,255, F34->as_VMReg()->next());
+reg_def R_D36 (SOC, SOC, Op_RegD, 5, F36->as_VMReg());
+reg_def R_D36x(SOC, SOC, Op_RegD,255, F36->as_VMReg()->next());
+reg_def R_D38 (SOC, SOC, Op_RegD, 7, F38->as_VMReg());
+reg_def R_D38x(SOC, SOC, Op_RegD,255, F38->as_VMReg()->next());
+reg_def R_D40 (SOC, SOC, Op_RegD, 9, F40->as_VMReg());
+reg_def R_D40x(SOC, SOC, Op_RegD,255, F40->as_VMReg()->next());
+reg_def R_D42 (SOC, SOC, Op_RegD, 11, F42->as_VMReg());
+reg_def R_D42x(SOC, SOC, Op_RegD,255, F42->as_VMReg()->next());
+reg_def R_D44 (SOC, SOC, Op_RegD, 13, F44->as_VMReg());
+reg_def R_D44x(SOC, SOC, Op_RegD,255, F44->as_VMReg()->next());
+reg_def R_D46 (SOC, SOC, Op_RegD, 15, F46->as_VMReg());
+reg_def R_D46x(SOC, SOC, Op_RegD,255, F46->as_VMReg()->next());
+reg_def R_D48 (SOC, SOC, Op_RegD, 17, F48->as_VMReg());
+reg_def R_D48x(SOC, SOC, Op_RegD,255, F48->as_VMReg()->next());
+reg_def R_D50 (SOC, SOC, Op_RegD, 19, F50->as_VMReg());
+reg_def R_D50x(SOC, SOC, Op_RegD,255, F50->as_VMReg()->next());
+reg_def R_D52 (SOC, SOC, Op_RegD, 21, F52->as_VMReg());
+reg_def R_D52x(SOC, SOC, Op_RegD,255, F52->as_VMReg()->next());
+reg_def R_D54 (SOC, SOC, Op_RegD, 23, F54->as_VMReg());
+reg_def R_D54x(SOC, SOC, Op_RegD,255, F54->as_VMReg()->next());
+reg_def R_D56 (SOC, SOC, Op_RegD, 25, F56->as_VMReg());
+reg_def R_D56x(SOC, SOC, Op_RegD,255, F56->as_VMReg()->next());
+reg_def R_D58 (SOC, SOC, Op_RegD, 27, F58->as_VMReg());
+reg_def R_D58x(SOC, SOC, Op_RegD,255, F58->as_VMReg()->next());
+reg_def R_D60 (SOC, SOC, Op_RegD, 29, F60->as_VMReg());
+reg_def R_D60x(SOC, SOC, Op_RegD,255, F60->as_VMReg()->next());
+reg_def R_D62 (SOC, SOC, Op_RegD, 31, F62->as_VMReg());
+reg_def R_D62x(SOC, SOC, Op_RegD,255, F62->as_VMReg()->next());
// ----------------------------
@@ -1803,8 +1803,9 @@
// to implement the UseStrictFP mode.
const bool Matcher::strict_fp_requires_explicit_rounding = false;
-// Do floats take an entire double register or just half?
-const bool Matcher::float_in_double = false;
+// Are floats conerted to double when stored to stack during deoptimization?
+// Sparc does not handle callee-save floats.
+bool Matcher::float_in_double() { return false; }
// Do ints take an entire long register or just half?
// Note that we if-def off of _LP64.
@@ -1885,6 +1886,10 @@
return RegMask();
}
+const RegMask Matcher::method_handle_invoke_SP_save_mask() {
+ return RegMask();
+}
+
%}
@@ -2838,63 +2843,41 @@
%}
- enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
+ enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result) %{
Label Ldone, Lloop;
MacroAssembler _masm(&cbuf);
Register str1_reg = reg_to_register_object($str1$$reg);
Register str2_reg = reg_to_register_object($str2$$reg);
- Register tmp1_reg = reg_to_register_object($tmp1$$reg);
- Register tmp2_reg = reg_to_register_object($tmp2$$reg);
+ Register cnt1_reg = reg_to_register_object($cnt1$$reg);
+ Register cnt2_reg = reg_to_register_object($cnt2$$reg);
Register result_reg = reg_to_register_object($result$$reg);
- // Get the first character position in both strings
- // [8] char array, [12] offset, [16] count
- int value_offset = java_lang_String:: value_offset_in_bytes();
- int offset_offset = java_lang_String::offset_offset_in_bytes();
- int count_offset = java_lang_String:: count_offset_in_bytes();
-
- // load str1 (jchar*) base address into tmp1_reg
- __ load_heap_oop(str1_reg, value_offset, tmp1_reg);
- __ ld(str1_reg, offset_offset, result_reg);
- __ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg);
- __ ld(str1_reg, count_offset, str1_reg); // hoisted
- __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
- __ load_heap_oop(str2_reg, value_offset, tmp2_reg); // hoisted
- __ add(result_reg, tmp1_reg, tmp1_reg);
-
- // load str2 (jchar*) base address into tmp2_reg
- // __ ld_ptr(str2_reg, value_offset, tmp2_reg); // hoisted
- __ ld(str2_reg, offset_offset, result_reg);
- __ add(tmp2_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp2_reg);
- __ ld(str2_reg, count_offset, str2_reg); // hoisted
- __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
- __ subcc(str1_reg, str2_reg, O7); // hoisted
- __ add(result_reg, tmp2_reg, tmp2_reg);
+ assert(result_reg != str1_reg &&
+ result_reg != str2_reg &&
+ result_reg != cnt1_reg &&
+ result_reg != cnt2_reg ,
+ "need different registers");
// Compute the minimum of the string lengths(str1_reg) and the
// difference of the string lengths (stack)
- // discard string base pointers, after loading up the lengths
- // __ ld(str1_reg, count_offset, str1_reg); // hoisted
- // __ ld(str2_reg, count_offset, str2_reg); // hoisted
-
// See if the lengths are different, and calculate min in str1_reg.
// Stash diff in O7 in case we need it for a tie-breaker.
Label Lskip;
- // __ subcc(str1_reg, str2_reg, O7); // hoisted
- __ sll(str1_reg, exact_log2(sizeof(jchar)), str1_reg); // scale the limit
+ __ subcc(cnt1_reg, cnt2_reg, O7);
+ __ sll(cnt1_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit
__ br(Assembler::greater, true, Assembler::pt, Lskip);
- // str2 is shorter, so use its count:
- __ delayed()->sll(str2_reg, exact_log2(sizeof(jchar)), str1_reg); // scale the limit
+ // cnt2 is shorter, so use its count:
+ __ delayed()->sll(cnt2_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit
__ bind(Lskip);
- // reallocate str1_reg, str2_reg, result_reg
+ // reallocate cnt1_reg, cnt2_reg, result_reg
// Note: limit_reg holds the string length pre-scaled by 2
- Register limit_reg = str1_reg;
- Register chr2_reg = str2_reg;
+ Register limit_reg = cnt1_reg;
+ Register chr2_reg = cnt2_reg;
Register chr1_reg = result_reg;
- // tmp{12} are the base pointers
+ // str{12} are the base pointers
// Is the minimum length zero?
__ cmp(limit_reg, (int)(0 * sizeof(jchar))); // use cast to resolve overloading ambiguity
@@ -2902,8 +2885,8 @@
__ delayed()->mov(O7, result_reg); // result is difference in lengths
// Load first characters
- __ lduh(tmp1_reg, 0, chr1_reg);
- __ lduh(tmp2_reg, 0, chr2_reg);
+ __ lduh(str1_reg, 0, chr1_reg);
+ __ lduh(str2_reg, 0, chr2_reg);
// Compare first characters
__ subcc(chr1_reg, chr2_reg, chr1_reg);
@@ -2915,7 +2898,7 @@
// Check after comparing first character to see if strings are equivalent
Label LSkip2;
// Check if the strings start at same location
- __ cmp(tmp1_reg, tmp2_reg);
+ __ cmp(str1_reg, str2_reg);
__ brx(Assembler::notEqual, true, Assembler::pt, LSkip2);
__ delayed()->nop();
@@ -2932,23 +2915,23 @@
__ br(Assembler::equal, true, Assembler::pn, Ldone);
__ delayed()->mov(O7, result_reg); // result is difference in lengths
- // Shift tmp1_reg and tmp2_reg to the end of the arrays, negate limit
- __ add(tmp1_reg, limit_reg, tmp1_reg);
- __ add(tmp2_reg, limit_reg, tmp2_reg);
+ // Shift str1_reg and str2_reg to the end of the arrays, negate limit
+ __ add(str1_reg, limit_reg, str1_reg);
+ __ add(str2_reg, limit_reg, str2_reg);
__ neg(chr1_reg, limit_reg); // limit = -(limit-2)
// Compare the rest of the characters
- __ lduh(tmp1_reg, limit_reg, chr1_reg);
+ __ lduh(str1_reg, limit_reg, chr1_reg);
__ bind(Lloop);
- // __ lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted
- __ lduh(tmp2_reg, limit_reg, chr2_reg);
+ // __ lduh(str1_reg, limit_reg, chr1_reg); // hoisted
+ __ lduh(str2_reg, limit_reg, chr2_reg);
__ subcc(chr1_reg, chr2_reg, chr1_reg);
__ br(Assembler::notZero, false, Assembler::pt, Ldone);
assert(chr1_reg == result_reg, "result must be pre-placed");
__ delayed()->inccc(limit_reg, sizeof(jchar));
// annul LDUH if branch is not taken to prevent access past end of string
__ br(Assembler::notZero, true, Assembler::pt, Lloop);
- __ delayed()->lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted
+ __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted
// If strings are equal up to min length, return the length difference.
__ mov(O7, result_reg);
@@ -2957,125 +2940,80 @@
__ bind(Ldone);
%}
-enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
- Label Lword, Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone;
+enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result) %{
+ Label Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone;
MacroAssembler _masm(&cbuf);
Register str1_reg = reg_to_register_object($str1$$reg);
Register str2_reg = reg_to_register_object($str2$$reg);
- Register tmp1_reg = reg_to_register_object($tmp1$$reg);
- Register tmp2_reg = reg_to_register_object($tmp2$$reg);
+ Register cnt_reg = reg_to_register_object($cnt$$reg);
+ Register tmp1_reg = O7;
Register result_reg = reg_to_register_object($result$$reg);
- // Get the first character position in both strings
- // [8] char array, [12] offset, [16] count
- int value_offset = java_lang_String:: value_offset_in_bytes();
- int offset_offset = java_lang_String::offset_offset_in_bytes();
- int count_offset = java_lang_String:: count_offset_in_bytes();
-
- // load str1 (jchar*) base address into tmp1_reg
- __ load_heap_oop(Address(str1_reg, value_offset), tmp1_reg);
- __ ld(Address(str1_reg, offset_offset), result_reg);
- __ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg);
- __ ld(Address(str1_reg, count_offset), str1_reg); // hoisted
- __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
- __ load_heap_oop(Address(str2_reg, value_offset), tmp2_reg); // hoisted
- __ add(result_reg, tmp1_reg, tmp1_reg);
-
- // load str2 (jchar*) base address into tmp2_reg
- // __ ld_ptr(Address(str2_reg, value_offset), tmp2_reg); // hoisted
- __ ld(Address(str2_reg, offset_offset), result_reg);
- __ add(tmp2_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp2_reg);
- __ ld(Address(str2_reg, count_offset), str2_reg); // hoisted
- __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
- __ cmp(str1_reg, str2_reg); // hoisted
- __ add(result_reg, tmp2_reg, tmp2_reg);
-
- __ sll(str1_reg, exact_log2(sizeof(jchar)), str1_reg);
- __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
- __ delayed()->mov(G0, result_reg); // not equal
-
- __ br_zero(Assembler::equal, true, Assembler::pn, str1_reg, Ldone);
- __ delayed()->add(G0, 1, result_reg); //equals
-
- __ cmp(tmp1_reg, tmp2_reg); //same string ?
+ assert(result_reg != str1_reg &&
+ result_reg != str2_reg &&
+ result_reg != cnt_reg &&
+ result_reg != tmp1_reg ,
+ "need different registers");
+
+ __ cmp(str1_reg, str2_reg); //same char[] ?
__ brx(Assembler::equal, true, Assembler::pn, Ldone);
__ delayed()->add(G0, 1, result_reg);
+ __ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, cnt_reg, Ldone);
+ __ delayed()->add(G0, 1, result_reg); // count == 0
+
//rename registers
- Register limit_reg = str1_reg;
- Register chr2_reg = str2_reg;
+ Register limit_reg = cnt_reg;
Register chr1_reg = result_reg;
- // tmp{12} are the base pointers
+ Register chr2_reg = tmp1_reg;
//check for alignment and position the pointers to the ends
- __ or3(tmp1_reg, tmp2_reg, chr1_reg);
- __ andcc(chr1_reg, 0x3, chr1_reg); // notZero means at least one not 4-byte aligned
- __ br(Assembler::notZero, false, Assembler::pn, Lchar);
- __ delayed()->nop();
-
- __ bind(Lword);
- __ and3(limit_reg, 0x2, O7); //remember the remainder (either 0 or 2)
- __ andn(limit_reg, 0x3, limit_reg);
- __ br_zero(Assembler::zero, false, Assembler::pn, limit_reg, Lpost_word);
- __ delayed()->nop();
-
- __ add(tmp1_reg, limit_reg, tmp1_reg);
- __ add(tmp2_reg, limit_reg, tmp2_reg);
- __ neg(limit_reg);
-
- __ lduw(tmp1_reg, limit_reg, chr1_reg);
- __ bind(Lword_loop);
- __ lduw(tmp2_reg, limit_reg, chr2_reg);
- __ cmp(chr1_reg, chr2_reg);
- __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
- __ delayed()->mov(G0, result_reg);
- __ inccc(limit_reg, 2*sizeof(jchar));
- // annul LDUW if branch i s not taken to prevent access past end of string
- __ br(Assembler::notZero, true, Assembler::pt, Lword_loop); //annul on taken
- __ delayed()->lduw(tmp1_reg, limit_reg, chr1_reg); // hoisted
-
- __ bind(Lpost_word);
- __ br_zero(Assembler::zero, true, Assembler::pt, O7, Ldone);
- __ delayed()->add(G0, 1, result_reg);
-
- __ lduh(tmp1_reg, 0, chr1_reg);
- __ lduh(tmp2_reg, 0, chr2_reg);
- __ cmp (chr1_reg, chr2_reg);
- __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
- __ delayed()->mov(G0, result_reg);
+ __ or3(str1_reg, str2_reg, chr1_reg);
+ __ andcc(chr1_reg, 0x3, chr1_reg);
+ // notZero means at least one not 4-byte aligned.
+ // We could optimize the case when both arrays are not aligned
+ // but it is not frequent case and it requires additional checks.
+ __ br(Assembler::notZero, false, Assembler::pn, Lchar); // char by char compare
+ __ delayed()->sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); // set byte count
+
+ // Compare char[] arrays aligned to 4 bytes.
+ __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
+ chr1_reg, chr2_reg, Ldone);
__ ba(false,Ldone);
__ delayed()->add(G0, 1, result_reg);
+ // char by char compare
__ bind(Lchar);
- __ add(tmp1_reg, limit_reg, tmp1_reg);
- __ add(tmp2_reg, limit_reg, tmp2_reg);
+ __ add(str1_reg, limit_reg, str1_reg);
+ __ add(str2_reg, limit_reg, str2_reg);
__ neg(limit_reg); //negate count
- __ lduh(tmp1_reg, limit_reg, chr1_reg);
+ __ lduh(str1_reg, limit_reg, chr1_reg);
+ // Lchar_loop
__ bind(Lchar_loop);
- __ lduh(tmp2_reg, limit_reg, chr2_reg);
+ __ lduh(str2_reg, limit_reg, chr2_reg);
__ cmp(chr1_reg, chr2_reg);
__ br(Assembler::notEqual, true, Assembler::pt, Ldone);
__ delayed()->mov(G0, result_reg); //not equal
__ inccc(limit_reg, sizeof(jchar));
// annul LDUH if branch is not taken to prevent access past end of string
- __ br(Assembler::notZero, true, Assembler::pt, Lchar_loop); //annul on taken
- __ delayed()->lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted
+ __ br(Assembler::notZero, true, Assembler::pt, Lchar_loop);
+ __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted
__ add(G0, 1, result_reg); //equal
__ bind(Ldone);
%}
-enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{
+enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, notemp_iRegI result) %{
Label Lvector, Ldone, Lloop;
MacroAssembler _masm(&cbuf);
Register ary1_reg = reg_to_register_object($ary1$$reg);
Register ary2_reg = reg_to_register_object($ary2$$reg);
Register tmp1_reg = reg_to_register_object($tmp1$$reg);
- Register tmp2_reg = reg_to_register_object($tmp2$$reg);
+ Register tmp2_reg = O7;
Register result_reg = reg_to_register_object($result$$reg);
int length_offset = arrayOopDesc::length_offset_in_bytes();
@@ -3083,7 +3021,7 @@
// return true if the same array
__ cmp(ary1_reg, ary2_reg);
- __ br(Assembler::equal, true, Assembler::pn, Ldone);
+ __ brx(Assembler::equal, true, Assembler::pn, Ldone);
__ delayed()->add(G0, 1, result_reg); // equal
__ br_null(ary1_reg, true, Assembler::pn, Ldone);
@@ -3101,7 +3039,7 @@
__ br(Assembler::notEqual, true, Assembler::pn, Ldone);
__ delayed()->mov(G0, result_reg); // not equal
- __ br_zero(Assembler::zero, true, Assembler::pn, tmp1_reg, Ldone);
+ __ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, tmp1_reg, Ldone);
__ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal
// load array addresses
@@ -3109,45 +3047,16 @@
__ add(ary2_reg, base_offset, ary2_reg);
// renaming registers
- Register chr1_reg = tmp2_reg; // for characters in ary1
- Register chr2_reg = result_reg; // for characters in ary2
+ Register chr1_reg = result_reg; // for characters in ary1
+ Register chr2_reg = tmp2_reg; // for characters in ary2
Register limit_reg = tmp1_reg; // length
// set byte count
__ sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg);
- __ andcc(limit_reg, 0x2, chr1_reg); //trailing character ?
- __ br(Assembler::zero, false, Assembler::pt, Lvector);
- __ delayed()->nop();
-
- //compare the trailing char
- __ sub(limit_reg, sizeof(jchar), limit_reg);
- __ lduh(ary1_reg, limit_reg, chr1_reg);
- __ lduh(ary2_reg, limit_reg, chr2_reg);
- __ cmp(chr1_reg, chr2_reg);
- __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
- __ delayed()->mov(G0, result_reg); // not equal
-
- // only one char ?
- __ br_zero(Assembler::zero, true, Assembler::pn, limit_reg, Ldone);
- __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal
-
- __ bind(Lvector);
- // Shift ary1_reg and ary2_reg to the end of the arrays, negate limit
- __ add(ary1_reg, limit_reg, ary1_reg);
- __ add(ary2_reg, limit_reg, ary2_reg);
- __ neg(limit_reg, limit_reg);
-
- __ lduw(ary1_reg, limit_reg, chr1_reg);
- __ bind(Lloop);
- __ lduw(ary2_reg, limit_reg, chr2_reg);
- __ cmp(chr1_reg, chr2_reg);
- __ br(Assembler::notEqual, false, Assembler::pt, Ldone);
- __ delayed()->mov(G0, result_reg); // not equal
- __ inccc(limit_reg, 2*sizeof(jchar));
- // annul LDUW if branch is not taken to prevent access past end of string
- __ br(Assembler::notZero, true, Assembler::pt, Lloop); //annul on taken
- __ delayed()->lduw(ary1_reg, limit_reg, chr1_reg); // hoisted
-
+
+ // Compare char[] arrays aligned to 4 bytes.
+ __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg,
+ chr1_reg, chr2_reg, Ldone);
__ add(G0, 1, result_reg); // equals
__ bind(Ldone);
@@ -5707,7 +5616,7 @@
effect(TEMP dst, TEMP tmp);
ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
- size(3*4);
+ size((3+1)*4); // set may use two instructions.
format %{ "LDUH $mem,$dst\t! ushort/char & 16-bit mask -> long\n\t"
"SET $mask,$tmp\n\t"
"AND $dst,$tmp,$dst" %}
@@ -5851,7 +5760,7 @@
effect(TEMP dst, TEMP tmp);
ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
- size(3*4);
+ size((3+1)*4); // set may use two instructions.
format %{ "LDUW $mem,$dst\t! int & 32-bit mask -> long\n\t"
"SET $mask,$tmp\n\t"
"AND $dst,$tmp,$dst" %}
@@ -6760,7 +6669,7 @@
ins_pipe(ialu_imm);
%}
-instruct cmovII_U_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
+instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
ins_cost(150);
size(4);
@@ -6769,7 +6678,7 @@
ins_pipe(ialu_reg);
%}
-instruct cmovII_U_imm(cmpOpU cmp, flagsRegU icc, iRegI dst, immI11 src) %{
+instruct cmovIIu_imm(cmpOpU cmp, flagsRegU icc, iRegI dst, immI11 src) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
ins_cost(140);
size(4);
@@ -6815,6 +6724,16 @@
ins_pipe(ialu_reg);
%}
+// This instruction also works with CmpN so we don't need cmovNN_reg.
+instruct cmovNIu_reg(cmpOpU cmp, flagsRegU icc, iRegN dst, iRegN src) %{
+ match(Set dst (CMoveN (Binary cmp icc) (Binary dst src)));
+ ins_cost(150);
+ size(4);
+ format %{ "MOV$cmp $icc,$src,$dst" %}
+ ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) );
+ ins_pipe(ialu_reg);
+%}
+
instruct cmovNF_reg(cmpOpF cmp, flagsRegF fcc, iRegN dst, iRegN src) %{
match(Set dst (CMoveN (Binary cmp fcc) (Binary dst src)));
ins_cost(150);
@@ -6852,6 +6771,16 @@
ins_pipe(ialu_reg);
%}
+instruct cmovPIu_reg(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src) %{
+ match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
+ ins_cost(150);
+
+ size(4);
+ format %{ "MOV$cmp $icc,$src,$dst\t! ptr" %}
+ ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) );
+ ins_pipe(ialu_reg);
+%}
+
instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{
match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
ins_cost(140);
@@ -6862,6 +6791,16 @@
ins_pipe(ialu_imm);
%}
+instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{
+ match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
+ ins_cost(140);
+
+ size(4);
+ format %{ "MOV$cmp $icc,$src,$dst\t! ptr" %}
+ ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::icc)) );
+ ins_pipe(ialu_imm);
+%}
+
instruct cmovPF_reg(cmpOpF cmp, flagsRegF fcc, iRegP dst, iRegP src) %{
match(Set dst (CMoveP (Binary cmp fcc) (Binary dst src)));
ins_cost(150);
@@ -6901,6 +6840,17 @@
ins_pipe(int_conditional_float_move);
%}
+instruct cmovFIu_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src) %{
+ match(Set dst (CMoveF (Binary cmp icc) (Binary dst src)));
+ ins_cost(150);
+
+ size(4);
+ format %{ "FMOVS$cmp $icc,$src,$dst" %}
+ opcode(0x101);
+ ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::icc)) );
+ ins_pipe(int_conditional_float_move);
+%}
+
// Conditional move,
instruct cmovFF_reg(cmpOpF cmp, flagsRegF fcc, regF dst, regF src) %{
match(Set dst (CMoveF (Binary cmp fcc) (Binary dst src)));
@@ -6934,6 +6884,17 @@
ins_pipe(int_conditional_double_move);
%}
+instruct cmovDIu_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src) %{
+ match(Set dst (CMoveD (Binary cmp icc) (Binary dst src)));
+ ins_cost(150);
+
+ size(4);
+ format %{ "FMOVD$cmp $icc,$src,$dst" %}
+ opcode(0x102);
+ ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::icc)) );
+ ins_pipe(int_conditional_double_move);
+%}
+
// Conditional move,
instruct cmovDF_reg(cmpOpF cmp, flagsRegF fcc, regD dst, regD src) %{
match(Set dst (CMoveD (Binary cmp fcc) (Binary dst src)));
@@ -6973,6 +6934,17 @@
%}
+instruct cmovLIu_reg(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src) %{
+ match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
+ ins_cost(150);
+
+ size(4);
+ format %{ "MOV$cmp $icc,$src,$dst\t! long" %}
+ ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) );
+ ins_pipe(ialu_reg);
+%}
+
+
instruct cmovLF_reg(cmpOpF cmp, flagsRegF fcc, iRegL dst, iRegL src) %{
match(Set dst (CMoveL (Binary cmp fcc) (Binary dst src)));
ins_cost(150);
@@ -9471,33 +9443,33 @@
ins_pipe(long_memory_op);
%}
-instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
- o7RegI tmp3, flagsReg ccr) %{
- match(Set result (StrComp str1 str2));
- effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3);
+instruct string_compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result,
+ o7RegI tmp, flagsReg ccr) %{
+ match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp);
ins_cost(300);
- format %{ "String Compare $str1,$str2 -> $result" %}
- ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, result) );
+ format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp" %}
+ ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result) );
ins_pipe(long_memory_op);
%}
-instruct string_equals(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
- o7RegI tmp3, flagsReg ccr) %{
- match(Set result (StrEquals str1 str2));
- effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3);
+instruct string_equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result,
+ o7RegI tmp, flagsReg ccr) %{
+ match(Set result (StrEquals (Binary str1 str2) cnt));
+ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp, KILL ccr);
ins_cost(300);
- format %{ "String Equals $str1,$str2 -> $result" %}
- ins_encode( enc_String_Equals(str1, str2, tmp1, tmp2, result) );
+ format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp" %}
+ ins_encode( enc_String_Equals(str1, str2, cnt, result) );
ins_pipe(long_memory_op);
%}
-instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
- flagsReg ccr) %{
+instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegI tmp1, notemp_iRegI result,
+ o7RegI tmp2, flagsReg ccr) %{
match(Set result (AryEq ary1 ary2));
effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr);
ins_cost(300);
- format %{ "Array Equals $ary1,$ary2 -> $result" %}
- ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result));
+ format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1,$tmp2" %}
+ ins_encode( enc_Array_Equals(ary1, ary2, tmp1, result));
ins_pipe(long_memory_op);
%}
@@ -9515,8 +9487,9 @@
// x |= (x >> 8);
// x |= (x >> 16);
// return (WORDBITS - popc(x));
- format %{ "SRL $src,1,$dst\t! count leading zeros (int)\n\t"
- "OR $src,$tmp,$dst\n\t"
+ format %{ "SRL $src,1,$tmp\t! count leading zeros (int)\n\t"
+ "SRL $src,0,$dst\t! 32-bit zero extend\n\t"
+ "OR $dst,$tmp,$dst\n\t"
"SRL $dst,2,$tmp\n\t"
"OR $dst,$tmp,$dst\n\t"
"SRL $dst,4,$tmp\n\t"
@@ -9533,7 +9506,8 @@
Register Rsrc = $src$$Register;
Register Rtmp = $tmp$$Register;
__ srl(Rsrc, 1, Rtmp);
- __ or3(Rsrc, Rtmp, Rdst);
+ __ srl(Rsrc, 0, Rdst);
+ __ or3(Rdst, Rtmp, Rdst);
__ srl(Rdst, 2, Rtmp);
__ or3(Rdst, Rtmp, Rdst);
__ srl(Rdst, 4, Rtmp);
@@ -9561,7 +9535,7 @@
// x |= (x >> 16);
// x |= (x >> 32);
// return (WORDBITS - popc(x));
- format %{ "SRLX $src,1,$dst\t! count leading zeros (long)\n\t"
+ format %{ "SRLX $src,1,$tmp\t! count leading zeros (long)\n\t"
"OR $src,$tmp,$dst\n\t"
"SRLX $dst,2,$tmp\n\t"
"OR $dst,$tmp,$dst\n\t"
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/stubGenerator_sparc.cpp
--- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -2862,6 +2862,9 @@
// arraycopy stubs used by compilers
generate_arraycopy_stubs();
+
+ // Don't initialize the platform math functions since sparc
+ // doesn't have intrinsics for these operations.
}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/sparc/vm/templateInterpreter_sparc.cpp
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -150,8 +150,7 @@
}
-address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, bool unbox) {
- assert(!unbox, "NYI");//6815692//
+address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) {
address compiled_entry = __ pc();
Label cont;
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/assembler_x86.cpp
--- a/src/cpu/x86/vm/assembler_x86.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/assembler_x86.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -2251,6 +2251,7 @@
emit_byte(0x9D);
}
+#ifndef _LP64 // no 32bit push/pop on amd64
void Assembler::popl(Address dst) {
// NOTE: this will adjust stack by 8byte on 64bits
InstructionMark im(this);
@@ -2258,6 +2259,7 @@
emit_byte(0x8F);
emit_operand(rax, dst);
}
+#endif
void Assembler::prefetch_prefix(Address src) {
prefix(src);
@@ -2428,6 +2430,7 @@
emit_byte(0x9C);
}
+#ifndef _LP64 // no 32bit push/pop on amd64
void Assembler::pushl(Address src) {
// Note this will push 64bit on 64bit
InstructionMark im(this);
@@ -2435,6 +2438,7 @@
emit_byte(0xFF);
emit_operand(rsi, src);
}
+#endif
void Assembler::pxor(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
@@ -5591,7 +5595,12 @@
}
void MacroAssembler::andpd(XMMRegister dst, AddressLiteral src) {
- andpd(dst, as_Address(src));
+ if (reachable(src)) {
+ andpd(dst, as_Address(src));
+ } else {
+ lea(rscratch1, src);
+ andpd(dst, Address(rscratch1, 0));
+ }
}
void MacroAssembler::andptr(Register dst, int32_t imm32) {
@@ -6078,11 +6087,21 @@
}
void MacroAssembler::comisd(XMMRegister dst, AddressLiteral src) {
- comisd(dst, as_Address(src));
+ if (reachable(src)) {
+ comisd(dst, as_Address(src));
+ } else {
+ lea(rscratch1, src);
+ comisd(dst, Address(rscratch1, 0));
+ }
}
void MacroAssembler::comiss(XMMRegister dst, AddressLiteral src) {
- comiss(dst, as_Address(src));
+ if (reachable(src)) {
+ comiss(dst, as_Address(src));
+ } else {
+ lea(rscratch1, src);
+ comiss(dst, Address(rscratch1, 0));
+ }
}
@@ -7647,7 +7666,7 @@
#ifdef ASSERT
Label L;
- testl(tmp, tmp);
+ testptr(tmp, tmp);
jccb(Assembler::notZero, L);
hlt();
bind(L);
@@ -8214,6 +8233,15 @@
}
}
+// Used for storing NULLs.
+void MacroAssembler::store_heap_oop_null(Address dst) {
+ if (UseCompressedOops) {
+ movl(dst, (int32_t)NULL_WORD);
+ } else {
+ movslq(dst, (int32_t)NULL_WORD);
+ }
+}
+
// Algorithm must match oop.inline.hpp encode_heap_oop.
void MacroAssembler::encode_heap_oop(Register r) {
assert (UseCompressedOops, "should be compressed");
@@ -8404,6 +8432,321 @@
}
#endif // _LP64
+// IndexOf substring.
+void MacroAssembler::string_indexof(Register str1, Register str2,
+ Register cnt1, Register cnt2, Register result,
+ XMMRegister vec, Register tmp) {
+ assert(UseSSE42Intrinsics, "SSE4.2 is required");
+
+ Label RELOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,
+ SCAN_SUBSTR, RET_NOT_FOUND, CLEANUP;
+
+ push(str1); // string addr
+ push(str2); // substr addr
+ push(cnt2); // substr count
+ jmpb(PREP_FOR_SCAN);
+
+ // Substr count saved at sp
+ // Substr saved at sp+1*wordSize
+ // String saved at sp+2*wordSize
+
+ // Reload substr for rescan
+ bind(RELOAD_SUBSTR);
+ movl(cnt2, Address(rsp, 0));
+ movptr(str2, Address(rsp, wordSize));
+ // We came here after the beginninig of the substring was
+ // matched but the rest of it was not so we need to search
+ // again. Start from the next element after the previous match.
+ subptr(str1, result); // Restore counter
+ shrl(str1, 1);
+ addl(cnt1, str1);
+ lea(str1, Address(result, 2)); // Reload string
+
+ // Load substr
+ bind(PREP_FOR_SCAN);
+ movdqu(vec, Address(str2, 0));
+ addl(cnt1, 8); // prime the loop
+ subptr(str1, 16);
+
+ // Scan string for substr in 16-byte vectors
+ bind(SCAN_TO_SUBSTR);
+ subl(cnt1, 8);
+ addptr(str1, 16);
+
+ // pcmpestri
+ // inputs:
+ // xmm - substring
+ // rax - substring length (elements count)
+ // mem - scaned string
+ // rdx - string length (elements count)
+ // 0xd - mode: 1100 (substring search) + 01 (unsigned shorts)
+ // outputs:
+ // rcx - matched index in string
+ assert(cnt1 == rdx && cnt2 == rax && tmp == rcx, "pcmpestri");
+
+ pcmpestri(vec, Address(str1, 0), 0x0d);
+ jcc(Assembler::above, SCAN_TO_SUBSTR); // CF == 0 && ZF == 0
+ jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 0
+
+ // Fallthrough: found a potential substr
+
+ // Make sure string is still long enough
+ subl(cnt1, tmp);
+ cmpl(cnt1, cnt2);
+ jccb(Assembler::negative, RET_NOT_FOUND);
+ // Compute start addr of substr
+ lea(str1, Address(str1, tmp, Address::times_2));
+ movptr(result, str1); // save
+
+ // Compare potential substr
+ addl(cnt1, 8); // prime the loop
+ addl(cnt2, 8);
+ subptr(str1, 16);
+ subptr(str2, 16);
+
+ // Scan 16-byte vectors of string and substr
+ bind(SCAN_SUBSTR);
+ subl(cnt1, 8);
+ subl(cnt2, 8);
+ addptr(str1, 16);
+ addptr(str2, 16);
+ movdqu(vec, Address(str2, 0));
+ pcmpestri(vec, Address(str1, 0), 0x0d);
+ jcc(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0
+ jcc(Assembler::positive, SCAN_SUBSTR); // SF == 0
+
+ // Compute substr offset
+ subptr(result, Address(rsp, 2*wordSize));
+ shrl(result, 1); // index
+ jmpb(CLEANUP);
+
+ bind(RET_NOT_FOUND);
+ movl(result, -1);
+
+ bind(CLEANUP);
+ addptr(rsp, 3*wordSize);
+}
+
+// Compare strings.
+void MacroAssembler::string_compare(Register str1, Register str2,
+ Register cnt1, Register cnt2, Register result,
+ XMMRegister vec1, XMMRegister vec2) {
+ Label LENGTH_DIFF_LABEL, POP_LABEL, DONE_LABEL, WHILE_HEAD_LABEL;
+
+ // Compute the minimum of the string lengths and the
+ // difference of the string lengths (stack).
+ // Do the conditional move stuff
+ movl(result, cnt1);
+ subl(cnt1, cnt2);
+ push(cnt1);
+ if (VM_Version::supports_cmov()) {
+ cmovl(Assembler::lessEqual, cnt2, result);
+ } else {
+ Label GT_LABEL;
+ jccb(Assembler::greater, GT_LABEL);
+ movl(cnt2, result);
+ bind(GT_LABEL);
+ }
+
+ // Is the minimum length zero?
+ testl(cnt2, cnt2);
+ jcc(Assembler::zero, LENGTH_DIFF_LABEL);
+
+ // Load first characters
+ load_unsigned_short(result, Address(str1, 0));
+ load_unsigned_short(cnt1, Address(str2, 0));
+
+ // Compare first characters
+ subl(result, cnt1);
+ jcc(Assembler::notZero, POP_LABEL);
+ decrementl(cnt2);
+ jcc(Assembler::zero, LENGTH_DIFF_LABEL);
+
+ {
+ // Check after comparing first character to see if strings are equivalent
+ Label LSkip2;
+ // Check if the strings start at same location
+ cmpptr(str1, str2);
+ jccb(Assembler::notEqual, LSkip2);
+
+ // Check if the length difference is zero (from stack)
+ cmpl(Address(rsp, 0), 0x0);
+ jcc(Assembler::equal, LENGTH_DIFF_LABEL);
+
+ // Strings might not be equivalent
+ bind(LSkip2);
+ }
+
+ // Advance to next character
+ addptr(str1, 2);
+ addptr(str2, 2);
+
+ if (UseSSE42Intrinsics) {
+ // With SSE4.2, use double quad vector compare
+ Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;
+ // Setup to compare 16-byte vectors
+ movl(cnt1, cnt2);
+ andl(cnt2, 0xfffffff8); // cnt2 holds the vector count
+ andl(cnt1, 0x00000007); // cnt1 holds the tail count
+ testl(cnt2, cnt2);
+ jccb(Assembler::zero, COMPARE_TAIL);
+
+ lea(str2, Address(str2, cnt2, Address::times_2));
+ lea(str1, Address(str1, cnt2, Address::times_2));
+ negptr(cnt2);
+
+ bind(COMPARE_VECTORS);
+ movdqu(vec1, Address(str1, cnt2, Address::times_2));
+ movdqu(vec2, Address(str2, cnt2, Address::times_2));
+ pxor(vec1, vec2);
+ ptest(vec1, vec1);
+ jccb(Assembler::notZero, VECTOR_NOT_EQUAL);
+ addptr(cnt2, 8);
+ jcc(Assembler::notZero, COMPARE_VECTORS);
+ jmpb(COMPARE_TAIL);
+
+ // Mismatched characters in the vectors
+ bind(VECTOR_NOT_EQUAL);
+ lea(str1, Address(str1, cnt2, Address::times_2));
+ lea(str2, Address(str2, cnt2, Address::times_2));
+ movl(cnt1, 8);
+
+ // Compare tail (< 8 chars), or rescan last vectors to
+ // find 1st mismatched characters
+ bind(COMPARE_TAIL);
+ testl(cnt1, cnt1);
+ jccb(Assembler::zero, LENGTH_DIFF_LABEL);
+ movl(cnt2, cnt1);
+ // Fallthru to tail compare
+ }
+
+ // Shift str2 and str1 to the end of the arrays, negate min
+ lea(str1, Address(str1, cnt2, Address::times_2, 0));
+ lea(str2, Address(str2, cnt2, Address::times_2, 0));
+ negptr(cnt2);
+
+ // Compare the rest of the characters
+ bind(WHILE_HEAD_LABEL);
+ load_unsigned_short(result, Address(str1, cnt2, Address::times_2, 0));
+ load_unsigned_short(cnt1, Address(str2, cnt2, Address::times_2, 0));
+ subl(result, cnt1);
+ jccb(Assembler::notZero, POP_LABEL);
+ increment(cnt2);
+ jcc(Assembler::notZero, WHILE_HEAD_LABEL);
+
+ // Strings are equal up to min length. Return the length difference.
+ bind(LENGTH_DIFF_LABEL);
+ pop(result);
+ jmpb(DONE_LABEL);
+
+ // Discard the stored length difference
+ bind(POP_LABEL);
+ addptr(rsp, wordSize);
+
+ // That's it
+ bind(DONE_LABEL);
+}
+
+// Compare char[] arrays aligned to 4 bytes or substrings.
+void MacroAssembler::char_arrays_equals(bool is_array_equ, Register ary1, Register ary2,
+ Register limit, Register result, Register chr,
+ XMMRegister vec1, XMMRegister vec2) {
+ Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
+
+ int length_offset = arrayOopDesc::length_offset_in_bytes();
+ int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
+
+ // Check the input args
+ cmpptr(ary1, ary2);
+ jcc(Assembler::equal, TRUE_LABEL);
+
+ if (is_array_equ) {
+ // Need additional checks for arrays_equals.
+ testptr(ary1, ary1);
+ jcc(Assembler::zero, FALSE_LABEL);
+ testptr(ary2, ary2);
+ jcc(Assembler::zero, FALSE_LABEL);
+
+ // Check the lengths
+ movl(limit, Address(ary1, length_offset));
+ cmpl(limit, Address(ary2, length_offset));
+ jcc(Assembler::notEqual, FALSE_LABEL);
+ }
+
+ // count == 0
+ testl(limit, limit);
+ jcc(Assembler::zero, TRUE_LABEL);
+
+ if (is_array_equ) {
+ // Load array address
+ lea(ary1, Address(ary1, base_offset));
+ lea(ary2, Address(ary2, base_offset));
+ }
+
+ shll(limit, 1); // byte count != 0
+ movl(result, limit); // copy
+
+ if (UseSSE42Intrinsics) {
+ // With SSE4.2, use double quad vector compare
+ Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
+ // Compare 16-byte vectors
+ andl(result, 0x0000000e); // tail count (in bytes)
+ andl(limit, 0xfffffff0); // vector count (in bytes)
+ jccb(Assembler::zero, COMPARE_TAIL);
+
+ lea(ary1, Address(ary1, limit, Address::times_1));
+ lea(ary2, Address(ary2, limit, Address::times_1));
+ negptr(limit);
+
+ bind(COMPARE_WIDE_VECTORS);
+ movdqu(vec1, Address(ary1, limit, Address::times_1));
+ movdqu(vec2, Address(ary2, limit, Address::times_1));
+ pxor(vec1, vec2);
+ ptest(vec1, vec1);
+ jccb(Assembler::notZero, FALSE_LABEL);
+ addptr(limit, 16);
+ jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
+
+ bind(COMPARE_TAIL); // limit is zero
+ movl(limit, result);
+ // Fallthru to tail compare
+ }
+
+ // Compare 4-byte vectors
+ andl(limit, 0xfffffffc); // vector count (in bytes)
+ jccb(Assembler::zero, COMPARE_CHAR);
+
+ lea(ary1, Address(ary1, limit, Address::times_1));
+ lea(ary2, Address(ary2, limit, Address::times_1));
+ negptr(limit);
+
+ bind(COMPARE_VECTORS);
+ movl(chr, Address(ary1, limit, Address::times_1));
+ cmpl(chr, Address(ary2, limit, Address::times_1));
+ jccb(Assembler::notEqual, FALSE_LABEL);
+ addptr(limit, 4);
+ jcc(Assembler::notZero, COMPARE_VECTORS);
+
+ // Compare trailing char (final 2 bytes), if any
+ bind(COMPARE_CHAR);
+ testl(result, 0x2); // tail char
+ jccb(Assembler::zero, TRUE_LABEL);
+ load_unsigned_short(chr, Address(ary1, 0));
+ load_unsigned_short(limit, Address(ary2, 0));
+ cmpl(chr, limit);
+ jccb(Assembler::notEqual, FALSE_LABEL);
+
+ bind(TRUE_LABEL);
+ movl(result, 1); // return true
+ jmpb(DONE);
+
+ bind(FALSE_LABEL);
+ xorl(result, result); // return false
+
+ // That's it
+ bind(DONE);
+}
+
Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
switch (cond) {
// Note some conditions are synonyms for others
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/assembler_x86.hpp
--- a/src/cpu/x86/vm/assembler_x86.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/assembler_x86.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -1244,7 +1244,9 @@
void pcmpestri(XMMRegister xmm1, XMMRegister xmm2, int imm8);
void pcmpestri(XMMRegister xmm1, Address src, int imm8);
+#ifndef _LP64 // no 32bit push/pop on amd64
void popl(Address dst);
+#endif
#ifdef _LP64
void popq(Address dst);
@@ -1285,7 +1287,9 @@
// Interleave Low Bytes
void punpcklbw(XMMRegister dst, XMMRegister src);
+#ifndef _LP64 // no 32bit push/pop on amd64
void pushl(Address src);
+#endif
void pushq(Address src);
@@ -1682,6 +1686,17 @@
void load_heap_oop(Register dst, Address src);
void store_heap_oop(Address dst, Register src);
+
+ // This dummy is to prevent a call to store_heap_oop from
+ // converting a zero (like NULL) into a Register by giving
+ // the compiler two choices it can't resolve
+
+ void store_heap_oop(Address dst, void* dummy);
+
+ // Used for storing NULL. All other oop constants should be
+ // stored using routines that take a jobject.
+ void store_heap_oop_null(Address dst);
+
void encode_heap_oop(Register r);
void decode_heap_oop(Register r);
void encode_heap_oop_not_null(Register r);
@@ -2206,6 +2221,20 @@
void movl2ptr(Register dst, Address src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(movl(dst, src)); }
void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); }
+ // IndexOf strings.
+ void string_indexof(Register str1, Register str2,
+ Register cnt1, Register cnt2, Register result,
+ XMMRegister vec, Register tmp);
+
+ // Compare strings.
+ void string_compare(Register str1, Register str2,
+ Register cnt1, Register cnt2, Register result,
+ XMMRegister vec1, XMMRegister vec2);
+
+ // Compare char[] arrays.
+ void char_arrays_equals(bool is_array_equ, Register ary1, Register ary2,
+ Register limit, Register result, Register chr,
+ XMMRegister vec1, XMMRegister vec2);
#undef VIRTUAL
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
--- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2010 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
@@ -301,22 +301,25 @@
Register OSR_buf = osrBufferPointer()->as_pointer_register();
{ assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
int monitor_offset = BytesPerWord * method()->max_locals() +
- (BasicObjectLock::size() * BytesPerWord) * (number_of_locks - 1);
+ (2 * BytesPerWord) * (number_of_locks - 1);
+ // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in
+ // the OSR buffer using 2 word entries: first the lock and then
+ // the oop.
for (int i = 0; i < number_of_locks; i++) {
- int slot_offset = monitor_offset - ((i * BasicObjectLock::size()) * BytesPerWord);
+ int slot_offset = monitor_offset - ((i * 2) * BytesPerWord);
#ifdef ASSERT
// verify the interpreter's monitor has a non-null object
{
Label L;
- __ cmpptr(Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD);
+ __ cmpptr(Address(OSR_buf, slot_offset + 1*BytesPerWord), (int32_t)NULL_WORD);
__ jcc(Assembler::notZero, L);
__ stop("locked object is NULL");
__ bind(L);
}
#endif
- __ movptr(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::lock_offset_in_bytes()));
+ __ movptr(rbx, Address(OSR_buf, slot_offset + 0));
__ movptr(frame_map()->address_for_monitor_lock(i), rbx);
- __ movptr(rbx, Address(OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes()));
+ __ movptr(rbx, Address(OSR_buf, slot_offset + 1*BytesPerWord));
__ movptr(frame_map()->address_for_monitor_object(i), rbx);
}
}
@@ -415,13 +418,12 @@
}
-void LIR_Assembler::emit_exception_handler() {
+int LIR_Assembler::emit_exception_handler() {
// if the last instruction is a call (typically to do a throw which
// is coming at the end after block reordering) the return address
// must still point into the code area in order to avoid assertion
// failures when searching for the corresponding bci => add a nop
// (was bug 5/14/1999 - gri)
-
__ nop();
// generate code for exception handler
@@ -429,17 +431,14 @@
if (handler_base == NULL) {
// not enough space left for the handler
bailout("exception handler overflow");
- return;
+ return -1;
}
-#ifdef ASSERT
+
int offset = code_offset();
-#endif // ASSERT
-
- compilation()->offsets()->set_value(CodeOffsets::Exceptions, code_offset());
// if the method does not have an exception handler, then there is
// no reason to search for one
- if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_exceptions()) {
+ if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_on_exceptions()) {
// the exception oop and pc are in rax, and rdx
// no other registers need to be preserved, so invalidate them
__ invalidate_registers(false, true, true, false, true, true);
@@ -471,19 +470,19 @@
// unwind activation and forward exception to caller
// rax,: exception
__ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id)));
-
assert(code_offset() - offset <= exception_handler_size, "overflow");
-
__ end_a_stub();
+
+ return offset;
}
-void LIR_Assembler::emit_deopt_handler() {
+
+int LIR_Assembler::emit_deopt_handler() {
// if the last instruction is a call (typically to do a throw which
// is coming at the end after block reordering) the return address
// must still point into the code area in order to avoid assertion
// failures when searching for the corresponding bci => add a nop
// (was bug 5/14/1999 - gri)
-
__ nop();
// generate code for exception handler
@@ -491,23 +490,17 @@
if (handler_base == NULL) {
// not enough space left for the handler
bailout("deopt handler overflow");
- return;
+ return -1;
}
-#ifdef ASSERT
+
int offset = code_offset();
-#endif // ASSERT
-
- compilation()->offsets()->set_value(CodeOffsets::Deopt, code_offset());
-
InternalAddress here(__ pc());
__ pushptr(here.addr());
-
__ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
-
assert(code_offset() - offset <= deopt_handler_size, "overflow");
-
__ end_a_stub();
+ return offset;
}
@@ -785,7 +778,13 @@
ShouldNotReachHere();
__ movoop(as_Address(addr, noreg), c->as_jobject());
} else {
+#ifdef _LP64
+ __ movoop(rscratch1, c->as_jobject());
+ null_check_here = code_offset();
+ __ movptr(as_Address_lo(addr), rscratch1);
+#else
__ movoop(as_Address(addr), c->as_jobject());
+#endif
}
}
break;
@@ -1118,8 +1117,14 @@
__ pushptr(frame_map()->address_for_slot(src ->single_stack_ix()));
__ popptr (frame_map()->address_for_slot(dest->single_stack_ix()));
} else {
+#ifndef _LP64
__ pushl(frame_map()->address_for_slot(src ->single_stack_ix()));
__ popl (frame_map()->address_for_slot(dest->single_stack_ix()));
+#else
+ //no pushl on 64bits
+ __ movl(rscratch1, frame_map()->address_for_slot(src ->single_stack_ix()));
+ __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), rscratch1);
+#endif
}
} else if (src->is_double_stack()) {
@@ -1638,7 +1643,7 @@
jobject2reg_with_patching(k_RInfo, op->info_for_patch());
} else {
#ifdef _LP64
- __ movoop(k_RInfo, k->encoding());
+ __ movoop(k_RInfo, k->constant_encoding());
#else
k_RInfo = noreg;
#endif // _LP64
@@ -1661,7 +1666,7 @@
assert(data != NULL, "need data for checkcast");
assert(data->is_BitData(), "need BitData for checkcast");
Register mdo = klass_RInfo;
- __ movoop(mdo, md->encoding());
+ __ movoop(mdo, md->constant_encoding());
Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
__ orl(data_addr, header_bits);
@@ -1679,7 +1684,7 @@
#ifdef _LP64
__ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
#else
- __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->encoding());
+ __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding());
#endif // _LP64
} else {
__ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
@@ -1696,7 +1701,7 @@
#ifdef _LP64
__ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset()));
#else
- __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->encoding());
+ __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding());
#endif // _LP64
if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) {
__ jcc(Assembler::notEqual, *stub->entry());
@@ -1707,7 +1712,7 @@
#ifdef _LP64
__ cmpptr(klass_RInfo, k_RInfo);
#else
- __ cmpoop(klass_RInfo, k->encoding());
+ __ cmpoop(klass_RInfo, k->constant_encoding());
#endif // _LP64
__ jcc(Assembler::equal, done);
@@ -1715,7 +1720,7 @@
#ifdef _LP64
__ push(k_RInfo);
#else
- __ pushoop(k->encoding());
+ __ pushoop(k->constant_encoding());
#endif // _LP64
__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
__ pop(klass_RInfo);
@@ -1763,7 +1768,7 @@
if (!k->is_loaded()) {
jobject2reg_with_patching(k_RInfo, op->info_for_patch());
} else {
- LP64_ONLY(__ movoop(k_RInfo, k->encoding()));
+ LP64_ONLY(__ movoop(k_RInfo, k->constant_encoding()));
}
assert(obj != k_RInfo, "must be different");
@@ -1774,7 +1779,7 @@
// get object class
// not a safepoint as obj null check happens earlier
if (LP64_ONLY(false &&) k->is_loaded()) {
- NOT_LP64(__ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->encoding()));
+ NOT_LP64(__ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()));
k_RInfo = noreg;
} else {
__ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
@@ -1791,14 +1796,14 @@
#ifndef _LP64
if (k->is_loaded()) {
// See if we get an immediate positive hit
- __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->encoding());
+ __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding());
__ jcc(Assembler::equal, one);
if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() == k->super_check_offset()) {
// check for self
- __ cmpoop(klass_RInfo, k->encoding());
+ __ cmpoop(klass_RInfo, k->constant_encoding());
__ jcc(Assembler::equal, one);
__ push(klass_RInfo);
- __ pushoop(k->encoding());
+ __ pushoop(k->constant_encoding());
__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
__ pop(klass_RInfo);
__ pop(dst);
@@ -3112,7 +3117,7 @@
// subtype which we can't check or src is the same array as dst
// but not necessarily exactly of type default_type.
Label known_ok, halt;
- __ movoop(tmp, default_type->encoding());
+ __ movoop(tmp, default_type->constant_encoding());
if (basic_type != T_OBJECT) {
__ cmpptr(tmp, dst_klass_addr);
__ jcc(Assembler::notEqual, halt);
@@ -3136,8 +3141,10 @@
#ifdef _LP64
assert_different_registers(c_rarg0, dst, dst_pos, length);
+ __ movl2ptr(src_pos, src_pos); //higher 32bits must be null
__ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
assert_different_registers(c_rarg1, length);
+ __ movl2ptr(dst_pos, dst_pos); //higher 32bits must be null
__ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
__ mov(c_rarg2, length);
@@ -3200,9 +3207,8 @@
assert(data->is_CounterData(), "need CounterData for calls");
assert(op->mdo()->is_single_cpu(), "mdo must be allocated");
Register mdo = op->mdo()->as_register();
- __ movoop(mdo, md->encoding());
+ __ movoop(mdo, md->constant_encoding());
Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
- __ addl(counter_addr, DataLayout::counter_increment);
Bytecodes::Code bc = method->java_code_at_bci(bci);
// Perform additional virtual call profiling for invokevirtual and
// invokeinterface bytecodes
@@ -3240,7 +3246,7 @@
ciKlass* receiver = vc_data->receiver(i);
if (receiver == NULL) {
Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)));
- __ movoop(recv_addr, known_klass->encoding());
+ __ movoop(recv_addr, known_klass->constant_encoding());
Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
__ addl(data_addr, DataLayout::counter_increment);
return;
@@ -3269,14 +3275,18 @@
__ jcc(Assembler::notEqual, next_test);
__ movptr(recv_addr, recv);
__ movl(Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))), DataLayout::counter_increment);
- if (i < (VirtualCallData::row_limit() - 1)) {
- __ jmp(update_done);
- }
+ __ jmp(update_done);
__ bind(next_test);
}
+ // Receiver did not match any saved receiver and there is no empty row for it.
+ // Increment total counter to indicate polymorphic case.
+ __ addl(counter_addr, DataLayout::counter_increment);
__ bind(update_done);
}
+ } else {
+ // Static call
+ __ addl(counter_addr, DataLayout::counter_increment);
}
}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
--- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005-2009 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
@@ -755,8 +755,19 @@
}
LIR_Opr addr = new_pointer_register();
- __ move(obj.result(), addr);
- __ add(addr, offset.result(), addr);
+ LIR_Address* a;
+ if(offset.result()->is_constant()) {
+ a = new LIR_Address(obj.result(),
+ NOT_LP64(offset.result()->as_constant_ptr()->as_jint()) LP64_ONLY((int)offset.result()->as_constant_ptr()->as_jlong()),
+ as_BasicType(type));
+ } else {
+ a = new LIR_Address(obj.result(),
+ offset.result(),
+ LIR_Address::times_1,
+ 0,
+ as_BasicType(type));
+ }
+ __ leal(LIR_OprFact::address(a), addr);
if (type == objectType) { // Write-barrier needed for Object fields.
// Do the pre-write barrier, if any.
@@ -827,8 +838,8 @@
case vmIntrinsics::_dsin: __ sin (calc_input, calc_result, tmp1, tmp2); break;
case vmIntrinsics::_dcos: __ cos (calc_input, calc_result, tmp1, tmp2); break;
case vmIntrinsics::_dtan: __ tan (calc_input, calc_result, tmp1, tmp2); break;
- case vmIntrinsics::_dlog: __ log (calc_input, calc_result, LIR_OprFact::illegalOpr); break;
- case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, LIR_OprFact::illegalOpr); break;
+ case vmIntrinsics::_dlog: __ log (calc_input, calc_result, tmp1); break;
+ case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1); break;
default: ShouldNotReachHere();
}
@@ -994,7 +1005,7 @@
LIR_Opr len = length.result();
BasicType elem_type = x->elt_type();
- __ oop2reg(ciTypeArrayKlass::make(elem_type)->encoding(), klass_reg);
+ __ oop2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg);
CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);
__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);
@@ -1047,16 +1058,17 @@
items->at_put(i, size);
}
- // need to get the info before, as the items may become invalid through item_free
+ // Evaluate state_for early since it may emit code.
CodeEmitInfo* patching_info = NULL;
if (!x->klass()->is_loaded() || PatchALot) {
patching_info = state_for(x, x->state_before());
// cannot re-use same xhandlers for multiple CodeEmitInfos, so
- // clone all handlers.
+ // clone all handlers. This is handled transparently in other
+ // places by the CodeEmitInfo cloning logic but is handled
+ // specially here because a stub isn't being used.
x->set_exception_handlers(new XHandlers(x->exception_handlers()));
}
-
CodeEmitInfo* info = state_for(x, x->state());
i = dims->length();
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/c1_LinearScan_x86.cpp
--- a/src/cpu/x86/vm/c1_LinearScan_x86.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/c1_LinearScan_x86.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -764,8 +764,6 @@
break;
}
- case lir_log:
- case lir_log10:
case lir_abs:
case lir_sqrt: {
// Right argument appears to be unused
@@ -785,6 +783,30 @@
break;
}
+ case lir_log:
+ case lir_log10: {
+ // log and log10 needs one temporary fpu stack slot, so there is ontemporary
+ // registers stored in temp of the operation.
+ // the stack allocator must guarantee that the stack slots are really free,
+ // otherwise there might be a stack overflow.
+ assert(right->is_illegal(), "must be");
+ assert(left->is_fpu_register(), "must be");
+ assert(res->is_fpu_register(), "must be");
+ assert(op2->tmp_opr()->is_fpu_register(), "must be");
+
+ insert_free_if_dead(op2->tmp_opr());
+ insert_free_if_dead(res, left);
+ insert_exchange(left);
+ do_rename(left, res);
+
+ new_left = to_fpu_stack_top(res);
+ new_res = new_left;
+
+ op2->set_fpu_stack_size(sim()->stack_size());
+ assert(sim()->stack_size() <= 7, "at least one stack slot must be free");
+ break;
+ }
+
case lir_tan:
case lir_sin:
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/c1_globals_x86.hpp
--- a/src/cpu/x86/vm/c1_globals_x86.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/c1_globals_x86.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -22,10 +22,8 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the client compiler.
// (see c1_globals.hpp)
-//
#ifndef TIERED
define_pd_global(bool, BackgroundCompilation, true );
@@ -48,27 +46,24 @@
define_pd_global(intx, OnStackReplacePercentage, 933 );
define_pd_global(intx, FreqInlineSize, 325 );
-define_pd_global(intx, NewRatio, 12 );
define_pd_global(intx, NewSizeThreadIncrease, 4*K );
define_pd_global(intx, InitialCodeCacheSize, 160*K);
define_pd_global(intx, ReservedCodeCacheSize, 32*M );
define_pd_global(bool, ProfileInterpreter, false);
define_pd_global(intx, CodeCacheExpansionSize, 32*K );
define_pd_global(uintx,CodeCacheMinBlockLength, 1);
-define_pd_global(uintx, PermSize, 12*M );
-define_pd_global(uintx, MaxPermSize, 64*M );
-define_pd_global(bool, NeverActAsServerClassMachine, true);
-define_pd_global(uintx, DefaultMaxRAM, 1*G);
+define_pd_global(uintx,PermSize, 12*M );
+define_pd_global(uintx,MaxPermSize, 64*M );
+define_pd_global(bool, NeverActAsServerClassMachine, true );
+define_pd_global(uint64_t,MaxRAM, 1ULL*G);
define_pd_global(bool, CICompileOSR, true );
-#endif // TIERED
+#endif // !TIERED
define_pd_global(bool, UseTypeProfile, false);
define_pd_global(bool, RoundFPResults, true );
-
define_pd_global(bool, LIRFillDelaySlots, false);
-define_pd_global(bool, OptimizeSinglePrecision, true);
+define_pd_global(bool, OptimizeSinglePrecision, true );
define_pd_global(bool, CSEArrayLength, false);
-define_pd_global(bool, TwoOperandLIRForm, true);
+define_pd_global(bool, TwoOperandLIRForm, true );
-
-define_pd_global(intx, SafepointPollOffset, 256);
+define_pd_global(intx, SafepointPollOffset, 256 );
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/c2_globals_x86.hpp
--- a/src/cpu/x86/vm/c2_globals_x86.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/c2_globals_x86.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -22,7 +22,6 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the server compiler.
// (see c2_globals.hpp). Alpha-sorted.
@@ -46,8 +45,8 @@
define_pd_global(intx, CompileThreshold, 10000);
#endif // TIERED
define_pd_global(intx, Tier2CompileThreshold, 10000);
-define_pd_global(intx, Tier3CompileThreshold, 20000 );
-define_pd_global(intx, Tier4CompileThreshold, 40000 );
+define_pd_global(intx, Tier3CompileThreshold, 20000);
+define_pd_global(intx, Tier4CompileThreshold, 40000);
define_pd_global(intx, BackEdgeThreshold, 100000);
define_pd_global(intx, Tier2BackEdgeThreshold, 100000);
@@ -61,7 +60,6 @@
#ifdef AMD64
define_pd_global(intx, INTPRESSURE, 13);
define_pd_global(intx, InteriorEntryAlignment, 16);
-define_pd_global(intx, NewRatio, 2);
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
define_pd_global(intx, LoopUnrollLimit, 60);
// InitialCodeCacheSize derived from specjbb2000 run.
@@ -69,19 +67,18 @@
define_pd_global(intx, CodeCacheExpansionSize, 64*K);
// Ergonomics related flags
-define_pd_global(uintx, DefaultMaxRAM, 32*G);
+define_pd_global(uint64_t,MaxRAM, 128ULL*G);
#else
define_pd_global(intx, INTPRESSURE, 6);
define_pd_global(intx, InteriorEntryAlignment, 4);
-define_pd_global(intx, NewRatio, 8); // Design center runs on 1.3.1
define_pd_global(intx, NewSizeThreadIncrease, 4*K);
-define_pd_global(intx, LoopUnrollLimit, 50); // Design center runs on 1.3.1
+define_pd_global(intx, LoopUnrollLimit, 50); // Design center runs on 1.3.1
// InitialCodeCacheSize derived from specjbb2000 run.
define_pd_global(intx, InitialCodeCacheSize, 2304*K); // Integral multiple of CodeCacheExpansionSize
define_pd_global(intx, CodeCacheExpansionSize, 32*K);
// Ergonomics related flags
-define_pd_global(uintx, DefaultMaxRAM, 1*G);
+define_pd_global(uint64_t,MaxRAM, 4ULL*G);
#endif // AMD64
define_pd_global(intx, OptoLoopAlignment, 16);
define_pd_global(intx, RegisterCostAreaRatio, 16000);
@@ -97,8 +94,8 @@
define_pd_global(uintx,CodeCacheMinBlockLength, 4);
// Heap related flags
-define_pd_global(uintx, PermSize, ScaleForWordSize(16*M));
-define_pd_global(uintx, MaxPermSize, ScaleForWordSize(64*M));
+define_pd_global(uintx,PermSize, ScaleForWordSize(16*M));
+define_pd_global(uintx,MaxPermSize, ScaleForWordSize(64*M));
// Ergonomics related flags
define_pd_global(bool, NeverActAsServerClassMachine, false);
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/frame_x86.cpp
--- a/src/cpu/x86/vm/frame_x86.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/frame_x86.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -222,9 +222,9 @@
}
((address *)sp())[-1] = pc;
_cb = CodeCache::find_blob(pc);
- if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) {
- address orig = (((nmethod*)_cb)->get_original_pc(this));
- assert(orig == _pc, "expected original to be stored before patching");
+ address original_pc = nmethod::get_deopt_original_pc(this);
+ if (original_pc != NULL) {
+ assert(original_pc == _pc, "expected original PC to be stored before patching");
_deopt_state = is_deoptimized;
// leave _pc as is
} else {
@@ -323,13 +323,63 @@
return fr;
}
+
+//------------------------------------------------------------------------------
+// frame::verify_deopt_original_pc
+//
+// Verifies the calculated original PC of a deoptimization PC for the
+// given unextended SP. The unextended SP might also be the saved SP
+// for MethodHandle call sites.
+#if ASSERT
+void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) {
+ frame fr;
+
+ // This is ugly but it's better than to change {get,set}_original_pc
+ // to take an SP value as argument. And it's only a debugging
+ // method anyway.
+ fr._unextended_sp = unextended_sp;
+
+ address original_pc = nm->get_original_pc(&fr);
+ assert(nm->code_contains(original_pc), "original PC must be in nmethod");
+ assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be");
+}
+#endif
+
+
+//------------------------------------------------------------------------------
+// frame::sender_for_interpreter_frame
frame frame::sender_for_interpreter_frame(RegisterMap* map) const {
- // sp is the raw sp from the sender after adapter or interpreter extension
- intptr_t* sp = (intptr_t*) addr_at(sender_sp_offset);
+ // SP is the raw SP from the sender after adapter or interpreter
+ // extension.
+ intptr_t* sender_sp = this->sender_sp();
// This is the sp before any possible extension (adapter/locals).
intptr_t* unextended_sp = interpreter_frame_sender_sp();
+ // Stored FP.
+ intptr_t* saved_fp = link();
+
+ address sender_pc = this->sender_pc();
+ CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc);
+ assert(sender_cb, "sanity");
+ nmethod* sender_nm = sender_cb->as_nmethod_or_null();
+
+ if (sender_nm != NULL) {
+ // If the sender PC is a deoptimization point, get the original
+ // PC. For MethodHandle call site the unextended_sp is stored in
+ // saved_fp.
+ if (sender_nm->is_deopt_mh_entry(sender_pc)) {
+ DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, saved_fp));
+ unextended_sp = saved_fp;
+ }
+ else if (sender_nm->is_deopt_entry(sender_pc)) {
+ DEBUG_ONLY(verify_deopt_original_pc(sender_nm, unextended_sp));
+ }
+ else if (sender_nm->is_method_handle_return(sender_pc)) {
+ unextended_sp = saved_fp;
+ }
+ }
+
// The interpreter and compiler(s) always save EBP/RBP in a known
// location on entry. We must record where that location is
// so this if EBP/RBP was live on callout from c2 we can find
@@ -351,29 +401,52 @@
}
#endif // AMD64
}
-#endif /* COMPILER2 */
- return frame(sp, unextended_sp, link(), sender_pc());
+#endif // COMPILER2
+
+ return frame(sender_sp, unextended_sp, saved_fp, sender_pc);
}
-//------------------------------sender_for_compiled_frame-----------------------
+//------------------------------------------------------------------------------
+// frame::sender_for_compiled_frame
frame frame::sender_for_compiled_frame(RegisterMap* map) const {
assert(map != NULL, "map must be set");
- const bool c1_compiled = _cb->is_compiled_by_c1();
// frame owned by optimizing compiler
- intptr_t* sender_sp = NULL;
-
assert(_cb->frame_size() >= 0, "must have non-zero frame size");
- sender_sp = unextended_sp() + _cb->frame_size();
+ intptr_t* sender_sp = unextended_sp() + _cb->frame_size();
+ intptr_t* unextended_sp = sender_sp;
// On Intel the return_address is always the word on the stack
address sender_pc = (address) *(sender_sp-1);
- // This is the saved value of ebp which may or may not really be an fp.
- // it is only an fp if the sender is an interpreter frame (or c1?)
+ // This is the saved value of EBP which may or may not really be an FP.
+ // It is only an FP if the sender is an interpreter frame (or C1?).
+ intptr_t* saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset);
+
+ // If we are returning to a compiled MethodHandle call site, the
+ // saved_fp will in fact be a saved value of the unextended SP. The
+ // simplest way to tell whether we are returning to such a call site
+ // is as follows:
+ CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc);
+ assert(sender_cb, "sanity");
+ nmethod* sender_nm = sender_cb->as_nmethod_or_null();
- intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
+ if (sender_nm != NULL) {
+ // If the sender PC is a deoptimization point, get the original
+ // PC. For MethodHandle call site the unextended_sp is stored in
+ // saved_fp.
+ if (sender_nm->is_deopt_mh_entry(sender_pc)) {
+ DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, saved_fp));
+ unextended_sp = saved_fp;
+ }
+ else if (sender_nm->is_deopt_entry(sender_pc)) {
+ DEBUG_ONLY(verify_deopt_original_pc(sender_nm, unextended_sp));
+ }
+ else if (sender_nm->is_method_handle_return(sender_pc)) {
+ unextended_sp = saved_fp;
+ }
+ }
if (map->update_map()) {
// Tell GC to use argument oopmaps for some runtime stubs that need it.
@@ -383,7 +456,7 @@
if (_cb->oop_maps() != NULL) {
OopMapSet::update_register_map(this, map);
}
- // Since the prolog does the save and restore of epb there is no oopmap
+ // Since the prolog does the save and restore of EBP there is no oopmap
// for it so we must fill in its location as if there was an oopmap entry
// since if our caller was compiled code there could be live jvm state in it.
map->set_location(rbp->as_VMReg(), (address) (sender_sp - frame::sender_sp_offset));
@@ -399,9 +472,12 @@
}
assert(sender_sp != sp(), "must have changed");
- return frame(sender_sp, saved_fp, sender_pc);
+ return frame(sender_sp, unextended_sp, saved_fp, sender_pc);
}
+
+//------------------------------------------------------------------------------
+// frame::sender
frame frame::sender(RegisterMap* map) const {
// Default is we done have to follow them. The sender_for_xxx will
// update it accordingly
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/frame_x86.hpp
--- a/src/cpu/x86/vm/frame_x86.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/frame_x86.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -163,6 +163,14 @@
return (intptr_t*) addr_at(offset);
}
+#if ASSERT
+ // Used in frame::sender_for_{interpreter,compiled}_frame
+ static void verify_deopt_original_pc( nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return = false);
+ static void verify_deopt_mh_original_pc(nmethod* nm, intptr_t* unextended_sp) {
+ verify_deopt_original_pc(nm, unextended_sp, true);
+ }
+#endif
+
public:
// Constructors
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/frame_x86.inline.hpp
--- a/src/cpu/x86/vm/frame_x86.inline.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/frame_x86.inline.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -35,32 +35,35 @@
_deopt_state = unknown;
}
-inline frame:: frame(intptr_t* sp, intptr_t* fp, address pc) {
+inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) {
_sp = sp;
_unextended_sp = sp;
_fp = fp;
_pc = pc;
assert(pc != NULL, "no pc?");
_cb = CodeCache::find_blob(pc);
- _deopt_state = not_deoptimized;
- if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) {
- _pc = (((nmethod*)_cb)->get_original_pc(this));
+
+ address original_pc = nmethod::get_deopt_original_pc(this);
+ if (original_pc != NULL) {
+ _pc = original_pc;
_deopt_state = is_deoptimized;
} else {
_deopt_state = not_deoptimized;
}
}
-inline frame:: frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) {
+inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) {
_sp = sp;
_unextended_sp = unextended_sp;
_fp = fp;
_pc = pc;
assert(pc != NULL, "no pc?");
_cb = CodeCache::find_blob(pc);
- _deopt_state = not_deoptimized;
- if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) {
- _pc = (((nmethod*)_cb)->get_original_pc(this));
+
+ address original_pc = nmethod::get_deopt_original_pc(this);
+ if (original_pc != NULL) {
+ _pc = original_pc;
+ assert(((nmethod*)_cb)->code_contains(_pc), "original PC must be in nmethod");
_deopt_state = is_deoptimized;
} else {
_deopt_state = not_deoptimized;
@@ -86,9 +89,9 @@
_cb = CodeCache::find_blob(_pc);
- _deopt_state = not_deoptimized;
- if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) {
- _pc = (((nmethod*)_cb)->get_original_pc(this));
+ address original_pc = nmethod::get_deopt_original_pc(this);
+ if (original_pc != NULL) {
+ _pc = original_pc;
_deopt_state = is_deoptimized;
} else {
_deopt_state = not_deoptimized;
@@ -225,11 +228,13 @@
// top of expression stack
inline intptr_t* frame::interpreter_frame_tos_address() const {
intptr_t* last_sp = interpreter_frame_last_sp();
- if (last_sp == NULL ) {
+ if (last_sp == NULL) {
return sp();
} else {
- // sp() may have been extended by an adapter
- assert(last_sp < fp() && last_sp >= sp(), "bad tos");
+ // sp() may have been extended or shrunk by an adapter. At least
+ // check that we don't fall behind the legal region.
+ // For top deoptimized frame last_sp == interpreter_frame_monitor_end.
+ assert(last_sp <= (intptr_t*) interpreter_frame_monitor_end(), "bad tos");
return last_sp;
}
}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/globals_x86.hpp
--- a/src/cpu/x86/vm/globals_x86.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/globals_x86.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -22,17 +22,16 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the runtime system.
// (see globals.hpp)
-//
-define_pd_global(bool, ConvertSleepToYield, true);
-define_pd_global(bool, ShareVtableStubs, true);
-define_pd_global(bool, CountInterpCalls, true);
+define_pd_global(bool, ConvertSleepToYield, true);
+define_pd_global(bool, ShareVtableStubs, true);
+define_pd_global(bool, CountInterpCalls, true);
+define_pd_global(bool, NeedsDeoptSuspend, false); // only register window machines need this
-define_pd_global(bool, ImplicitNullChecks, true); // Generate code for implicit null checks
-define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast
+define_pd_global(bool, ImplicitNullChecks, true); // Generate code for implicit null checks
+define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast
// See 4827828 for this change. There is no globals_core_i486.hpp. I can't
// assign a different value for C2 without touching a number of files. Use
@@ -42,29 +41,24 @@
// the uep and the vep doesn't get real alignment but just slops on by
// only assured that the entry instruction meets the 5 byte size requirement.
#ifdef COMPILER2
-define_pd_global(intx, CodeEntryAlignment, 32);
+define_pd_global(intx, CodeEntryAlignment, 32);
#else
-define_pd_global(intx, CodeEntryAlignment, 16);
+define_pd_global(intx, CodeEntryAlignment, 16);
#endif // COMPILER2
+define_pd_global(intx, InlineFrequencyCount, 100);
+define_pd_global(intx, InlineSmallCode, 1000);
-define_pd_global(bool, NeedsDeoptSuspend, false); // only register window machines need this
-
-define_pd_global(uintx, TLABSize, 0);
+define_pd_global(intx, StackYellowPages, 2);
+define_pd_global(intx, StackRedPages, 1);
#ifdef AMD64
-define_pd_global(uintx, NewSize, ScaleForWordSize(2048 * K));
// Very large C++ stack frames using solaris-amd64 optimized builds
// due to lack of optimization caused by C++ compiler bugs
define_pd_global(intx, StackShadowPages, SOLARIS_ONLY(20) NOT_SOLARIS(6) DEBUG_ONLY(+2));
#else
-define_pd_global(uintx, NewSize, 1024 * K);
define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+1));
#endif // AMD64
-define_pd_global(intx, InlineFrequencyCount, 100);
-define_pd_global(intx, InlineSmallCode, 1000);
-define_pd_global(intx, PreInflateSpin, 10);
-define_pd_global(intx, StackYellowPages, 2);
-define_pd_global(intx, StackRedPages, 1);
+define_pd_global(intx, PreInflateSpin, 10);
define_pd_global(bool, RewriteBytecodes, true);
define_pd_global(bool, RewriteFrequentPairs, true);
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/interp_masm_x86_32.cpp
--- a/src/cpu/x86/vm/interp_masm_x86_32.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -196,6 +196,9 @@
} else {
assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
movl(reg, Address(rsi, bcp_offset));
+ // Check if the secondary index definition is still ~x, otherwise
+ // we have to change the following assembler code to calculate the
+ // plain index.
assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
notl(reg); // convert to plain index
}
@@ -1236,17 +1239,19 @@
// If no method data exists, go to profile_continue.
test_method_data_pointer(mdp, profile_continue);
- // We are making a call. Increment the count.
- increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
-
Label skip_receiver_profile;
if (receiver_can_be_null) {
+ Label not_null;
testptr(receiver, receiver);
- jcc(Assembler::zero, skip_receiver_profile);
+ jccb(Assembler::notZero, not_null);
+ // We are making a call. Increment the count for null receiver.
+ increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
+ jmp(skip_receiver_profile);
+ bind(not_null);
}
// Record the receiver type.
- record_klass_in_profile(receiver, mdp, reg2);
+ record_klass_in_profile(receiver, mdp, reg2, true);
bind(skip_receiver_profile);
// The method data pointer needs to be updated to reflect the new target.
@@ -1260,8 +1265,15 @@
void InterpreterMacroAssembler::record_klass_in_profile_helper(
Register receiver, Register mdp,
- Register reg2,
- int start_row, Label& done) {
+ Register reg2, int start_row,
+ Label& done, bool is_virtual_call) {
+ if (TypeProfileWidth == 0) {
+ if (is_virtual_call) {
+ increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
+ }
+ return;
+ }
+
int last_row = VirtualCallData::row_limit() - 1;
assert(start_row <= last_row, "must be work left to do");
// Test this row for both the receiver and for null.
@@ -1288,19 +1300,28 @@
bind(next_test);
if (row == start_row) {
+ Label found_null;
// Failed the equality check on receiver[n]... Test for null.
testptr(reg2, reg2);
if (start_row == last_row) {
// The only thing left to do is handle the null case.
- jcc(Assembler::notZero, done);
+ if (is_virtual_call) {
+ jccb(Assembler::zero, found_null);
+ // Receiver did not match any saved receiver and there is no empty row for it.
+ // Increment total counter to indicate polymorphic case.
+ increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
+ jmp(done);
+ bind(found_null);
+ } else {
+ jcc(Assembler::notZero, done);
+ }
break;
}
// Since null is rare, make it be the branch-taken case.
- Label found_null;
jcc(Assembler::zero, found_null);
// Put all the "Case 3" tests here.
- record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done);
+ record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done, is_virtual_call);
// Found a null. Keep searching for a matching receiver,
// but remember that this is an empty (unused) slot.
@@ -1317,16 +1338,18 @@
int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row));
movptr(reg2, (int32_t)DataLayout::counter_increment);
set_mdp_data_at(mdp, count_offset, reg2);
- jmp(done);
+ if (start_row > 0) {
+ jmp(done);
+ }
}
void InterpreterMacroAssembler::record_klass_in_profile(Register receiver,
- Register mdp,
- Register reg2) {
+ Register mdp, Register reg2,
+ bool is_virtual_call) {
assert(ProfileInterpreter, "must be profiling");
Label done;
- record_klass_in_profile_helper(receiver, mdp, reg2, 0, done);
+ record_klass_in_profile_helper(receiver, mdp, reg2, 0, done, is_virtual_call);
bind (done);
}
@@ -1419,7 +1442,7 @@
mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
// Record the object type.
- record_klass_in_profile(klass, mdp, reg2);
+ record_klass_in_profile(klass, mdp, reg2, false);
assert(reg2 == rdi, "we know how to fix this blown reg");
restore_locals(); // Restore EDI
}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/interp_masm_x86_32.hpp
--- a/src/cpu/x86/vm/interp_masm_x86_32.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/interp_masm_x86_32.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -213,10 +213,10 @@
Label& not_equal_continue);
void record_klass_in_profile(Register receiver, Register mdp,
- Register reg2);
+ Register reg2, bool is_virtual_call);
void record_klass_in_profile_helper(Register receiver, Register mdp,
- Register reg2,
- int start_row, Label& done);
+ Register reg2, int start_row,
+ Label& done, bool is_virtual_call);
void update_mdp_by_offset(Register mdp_in, int offset_of_offset);
void update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp);
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/interp_masm_x86_64.cpp
--- a/src/cpu/x86/vm/interp_masm_x86_64.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 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
@@ -185,12 +185,30 @@
}
+void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index,
+ int bcp_offset,
+ bool giant_index) {
+ assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
+ if (!giant_index) {
+ load_unsigned_short(index, Address(r13, bcp_offset));
+ } else {
+ assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
+ movl(index, Address(r13, bcp_offset));
+ // Check if the secondary index definition is still ~x, otherwise
+ // we have to change the following assembler code to calculate the
+ // plain index.
+ assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
+ notl(index); // convert to plain index
+ }
+}
+
+
void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
Register index,
- int bcp_offset) {
- assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
+ int bcp_offset,
+ bool giant_index) {
assert(cache != index, "must use different registers");
- load_unsigned_short(index, Address(r13, bcp_offset));
+ get_cache_index_at_bcp(index, bcp_offset, giant_index);
movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
// convert from field index to ConstantPoolCacheEntry index
@@ -200,10 +218,10 @@
void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
Register tmp,
- int bcp_offset) {
- assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
+ int bcp_offset,
+ bool giant_index) {
assert(cache != tmp, "must use different register");
- load_unsigned_short(tmp, Address(r13, bcp_offset));
+ get_cache_index_at_bcp(tmp, bcp_offset, giant_index);
assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
// convert from field index to ConstantPoolCacheEntry index
// and from word offset to byte offset
@@ -1236,18 +1254,28 @@
void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
Register mdp,
- Register reg2) {
+ Register reg2,
+ bool receiver_can_be_null) {
if (ProfileInterpreter) {
Label profile_continue;
// If no method data exists, go to profile_continue.
test_method_data_pointer(mdp, profile_continue);
- // We are making a call. Increment the count.
- increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
+ Label skip_receiver_profile;
+ if (receiver_can_be_null) {
+ Label not_null;
+ testptr(receiver, receiver);
+ jccb(Assembler::notZero, not_null);
+ // We are making a call. Increment the count for null receiver.
+ increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
+ jmp(skip_receiver_profile);
+ bind(not_null);
+ }
// Record the receiver type.
- record_klass_in_profile(receiver, mdp, reg2);
+ record_klass_in_profile(receiver, mdp, reg2, true);
+ bind(skip_receiver_profile);
// The method data pointer needs to be updated to reflect the new target.
update_mdp_by_constant(mdp,
@@ -1270,8 +1298,15 @@
// See below for example code.
void InterpreterMacroAssembler::record_klass_in_profile_helper(
Register receiver, Register mdp,
- Register reg2,
- int start_row, Label& done) {
+ Register reg2, int start_row,
+ Label& done, bool is_virtual_call) {
+ if (TypeProfileWidth == 0) {
+ if (is_virtual_call) {
+ increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
+ }
+ return;
+ }
+
int last_row = VirtualCallData::row_limit() - 1;
assert(start_row <= last_row, "must be work left to do");
// Test this row for both the receiver and for null.
@@ -1298,19 +1333,28 @@
bind(next_test);
if (test_for_null_also) {
+ Label found_null;
// Failed the equality check on receiver[n]... Test for null.
testptr(reg2, reg2);
if (start_row == last_row) {
// The only thing left to do is handle the null case.
- jcc(Assembler::notZero, done);
+ if (is_virtual_call) {
+ jccb(Assembler::zero, found_null);
+ // Receiver did not match any saved receiver and there is no empty row for it.
+ // Increment total counter to indicate polymorphic case.
+ increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
+ jmp(done);
+ bind(found_null);
+ } else {
+ jcc(Assembler::notZero, done);
+ }
break;
}
// Since null is rare, make it be the branch-taken case.
- Label found_null;
jcc(Assembler::zero, found_null);
// Put all the "Case 3" tests here.
- record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done);
+ record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done, is_virtual_call);
// Found a null. Keep searching for a matching receiver,
// but remember that this is an empty (unused) slot.
@@ -1327,7 +1371,9 @@
int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row));
movl(reg2, DataLayout::counter_increment);
set_mdp_data_at(mdp, count_offset, reg2);
- jmp(done);
+ if (start_row > 0) {
+ jmp(done);
+ }
}
// Example state machine code for three profile rows:
@@ -1339,7 +1385,7 @@
// if (row[1].rec != NULL) {
// // degenerate decision tree, rooted at row[2]
// if (row[2].rec == rec) { row[2].incr(); goto done; }
-// if (row[2].rec != NULL) { goto done; } // overflow
+// if (row[2].rec != NULL) { count.incr(); goto done; } // overflow
// row[2].init(rec); goto done;
// } else {
// // remember row[1] is empty
@@ -1352,14 +1398,15 @@
// if (row[2].rec == rec) { row[2].incr(); goto done; }
// row[0].init(rec); goto done;
// }
+// done:
void InterpreterMacroAssembler::record_klass_in_profile(Register receiver,
- Register mdp,
- Register reg2) {
+ Register mdp, Register reg2,
+ bool is_virtual_call) {
assert(ProfileInterpreter, "must be profiling");
Label done;
- record_klass_in_profile_helper(receiver, mdp, reg2, 0, done);
+ record_klass_in_profile_helper(receiver, mdp, reg2, 0, done, is_virtual_call);
bind (done);
}
@@ -1455,7 +1502,7 @@
mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
// Record the object type.
- record_klass_in_profile(klass, mdp, reg2);
+ record_klass_in_profile(klass, mdp, reg2, false);
}
update_mdp_by_constant(mdp, mdp_delta);
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/interp_masm_x86_64.hpp
--- a/src/cpu/x86/vm/interp_masm_x86_64.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/interp_masm_x86_64.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -95,9 +95,10 @@
void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset);
void get_cache_and_index_at_bcp(Register cache, Register index,
- int bcp_offset);
+ int bcp_offset, bool giant_index = false);
void get_cache_entry_pointer_at_bcp(Register cache, Register tmp,
- int bcp_offset);
+ int bcp_offset, bool giant_index = false);
+ void get_cache_index_at_bcp(Register index, int bcp_offset, bool giant_index = false);
void pop_ptr(Register r = rax);
@@ -221,10 +222,10 @@
Label& not_equal_continue);
void record_klass_in_profile(Register receiver, Register mdp,
- Register reg2);
+ Register reg2, bool is_virtual_call);
void record_klass_in_profile_helper(Register receiver, Register mdp,
- Register reg2,
- int start_row, Label& done);
+ Register reg2, int start_row,
+ Label& done, bool is_virtual_call);
void update_mdp_by_offset(Register mdp_in, int offset_of_offset);
void update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp);
@@ -236,7 +237,8 @@
void profile_call(Register mdp);
void profile_final_call(Register mdp);
void profile_virtual_call(Register receiver, Register mdp,
- Register scratch2);
+ Register scratch2,
+ bool receiver_can_be_null = false);
void profile_ret(Register return_bci, Register mdp);
void profile_null_seen(Register mdp);
void profile_typecheck(Register mdp, Register klass, Register scratch);
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/interpreter_x86_64.cpp
--- a/src/cpu/x86/vm/interpreter_x86_64.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/interpreter_x86_64.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -277,12 +277,11 @@
address entry_point = __ pc();
// abstract method entry
- // remove return address. Not really needed, since exception
- // handling throws away expression stack
- __ pop(rbx);
- // adjust stack to what a normal return would do
- __ mov(rsp, r13);
+ // pop return address, reset last_sp to NULL
+ __ empty_expression_stack();
+ __ restore_bcp(); // rsi must be correct for exception handler (was destroyed)
+ __ restore_locals(); // make sure locals pointer is correct as well (was destroyed)
// throw exception
__ call_VM(noreg, CAST_FROM_FN_PTR(address,
@@ -300,7 +299,10 @@
if (!EnableMethodHandles) {
return generate_abstract_entry();
}
- return generate_abstract_entry(); //6815692//
+
+ address entry_point = MethodHandles::generate_method_handle_interpreter_entry(_masm);
+
+ return entry_point;
}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/methodHandles_x86.cpp
--- a/src/cpu/x86/vm/methodHandles_x86.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/methodHandles_x86.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -65,9 +65,9 @@
// Verify that argslot lies within (rsp, rbp].
Label L_ok, L_bad;
__ cmpptr(rax_argslot, rbp);
- __ jcc(Assembler::above, L_bad);
+ __ jccb(Assembler::above, L_bad);
__ cmpptr(rsp, rax_argslot);
- __ jcc(Assembler::below, L_ok);
+ __ jccb(Assembler::below, L_ok);
__ bind(L_bad);
__ stop(error_message);
__ bind(L_ok);
@@ -136,9 +136,9 @@
if (arg_slots.is_register()) {
Label L_ok, L_bad;
__ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD);
- __ jcc(Assembler::greater, L_bad);
+ __ jccb(Assembler::greater, L_bad);
__ testl(arg_slots.as_register(), -stack_move_unit() - 1);
- __ jcc(Assembler::zero, L_ok);
+ __ jccb(Assembler::zero, L_ok);
__ bind(L_bad);
__ stop("assert arg_slots <= 0 and clear low bits");
__ bind(L_ok);
@@ -173,7 +173,7 @@
__ movptr(Address(rdx_temp, arg_slots, Address::times_ptr), rbx_temp);
__ addptr(rdx_temp, wordSize);
__ cmpptr(rdx_temp, rax_argslot);
- __ jcc(Assembler::less, loop);
+ __ jccb(Assembler::less, loop);
}
// Now move the argslot down, to point to the opened-up space.
@@ -211,9 +211,9 @@
Label L_ok, L_bad;
__ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr));
__ cmpptr(rbx_temp, rbp);
- __ jcc(Assembler::above, L_bad);
+ __ jccb(Assembler::above, L_bad);
__ cmpptr(rsp, rax_argslot);
- __ jcc(Assembler::below, L_ok);
+ __ jccb(Assembler::below, L_ok);
__ bind(L_bad);
__ stop("deleted argument(s) must fall within current frame");
__ bind(L_ok);
@@ -221,9 +221,9 @@
if (arg_slots.is_register()) {
Label L_ok, L_bad;
__ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD);
- __ jcc(Assembler::less, L_bad);
+ __ jccb(Assembler::less, L_bad);
__ testl(arg_slots.as_register(), -stack_move_unit() - 1);
- __ jcc(Assembler::zero, L_ok);
+ __ jccb(Assembler::zero, L_ok);
__ bind(L_bad);
__ stop("assert arg_slots >= 0 and clear low bits");
__ bind(L_ok);
@@ -258,7 +258,7 @@
__ movptr(Address(rdx_temp, arg_slots, Address::times_ptr), rbx_temp);
__ addptr(rdx_temp, -wordSize);
__ cmpptr(rdx_temp, rsp);
- __ jcc(Assembler::greaterEqual, loop);
+ __ jccb(Assembler::greaterEqual, loop);
}
// Now move the argslot up, to point to the just-copied block.
@@ -268,12 +268,20 @@
}
#ifndef PRODUCT
+extern "C" void print_method_handle(oop mh);
void trace_method_handle_stub(const char* adaptername,
- oopDesc* mh,
+ oop mh,
intptr_t* entry_sp,
- intptr_t* saved_sp) {
+ intptr_t* saved_sp,
+ intptr_t* saved_bp) {
// called as a leaf from native code: do not block the JVM!
- printf("MH %s "PTR_FORMAT" "PTR_FORMAT" "INTX_FORMAT"\n", adaptername, (void*)mh, entry_sp, entry_sp - saved_sp);
+ intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset];
+ intptr_t* base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset];
+ printf("MH %s mh="INTPTR_FORMAT" sp=("INTPTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="INTPTR_FORMAT"\n",
+ adaptername, (intptr_t)mh, (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp);
+ if (last_sp != saved_sp)
+ printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp);
+ if (Verbose) print_method_handle(mh);
}
#endif //PRODUCT
@@ -293,6 +301,10 @@
Register rbx_temp = rbx;
Register rdx_temp = rdx;
+ // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls)
+ // and gen_c2i_adapter (from compiled calls):
+ Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi);
+
guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
// some handy addresses
@@ -315,6 +327,8 @@
assert(tag_offset = wordSize, "stack grows as expected");
}
+ const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
+
if (have_entry(ek)) {
__ nop(); // empty stubs make SG sick
return;
@@ -328,45 +342,65 @@
__ push(rax); __ push(rbx); __ push(rcx); __ push(rdx); __ push(rsi); __ push(rdi);
__ lea(rax, Address(rsp, wordSize*6)); // entry_sp
// arguments:
+ __ push(rbp); // interpreter frame pointer
__ push(rsi); // saved_sp
__ push(rax); // entry_sp
__ push(rcx); // mh
__ push(rcx);
__ movptr(Address(rsp, 0), (intptr_t)entry_name(ek));
- __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), 4);
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), 5);
__ pop(rdi); __ pop(rsi); __ pop(rdx); __ pop(rcx); __ pop(rbx); __ pop(rax);
}
#endif //PRODUCT
switch ((int) ek) {
- case _check_mtype:
+ case _raise_exception:
{
- // this stub is special, because it requires a live mtype argument
- Register rax_mtype = rax;
+ // Not a real MH entry, but rather shared code for raising an exception.
+ // Extra local arguments are pushed on stack, as required type at TOS+8,
+ // failing object (or NULL) at TOS+4, failing bytecode type at TOS.
+ // Beyond those local arguments are the PC, of course.
+ Register rdx_code = rdx_temp;
+ Register rcx_fail = rcx_recv;
+ Register rax_want = rax_argslot;
+ Register rdi_pc = rdi;
+ __ pop(rdx_code); // TOS+0
+ __ pop(rcx_fail); // TOS+4
+ __ pop(rax_want); // TOS+8
+ __ pop(rdi_pc); // caller PC
- // emit WrongMethodType path first, to enable jccb back-branch
- Label wrong_method_type;
- __ bind(wrong_method_type);
- __ movptr(rdx_temp, ExternalAddress((address) &_entries[_wrong_method_type]));
- __ jmp(Address(rdx_temp, MethodHandleEntry::from_interpreted_entry_offset_in_bytes()));
- __ hlt();
+ __ mov(rsp, rsi); // cut the stack back to where the caller started
- interp_entry = __ pc();
- __ check_method_handle_type(rax_mtype, rcx_recv, rdx_temp, wrong_method_type);
- // now rax_mtype is dead; subsequent stubs will use it as a temp
-
- __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
- }
- break;
+ // Repush the arguments as if coming from the interpreter.
+ if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_INT));
+ __ push(rdx_code);
+ if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_OBJECT));
+ __ push(rcx_fail);
+ if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_OBJECT));
+ __ push(rax_want);
- case _wrong_method_type:
- {
- // this stub is special, because it requires a live mtype argument
- Register rax_mtype = rax;
+ Register rbx_method = rbx_temp;
+ Label no_method;
+ // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
+ __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method));
+ __ testptr(rbx_method, rbx_method);
+ __ jccb(Assembler::zero, no_method);
+ int jobject_oop_offset = 0;
+ __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject
+ __ testptr(rbx_method, rbx_method);
+ __ jccb(Assembler::zero, no_method);
+ __ verify_oop(rbx_method);
+ __ push(rdi_pc); // and restore caller PC
+ __ jmp(rbx_method_fie);
- interp_entry = __ pc();
- __ push(rax_mtype); // required mtype
- __ push(rcx_recv); // random mh (1st stacked argument)
+ // If we get here, the Java runtime did not do its job of creating the exception.
+ // Do something that is at least causes a valid throw from the interpreter.
+ __ bind(no_method);
+ __ pop(rax_want);
+ if (TaggedStackInterpreter) __ pop(rcx_fail);
+ __ pop(rcx_fail);
+ __ push(rax_want);
+ __ push(rcx_fail);
__ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
}
break;
@@ -416,7 +450,7 @@
rbx_index, Address::times_ptr,
base + vtableEntry::method_offset_in_bytes());
Register rbx_method = rbx_temp;
- __ movl(rbx_method, vtable_entry_addr);
+ __ movptr(rbx_method, vtable_entry_addr);
__ verify_oop(rbx_method);
__ jmp(rbx_method_fie);
@@ -442,7 +476,7 @@
__ load_klass(rax_klass, rcx_recv);
__ verify_oop(rax_klass);
- Register rcx_temp = rcx_recv;
+ Register rdi_temp = rdi;
Register rbx_method = rbx_index;
// get interface klass
@@ -451,7 +485,7 @@
__ lookup_interface_method(rax_klass, rdx_intf,
// note: next two args must be the same:
rbx_index, rbx_method,
- rcx_temp,
+ rdi_temp,
no_such_interface);
__ verify_oop(rbx_method);
@@ -461,7 +495,10 @@
__ bind(no_such_interface);
// Throw an exception.
// For historical reasons, it will be IncompatibleClassChangeError.
- __ should_not_reach_here(); // %%% FIXME NYI
+ __ pushptr(Address(rdx_intf, java_mirror_offset)); // required interface
+ __ push(rcx_recv); // bad receiver
+ __ push((int)Bytecodes::_invokeinterface); // who is complaining?
+ __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
}
break;
@@ -498,16 +535,15 @@
if (arg_type == T_OBJECT) {
__ movptr(Address(rax_argslot, 0), rbx_temp);
} else {
- __ load_sized_value(rbx_temp, prim_value_addr,
+ __ load_sized_value(rdx_temp, prim_value_addr,
type2aelembytes(arg_type), is_signed_subword_type(arg_type));
- __ movptr(Address(rax_argslot, 0), rbx_temp);
+ __ movptr(Address(rax_argslot, 0), rdx_temp);
#ifndef _LP64
if (arg_slots == 2) {
- __ movl(rbx_temp, prim_value_addr.plus_disp(wordSize));
- __ movl(Address(rax_argslot, Interpreter::stackElementSize()), rbx_temp);
+ __ movl(rdx_temp, prim_value_addr.plus_disp(wordSize));
+ __ movl(Address(rax_argslot, Interpreter::stackElementSize()), rdx_temp);
}
#endif //_LP64
- break;
}
if (direct_to_method) {
@@ -524,6 +560,7 @@
break;
case _adapter_retype_only:
+ case _adapter_retype_raw:
// immediately jump to the next MH layer:
__ movptr(rcx_recv, rcx_mh_vmtarget);
__ verify_oop(rcx_recv);
@@ -545,30 +582,32 @@
__ movptr(rbx_klass, rcx_amh_argument); // this is a Class object!
__ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
- // get the new MH:
- __ movptr(rcx_recv, rcx_mh_vmtarget);
- // (now we are done with the old MH)
-
Label done;
__ movptr(rdx_temp, vmarg);
- __ testl(rdx_temp, rdx_temp);
- __ jcc(Assembler::zero, done); // no cast if null
+ __ testptr(rdx_temp, rdx_temp);
+ __ jccb(Assembler::zero, done); // no cast if null
__ load_klass(rdx_temp, rdx_temp);
// live at this point:
// - rbx_klass: klass required by the target method
// - rdx_temp: argument klass to test
- // - rcx_recv: method handle to invoke (after cast succeeds)
+ // - rcx_recv: adapter method handle
__ check_klass_subtype(rdx_temp, rbx_klass, rax_argslot, done);
// If we get here, the type check failed!
// Call the wrong_method_type stub, passing the failing argument type in rax.
Register rax_mtype = rax_argslot;
- __ push(rbx_klass); // missed klass (required type)
- __ push(rdx_temp); // bad actual type (1st stacked argument)
- __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
+ __ movl(rax_argslot, rcx_amh_vmargslot); // reload argslot field
+ __ movptr(rdx_temp, vmarg);
+
+ __ pushptr(rcx_amh_argument); // required class
+ __ push(rdx_temp); // bad object
+ __ push((int)Bytecodes::_checkcast); // who is complaining?
+ __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
__ bind(done);
+ // get the new MH:
+ __ movptr(rcx_recv, rcx_mh_vmtarget);
__ jump_to_method_handle_entry(rcx_recv, rdx_temp);
}
break;
@@ -637,24 +676,24 @@
// (now we are done with the old MH)
// original 32-bit vmdata word must be of this form:
- // | MBZ:16 | signBitCount:8 | srcDstTypes:8 | conversionOp:8 |
- __ xchgl(rcx, rbx_vminfo); // free rcx for shifts
+ // | MBZ:6 | signBitCount:8 | srcDstTypes:8 | conversionOp:8 |
+ __ xchgptr(rcx, rbx_vminfo); // free rcx for shifts
__ shll(rdx_temp /*, rcx*/);
Label zero_extend, done;
__ testl(rcx, CONV_VMINFO_SIGN_FLAG);
- __ jcc(Assembler::zero, zero_extend);
+ __ jccb(Assembler::zero, zero_extend);
// this path is taken for int->byte, int->short
__ sarl(rdx_temp /*, rcx*/);
- __ jmp(done);
+ __ jmpb(done);
__ bind(zero_extend);
// this is taken for int->char
__ shrl(rdx_temp /*, rcx*/);
__ bind(done);
- __ movptr(vmarg, rdx_temp);
- __ xchgl(rcx, rbx_vminfo); // restore rcx_recv
+ __ movl(vmarg, rdx_temp);
+ __ xchgptr(rcx, rbx_vminfo); // restore rcx_recv
__ jump_to_method_handle_entry(rcx_recv, rdx_temp);
}
@@ -823,7 +862,7 @@
// Verify that argslot > destslot, by at least swap_bytes.
Label L_ok;
__ cmpptr(rax_argslot, rbx_destslot);
- __ jcc(Assembler::aboveEqual, L_ok);
+ __ jccb(Assembler::aboveEqual, L_ok);
__ stop("source must be above destination (upward rotation)");
__ bind(L_ok);
}
@@ -839,7 +878,7 @@
__ movptr(Address(rax_argslot, swap_bytes), rdx_temp);
__ addptr(rax_argslot, -wordSize);
__ cmpptr(rax_argslot, rbx_destslot);
- __ jcc(Assembler::aboveEqual, loop);
+ __ jccb(Assembler::aboveEqual, loop);
} else {
__ addptr(rax_argslot, swap_bytes);
#ifdef ASSERT
@@ -847,7 +886,7 @@
// Verify that argslot < destslot, by at least swap_bytes.
Label L_ok;
__ cmpptr(rax_argslot, rbx_destslot);
- __ jcc(Assembler::belowEqual, L_ok);
+ __ jccb(Assembler::belowEqual, L_ok);
__ stop("source must be below destination (downward rotation)");
__ bind(L_ok);
}
@@ -863,7 +902,7 @@
__ movptr(Address(rax_argslot, -swap_bytes), rdx_temp);
__ addptr(rax_argslot, wordSize);
__ cmpptr(rax_argslot, rbx_destslot);
- __ jcc(Assembler::belowEqual, loop);
+ __ jccb(Assembler::belowEqual, loop);
}
// pop the original first chunk into the destination slot, now free
@@ -929,7 +968,7 @@
__ addptr(rax_argslot, wordSize);
__ addptr(rdx_newarg, wordSize);
__ cmpptr(rdx_newarg, rbx_oldarg);
- __ jcc(Assembler::less, loop);
+ __ jccb(Assembler::less, loop);
__ pop(rdi); // restore temp
@@ -1081,7 +1120,7 @@
}
__ addptr(rax_argslot, Interpreter::stackElementSize());
__ cmpptr(rax_argslot, rdx_argslot_limit);
- __ jcc(Assembler::less, loop);
+ __ jccb(Assembler::less, loop);
} else if (length_constant == 0) {
__ bind(skip_array_check);
// nothing to copy
@@ -1107,11 +1146,17 @@
__ bind(bad_array_klass);
UNPUSH_RSI_RDI;
- __ stop("bad array klass NYI");
+ __ pushptr(Address(rdx_array_klass, java_mirror_offset)); // required type
+ __ pushptr(vmarg); // bad array
+ __ push((int)Bytecodes::_aaload); // who is complaining?
+ __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
__ bind(bad_array_length);
UNPUSH_RSI_RDI;
- __ stop("bad array length NYI");
+ __ push(rcx_recv); // AMH requiring a certain length
+ __ pushptr(vmarg); // bad array
+ __ push((int)Bytecodes::_arraylength); // who is complaining?
+ __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
#undef UNPUSH_RSI_RDI
}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/runtime_x86_32.cpp
--- a/src/cpu/x86/vm/runtime_x86_32.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/runtime_x86_32.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -43,11 +43,11 @@
// This code is entered with a jmp.
//
// Arguments:
-// rax,: exception oop
+// rax: exception oop
// rdx: exception pc
//
// Results:
-// rax,: exception oop
+// rax: exception oop
// rdx: exception pc in caller or ???
// destination: exception handler of caller
//
@@ -113,17 +113,17 @@
__ addptr(rsp, return_off * wordSize); // Epilog!
__ pop(rdx); // Exception pc
+ // rax: exception handler for given
- // rax,: exception handler for given
+ // Restore SP from BP if the exception PC is a MethodHandle call.
+ __ cmpl(Address(rcx, JavaThread::is_method_handle_exception_offset()), 0);
+ __ cmovptr(Assembler::notEqual, rsp, rbp);
// We have a handler in rax, (could be deopt blob)
// rdx - throwing pc, deopt blob will need it.
__ push(rax);
- // rcx contains handler address
-
- __ get_thread(rcx); // TLS
// Get the exception
__ movptr(rax, Address(rcx, JavaThread::exception_oop_offset()));
// Get the exception pc in case we are deoptimized
@@ -137,7 +137,7 @@
__ pop(rcx);
- // rax,: exception oop
+ // rax: exception oop
// rcx: exception handler
// rdx: exception pc
__ jmp (rcx);
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/sharedRuntime_x86_32.cpp
--- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 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
@@ -907,7 +907,8 @@
int total_args_passed,
int comp_args_on_stack,
const BasicType *sig_bt,
- const VMRegPair *regs) {
+ const VMRegPair *regs,
+ AdapterFingerPrint* fingerprint) {
address i2c_entry = __ pc();
gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs);
@@ -954,7 +955,7 @@
gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
__ flush();
- return new AdapterHandlerEntry(i2c_entry, c2i_entry, c2i_unverified_entry);
+ return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
}
int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
@@ -2381,7 +2382,7 @@
// Save everything in sight.
- map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words);
+ map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false);
// Normal deoptimization
__ push(Deoptimization::Unpack_deopt);
__ jmp(cont);
@@ -2392,7 +2393,7 @@
// return address is the pc describes what bci to do re-execute at
// No need to update map as each call to save_live_registers will produce identical oopmap
- (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words);
+ (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false);
__ push(Deoptimization::Unpack_reexecute);
__ jmp(cont);
@@ -2428,7 +2429,7 @@
// Save everything in sight.
// No need to update map as each call to save_live_registers will produce identical oopmap
- (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words);
+ (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false);
// Now it is safe to overwrite any register
@@ -2515,6 +2516,11 @@
RegisterSaver::restore_result_registers(masm);
+ // Non standard control word may be leaked out through a safepoint blob, and we can
+ // deopt at a poll point with the non standard control word. However, we should make
+ // sure the control word is correct after restore_result_registers.
+ __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
+
// All of the register save area has been popped of the stack. Only the
// return address remains.
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/sharedRuntime_x86_64.cpp
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 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
@@ -638,6 +638,10 @@
__ movptr(rax, Address(rsp, 0));
+ // Must preserve original SP for loading incoming arguments because
+ // we need to align the outgoing SP for compiled code.
+ __ movptr(r11, rsp);
+
// Cut-out for having no stack args. Since up to 2 int/oop args are passed
// in registers, we will occasionally have no stack args.
int comp_words_on_stack = 0;
@@ -661,6 +665,10 @@
// as far as the placement of the call instruction
__ push(rax);
+ // Put saved SP in another register
+ const Register saved_sp = rax;
+ __ movptr(saved_sp, r11);
+
// Will jump to the compiled code just as if compiled code was doing it.
// Pre-load the register-jump target early, to schedule it better.
__ movptr(r11, Address(rbx, in_bytes(methodOopDesc::from_compiled_offset())));
@@ -680,11 +688,7 @@
assert(!regs[i].second()->is_valid() || regs[i].first()->next() == regs[i].second(),
"scrambled load targets?");
// Load in argument order going down.
- // int ld_off = (total_args_passed + comp_words_on_stack -i)*wordSize;
- // base ld_off on r13 (sender_sp) as the stack alignment makes offsets from rsp
- // unpredictable
- int ld_off = ((total_args_passed - 1) - i)*Interpreter::stackElementSize();
-
+ int ld_off = (total_args_passed - i)*Interpreter::stackElementSize() + Interpreter::value_offset_in_bytes();
// Point to interpreter value (vs. tag)
int next_off = ld_off - Interpreter::stackElementSize();
//
@@ -699,10 +703,14 @@
if (r_1->is_stack()) {
// Convert stack slot to an SP offset (+ wordSize to account for return address )
int st_off = regs[i].first()->reg2stack()*VMRegImpl::stack_slot_size + wordSize;
+
+ // We can use r13 as a temp here because compiled code doesn't need r13 as an input
+ // and if we end up going thru a c2i because of a miss a reasonable value of r13
+ // will be generated.
if (!r_2->is_valid()) {
// sign extend???
- __ movl(rax, Address(r13, ld_off));
- __ movptr(Address(rsp, st_off), rax);
+ __ movl(r13, Address(saved_sp, ld_off));
+ __ movptr(Address(rsp, st_off), r13);
} else {
//
// We are using two optoregs. This can be either T_OBJECT, T_ADDRESS, T_LONG, or T_DOUBLE
@@ -715,9 +723,9 @@
// ld_off is MSW so get LSW
const int offset = (sig_bt[i]==T_LONG||sig_bt[i]==T_DOUBLE)?
next_off : ld_off;
- __ movq(rax, Address(r13, offset));
+ __ movq(r13, Address(saved_sp, offset));
// st_off is LSW (i.e. reg.first())
- __ movq(Address(rsp, st_off), rax);
+ __ movq(Address(rsp, st_off), r13);
}
} else if (r_1->is_Register()) { // Register argument
Register r = r_1->as_Register();
@@ -732,16 +740,16 @@
next_off : ld_off;
// this can be a misaligned move
- __ movq(r, Address(r13, offset));
+ __ movq(r, Address(saved_sp, offset));
} else {
// sign extend and use a full word?
- __ movl(r, Address(r13, ld_off));
+ __ movl(r, Address(saved_sp, ld_off));
}
} else {
if (!r_2->is_valid()) {
- __ movflt(r_1->as_XMMRegister(), Address(r13, ld_off));
+ __ movflt(r_1->as_XMMRegister(), Address(saved_sp, ld_off));
} else {
- __ movdbl(r_1->as_XMMRegister(), Address(r13, next_off));
+ __ movdbl(r_1->as_XMMRegister(), Address(saved_sp, next_off));
}
}
}
@@ -770,7 +778,8 @@
int total_args_passed,
int comp_args_on_stack,
const BasicType *sig_bt,
- const VMRegPair *regs) {
+ const VMRegPair *regs,
+ AdapterFingerPrint* fingerprint) {
address i2c_entry = __ pc();
gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs);
@@ -816,7 +825,7 @@
gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
__ flush();
- return new AdapterHandlerEntry(i2c_entry, c2i_entry, c2i_unverified_entry);
+ return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
}
int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
@@ -3319,6 +3328,10 @@
// rax: exception handler
+ // Restore SP from BP if the exception PC is a MethodHandle call.
+ __ cmpl(Address(r15_thread, JavaThread::is_method_handle_exception_offset()), 0);
+ __ cmovptr(Assembler::notEqual, rsp, rbp);
+
// We have a handler in rax (could be deopt blob).
__ mov(r8, rax);
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/stubGenerator_x86_32.cpp
--- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -718,10 +718,8 @@
case BarrierSet::G1SATBCTLogging:
{
__ pusha(); // push registers
- __ push(count);
- __ push(start);
- __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre)));
- __ addptr(rsp, 2*wordSize);
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre),
+ start, count);
__ popa();
}
break;
@@ -752,10 +750,8 @@
case BarrierSet::G1SATBCTLogging:
{
__ pusha(); // push registers
- __ push(count);
- __ push(start);
- __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post)));
- __ addptr(rsp, 2*wordSize);
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post),
+ start, count);
__ popa();
}
break;
@@ -2030,6 +2026,54 @@
entry_checkcast_arraycopy);
}
+ void generate_math_stubs() {
+ {
+ StubCodeMark mark(this, "StubRoutines", "log");
+ StubRoutines::_intrinsic_log = (double (*)(double)) __ pc();
+
+ __ fld_d(Address(rsp, 4));
+ __ flog();
+ __ ret(0);
+ }
+ {
+ StubCodeMark mark(this, "StubRoutines", "log10");
+ StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc();
+
+ __ fld_d(Address(rsp, 4));
+ __ flog10();
+ __ ret(0);
+ }
+ {
+ StubCodeMark mark(this, "StubRoutines", "sin");
+ StubRoutines::_intrinsic_sin = (double (*)(double)) __ pc();
+
+ __ fld_d(Address(rsp, 4));
+ __ trigfunc('s');
+ __ ret(0);
+ }
+ {
+ StubCodeMark mark(this, "StubRoutines", "cos");
+ StubRoutines::_intrinsic_cos = (double (*)(double)) __ pc();
+
+ __ fld_d(Address(rsp, 4));
+ __ trigfunc('c');
+ __ ret(0);
+ }
+ {
+ StubCodeMark mark(this, "StubRoutines", "tan");
+ StubRoutines::_intrinsic_tan = (double (*)(double)) __ pc();
+
+ __ fld_d(Address(rsp, 4));
+ __ trigfunc('t');
+ __ ret(0);
+ }
+
+ // The intrinsic version of these seem to return the same value as
+ // the strict version.
+ StubRoutines::_intrinsic_exp = SharedRuntime::dexp;
+ StubRoutines::_intrinsic_pow = SharedRuntime::dpow;
+ }
+
public:
// Information about frame layout at time of blocking runtime call.
// Note that we only have to preserve callee-saved registers since
@@ -2228,6 +2272,8 @@
MethodHandles::generate_method_handle_stub(_masm, ek);
}
}
+
+ generate_math_stubs();
}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/stubGenerator_x86_64.cpp
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 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
@@ -1172,7 +1172,7 @@
__ movptr(c_rarg0, addr);
__ movptr(c_rarg1, count);
}
- __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre)));
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
__ popa();
}
break;
@@ -1212,7 +1212,7 @@
__ shrptr(scratch, LogBytesPerHeapOop); // convert to element count
__ mov(c_rarg0, start);
__ mov(c_rarg1, scratch);
- __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post)));
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
__ popa();
}
break;
@@ -2731,6 +2731,79 @@
StubRoutines::_arrayof_oop_arraycopy = StubRoutines::_oop_arraycopy;
}
+ void generate_math_stubs() {
+ {
+ StubCodeMark mark(this, "StubRoutines", "log");
+ StubRoutines::_intrinsic_log = (double (*)(double)) __ pc();
+
+ __ subq(rsp, 8);
+ __ movdbl(Address(rsp, 0), xmm0);
+ __ fld_d(Address(rsp, 0));
+ __ flog();
+ __ fstp_d(Address(rsp, 0));
+ __ movdbl(xmm0, Address(rsp, 0));
+ __ addq(rsp, 8);
+ __ ret(0);
+ }
+ {
+ StubCodeMark mark(this, "StubRoutines", "log10");
+ StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc();
+
+ __ subq(rsp, 8);
+ __ movdbl(Address(rsp, 0), xmm0);
+ __ fld_d(Address(rsp, 0));
+ __ flog10();
+ __ fstp_d(Address(rsp, 0));
+ __ movdbl(xmm0, Address(rsp, 0));
+ __ addq(rsp, 8);
+ __ ret(0);
+ }
+ {
+ StubCodeMark mark(this, "StubRoutines", "sin");
+ StubRoutines::_intrinsic_sin = (double (*)(double)) __ pc();
+
+ __ subq(rsp, 8);
+ __ movdbl(Address(rsp, 0), xmm0);
+ __ fld_d(Address(rsp, 0));
+ __ trigfunc('s');
+ __ fstp_d(Address(rsp, 0));
+ __ movdbl(xmm0, Address(rsp, 0));
+ __ addq(rsp, 8);
+ __ ret(0);
+ }
+ {
+ StubCodeMark mark(this, "StubRoutines", "cos");
+ StubRoutines::_intrinsic_cos = (double (*)(double)) __ pc();
+
+ __ subq(rsp, 8);
+ __ movdbl(Address(rsp, 0), xmm0);
+ __ fld_d(Address(rsp, 0));
+ __ trigfunc('c');
+ __ fstp_d(Address(rsp, 0));
+ __ movdbl(xmm0, Address(rsp, 0));
+ __ addq(rsp, 8);
+ __ ret(0);
+ }
+ {
+ StubCodeMark mark(this, "StubRoutines", "tan");
+ StubRoutines::_intrinsic_tan = (double (*)(double)) __ pc();
+
+ __ subq(rsp, 8);
+ __ movdbl(Address(rsp, 0), xmm0);
+ __ fld_d(Address(rsp, 0));
+ __ trigfunc('t');
+ __ fstp_d(Address(rsp, 0));
+ __ movdbl(xmm0, Address(rsp, 0));
+ __ addq(rsp, 8);
+ __ ret(0);
+ }
+
+ // The intrinsic version of these seem to return the same value as
+ // the strict version.
+ StubRoutines::_intrinsic_exp = SharedRuntime::dexp;
+ StubRoutines::_intrinsic_pow = SharedRuntime::dpow;
+ }
+
#undef __
#define __ masm->
@@ -2935,6 +3008,18 @@
// arraycopy stubs used by compilers
generate_arraycopy_stubs();
+
+ // generic method handle stubs
+ if (EnableMethodHandles && SystemDictionary::MethodHandle_klass() != NULL) {
+ for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST;
+ ek < MethodHandles::_EK_LIMIT;
+ ek = MethodHandles::EntryKind(1 + (int)ek)) {
+ StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
+ MethodHandles::generate_method_handle_stub(_masm, ek);
+ }
+ }
+
+ generate_math_stubs();
}
public:
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/templateInterpreter_x86_32.cpp
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -92,8 +92,7 @@
return entry;
}
-// Arguments are: required type at TOS+8, failing object (or NULL) at TOS+4.
-// pc at TOS (just for debugging)
+// Arguments are: required type at TOS+4, failing object (or NULL) at TOS.
address TemplateInterpreterGenerator::generate_WrongMethodType_handler() {
address entry = __ pc();
@@ -156,15 +155,8 @@
}
-address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, bool unbox) {
+address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) {
TosState incoming_state = state;
- if (EnableInvokeDynamic) {
- if (unbox) {
- incoming_state = atos;
- }
- } else {
- assert(!unbox, "old behavior");
- }
Label interpreter_entry;
address compiled_entry = __ pc();
@@ -217,46 +209,6 @@
__ restore_bcp();
__ restore_locals();
- Label L_fail;
-
- if (unbox && state != atos) {
- // cast and unbox
- BasicType type = as_BasicType(state);
- if (type == T_BYTE) type = T_BOOLEAN; // FIXME
- KlassHandle boxk = SystemDictionaryHandles::box_klass(type);
- __ mov32(rbx, ExternalAddress((address) boxk.raw_value()));
- __ testl(rax, rax);
- Label L_got_value, L_get_value;
- // convert nulls to zeroes (avoid NPEs here)
- if (!(type == T_FLOAT || type == T_DOUBLE)) {
- // if rax already contains zero bits, forge ahead
- __ jcc(Assembler::zero, L_got_value);
- } else {
- __ jcc(Assembler::notZero, L_get_value);
- __ fldz();
- __ jmp(L_got_value);
- }
- __ bind(L_get_value);
- __ cmp32(rbx, Address(rax, oopDesc::klass_offset_in_bytes()));
- __ jcc(Assembler::notEqual, L_fail);
- int offset = java_lang_boxing_object::value_offset_in_bytes(type);
- // Cf. TemplateTable::getfield_or_static
- switch (type) {
- case T_BYTE: // fall through:
- case T_BOOLEAN: __ load_signed_byte(rax, Address(rax, offset)); break;
- case T_CHAR: __ load_unsigned_short(rax, Address(rax, offset)); break;
- case T_SHORT: __ load_signed_short(rax, Address(rax, offset)); break;
- case T_INT: __ movl(rax, Address(rax, offset)); break;
- case T_FLOAT: __ fld_s(Address(rax, offset)); break;
- case T_DOUBLE: __ fld_d(Address(rax, offset)); break;
- // Access to java.lang.Double.value does not need to be atomic:
- case T_LONG: { __ movl(rdx, Address(rax, offset + 4));
- __ movl(rax, Address(rax, offset + 0)); } break;
- default: ShouldNotReachHere();
- }
- __ bind(L_got_value);
- }
-
Label L_got_cache, L_giant_index;
if (EnableInvokeDynamic) {
__ cmpb(Address(rsi, 0), Bytecodes::_invokedynamic);
@@ -264,32 +216,6 @@
}
__ get_cache_and_index_at_bcp(rbx, rcx, 1, false);
__ bind(L_got_cache);
- if (unbox && state == atos) {
- // insert a casting conversion, to keep verifier sane
- Label L_ok, L_ok_pops;
- __ testl(rax, rax);
- __ jcc(Assembler::zero, L_ok);
- __ push(rax); // save the object to check
- __ push(rbx); // save CP cache reference
- __ movl(rdx, Address(rax, oopDesc::klass_offset_in_bytes()));
- __ movl(rbx, Address(rbx, rcx,
- Address::times_4, constantPoolCacheOopDesc::base_offset() +
- ConstantPoolCacheEntry::f1_offset()));
- __ movl(rbx, Address(rbx, __ delayed_value(sun_dyn_CallSiteImpl::type_offset_in_bytes, rcx)));
- __ movl(rbx, Address(rbx, __ delayed_value(java_dyn_MethodType::rtype_offset_in_bytes, rcx)));
- __ movl(rax, Address(rbx, __ delayed_value(java_lang_Class::klass_offset_in_bytes, rcx)));
- __ check_klass_subtype(rdx, rax, rbx, L_ok_pops);
- __ pop(rcx); // pop and discard CP cache
- __ mov(rbx, rax); // target supertype into rbx for L_fail
- __ pop(rax); // failed object into rax for L_fail
- __ jmp(L_fail);
-
- __ bind(L_ok_pops);
- // restore pushed temp regs:
- __ pop(rbx);
- __ pop(rax);
- __ bind(L_ok);
- }
__ movl(rbx, Address(rbx, rcx,
Address::times_ptr, constantPoolCacheOopDesc::base_offset() +
ConstantPoolCacheEntry::flags_offset()));
@@ -302,14 +228,6 @@
__ bind(L_giant_index);
__ get_cache_and_index_at_bcp(rbx, rcx, 1, true);
__ jmp(L_got_cache);
-
- if (unbox) {
- __ bind(L_fail);
- __ push(rbx); // missed klass (required)
- __ push(rax); // bad object (actual)
- __ movptr(rdx, ExternalAddress((address) &Interpreter::_throw_WrongMethodType_entry));
- __ call(rdx);
- }
}
return entry;
@@ -1513,6 +1431,23 @@
}
+// These should never be compiled since the interpreter will prefer
+// the compiled version to the intrinsic version.
+bool AbstractInterpreter::can_be_compiled(methodHandle m) {
+ switch (method_kind(m)) {
+ case Interpreter::java_lang_math_sin : // fall thru
+ case Interpreter::java_lang_math_cos : // fall thru
+ case Interpreter::java_lang_math_tan : // fall thru
+ case Interpreter::java_lang_math_abs : // fall thru
+ case Interpreter::java_lang_math_log : // fall thru
+ case Interpreter::java_lang_math_log10 : // fall thru
+ case Interpreter::java_lang_math_sqrt :
+ return false;
+ default:
+ return true;
+ }
+}
+
// How much stack a method activation needs in words.
int AbstractInterpreter::size_top_interpreter_activation(methodOop method) {
@@ -1570,7 +1505,10 @@
if (interpreter_frame != NULL) {
#ifdef ASSERT
- assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
+ if (!EnableMethodHandles)
+ // @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences?
+ // Probably, since deoptimization doesn't work yet.
+ assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable(2)");
#endif
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/templateInterpreter_x86_64.cpp
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 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
@@ -100,21 +100,26 @@
return entry;
}
-// Arguments are: required type in rarg1, failing object (or NULL) in rarg2
+// Arguments are: required type at TOS+8, failing object (or NULL) at TOS+4.
address TemplateInterpreterGenerator::generate_WrongMethodType_handler() {
address entry = __ pc();
__ pop(c_rarg2); // failing object is at TOS
__ pop(c_rarg1); // required type is at TOS+8
- // expression stack must be empty before entering the VM if an
- // exception happened
+ __ verify_oop(c_rarg1);
+ __ verify_oop(c_rarg2);
+
+ // Various method handle types use interpreter registers as temps.
+ __ restore_bcp();
+ __ restore_locals();
+
+ // Expression stack must be empty before entering the VM for an exception.
__ empty_expression_stack();
__ call_VM(noreg,
CAST_FROM_FN_PTR(address,
- InterpreterRuntime::
- throw_WrongMethodTypeException),
+ InterpreterRuntime::throw_WrongMethodTypeException),
// pass required type, failing object (or NULL)
c_rarg1, c_rarg2);
return entry;
@@ -166,8 +171,7 @@
address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
- int step, bool unbox) {
- assert(!unbox, "NYI");//6815692//
+ int step) {
// amd64 doesn't need to do anything special about compiled returns
// to the interpreter so the code that exists on x86 to place a sentinel
@@ -183,15 +187,29 @@
__ restore_bcp();
__ restore_locals();
- __ get_cache_and_index_at_bcp(rbx, rcx, 1);
+ Label L_got_cache, L_giant_index;
+ if (EnableInvokeDynamic) {
+ __ cmpb(Address(r13, 0), Bytecodes::_invokedynamic);
+ __ jcc(Assembler::equal, L_giant_index);
+ }
+ __ get_cache_and_index_at_bcp(rbx, rcx, 1, false);
+ __ bind(L_got_cache);
__ movl(rbx, Address(rbx, rcx,
- Address::times_8,
+ Address::times_ptr,
in_bytes(constantPoolCacheOopDesc::base_offset()) +
3 * wordSize));
__ andl(rbx, 0xFF);
if (TaggedStackInterpreter) __ shll(rbx, 1); // 2 slots per parameter.
__ lea(rsp, Address(rsp, rbx, Address::times_8));
__ dispatch_next(state, step);
+
+ // out of the main line of code...
+ if (EnableInvokeDynamic) {
+ __ bind(L_giant_index);
+ __ get_cache_and_index_at_bcp(rbx, rcx, 1, true);
+ __ jmp(L_got_cache);
+ }
+
return entry;
}
@@ -431,8 +449,12 @@
__ addptr(rax, stack_base);
__ subptr(rax, stack_size);
+ // Use the maximum number of pages we might bang.
+ const int max_pages = StackShadowPages > (StackRedPages+StackYellowPages) ? StackShadowPages :
+ (StackRedPages+StackYellowPages);
+
// add in the red and yellow zone sizes
- __ addptr(rax, (StackRedPages + StackYellowPages) * page_size);
+ __ addptr(rax, max_pages * page_size);
// check against the current stack bottom
__ cmpptr(rsp, rax);
@@ -1434,6 +1456,23 @@
generate_normal_entry(synchronized);
}
+// These should never be compiled since the interpreter will prefer
+// the compiled version to the intrinsic version.
+bool AbstractInterpreter::can_be_compiled(methodHandle m) {
+ switch (method_kind(m)) {
+ case Interpreter::java_lang_math_sin : // fall thru
+ case Interpreter::java_lang_math_cos : // fall thru
+ case Interpreter::java_lang_math_tan : // fall thru
+ case Interpreter::java_lang_math_abs : // fall thru
+ case Interpreter::java_lang_math_log : // fall thru
+ case Interpreter::java_lang_math_log10 : // fall thru
+ case Interpreter::java_lang_math_sqrt :
+ return false;
+ default:
+ return true;
+ }
+}
+
// How much stack a method activation needs in words.
int AbstractInterpreter::size_top_interpreter_activation(methodOop method) {
const int entry_size = frame::interpreter_frame_monitor_size();
@@ -1484,8 +1523,10 @@
tempcount* Interpreter::stackElementWords() + popframe_extra_args;
if (interpreter_frame != NULL) {
#ifdef ASSERT
- assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(),
- "Frame not properly walkable");
+ if (!EnableMethodHandles)
+ // @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences?
+ // Probably, since deoptimization doesn't work yet.
+ assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable(2)");
#endif
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/templateTable_x86_32.cpp
--- a/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -2890,9 +2890,6 @@
void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
- bool is_invdyn_bootstrap = (byte_no < 0);
- if (is_invdyn_bootstrap) byte_no = -byte_no;
-
// determine flags
Bytecodes::Code code = bytecode();
const bool is_invokeinterface = code == Bytecodes::_invokeinterface;
@@ -2907,8 +2904,6 @@
const Register flags = rdx;
assert_different_registers(method, index, recv, flags);
- assert(!is_invdyn_bootstrap || is_invokedynamic, "byte_no<0 hack only for invdyn");
-
// save 'interpreter return address'
__ save_bcp();
@@ -2944,9 +2939,7 @@
// load return address
{
address table_addr;
- if (is_invdyn_bootstrap)
- table_addr = (address)Interpreter::return_5_unbox_addrs_by_index_table();
- else if (is_invokeinterface || is_invokedynamic)
+ if (is_invokeinterface || is_invokedynamic)
table_addr = (address)Interpreter::return_5_addrs_by_index_table();
else
table_addr = (address)Interpreter::return_3_addrs_by_index_table();
@@ -3153,54 +3146,10 @@
__ profile_call(rsi);
}
- Label handle_unlinked_site;
- __ movptr(rcx, Address(rax, __ delayed_value(sun_dyn_CallSiteImpl::target_offset_in_bytes, rcx)));
- __ testptr(rcx, rcx);
- __ jcc(Assembler::zero, handle_unlinked_site);
-
+ __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
+ __ null_check(rcx);
__ prepare_to_jump_from_interpreted();
__ jump_to_method_handle_entry(rcx, rdx);
-
- // Initial calls come here...
- __ bind(handle_unlinked_site);
- __ pop(rcx); // remove return address pushed by prepare_invoke
-
- // box stacked arguments into an array for the bootstrap method
- address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::bootstrap_invokedynamic);
- __ restore_bcp(); // rsi must be correct for call_VM
- __ call_VM(rax, entry, rax);
- __ movl(rdi, rax); // protect bootstrap MH from prepare_invoke
-
- // recompute return address
- __ restore_bcp(); // rsi must be correct for prepare_invoke
- prepare_invoke(rax, rbx, -byte_no); // smashes rcx, rdx
- // rax: CallSite object (f1)
- // rbx: unused (f2)
- // rdi: bootstrap MH
- // rdx: flags
-
- // now load up the arglist, which has been neatly boxed
- __ get_thread(rcx);
- __ movptr(rdx, Address(rcx, JavaThread::vm_result_2_offset()));
- __ movptr(Address(rcx, JavaThread::vm_result_2_offset()), NULL_WORD);
- __ verify_oop(rdx);
- // rdx = arglist
-
- // save SP now, before we add the bootstrap call to the stack
- // We must preserve a fiction that the original arguments are outgoing,
- // because the return sequence will reset the stack to this point
- // and then pop all those arguments. It seems error-prone to use
- // a different argument list size just for bootstrapping.
- __ prepare_to_jump_from_interpreted();
-
- // Now let's play adapter, pushing the real arguments on the stack.
- __ pop(rbx); // return PC
- __ push(rdi); // boot MH
- __ push(rax); // call site
- __ push(rdx); // arglist
- __ push(rbx); // return PC, again
- __ mov(rcx, rdi);
- __ jump_to_method_handle_entry(rcx, rdx);
}
//----------------------------------------------------------------------------------------------------
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/templateTable_x86_64.cpp
--- a/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -139,7 +139,7 @@
}
__ g1_write_barrier_pre(rdx, r8, rbx, val != noreg);
if (val == noreg) {
- __ store_heap_oop(Address(rdx, 0), NULL_WORD);
+ __ store_heap_oop_null(Address(rdx, 0));
} else {
__ store_heap_oop(Address(rdx, 0), val);
__ g1_write_barrier_post(rdx, val, r8, rbx);
@@ -152,7 +152,7 @@
case BarrierSet::CardTableExtension:
{
if (val == noreg) {
- __ store_heap_oop(obj, NULL_WORD);
+ __ store_heap_oop_null(obj);
} else {
__ store_heap_oop(obj, val);
// flatten object address if needed
@@ -168,7 +168,7 @@
case BarrierSet::ModRef:
case BarrierSet::Other:
if (val == noreg) {
- __ store_heap_oop(obj, NULL_WORD);
+ __ store_heap_oop_null(obj);
} else {
__ store_heap_oop(obj, val);
}
@@ -203,18 +203,15 @@
__ jcc(Assembler::notEqual, fast_patch);
__ get_method(scratch);
// Let breakpoint table handling rewrite to quicker bytecode
- __ call_VM(noreg,
- CAST_FROM_FN_PTR(address,
- InterpreterRuntime::set_original_bytecode_at),
- scratch, r13, bc);
+ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, r13, bc);
#ifndef ASSERT
__ jmpb(patch_done);
+#else
+ __ jmp(patch_done);
+#endif
__ bind(fast_patch);
}
-#else
- __ jmp(patch_done);
- __ bind(fast_patch);
- }
+#ifdef ASSERT
Label okay;
__ load_unsigned_byte(scratch, at_bcp(0));
__ cmpl(scratch, (int) Bytecodes::java_code(bytecode));
@@ -2054,26 +2051,28 @@
}
}
-void TemplateTable::resolve_cache_and_index(int byte_no,
- Register Rcache,
- Register index) {
+void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Register index) {
assert(byte_no == 1 || byte_no == 2, "byte_no out of range");
+ bool is_invokedynamic = (bytecode() == Bytecodes::_invokedynamic);
const Register temp = rbx;
assert_different_registers(Rcache, index, temp);
const int shift_count = (1 + byte_no) * BitsPerByte;
Label resolved;
- __ get_cache_and_index_at_bcp(Rcache, index, 1);
- __ movl(temp, Address(Rcache,
- index, Address::times_8,
- constantPoolCacheOopDesc::base_offset() +
- ConstantPoolCacheEntry::indices_offset()));
- __ shrl(temp, shift_count);
- // have we resolved this bytecode?
- __ andl(temp, 0xFF);
- __ cmpl(temp, (int) bytecode());
- __ jcc(Assembler::equal, resolved);
+ __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
+ if (is_invokedynamic) {
+ // we are resolved if the f1 field contains a non-null CallSite object
+ __ cmpptr(Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()), (int32_t) NULL_WORD);
+ __ jcc(Assembler::notEqual, resolved);
+ } else {
+ __ movl(temp, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset()));
+ __ shrl(temp, shift_count);
+ // have we resolved this bytecode?
+ __ andl(temp, 0xFF);
+ __ cmpl(temp, (int) bytecode());
+ __ jcc(Assembler::equal, resolved);
+ }
// resolve first time through
address entry;
@@ -2090,6 +2089,9 @@
case Bytecodes::_invokeinterface:
entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);
break;
+ case Bytecodes::_invokedynamic:
+ entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);
+ break;
default:
ShouldNotReachHere();
break;
@@ -2098,7 +2100,7 @@
__ call_VM(noreg, entry, temp);
// Update registers with resolved info
- __ get_cache_and_index_at_bcp(Rcache, index, 1);
+ __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
__ bind(resolved);
}
@@ -2832,15 +2834,14 @@
ShouldNotReachHere();
}
-void TemplateTable::prepare_invoke(Register method,
- Register index,
- int byte_no,
- Bytecodes::Code code) {
+void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
// determine flags
+ Bytecodes::Code code = bytecode();
const bool is_invokeinterface = code == Bytecodes::_invokeinterface;
+ const bool is_invokedynamic = code == Bytecodes::_invokedynamic;
const bool is_invokevirtual = code == Bytecodes::_invokevirtual;
const bool is_invokespecial = code == Bytecodes::_invokespecial;
- const bool load_receiver = code != Bytecodes::_invokestatic;
+ const bool load_receiver = (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic);
const bool receiver_null_check = is_invokespecial;
const bool save_flags = is_invokeinterface || is_invokevirtual;
// setup registers & access constant pool cache
@@ -2858,9 +2859,13 @@
__ movl(recv, flags);
__ andl(recv, 0xFF);
if (TaggedStackInterpreter) __ shll(recv, 1); // index*2
- __ movptr(recv, Address(rsp, recv, Address::times_8,
- -Interpreter::expr_offset_in_bytes(1)));
- __ verify_oop(recv);
+ Address recv_addr(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1));
+ if (is_invokedynamic) {
+ __ lea(recv, recv_addr);
+ } else {
+ __ movptr(recv, recv_addr);
+ __ verify_oop(recv);
+ }
}
// do null check if needed
@@ -2878,10 +2883,14 @@
ConstantPoolCacheEntry::verify_tosBits();
// load return address
{
- ExternalAddress return_5((address)Interpreter::return_5_addrs_by_index_table());
- ExternalAddress return_3((address)Interpreter::return_3_addrs_by_index_table());
- __ lea(rscratch1, (is_invokeinterface ? return_5 : return_3));
- __ movptr(flags, Address(rscratch1, flags, Address::times_8));
+ address table_addr;
+ if (is_invokeinterface || is_invokedynamic)
+ table_addr = (address)Interpreter::return_5_addrs_by_index_table();
+ else
+ table_addr = (address)Interpreter::return_3_addrs_by_index_table();
+ ExternalAddress table(table_addr);
+ __ lea(rscratch1, table);
+ __ movptr(flags, Address(rscratch1, flags, Address::times_ptr));
}
// push return address
@@ -2947,7 +2956,7 @@
void TemplateTable::invokevirtual(int byte_no) {
transition(vtos, vtos);
- prepare_invoke(rbx, noreg, byte_no, bytecode());
+ prepare_invoke(rbx, noreg, byte_no);
// rbx: index
// rcx: receiver
@@ -2959,7 +2968,7 @@
void TemplateTable::invokespecial(int byte_no) {
transition(vtos, vtos);
- prepare_invoke(rbx, noreg, byte_no, bytecode());
+ prepare_invoke(rbx, noreg, byte_no);
// do the call
__ verify_oop(rbx);
__ profile_call(rax);
@@ -2969,7 +2978,7 @@
void TemplateTable::invokestatic(int byte_no) {
transition(vtos, vtos);
- prepare_invoke(rbx, noreg, byte_no, bytecode());
+ prepare_invoke(rbx, noreg, byte_no);
// do the call
__ verify_oop(rbx);
__ profile_call(rax);
@@ -2983,7 +2992,7 @@
void TemplateTable::invokeinterface(int byte_no) {
transition(vtos, vtos);
- prepare_invoke(rax, rbx, byte_no, bytecode());
+ prepare_invoke(rax, rbx, byte_no);
// rax: Interface
// rbx: index
@@ -3072,7 +3081,24 @@
return;
}
- __ stop("invokedynamic NYI");//6815692//
+ prepare_invoke(rax, rbx, byte_no);
+
+ // rax: CallSite object (f1)
+ // rbx: unused (f2)
+ // rcx: receiver address
+ // rdx: flags (unused)
+
+ if (ProfileInterpreter) {
+ Label L;
+ // %%% should make a type profile for any invokedynamic that takes a ref argument
+ // profile this call
+ __ profile_call(r13);
+ }
+
+ __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
+ __ null_check(rcx);
+ __ prepare_to_jump_from_interpreted();
+ __ jump_to_method_handle_entry(rcx, rdx);
}
@@ -3212,17 +3238,19 @@
__ xorl(rcx, rcx); // use zero reg to clear memory (shorter code)
__ store_klass_gap(rax, rcx); // zero klass gap for compressed oops
__ store_klass(rax, rsi); // store klass last
+
+ {
+ SkipIfEqual skip(_masm, &DTraceAllocProbes, false);
+ // Trigger dtrace event for fastpath
+ __ push(atos); // save the return value
+ __ call_VM_leaf(
+ CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc), rax);
+ __ pop(atos); // restore the return value
+
+ }
__ jmp(done);
}
- {
- SkipIfEqual skip(_masm, &DTraceAllocProbes, false);
- // Trigger dtrace event for fastpath
- __ push(atos); // save the return value
- __ call_VM_leaf(
- CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc), rax);
- __ pop(atos); // restore the return value
- }
// slow case
__ bind(slow_case);
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/templateTable_x86_64.hpp
--- a/src/cpu/x86/vm/templateTable_x86_64.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/templateTable_x86_64.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -22,8 +22,7 @@
*
*/
- static void prepare_invoke(Register method, Register index, int byte_no,
- Bytecodes::Code code);
+ static void prepare_invoke(Register method, Register index, int byte_no);
static void invokevirtual_helper(Register index, Register recv,
Register flags);
static void volatile_barrier(Assembler::Membar_mask_bits order_constraint);
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/vm_version_x86.cpp
--- a/src/cpu/x86/vm/vm_version_x86.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/vm_version_x86.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -255,6 +255,8 @@
if (!VM_Version::supports_sse2()) {
vm_exit_during_initialization("Unknown x64 processor: SSE2 not supported");
}
+ // in 64 bit the use of SSE2 is the minimum
+ if (UseSSE < 2) UseSSE = 2;
#endif
// If the OS doesn't support SSE, we can't use this feature even if the HW does
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/x86_32.ad
--- a/src/cpu/x86/vm/x86_32.ad Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/x86_32.ad Thu Mar 25 16:54:59 2010 -0700
@@ -235,6 +235,11 @@
//----------SOURCE BLOCK-------------------------------------------------------
// This is a block of C++ code which provides values, functions, and
// definitions necessary in the rest of the architecture description
+source_hpp %{
+// Must be visible to the DFA in dfa_x86_32.cpp
+extern bool is_operand_hi32_zero(Node* n);
+%}
+
source %{
#define RELOC_IMM32 Assembler::imm_operand
#define RELOC_DISP32 Assembler::disp32_operand
@@ -268,22 +273,36 @@
static jlong *float_signflip_pool = double_quadword(&fp_signmask_pool[3*2], CONST64(0x8000000080000000), CONST64(0x8000000080000000));
static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], CONST64(0x8000000000000000), CONST64(0x8000000000000000));
+// Offset hacking within calls.
+static int pre_call_FPU_size() {
+ if (Compile::current()->in_24_bit_fp_mode())
+ return 6; // fldcw
+ return 0;
+}
+
+static int preserve_SP_size() {
+ return LP64_ONLY(1 +) 2; // [rex,] op, rm(reg/reg)
+}
+
// !!!!! Special hack to get all type of calls to specify the byte offset
// from the start of the call to the point where the return address
// will point.
int MachCallStaticJavaNode::ret_addr_offset() {
- return 5 + (Compile::current()->in_24_bit_fp_mode() ? 6 : 0); // 5 bytes from start of call to where return address points
+ int offset = 5 + pre_call_FPU_size(); // 5 bytes from start of call to where return address points
+ if (_method_handle_invoke)
+ offset += preserve_SP_size();
+ return offset;
}
int MachCallDynamicJavaNode::ret_addr_offset() {
- return 10 + (Compile::current()->in_24_bit_fp_mode() ? 6 : 0); // 10 bytes from start of call to where return address points
+ return 10 + pre_call_FPU_size(); // 10 bytes from start of call to where return address points
}
static int sizeof_FFree_Float_Stack_All = -1;
int MachCallRuntimeNode::ret_addr_offset() {
assert(sizeof_FFree_Float_Stack_All != -1, "must have been emitted already");
- return sizeof_FFree_Float_Stack_All + 5 + (Compile::current()->in_24_bit_fp_mode() ? 6 : 0);
+ return sizeof_FFree_Float_Stack_All + 5 + pre_call_FPU_size();
}
// Indicate if the safepoint node needs the polling page as an input.
@@ -299,8 +318,16 @@
// The address of the call instruction needs to be 4-byte aligned to
// ensure that it does not span a cache line so that it can be patched.
int CallStaticJavaDirectNode::compute_padding(int current_offset) const {
- if (Compile::current()->in_24_bit_fp_mode())
- current_offset += 6; // skip fldcw in pre_call_FPU, if any
+ current_offset += pre_call_FPU_size(); // skip fldcw, if any
+ current_offset += 1; // skip call opcode byte
+ return round_to(current_offset, alignment_required()) - current_offset;
+}
+
+// The address of the call instruction needs to be 4-byte aligned to
+// ensure that it does not span a cache line so that it can be patched.
+int CallStaticJavaHandleNode::compute_padding(int current_offset) const {
+ current_offset += pre_call_FPU_size(); // skip fldcw, if any
+ current_offset += preserve_SP_size(); // skip mov rbp, rsp
current_offset += 1; // skip call opcode byte
return round_to(current_offset, alignment_required()) - current_offset;
}
@@ -308,8 +335,7 @@
// The address of the call instruction needs to be 4-byte aligned to
// ensure that it does not span a cache line so that it can be patched.
int CallDynamicJavaDirectNode::compute_padding(int current_offset) const {
- if (Compile::current()->in_24_bit_fp_mode())
- current_offset += 6; // skip fldcw in pre_call_FPU, if any
+ current_offset += pre_call_FPU_size(); // skip fldcw, if any
current_offset += 5; // skip MOV instruction
current_offset += 1; // skip call opcode byte
return round_to(current_offset, alignment_required()) - current_offset;
@@ -379,7 +405,7 @@
int format) {
#ifdef ASSERT
if (rspec.reloc()->type() == relocInfo::oop_type && d32 != 0 && d32 != (int)Universe::non_oop_word()) {
- assert(oop(d32)->is_oop() && oop(d32)->is_perm(), "cannot embed non-perm oops in code");
+ assert(oop(d32)->is_oop() && (ScavengeRootsInCode || !oop(d32)->is_scavengable()), "cannot embed scavengable oops in code");
}
#endif
cbuf.relocate(cbuf.inst_mark(), rspec, format);
@@ -1418,8 +1444,10 @@
// to implement the UseStrictFP mode.
const bool Matcher::strict_fp_requires_explicit_rounding = true;
-// Do floats take an entire double register or just half?
-const bool Matcher::float_in_double = true;
+// Are floats conerted to double when stored to stack during deoptimization?
+// On x32 it is stored with convertion only when FPU is used for floats.
+bool Matcher::float_in_double() { return (UseSSE == 0); }
+
// Do ints take an entire long register or just half?
const bool Matcher::int_in_long = false;
@@ -1460,6 +1488,25 @@
return RegMask();
}
+const RegMask Matcher::method_handle_invoke_SP_save_mask() {
+ return EBP_REG_mask;
+}
+
+// Returns true if the high 32 bits of the value is known to be zero.
+bool is_operand_hi32_zero(Node* n) {
+ int opc = n->Opcode();
+ if (opc == Op_LoadUI2L) {
+ return true;
+ }
+ if (opc == Op_AndL) {
+ Node* o2 = n->in(2);
+ if (o2->is_Con() && (o2->get_long() & 0xFFFFFFFF00000000LL) == 0LL) {
+ return true;
+ }
+ }
+ return false;
+}
+
%}
//----------ENCODING BLOCK-----------------------------------------------------
@@ -1772,10 +1819,13 @@
enc_class pre_call_FPU %{
// If method sets FPU control word restore it here
+ debug_only(int off0 = cbuf.code_size());
if( Compile::current()->in_24_bit_fp_mode() ) {
MacroAssembler masm(&cbuf);
masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
}
+ debug_only(int off1 = cbuf.code_size());
+ assert(off1 - off0 == pre_call_FPU_size(), "correct size prediction");
%}
enc_class post_call_FPU %{
@@ -1786,6 +1836,21 @@
}
%}
+ enc_class preserve_SP %{
+ debug_only(int off0 = cbuf.code_size());
+ MacroAssembler _masm(&cbuf);
+ // RBP is preserved across all calls, even compiled calls.
+ // Use it to preserve RSP in places where the callee might change the SP.
+ __ movptr(rbp, rsp);
+ debug_only(int off1 = cbuf.code_size());
+ assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
+ %}
+
+ enc_class restore_SP %{
+ MacroAssembler _masm(&cbuf);
+ __ movptr(rsp, rbp);
+ %}
+
enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL
// CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
// who we intended to call.
@@ -3701,458 +3766,6 @@
}
%}
- enc_class enc_String_Compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
- eAXRegI tmp3, eBXRegI tmp4, eCXRegI result) %{
- Label ECX_GOOD_LABEL, LENGTH_DIFF_LABEL,
- POP_LABEL, DONE_LABEL, CONT_LABEL,
- WHILE_HEAD_LABEL;
- MacroAssembler masm(&cbuf);
-
- XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);
- XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);
-
- // Get the first character position in both strings
- // [8] char array, [12] offset, [16] count
- int value_offset = java_lang_String::value_offset_in_bytes();
- int offset_offset = java_lang_String::offset_offset_in_bytes();
- int count_offset = java_lang_String::count_offset_in_bytes();
- int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
- masm.movptr(rax, Address(rsi, value_offset));
- masm.movl(rcx, Address(rsi, offset_offset));
- masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset));
- masm.movptr(rbx, Address(rdi, value_offset));
- masm.movl(rcx, Address(rdi, offset_offset));
- masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset));
-
- // Compute the minimum of the string lengths(rsi) and the
- // difference of the string lengths (stack)
-
- if (VM_Version::supports_cmov()) {
- masm.movl(rdi, Address(rdi, count_offset));
- masm.movl(rsi, Address(rsi, count_offset));
- masm.movl(rcx, rdi);
- masm.subl(rdi, rsi);
- masm.push(rdi);
- masm.cmovl(Assembler::lessEqual, rsi, rcx);
- } else {
- masm.movl(rdi, Address(rdi, count_offset));
- masm.movl(rcx, Address(rsi, count_offset));
- masm.movl(rsi, rdi);
- masm.subl(rdi, rcx);
- masm.push(rdi);
- masm.jccb(Assembler::lessEqual, ECX_GOOD_LABEL);
- masm.movl(rsi, rcx);
- // rsi holds min, rcx is unused
- }
-
- // Is the minimum length zero?
- masm.bind(ECX_GOOD_LABEL);
- masm.testl(rsi, rsi);
- masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
-
- // Load first characters
- masm.load_unsigned_short(rcx, Address(rbx, 0));
- masm.load_unsigned_short(rdi, Address(rax, 0));
-
- // Compare first characters
- masm.subl(rcx, rdi);
- masm.jcc(Assembler::notZero, POP_LABEL);
- masm.decrementl(rsi);
- masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
-
- {
- // Check after comparing first character to see if strings are equivalent
- Label LSkip2;
- // Check if the strings start at same location
- masm.cmpptr(rbx,rax);
- masm.jccb(Assembler::notEqual, LSkip2);
-
- // Check if the length difference is zero (from stack)
- masm.cmpl(Address(rsp, 0), 0x0);
- masm.jcc(Assembler::equal, LENGTH_DIFF_LABEL);
-
- // Strings might not be equivalent
- masm.bind(LSkip2);
- }
-
- // Advance to next character
- masm.addptr(rax, 2);
- masm.addptr(rbx, 2);
-
- if (UseSSE42Intrinsics) {
- // With SSE4.2, use double quad vector compare
- Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;
- // Setup to compare 16-byte vectors
- masm.movl(rdi, rsi);
- masm.andl(rsi, 0xfffffff8); // rsi holds the vector count
- masm.andl(rdi, 0x00000007); // rdi holds the tail count
- masm.testl(rsi, rsi);
- masm.jccb(Assembler::zero, COMPARE_TAIL);
-
- masm.lea(rax, Address(rax, rsi, Address::times_2));
- masm.lea(rbx, Address(rbx, rsi, Address::times_2));
- masm.negl(rsi);
-
- masm.bind(COMPARE_VECTORS);
- masm.movdqu(tmp1Reg, Address(rax, rsi, Address::times_2));
- masm.movdqu(tmp2Reg, Address(rbx, rsi, Address::times_2));
- masm.pxor(tmp1Reg, tmp2Reg);
- masm.ptest(tmp1Reg, tmp1Reg);
- masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL);
- masm.addl(rsi, 8);
- masm.jcc(Assembler::notZero, COMPARE_VECTORS);
- masm.jmpb(COMPARE_TAIL);
-
- // Mismatched characters in the vectors
- masm.bind(VECTOR_NOT_EQUAL);
- masm.lea(rax, Address(rax, rsi, Address::times_2));
- masm.lea(rbx, Address(rbx, rsi, Address::times_2));
- masm.movl(rdi, 8);
-
- // Compare tail (< 8 chars), or rescan last vectors to
- // find 1st mismatched characters
- masm.bind(COMPARE_TAIL);
- masm.testl(rdi, rdi);
- masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL);
- masm.movl(rsi, rdi);
- // Fallthru to tail compare
- }
-
- //Shift rax, and rbx, to the end of the arrays, negate min
- masm.lea(rax, Address(rax, rsi, Address::times_2, 0));
- masm.lea(rbx, Address(rbx, rsi, Address::times_2, 0));
- masm.negl(rsi);
-
- // Compare the rest of the characters
- masm.bind(WHILE_HEAD_LABEL);
- masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0));
- masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0));
- masm.subl(rcx, rdi);
- masm.jccb(Assembler::notZero, POP_LABEL);
- masm.incrementl(rsi);
- masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL);
-
- // Strings are equal up to min length. Return the length difference.
- masm.bind(LENGTH_DIFF_LABEL);
- masm.pop(rcx);
- masm.jmpb(DONE_LABEL);
-
- // Discard the stored length difference
- masm.bind(POP_LABEL);
- masm.addptr(rsp, 4);
-
- // That's it
- masm.bind(DONE_LABEL);
- %}
-
- enc_class enc_String_Equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
- eBXRegI tmp3, eCXRegI tmp4, eAXRegI result) %{
- Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR;
- MacroAssembler masm(&cbuf);
-
- XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);
- XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);
-
- int value_offset = java_lang_String::value_offset_in_bytes();
- int offset_offset = java_lang_String::offset_offset_in_bytes();
- int count_offset = java_lang_String::count_offset_in_bytes();
- int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
- // does source == target string?
- masm.cmpptr(rdi, rsi);
- masm.jcc(Assembler::equal, RET_TRUE);
-
- // get and compare counts
- masm.movl(rcx, Address(rdi, count_offset));
- masm.movl(rax, Address(rsi, count_offset));
- masm.cmpl(rcx, rax);
- masm.jcc(Assembler::notEqual, RET_FALSE);
- masm.testl(rax, rax);
- masm.jcc(Assembler::zero, RET_TRUE);
-
- // get source string offset and value
- masm.movptr(rbx, Address(rsi, value_offset));
- masm.movl(rax, Address(rsi, offset_offset));
- masm.leal(rsi, Address(rbx, rax, Address::times_2, base_offset));
-
- // get compare string offset and value
- masm.movptr(rbx, Address(rdi, value_offset));
- masm.movl(rax, Address(rdi, offset_offset));
- masm.leal(rdi, Address(rbx, rax, Address::times_2, base_offset));
-
- // Set byte count
- masm.shll(rcx, 1);
- masm.movl(rax, rcx);
-
- if (UseSSE42Intrinsics) {
- // With SSE4.2, use double quad vector compare
- Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
- // Compare 16-byte vectors
- masm.andl(rcx, 0xfffffff0); // vector count (in bytes)
- masm.andl(rax, 0x0000000e); // tail count (in bytes)
- masm.testl(rcx, rcx);
- masm.jccb(Assembler::zero, COMPARE_TAIL);
- masm.lea(rdi, Address(rdi, rcx, Address::times_1));
- masm.lea(rsi, Address(rsi, rcx, Address::times_1));
- masm.negl(rcx);
-
- masm.bind(COMPARE_WIDE_VECTORS);
- masm.movdqu(tmp1Reg, Address(rdi, rcx, Address::times_1));
- masm.movdqu(tmp2Reg, Address(rsi, rcx, Address::times_1));
- masm.pxor(tmp1Reg, tmp2Reg);
- masm.ptest(tmp1Reg, tmp1Reg);
- masm.jccb(Assembler::notZero, RET_FALSE);
- masm.addl(rcx, 16);
- masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
- masm.bind(COMPARE_TAIL);
- masm.movl(rcx, rax);
- // Fallthru to tail compare
- }
-
- // Compare 4-byte vectors
- masm.andl(rcx, 0xfffffffc); // vector count (in bytes)
- masm.andl(rax, 0x00000002); // tail char (in bytes)
- masm.testl(rcx, rcx);
- masm.jccb(Assembler::zero, COMPARE_CHAR);
- masm.lea(rdi, Address(rdi, rcx, Address::times_1));
- masm.lea(rsi, Address(rsi, rcx, Address::times_1));
- masm.negl(rcx);
-
- masm.bind(COMPARE_VECTORS);
- masm.movl(rbx, Address(rdi, rcx, Address::times_1));
- masm.cmpl(rbx, Address(rsi, rcx, Address::times_1));
- masm.jccb(Assembler::notEqual, RET_FALSE);
- masm.addl(rcx, 4);
- masm.jcc(Assembler::notZero, COMPARE_VECTORS);
-
- // Compare trailing char (final 2 bytes), if any
- masm.bind(COMPARE_CHAR);
- masm.testl(rax, rax);
- masm.jccb(Assembler::zero, RET_TRUE);
- masm.load_unsigned_short(rbx, Address(rdi, 0));
- masm.load_unsigned_short(rcx, Address(rsi, 0));
- masm.cmpl(rbx, rcx);
- masm.jccb(Assembler::notEqual, RET_FALSE);
-
- masm.bind(RET_TRUE);
- masm.movl(rax, 1); // return true
- masm.jmpb(DONE);
-
- masm.bind(RET_FALSE);
- masm.xorl(rax, rax); // return false
-
- masm.bind(DONE);
- %}
-
- enc_class enc_String_IndexOf(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2,
- eCXRegI tmp3, eDXRegI tmp4, eBXRegI result) %{
- // SSE4.2 version
- Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,
- SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE;
- MacroAssembler masm(&cbuf);
-
- XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);
-
- // Get the first character position in both strings
- // [8] char array, [12] offset, [16] count
- int value_offset = java_lang_String::value_offset_in_bytes();
- int offset_offset = java_lang_String::offset_offset_in_bytes();
- int count_offset = java_lang_String::count_offset_in_bytes();
- int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
- // Get counts for string and substr
- masm.movl(rdx, Address(rsi, count_offset));
- masm.movl(rax, Address(rdi, count_offset));
- // Check for substr count > string count
- masm.cmpl(rax, rdx);
- masm.jcc(Assembler::greater, RET_NEG_ONE);
-
- // Start the indexOf operation
- // Get start addr of string
- masm.movptr(rbx, Address(rsi, value_offset));
- masm.movl(rcx, Address(rsi, offset_offset));
- masm.lea(rsi, Address(rbx, rcx, Address::times_2, base_offset));
- masm.push(rsi);
-
- // Get start addr of substr
- masm.movptr(rbx, Address(rdi, value_offset));
- masm.movl(rcx, Address(rdi, offset_offset));
- masm.lea(rdi, Address(rbx, rcx, Address::times_2, base_offset));
- masm.push(rdi);
- masm.push(rax);
- masm.jmpb(PREP_FOR_SCAN);
-
- // Substr count saved at sp
- // Substr saved at sp+4
- // String saved at sp+8
-
- // Prep to load substr for scan
- masm.bind(LOAD_SUBSTR);
- masm.movptr(rdi, Address(rsp, 4));
- masm.movl(rax, Address(rsp, 0));
-
- // Load substr
- masm.bind(PREP_FOR_SCAN);
- masm.movdqu(tmp1Reg, Address(rdi, 0));
- masm.addl(rdx, 8); // prime the loop
- masm.subptr(rsi, 16);
-
- // Scan string for substr in 16-byte vectors
- masm.bind(SCAN_TO_SUBSTR);
- masm.subl(rdx, 8);
- masm.addptr(rsi, 16);
- masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
- masm.jcc(Assembler::above, SCAN_TO_SUBSTR); // CF == 0 && ZF == 0
- masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 0
-
- // Fallthru: found a potential substr
-
- // Make sure string is still long enough
- masm.subl(rdx, rcx);
- masm.cmpl(rdx, rax);
- masm.jccb(Assembler::negative, RET_NOT_FOUND);
- // Compute start addr of substr
- masm.lea(rsi, Address(rsi, rcx, Address::times_2));
- masm.movptr(rbx, rsi);
-
- // Compare potential substr
- masm.addl(rdx, 8); // prime the loop
- masm.addl(rax, 8);
- masm.subptr(rsi, 16);
- masm.subptr(rdi, 16);
-
- // Scan 16-byte vectors of string and substr
- masm.bind(SCAN_SUBSTR);
- masm.subl(rax, 8);
- masm.subl(rdx, 8);
- masm.addptr(rsi, 16);
- masm.addptr(rdi, 16);
- masm.movdqu(tmp1Reg, Address(rdi, 0));
- masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
- masm.jcc(Assembler::noOverflow, LOAD_SUBSTR); // OF == 0
- masm.jcc(Assembler::positive, SCAN_SUBSTR); // SF == 0
-
- // Compute substr offset
- masm.movptr(rsi, Address(rsp, 8));
- masm.subptr(rbx, rsi);
- masm.shrl(rbx, 1);
- masm.jmpb(CLEANUP);
-
- masm.bind(RET_NEG_ONE);
- masm.movl(rbx, -1);
- masm.jmpb(DONE);
-
- masm.bind(RET_NOT_FOUND);
- masm.movl(rbx, -1);
-
- masm.bind(CLEANUP);
- masm.addptr(rsp, 12);
-
- masm.bind(DONE);
- %}
-
- enc_class enc_Array_Equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2,
- eBXRegI tmp3, eDXRegI tmp4, eAXRegI result) %{
- Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
- MacroAssembler masm(&cbuf);
-
- XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);
- XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);
- Register ary1Reg = as_Register($ary1$$reg);
- Register ary2Reg = as_Register($ary2$$reg);
- Register tmp3Reg = as_Register($tmp3$$reg);
- Register tmp4Reg = as_Register($tmp4$$reg);
- Register resultReg = as_Register($result$$reg);
-
- int length_offset = arrayOopDesc::length_offset_in_bytes();
- int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
- // Check the input args
- masm.cmpptr(ary1Reg, ary2Reg);
- masm.jcc(Assembler::equal, TRUE_LABEL);
- masm.testptr(ary1Reg, ary1Reg);
- masm.jcc(Assembler::zero, FALSE_LABEL);
- masm.testptr(ary2Reg, ary2Reg);
- masm.jcc(Assembler::zero, FALSE_LABEL);
-
- // Check the lengths
- masm.movl(tmp4Reg, Address(ary1Reg, length_offset));
- masm.movl(resultReg, Address(ary2Reg, length_offset));
- masm.cmpl(tmp4Reg, resultReg);
- masm.jcc(Assembler::notEqual, FALSE_LABEL);
- masm.testl(resultReg, resultReg);
- masm.jcc(Assembler::zero, TRUE_LABEL);
-
- // Load array addrs
- masm.lea(ary1Reg, Address(ary1Reg, base_offset));
- masm.lea(ary2Reg, Address(ary2Reg, base_offset));
-
- // Set byte count
- masm.shll(tmp4Reg, 1);
- masm.movl(resultReg, tmp4Reg);
-
- if (UseSSE42Intrinsics) {
- // With SSE4.2, use double quad vector compare
- Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
- // Compare 16-byte vectors
- masm.andl(tmp4Reg, 0xfffffff0); // vector count (in bytes)
- masm.andl(resultReg, 0x0000000e); // tail count (in bytes)
- masm.testl(tmp4Reg, tmp4Reg);
- masm.jccb(Assembler::zero, COMPARE_TAIL);
- masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
- masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
- masm.negl(tmp4Reg);
-
- masm.bind(COMPARE_WIDE_VECTORS);
- masm.movdqu(tmp1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
- masm.movdqu(tmp2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
- masm.pxor(tmp1Reg, tmp2Reg);
- masm.ptest(tmp1Reg, tmp1Reg);
-
- masm.jccb(Assembler::notZero, FALSE_LABEL);
- masm.addl(tmp4Reg, 16);
- masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
- masm.bind(COMPARE_TAIL);
- masm.movl(tmp4Reg, resultReg);
- // Fallthru to tail compare
- }
-
- // Compare 4-byte vectors
- masm.andl(tmp4Reg, 0xfffffffc); // vector count (in bytes)
- masm.andl(resultReg, 0x00000002); // tail char (in bytes)
- masm.testl(tmp4Reg, tmp4Reg);
- masm.jccb(Assembler::zero, COMPARE_CHAR);
- masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
- masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
- masm.negl(tmp4Reg);
-
- masm.bind(COMPARE_VECTORS);
- masm.movl(tmp3Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
- masm.cmpl(tmp3Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
- masm.jccb(Assembler::notEqual, FALSE_LABEL);
- masm.addl(tmp4Reg, 4);
- masm.jcc(Assembler::notZero, COMPARE_VECTORS);
-
- // Compare trailing char (final 2 bytes), if any
- masm.bind(COMPARE_CHAR);
- masm.testl(resultReg, resultReg);
- masm.jccb(Assembler::zero, TRUE_LABEL);
- masm.load_unsigned_short(tmp3Reg, Address(ary1Reg, 0));
- masm.load_unsigned_short(tmp4Reg, Address(ary2Reg, 0));
- masm.cmpl(tmp3Reg, tmp4Reg);
- masm.jccb(Assembler::notEqual, FALSE_LABEL);
-
- masm.bind(TRUE_LABEL);
- masm.movl(resultReg, 1); // return true
- masm.jmpb(DONE);
-
- masm.bind(FALSE_LABEL);
- masm.xorl(resultReg, resultReg); // return false
-
- // That's it
- masm.bind(DONE);
- %}
enc_class enc_pop_rdx() %{
emit_opcode(cbuf,0x5A);
@@ -9008,6 +8621,63 @@
ins_pipe( pipe_slow );
%}
+// Multiply Register Long where the left operand's high 32 bits are zero
+instruct mulL_eReg_lhi0(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
+ predicate(is_operand_hi32_zero(n->in(1)));
+ match(Set dst (MulL dst src));
+ effect(KILL cr, TEMP tmp);
+ ins_cost(2*100+2*400);
+// Basic idea: lo(result) = lo(x_lo * y_lo)
+// hi(result) = hi(x_lo * y_lo) + lo(x_lo * y_hi) where lo(x_hi * y_lo) = 0 because x_hi = 0
+ format %{ "MOV $tmp,$src.hi\n\t"
+ "IMUL $tmp,EAX\n\t"
+ "MUL EDX:EAX,$src.lo\n\t"
+ "ADD EDX,$tmp" %}
+ ins_encode %{
+ __ movl($tmp$$Register, HIGH_FROM_LOW($src$$Register));
+ __ imull($tmp$$Register, rax);
+ __ mull($src$$Register);
+ __ addl(rdx, $tmp$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+// Multiply Register Long where the right operand's high 32 bits are zero
+instruct mulL_eReg_rhi0(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
+ predicate(is_operand_hi32_zero(n->in(2)));
+ match(Set dst (MulL dst src));
+ effect(KILL cr, TEMP tmp);
+ ins_cost(2*100+2*400);
+// Basic idea: lo(result) = lo(x_lo * y_lo)
+// hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) where lo(x_lo * y_hi) = 0 because y_hi = 0
+ format %{ "MOV $tmp,$src.lo\n\t"
+ "IMUL $tmp,EDX\n\t"
+ "MUL EDX:EAX,$src.lo\n\t"
+ "ADD EDX,$tmp" %}
+ ins_encode %{
+ __ movl($tmp$$Register, $src$$Register);
+ __ imull($tmp$$Register, rdx);
+ __ mull($src$$Register);
+ __ addl(rdx, $tmp$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+// Multiply Register Long where the left and the right operands' high 32 bits are zero
+instruct mulL_eReg_hi0(eADXRegL dst, eRegL src, eFlagsReg cr) %{
+ predicate(is_operand_hi32_zero(n->in(1)) && is_operand_hi32_zero(n->in(2)));
+ match(Set dst (MulL dst src));
+ effect(KILL cr);
+ ins_cost(1*400);
+// Basic idea: lo(result) = lo(x_lo * y_lo)
+// hi(result) = hi(x_lo * y_lo) where lo(x_hi * y_lo) = 0 and lo(x_lo * y_hi) = 0 because x_hi = 0 and y_hi = 0
+ format %{ "MUL EDX:EAX,$src.lo\n\t" %}
+ ins_encode %{
+ __ mull($src$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
// Multiply Register Long by small constant
instruct mulL_eReg_con(eADXRegL dst, immL_127 src, eRegI tmp, eFlagsReg cr) %{
match(Set dst (MulL dst src));
@@ -12718,48 +12388,64 @@
ins_pipe( pipe_slow );
%}
-instruct string_compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
- eAXRegI tmp3, eBXRegI tmp4, eCXRegI result, eFlagsReg cr) %{
- match(Set result (StrComp str1 str2));
- effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
- //ins_cost(300);
-
- format %{ "String Compare $str1,$str2 -> $result // KILL EAX, EBX" %}
- ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
+instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eBXRegI cnt2,
+ eAXRegI result, regXD tmp1, regXD tmp2, eFlagsReg cr) %{
+ match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
+
+ format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1, $tmp2" %}
+ ins_encode %{
+ __ string_compare($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register, $result$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+ %}
ins_pipe( pipe_slow );
%}
// fast string equals
-instruct string_equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
- eBXRegI tmp3, eCXRegI tmp4, eAXRegI result, eFlagsReg cr) %{
- match(Set result (StrEquals str1 str2));
- effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
-
- format %{ "String Equals $str1,$str2 -> $result // KILL EBX, ECX" %}
- ins_encode( enc_String_Equals(tmp1, tmp2, str1, str2, tmp3, tmp4, result) );
- ins_pipe( pipe_slow );
-%}
-
-instruct string_indexof(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2,
- eCXRegI tmp3, eDXRegI tmp4, eBXRegI result, eFlagsReg cr) %{
+instruct string_equals(eDIRegP str1, eSIRegP str2, eCXRegI cnt, eAXRegI result,
+ regXD tmp1, regXD tmp2, eBXRegI tmp3, eFlagsReg cr) %{
+ match(Set result (StrEquals (Binary str1 str2) cnt));
+ effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
+
+ format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
+ ins_encode %{
+ __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
+ $cnt$$Register, $result$$Register, $tmp3$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct string_indexof(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
+ eBXRegI result, regXD tmp1, eCXRegI tmp2, eFlagsReg cr) %{
predicate(UseSSE42Intrinsics);
- match(Set result (StrIndexOf str1 str2));
- effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr);
-
- format %{ "String IndexOf $str1,$str2 -> $result // KILL EAX, ECX, EDX" %}
- ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
+ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr);
+
+ format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp2, $tmp1" %}
+ ins_encode %{
+ __ string_indexof($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register, $result$$Register,
+ $tmp1$$XMMRegister, $tmp2$$Register);
+ %}
ins_pipe( pipe_slow );
%}
// fast array equals
-instruct array_equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2, eBXRegI tmp3,
- eDXRegI tmp4, eAXRegI result, eFlagsReg cr) %{
+instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
+ regXD tmp1, regXD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
+%{
match(Set result (AryEq ary1 ary2));
effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
//ins_cost(300);
- format %{ "Array Equals $ary1,$ary2 -> $result // KILL EBX, EDX" %}
- ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, tmp4, result) );
+ format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
+ ins_encode %{
+ __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
+ $tmp3$$Register, $result$$Register, $tmp4$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+ %}
ins_pipe( pipe_slow );
%}
@@ -13842,6 +13528,7 @@
// compute_padding() functions will have to be adjusted.
instruct CallStaticJavaDirect(method meth) %{
match(CallStaticJava);
+ predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke());
effect(USE meth);
ins_cost(300);
@@ -13856,6 +13543,30 @@
ins_alignment(4);
%}
+// Call Java Static Instruction (method handle version)
+// Note: If this code changes, the corresponding ret_addr_offset() and
+// compute_padding() functions will have to be adjusted.
+instruct CallStaticJavaHandle(method meth, eBPRegP ebp) %{
+ match(CallStaticJava);
+ predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
+ effect(USE meth);
+ // EBP is saved by all callees (for interpreter stack correction).
+ // We use it here for a similar purpose, in {preserve,restore}_SP.
+
+ ins_cost(300);
+ format %{ "CALL,static/MethodHandle " %}
+ opcode(0xE8); /* E8 cd */
+ ins_encode( pre_call_FPU,
+ preserve_SP,
+ Java_Static_Call( meth ),
+ restore_SP,
+ call_epilog,
+ post_call_FPU );
+ ins_pipe( pipe_slow );
+ ins_pc_relative(1);
+ ins_alignment(4);
+%}
+
// Call Java Dynamic Instruction
// Note: If this code changes, the corresponding ret_addr_offset() and
// compute_padding() functions will have to be adjusted.
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/x86/vm/x86_64.ad
--- a/src/cpu/x86/vm/x86_64.ad Thu Mar 25 16:27:12 2010 -0700
+++ b/src/cpu/x86/vm/x86_64.ad Thu Mar 25 16:54:59 2010 -0700
@@ -551,12 +551,19 @@
#define __ _masm.
+static int preserve_SP_size() {
+ return LP64_ONLY(1 +) 2; // [rex,] op, rm(reg/reg)
+}
+
// !!!!! Special hack to get all types of calls to specify the byte offset
// from the start of the call to the point where the return address
// will point.
int MachCallStaticJavaNode::ret_addr_offset()
{
- return 5; // 5 bytes from start of call to where return address points
+ int offset = 5; // 5 bytes from start of call to where return address points
+ if (_method_handle_invoke)
+ offset += preserve_SP_size();
+ return offset;
}
int MachCallDynamicJavaNode::ret_addr_offset()
@@ -589,6 +596,15 @@
// The address of the call instruction needs to be 4-byte aligned to
// ensure that it does not span a cache line so that it can be patched.
+int CallStaticJavaHandleNode::compute_padding(int current_offset) const
+{
+ current_offset += preserve_SP_size(); // skip mov rbp, rsp
+ current_offset += 1; // skip call opcode byte
+ return round_to(current_offset, alignment_required()) - current_offset;
+}
+
+// The address of the call instruction needs to be 4-byte aligned to
+// ensure that it does not span a cache line so that it can be patched.
int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
{
current_offset += 11; // skip movq instruction + call opcode byte
@@ -683,7 +699,7 @@
#ifdef ASSERT
if (rspec.reloc()->type() == relocInfo::oop_type &&
d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
- assert(oop((intptr_t)d32)->is_oop() && oop((intptr_t)d32)->is_perm(), "cannot embed non-perm oops in code");
+ assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
}
#endif
cbuf.relocate(cbuf.inst_mark(), rspec, format);
@@ -721,8 +737,8 @@
#ifdef ASSERT
if (rspec.reloc()->type() == relocInfo::oop_type &&
d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
- assert(oop(d64)->is_oop() && oop(d64)->is_perm(),
- "cannot embed non-perm oops in code");
+ assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()),
+ "cannot embed scavengable oops in code");
}
#endif
cbuf.relocate(cbuf.inst_mark(), rspec, format);
@@ -2058,8 +2074,10 @@
// implement the UseStrictFP mode.
const bool Matcher::strict_fp_requires_explicit_rounding = true;
-// Do floats take an entire double register or just half?
-const bool Matcher::float_in_double = true;
+// Are floats conerted to double when stored to stack during deoptimization?
+// On x64 it is stored without convertion so we can use normal access.
+bool Matcher::float_in_double() { return false; }
+
// Do ints take an entire long register or just half?
const bool Matcher::int_in_long = true;
@@ -2113,6 +2131,10 @@
return LONG_RDX_REG_mask;
}
+const RegMask Matcher::method_handle_invoke_SP_save_mask() {
+ return PTR_RBP_REG_mask;
+}
+
static Address build_address(int b, int i, int s, int d) {
Register index = as_Register(i);
Address::ScaleFactor scale = (Address::ScaleFactor)s;
@@ -2608,6 +2630,21 @@
RELOC_DISP32);
%}
+ enc_class preserve_SP %{
+ debug_only(int off0 = cbuf.code_size());
+ MacroAssembler _masm(&cbuf);
+ // RBP is preserved across all calls, even compiled calls.
+ // Use it to preserve RSP in places where the callee might change the SP.
+ __ movptr(rbp, rsp);
+ debug_only(int off1 = cbuf.code_size());
+ assert(off1 - off0 == preserve_SP_size(), "correct size prediction");
+ %}
+
+ enc_class restore_SP %{
+ MacroAssembler _masm(&cbuf);
+ __ movptr(rsp, rbp);
+ %}
+
enc_class Java_Static_Call(method meth)
%{
// JAVA STATIC CALL
@@ -3701,448 +3738,6 @@
}
%}
- enc_class enc_String_Compare(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,
- rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result) %{
- Label RCX_GOOD_LABEL, LENGTH_DIFF_LABEL,
- POP_LABEL, DONE_LABEL, CONT_LABEL,
- WHILE_HEAD_LABEL;
- MacroAssembler masm(&cbuf);
-
- XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);
- XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);
-
- // Get the first character position in both strings
- // [8] char array, [12] offset, [16] count
- int value_offset = java_lang_String::value_offset_in_bytes();
- int offset_offset = java_lang_String::offset_offset_in_bytes();
- int count_offset = java_lang_String::count_offset_in_bytes();
- int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
- masm.load_heap_oop(rax, Address(rsi, value_offset));
- masm.movl(rcx, Address(rsi, offset_offset));
- masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset));
- masm.load_heap_oop(rbx, Address(rdi, value_offset));
- masm.movl(rcx, Address(rdi, offset_offset));
- masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset));
-
- // Compute the minimum of the string lengths(rsi) and the
- // difference of the string lengths (stack)
-
- // do the conditional move stuff
- masm.movl(rdi, Address(rdi, count_offset));
- masm.movl(rsi, Address(rsi, count_offset));
- masm.movl(rcx, rdi);
- masm.subl(rdi, rsi);
- masm.push(rdi);
- masm.cmov(Assembler::lessEqual, rsi, rcx);
-
- // Is the minimum length zero?
- masm.bind(RCX_GOOD_LABEL);
- masm.testl(rsi, rsi);
- masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
-
- // Load first characters
- masm.load_unsigned_short(rcx, Address(rbx, 0));
- masm.load_unsigned_short(rdi, Address(rax, 0));
-
- // Compare first characters
- masm.subl(rcx, rdi);
- masm.jcc(Assembler::notZero, POP_LABEL);
- masm.decrementl(rsi);
- masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
-
- {
- // Check after comparing first character to see if strings are equivalent
- Label LSkip2;
- // Check if the strings start at same location
- masm.cmpptr(rbx, rax);
- masm.jccb(Assembler::notEqual, LSkip2);
-
- // Check if the length difference is zero (from stack)
- masm.cmpl(Address(rsp, 0), 0x0);
- masm.jcc(Assembler::equal, LENGTH_DIFF_LABEL);
-
- // Strings might not be equivalent
- masm.bind(LSkip2);
- }
-
- // Advance to next character
- masm.addptr(rax, 2);
- masm.addptr(rbx, 2);
-
- if (UseSSE42Intrinsics) {
- // With SSE4.2, use double quad vector compare
- Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;
- // Setup to compare 16-byte vectors
- masm.movl(rdi, rsi);
- masm.andl(rsi, 0xfffffff8); // rsi holds the vector count
- masm.andl(rdi, 0x00000007); // rdi holds the tail count
- masm.testl(rsi, rsi);
- masm.jccb(Assembler::zero, COMPARE_TAIL);
-
- masm.lea(rax, Address(rax, rsi, Address::times_2));
- masm.lea(rbx, Address(rbx, rsi, Address::times_2));
- masm.negptr(rsi);
-
- masm.bind(COMPARE_VECTORS);
- masm.movdqu(tmp1Reg, Address(rax, rsi, Address::times_2));
- masm.movdqu(tmp2Reg, Address(rbx, rsi, Address::times_2));
- masm.pxor(tmp1Reg, tmp2Reg);
- masm.ptest(tmp1Reg, tmp1Reg);
- masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL);
- masm.addptr(rsi, 8);
- masm.jcc(Assembler::notZero, COMPARE_VECTORS);
- masm.jmpb(COMPARE_TAIL);
-
- // Mismatched characters in the vectors
- masm.bind(VECTOR_NOT_EQUAL);
- masm.lea(rax, Address(rax, rsi, Address::times_2));
- masm.lea(rbx, Address(rbx, rsi, Address::times_2));
- masm.movl(rdi, 8);
-
- // Compare tail (< 8 chars), or rescan last vectors to
- // find 1st mismatched characters
- masm.bind(COMPARE_TAIL);
- masm.testl(rdi, rdi);
- masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL);
- masm.movl(rsi, rdi);
- // Fallthru to tail compare
- }
-
- // Shift RAX and RBX to the end of the arrays, negate min
- masm.lea(rax, Address(rax, rsi, Address::times_2, 0));
- masm.lea(rbx, Address(rbx, rsi, Address::times_2, 0));
- masm.negptr(rsi);
-
- // Compare the rest of the characters
- masm.bind(WHILE_HEAD_LABEL);
- masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0));
- masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0));
- masm.subl(rcx, rdi);
- masm.jccb(Assembler::notZero, POP_LABEL);
- masm.increment(rsi);
- masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL);
-
- // Strings are equal up to min length. Return the length difference.
- masm.bind(LENGTH_DIFF_LABEL);
- masm.pop(rcx);
- masm.jmpb(DONE_LABEL);
-
- // Discard the stored length difference
- masm.bind(POP_LABEL);
- masm.addptr(rsp, 8);
-
- // That's it
- masm.bind(DONE_LABEL);
- %}
-
- enc_class enc_String_IndexOf(rsi_RegP str1, rdi_RegP str2, regD tmp1, rax_RegI tmp2,
- rcx_RegI tmp3, rdx_RegI tmp4, rbx_RegI result) %{
- // SSE4.2 version
- Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,
- SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE;
- MacroAssembler masm(&cbuf);
-
- XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);
-
- // Get the first character position in both strings
- // [8] char array, [12] offset, [16] count
- int value_offset = java_lang_String::value_offset_in_bytes();
- int offset_offset = java_lang_String::offset_offset_in_bytes();
- int count_offset = java_lang_String::count_offset_in_bytes();
- int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
- // Get counts for string and substr
- masm.movl(rdx, Address(rsi, count_offset));
- masm.movl(rax, Address(rdi, count_offset));
- // Check for substr count > string count
- masm.cmpl(rax, rdx);
- masm.jcc(Assembler::greater, RET_NEG_ONE);
-
- // Start the indexOf operation
- // Get start addr of string
- masm.load_heap_oop(rbx, Address(rsi, value_offset));
- masm.movl(rcx, Address(rsi, offset_offset));
- masm.lea(rsi, Address(rbx, rcx, Address::times_2, base_offset));
- masm.push(rsi);
-
- // Get start addr of substr
- masm.load_heap_oop(rbx, Address(rdi, value_offset));
- masm.movl(rcx, Address(rdi, offset_offset));
- masm.lea(rdi, Address(rbx, rcx, Address::times_2, base_offset));
- masm.push(rdi);
- masm.push(rax);
- masm.jmpb(PREP_FOR_SCAN);
-
- // Substr count saved at sp
- // Substr saved at sp+8
- // String saved at sp+16
-
- // Prep to load substr for scan
- masm.bind(LOAD_SUBSTR);
- masm.movptr(rdi, Address(rsp, 8));
- masm.movl(rax, Address(rsp, 0));
-
- // Load substr
- masm.bind(PREP_FOR_SCAN);
- masm.movdqu(tmp1Reg, Address(rdi, 0));
- masm.addq(rdx, 8); // prime the loop
- masm.subptr(rsi, 16);
-
- // Scan string for substr in 16-byte vectors
- masm.bind(SCAN_TO_SUBSTR);
- masm.subq(rdx, 8);
- masm.addptr(rsi, 16);
- masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
- masm.jcc(Assembler::above, SCAN_TO_SUBSTR);
- masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND);
-
- // Fallthru: found a potential substr
-
- //Make sure string is still long enough
- masm.subl(rdx, rcx);
- masm.cmpl(rdx, rax);
- masm.jccb(Assembler::negative, RET_NOT_FOUND);
- // Compute start addr of substr
- masm.lea(rsi, Address(rsi, rcx, Address::times_2));
- masm.movptr(rbx, rsi);
-
- // Compare potential substr
- masm.addq(rdx, 8); // prime the loop
- masm.addq(rax, 8);
- masm.subptr(rsi, 16);
- masm.subptr(rdi, 16);
-
- // Scan 16-byte vectors of string and substr
- masm.bind(SCAN_SUBSTR);
- masm.subq(rax, 8);
- masm.subq(rdx, 8);
- masm.addptr(rsi, 16);
- masm.addptr(rdi, 16);
- masm.movdqu(tmp1Reg, Address(rdi, 0));
- masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
- masm.jcc(Assembler::noOverflow, LOAD_SUBSTR); // OF == 0
- masm.jcc(Assembler::positive, SCAN_SUBSTR); // SF == 0
-
- // Compute substr offset
- masm.movptr(rsi, Address(rsp, 16));
- masm.subptr(rbx, rsi);
- masm.shrl(rbx, 1);
- masm.jmpb(CLEANUP);
-
- masm.bind(RET_NEG_ONE);
- masm.movl(rbx, -1);
- masm.jmpb(DONE);
-
- masm.bind(RET_NOT_FOUND);
- masm.movl(rbx, -1);
-
- masm.bind(CLEANUP);
- masm.addptr(rsp, 24);
-
- masm.bind(DONE);
- %}
-
- enc_class enc_String_Equals(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,
- rbx_RegI tmp3, rcx_RegI tmp2, rax_RegI result) %{
- Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR;
- MacroAssembler masm(&cbuf);
-
- XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);
- XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);
-
- int value_offset = java_lang_String::value_offset_in_bytes();
- int offset_offset = java_lang_String::offset_offset_in_bytes();
- int count_offset = java_lang_String::count_offset_in_bytes();
- int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
- // does source == target string?
- masm.cmpptr(rdi, rsi);
- masm.jcc(Assembler::equal, RET_TRUE);
-
- // get and compare counts
- masm.movl(rcx, Address(rdi, count_offset));
- masm.movl(rax, Address(rsi, count_offset));
- masm.cmpl(rcx, rax);
- masm.jcc(Assembler::notEqual, RET_FALSE);
- masm.testl(rax, rax);
- masm.jcc(Assembler::zero, RET_TRUE);
-
- // get source string offset and value
- masm.load_heap_oop(rbx, Address(rsi, value_offset));
- masm.movl(rax, Address(rsi, offset_offset));
- masm.lea(rsi, Address(rbx, rax, Address::times_2, base_offset));
-
- // get compare string offset and value
- masm.load_heap_oop(rbx, Address(rdi, value_offset));
- masm.movl(rax, Address(rdi, offset_offset));
- masm.lea(rdi, Address(rbx, rax, Address::times_2, base_offset));
-
- // Set byte count
- masm.shll(rcx, 1);
- masm.movl(rax, rcx);
-
- if (UseSSE42Intrinsics) {
- // With SSE4.2, use double quad vector compare
- Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
- // Compare 16-byte vectors
- masm.andl(rcx, 0xfffffff0); // vector count (in bytes)
- masm.andl(rax, 0x0000000e); // tail count (in bytes)
- masm.testl(rcx, rcx);
- masm.jccb(Assembler::zero, COMPARE_TAIL);
- masm.lea(rdi, Address(rdi, rcx, Address::times_1));
- masm.lea(rsi, Address(rsi, rcx, Address::times_1));
- masm.negptr(rcx);
-
- masm.bind(COMPARE_WIDE_VECTORS);
- masm.movdqu(tmp1Reg, Address(rdi, rcx, Address::times_1));
- masm.movdqu(tmp2Reg, Address(rsi, rcx, Address::times_1));
- masm.pxor(tmp1Reg, tmp2Reg);
- masm.ptest(tmp1Reg, tmp1Reg);
- masm.jccb(Assembler::notZero, RET_FALSE);
- masm.addptr(rcx, 16);
- masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
- masm.bind(COMPARE_TAIL);
- masm.movl(rcx, rax);
- // Fallthru to tail compare
- }
-
- // Compare 4-byte vectors
- masm.andl(rcx, 0xfffffffc); // vector count (in bytes)
- masm.andl(rax, 0x00000002); // tail char (in bytes)
- masm.testl(rcx, rcx);
- masm.jccb(Assembler::zero, COMPARE_CHAR);
- masm.lea(rdi, Address(rdi, rcx, Address::times_1));
- masm.lea(rsi, Address(rsi, rcx, Address::times_1));
- masm.negptr(rcx);
-
- masm.bind(COMPARE_VECTORS);
- masm.movl(rbx, Address(rdi, rcx, Address::times_1));
- masm.cmpl(rbx, Address(rsi, rcx, Address::times_1));
- masm.jccb(Assembler::notEqual, RET_FALSE);
- masm.addptr(rcx, 4);
- masm.jcc(Assembler::notZero, COMPARE_VECTORS);
-
- // Compare trailing char (final 2 bytes), if any
- masm.bind(COMPARE_CHAR);
- masm.testl(rax, rax);
- masm.jccb(Assembler::zero, RET_TRUE);
- masm.load_unsigned_short(rbx, Address(rdi, 0));
- masm.load_unsigned_short(rcx, Address(rsi, 0));
- masm.cmpl(rbx, rcx);
- masm.jccb(Assembler::notEqual, RET_FALSE);
-
- masm.bind(RET_TRUE);
- masm.movl(rax, 1); // return true
- masm.jmpb(DONE);
-
- masm.bind(RET_FALSE);
- masm.xorl(rax, rax); // return false
-
- masm.bind(DONE);
- %}
-
- enc_class enc_Array_Equals(rdi_RegP ary1, rsi_RegP ary2, regD tmp1, regD tmp2,
- rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result) %{
- Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
- MacroAssembler masm(&cbuf);
-
- XMMRegister tmp1Reg = as_XMMRegister($tmp1$$reg);
- XMMRegister tmp2Reg = as_XMMRegister($tmp2$$reg);
- Register ary1Reg = as_Register($ary1$$reg);
- Register ary2Reg = as_Register($ary2$$reg);
- Register tmp3Reg = as_Register($tmp3$$reg);
- Register tmp4Reg = as_Register($tmp4$$reg);
- Register resultReg = as_Register($result$$reg);
-
- int length_offset = arrayOopDesc::length_offset_in_bytes();
- int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
- // Check the input args
- masm.cmpq(ary1Reg, ary2Reg);
- masm.jcc(Assembler::equal, TRUE_LABEL);
- masm.testq(ary1Reg, ary1Reg);
- masm.jcc(Assembler::zero, FALSE_LABEL);
- masm.testq(ary2Reg, ary2Reg);
- masm.jcc(Assembler::zero, FALSE_LABEL);
-
- // Check the lengths
- masm.movl(tmp4Reg, Address(ary1Reg, length_offset));
- masm.movl(resultReg, Address(ary2Reg, length_offset));
- masm.cmpl(tmp4Reg, resultReg);
- masm.jcc(Assembler::notEqual, FALSE_LABEL);
- masm.testl(resultReg, resultReg);
- masm.jcc(Assembler::zero, TRUE_LABEL);
-
- //load array address
- masm.lea(ary1Reg, Address(ary1Reg, base_offset));
- masm.lea(ary2Reg, Address(ary2Reg, base_offset));
-
- //set byte count
- masm.shll(tmp4Reg, 1);
- masm.movl(resultReg,tmp4Reg);
-
- if (UseSSE42Intrinsics){
- // With SSE4.2, use double quad vector compare
- Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
- // Compare 16-byte vectors
- masm.andl(tmp4Reg, 0xfffffff0); // vector count (in bytes)
- masm.andl(resultReg, 0x0000000e); // tail count (in bytes)
- masm.testl(tmp4Reg, tmp4Reg);
- masm.jccb(Assembler::zero, COMPARE_TAIL);
- masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
- masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
- masm.negptr(tmp4Reg);
-
- masm.bind(COMPARE_WIDE_VECTORS);
- masm.movdqu(tmp1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
- masm.movdqu(tmp2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
- masm.pxor(tmp1Reg, tmp2Reg);
- masm.ptest(tmp1Reg, tmp1Reg);
-
- masm.jccb(Assembler::notZero, FALSE_LABEL);
- masm.addptr(tmp4Reg, 16);
- masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
- masm.bind(COMPARE_TAIL);
- masm.movl(tmp4Reg, resultReg);
- // Fallthru to tail compare
- }
-
- // Compare 4-byte vectors
- masm.andl(tmp4Reg, 0xfffffffc); // vector count (in bytes)
- masm.andl(resultReg, 0x00000002); // tail char (in bytes)
- masm.testl(tmp4Reg, tmp4Reg); //if tmp2 == 0, only compare char
- masm.jccb(Assembler::zero, COMPARE_CHAR);
- masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
- masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
- masm.negptr(tmp4Reg);
-
- masm.bind(COMPARE_VECTORS);
- masm.movl(tmp3Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
- masm.cmpl(tmp3Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
- masm.jccb(Assembler::notEqual, FALSE_LABEL);
- masm.addptr(tmp4Reg, 4);
- masm.jcc(Assembler::notZero, COMPARE_VECTORS);
-
- // Compare trailing char (final 2 bytes), if any
- masm.bind(COMPARE_CHAR);
- masm.testl(resultReg, resultReg);
- masm.jccb(Assembler::zero, TRUE_LABEL);
- masm.load_unsigned_short(tmp3Reg, Address(ary1Reg, 0));
- masm.load_unsigned_short(tmp4Reg, Address(ary2Reg, 0));
- masm.cmpl(tmp3Reg, tmp4Reg);
- masm.jccb(Assembler::notEqual, FALSE_LABEL);
-
- masm.bind(TRUE_LABEL);
- masm.movl(resultReg, 1); // return true
- masm.jmpb(DONE);
-
- masm.bind(FALSE_LABEL);
- masm.xorl(resultReg, resultReg); // return false
-
- // That's it
- masm.bind(DONE);
- %}
enc_class enc_rethrow()
%{
@@ -12096,52 +11691,67 @@
ins_pipe(pipe_slow);
%}
-instruct string_compare(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2,
- rax_RegI tmp3, rbx_RegI tmp4, rcx_RegI result, rFlagsReg cr)
-%{
- match(Set result (StrComp str1 str2));
- effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
- //ins_cost(300);
-
- format %{ "String Compare $str1, $str2 -> $result // XXX KILL RAX, RBX" %}
- ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
+instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rbx_RegI cnt2,
+ rax_RegI result, regD tmp1, regD tmp2, rFlagsReg cr)
+%{
+ match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
+
+ format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1, $tmp2" %}
+ ins_encode %{
+ __ string_compare($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register, $result$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+ %}
ins_pipe( pipe_slow );
%}
-instruct string_indexof(rsi_RegP str1, rdi_RegP str2, regD tmp1, rax_RegI tmp2,
- rcx_RegI tmp3, rdx_RegI tmp4, rbx_RegI result, rFlagsReg cr)
+instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
+ rbx_RegI result, regD tmp1, rcx_RegI tmp2, rFlagsReg cr)
%{
predicate(UseSSE42Intrinsics);
- match(Set result (StrIndexOf str1 str2));
- effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr);
-
- format %{ "String IndexOf $str1,$str2 -> $result // KILL RAX, RCX, RDX" %}
- ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
+ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr);
+
+ format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1, $tmp2" %}
+ ins_encode %{
+ __ string_indexof($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register, $result$$Register,
+ $tmp1$$XMMRegister, $tmp2$$Register);
+ %}
ins_pipe( pipe_slow );
%}
// fast string equals
-instruct string_equals(rdi_RegP str1, rsi_RegP str2, regD tmp1, regD tmp2, rbx_RegI tmp3,
- rcx_RegI tmp4, rax_RegI result, rFlagsReg cr)
-%{
- match(Set result (StrEquals str1 str2));
- effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
-
- format %{ "String Equals $str1,$str2 -> $result // KILL RBX, RCX" %}
- ins_encode( enc_String_Equals(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );
+instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result,
+ regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr)
+%{
+ match(Set result (StrEquals (Binary str1 str2) cnt));
+ effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
+
+ format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
+ ins_encode %{
+ __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
+ $cnt$$Register, $result$$Register, $tmp3$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+ %}
ins_pipe( pipe_slow );
%}
// fast array equals
-instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, regD tmp1, regD tmp2, rax_RegI tmp3,
- rbx_RegI tmp4, rcx_RegI result, rFlagsReg cr)
+instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
+ regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
%{
match(Set result (AryEq ary1 ary2));
effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
//ins_cost(300);
- format %{ "Array Equals $ary1,$ary2 -> $result // KILL RAX, RBX" %}
- ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, tmp4, result) );
+ format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
+ ins_encode %{
+ __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
+ $tmp3$$Register, $result$$Register, $tmp4$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+ %}
ins_pipe( pipe_slow );
%}
@@ -12953,9 +12563,9 @@
// Call Java Static Instruction
// Note: If this code changes, the corresponding ret_addr_offset() and
// compute_padding() functions will have to be adjusted.
-instruct CallStaticJavaDirect(method meth)
-%{
+instruct CallStaticJavaDirect(method meth) %{
match(CallStaticJava);
+ predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke());
effect(USE meth);
ins_cost(300);
@@ -12967,6 +12577,28 @@
ins_alignment(4);
%}
+// Call Java Static Instruction (method handle version)
+// Note: If this code changes, the corresponding ret_addr_offset() and
+// compute_padding() functions will have to be adjusted.
+instruct CallStaticJavaHandle(method meth, rbp_RegP rbp) %{
+ match(CallStaticJava);
+ predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke());
+ effect(USE meth);
+ // RBP is saved by all callees (for interpreter stack correction).
+ // We use it here for a similar purpose, in {preserve,restore}_SP.
+
+ ins_cost(300);
+ format %{ "call,static/MethodHandle " %}
+ opcode(0xE8); /* E8 cd */
+ ins_encode(preserve_SP,
+ Java_Static_Call(meth),
+ restore_SP,
+ call_epilog);
+ ins_pipe(pipe_slow);
+ ins_pc_relative(1);
+ ins_alignment(4);
+%}
+
// Call Java Dynamic Instruction
// Note: If this code changes, the corresponding ret_addr_offset() and
// compute_padding() functions will have to be adjusted.
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/assembler_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/assembler_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_assembler_zero.cpp.incl"
+
+int AbstractAssembler::code_fill_byte() {
+ return 0;
+}
+
+void Assembler::pd_patch_instruction(address branch, address target) {
+ ShouldNotCallThis();
+}
+
+#ifndef PRODUCT
+void Assembler::pd_print_patched_instruction(address branch) {
+ ShouldNotCallThis();
+}
+#endif // PRODUCT
+
+void MacroAssembler::align(int modulus) {
+ while (offset() % modulus != 0)
+ emit_byte(AbstractAssembler::code_fill_byte());
+}
+
+void MacroAssembler::bang_stack_with_offset(int offset) {
+ ShouldNotCallThis();
+}
+
+void MacroAssembler::advance(int bytes) {
+ _code_pos += bytes;
+ sync();
+}
+
+RegisterOrConstant MacroAssembler::delayed_value_impl(
+ intptr_t* delayed_value_addr, Register tmpl, int offset) {
+ ShouldNotCallThis();
+}
+
+void MacroAssembler::store_oop(jobject obj) {
+ code_section()->relocate(pc(), oop_Relocation::spec_for_immediate());
+ emit_address((address) obj);
+}
+
+static void should_not_call() {
+ report_should_not_call(__FILE__, __LINE__);
+}
+
+address ShouldNotCallThisStub() {
+ return (address) should_not_call;
+}
+
+address ShouldNotCallThisEntry() {
+ return (address) should_not_call;
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/assembler_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/assembler_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// In normal, CPU-specific ports of HotSpot these two classes are used
+// for generating assembly language. We don't do any of this in zero,
+// of course, but we do sneak entry points around in CodeBuffers so we
+// generate those here.
+
+class Assembler : public AbstractAssembler {
+ public:
+ Assembler(CodeBuffer* code) : AbstractAssembler(code) {}
+
+ public:
+ void pd_patch_instruction(address branch, address target);
+#ifndef PRODUCT
+ static void pd_print_patched_instruction(address branch);
+#endif // PRODUCT
+};
+
+class MacroAssembler : public Assembler {
+ public:
+ MacroAssembler(CodeBuffer* code) : Assembler(code) {}
+
+ public:
+ void align(int modulus);
+ void bang_stack_with_offset(int offset);
+ bool needs_explicit_null_check(intptr_t offset);
+ RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr,
+ Register tmp, int offset);
+ public:
+ void advance(int bytes);
+ void store_oop(jobject obj);
+};
+
+#ifdef ASSERT
+inline bool AbstractAssembler::pd_check_instruction_mark() {
+ ShouldNotCallThis();
+}
+#endif
+
+address ShouldNotCallThisStub();
+address ShouldNotCallThisEntry();
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/assembler_zero.inline.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/assembler_zero.inline.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/bytecodeInterpreter_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/bytecodeInterpreter_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_cppInterpreter_zero.cpp.incl"
+
+#ifdef CC_INTERP
+
+const char *BytecodeInterpreter::name_of_field_at_address(address addr) {
+#define DO(member) {if (addr == (address) &(member)) return XSTR(member);}
+ DO(_thread);
+ DO(_bcp);
+ DO(_locals);
+ DO(_constants);
+ DO(_method);
+ DO(_mdx);
+ DO(_stack);
+ DO(_msg);
+ DO(_result);
+ DO(_prev_link);
+ DO(_oop_temp);
+ DO(_stack_base);
+ DO(_stack_limit);
+ DO(_monitor_base);
+ DO(_self_link);
+#undef DO
+ if (addr > (address) &_result && addr < (address) (&_result + 1))
+ return "_result)";
+ return NULL;
+}
+
+#endif // CC_INTERP
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/bytecodeInterpreter_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/bytecodeInterpreter_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// Platform specific for C++ based Interpreter
+
+#if defined(PPC) || defined(SPARC) || defined(IA64)
+#define LOTS_OF_REGS // Use plenty of registers
+#else
+#undef LOTS_OF_REGS // Loser platforms
+#endif
+
+ private:
+ interpreterState _self_link;
+
+ public:
+ inline void set_locals(intptr_t* new_locals) {
+ _locals = new_locals;
+ }
+ inline void set_method(methodOop new_method) {
+ _method = new_method;
+ }
+ inline interpreterState self_link() {
+ return _self_link;
+ }
+ inline void set_self_link(interpreterState new_self_link) {
+ _self_link = new_self_link;
+ }
+ inline interpreterState prev_link() {
+ return _prev_link;
+ }
+ inline void set_prev_link(interpreterState new_prev_link) {
+ _prev_link = new_prev_link;
+ }
+ inline void set_stack_limit(intptr_t* new_stack_limit) {
+ _stack_limit = new_stack_limit;
+ }
+ inline void set_stack_base(intptr_t* new_stack_base) {
+ _stack_base = new_stack_base;
+ }
+ inline void set_monitor_base(BasicObjectLock *new_monitor_base) {
+ _monitor_base = new_monitor_base;
+ }
+ inline void set_thread(JavaThread* new_thread) {
+ _thread = new_thread;
+ }
+ inline void set_constants(constantPoolCacheOop new_constants) {
+ _constants = new_constants;
+ }
+ inline oop oop_temp() {
+ return _oop_temp;
+ }
+ inline oop *oop_temp_addr() {
+ return &_oop_temp;
+ }
+ inline void set_oop_temp(oop new_oop_temp) {
+ _oop_temp = new_oop_temp;
+ }
+ inline address callee_entry_point() {
+ return _result._to_call._callee_entry_point;
+ }
+ inline address osr_buf() {
+ return _result._osr._osr_buf;
+ }
+ inline address osr_entry() {
+ return _result._osr._osr_entry;
+ }
+
+ public:
+ const char *name_of_field_at_address(address addr);
+
+// The frame manager handles this
+#define SET_LAST_JAVA_FRAME()
+#define RESET_LAST_JAVA_FRAME()
+
+// ZeroStack Implementation
+
+#undef STACK_INT
+#undef STACK_FLOAT
+#undef STACK_ADDR
+#undef STACK_OBJECT
+#undef STACK_DOUBLE
+#undef STACK_LONG
+
+#define GET_STACK_SLOT(offset) (*((intptr_t*) &topOfStack[-(offset)]))
+#define STACK_SLOT(offset) ((address) &topOfStack[-(offset)])
+#define STACK_ADDR(offset) (*((address *) &topOfStack[-(offset)]))
+#define STACK_INT(offset) (*((jint*) &topOfStack[-(offset)]))
+#define STACK_FLOAT(offset) (*((jfloat *) &topOfStack[-(offset)]))
+#define STACK_OBJECT(offset) (*((oop *) &topOfStack [-(offset)]))
+#define STACK_DOUBLE(offset) (((VMJavaVal64*) &topOfStack[-(offset)])->d)
+#define STACK_LONG(offset) (((VMJavaVal64 *) &topOfStack[-(offset)])->l)
+
+#define SET_STACK_SLOT(value, offset) (*(intptr_t*)&topOfStack[-(offset)] = *(intptr_t*)(value))
+#define SET_STACK_ADDR(value, offset) (*((address *)&topOfStack[-(offset)]) = (value))
+#define SET_STACK_INT(value, offset) (*((jint *)&topOfStack[-(offset)]) = (value))
+#define SET_STACK_FLOAT(value, offset) (*((jfloat *)&topOfStack[-(offset)]) = (value))
+#define SET_STACK_OBJECT(value, offset) (*((oop *)&topOfStack[-(offset)]) = (value))
+#define SET_STACK_DOUBLE(value, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->d = (value))
+#define SET_STACK_DOUBLE_FROM_ADDR(addr, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->d = \
+ ((VMJavaVal64*)(addr))->d)
+#define SET_STACK_LONG(value, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->l = (value))
+#define SET_STACK_LONG_FROM_ADDR(addr, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->l = \
+ ((VMJavaVal64*)(addr))->l)
+// JavaLocals implementation
+
+#define LOCALS_SLOT(offset) ((intptr_t*)&locals[-(offset)])
+#define LOCALS_ADDR(offset) ((address)locals[-(offset)])
+#define LOCALS_INT(offset) (*((jint*)&locals[-(offset)]))
+#define LOCALS_FLOAT(offset) (*((jfloat*)&locals[-(offset)]))
+#define LOCALS_OBJECT(offset) ((oop)locals[-(offset)])
+#define LOCALS_DOUBLE(offset) (((VMJavaVal64*)&locals[-((offset) + 1)])->d)
+#define LOCALS_LONG(offset) (((VMJavaVal64*)&locals[-((offset) + 1)])->l)
+#define LOCALS_LONG_AT(offset) (((address)&locals[-((offset) + 1)]))
+#define LOCALS_DOUBLE_AT(offset) (((address)&locals[-((offset) + 1)]))
+
+#define SET_LOCALS_SLOT(value, offset) (*(intptr_t*)&locals[-(offset)] = *(intptr_t *)(value))
+#define SET_LOCALS_ADDR(value, offset) (*((address *)&locals[-(offset)]) = (value))
+#define SET_LOCALS_INT(value, offset) (*((jint *)&locals[-(offset)]) = (value))
+#define SET_LOCALS_FLOAT(value, offset) (*((jfloat *)&locals[-(offset)]) = (value))
+#define SET_LOCALS_OBJECT(value, offset) (*((oop *)&locals[-(offset)]) = (value))
+#define SET_LOCALS_DOUBLE(value, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->d = (value))
+#define SET_LOCALS_LONG(value, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->l = (value))
+#define SET_LOCALS_DOUBLE_FROM_ADDR(addr, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->d = \
+ ((VMJavaVal64*)(addr))->d)
+#define SET_LOCALS_LONG_FROM_ADDR(addr, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->l = \
+ ((VMJavaVal64*)(addr))->l)
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/bytecodeInterpreter_zero.inline.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/bytecodeInterpreter_zero.inline.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,301 @@
+/*
+ * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// Inline interpreter functions for zero
+
+inline jfloat BytecodeInterpreter::VMfloatAdd(jfloat op1, jfloat op2) {
+ return op1 + op2;
+}
+
+inline jfloat BytecodeInterpreter::VMfloatSub(jfloat op1, jfloat op2) {
+ return op1 - op2;
+}
+
+inline jfloat BytecodeInterpreter::VMfloatMul(jfloat op1, jfloat op2) {
+ return op1 * op2;
+}
+
+inline jfloat BytecodeInterpreter::VMfloatDiv(jfloat op1, jfloat op2) {
+ return op1 / op2;
+}
+
+inline jfloat BytecodeInterpreter::VMfloatRem(jfloat op1, jfloat op2) {
+ return fmod(op1, op2);
+}
+
+inline jfloat BytecodeInterpreter::VMfloatNeg(jfloat op) {
+ return -op;
+}
+
+inline int32_t BytecodeInterpreter::VMfloatCompare(jfloat op1,
+ jfloat op2,
+ int32_t direction) {
+ return ( op1 < op2 ? -1 :
+ op1 > op2 ? 1 :
+ op1 == op2 ? 0 :
+ (direction == -1 || direction == 1) ? direction : 0);
+
+}
+
+inline void BytecodeInterpreter::VMmemCopy64(uint32_t to[2],
+ const uint32_t from[2]) {
+ *(uint64_t *) to = *(uint64_t *) from;
+}
+
+inline jlong BytecodeInterpreter::VMlongAdd(jlong op1, jlong op2) {
+ return op1 + op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongAnd(jlong op1, jlong op2) {
+ return op1 & op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongDiv(jlong op1, jlong op2) {
+ /* it's possible we could catch this special case implicitly */
+ if (op1 == (jlong) 0x8000000000000000LL && op2 == -1) return op1;
+ else return op1 / op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongMul(jlong op1, jlong op2) {
+ return op1 * op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongOr(jlong op1, jlong op2) {
+ return op1 | op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongSub(jlong op1, jlong op2) {
+ return op1 - op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongXor(jlong op1, jlong op2) {
+ return op1 ^ op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongRem(jlong op1, jlong op2) {
+ /* it's possible we could catch this special case implicitly */
+ if (op1 == (jlong) 0x8000000000000000LL && op2 == -1) return 0;
+ else return op1 % op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongUshr(jlong op1, jint op2) {
+ return ((unsigned long long) op1) >> (op2 & 0x3F);
+}
+
+inline jlong BytecodeInterpreter::VMlongShr(jlong op1, jint op2) {
+ return op1 >> (op2 & 0x3F);
+}
+
+inline jlong BytecodeInterpreter::VMlongShl(jlong op1, jint op2) {
+ return op1 << (op2 & 0x3F);
+}
+
+inline jlong BytecodeInterpreter::VMlongNeg(jlong op) {
+ return -op;
+}
+
+inline jlong BytecodeInterpreter::VMlongNot(jlong op) {
+ return ~op;
+}
+
+inline int32_t BytecodeInterpreter::VMlongLtz(jlong op) {
+ return (op <= 0);
+}
+
+inline int32_t BytecodeInterpreter::VMlongGez(jlong op) {
+ return (op >= 0);
+}
+
+inline int32_t BytecodeInterpreter::VMlongEqz(jlong op) {
+ return (op == 0);
+}
+
+inline int32_t BytecodeInterpreter::VMlongEq(jlong op1, jlong op2) {
+ return (op1 == op2);
+}
+
+inline int32_t BytecodeInterpreter::VMlongNe(jlong op1, jlong op2) {
+ return (op1 != op2);
+}
+
+inline int32_t BytecodeInterpreter::VMlongGe(jlong op1, jlong op2) {
+ return (op1 >= op2);
+}
+
+inline int32_t BytecodeInterpreter::VMlongLe(jlong op1, jlong op2) {
+ return (op1 <= op2);
+}
+
+inline int32_t BytecodeInterpreter::VMlongLt(jlong op1, jlong op2) {
+ return (op1 < op2);
+}
+
+inline int32_t BytecodeInterpreter::VMlongGt(jlong op1, jlong op2) {
+ return (op1 > op2);
+}
+
+inline int32_t BytecodeInterpreter::VMlongCompare(jlong op1, jlong op2) {
+ return (VMlongLt(op1, op2) ? -1 : VMlongGt(op1, op2) ? 1 : 0);
+}
+
+// Long conversions
+
+inline jdouble BytecodeInterpreter::VMlong2Double(jlong val) {
+ return (jdouble) val;
+}
+
+inline jfloat BytecodeInterpreter::VMlong2Float(jlong val) {
+ return (jfloat) val;
+}
+
+inline jint BytecodeInterpreter::VMlong2Int(jlong val) {
+ return (jint) val;
+}
+
+// Double Arithmetic
+
+inline jdouble BytecodeInterpreter::VMdoubleAdd(jdouble op1, jdouble op2) {
+ return op1 + op2;
+}
+
+inline jdouble BytecodeInterpreter::VMdoubleDiv(jdouble op1, jdouble op2) {
+ // Divide by zero... QQQ
+ return op1 / op2;
+}
+
+inline jdouble BytecodeInterpreter::VMdoubleMul(jdouble op1, jdouble op2) {
+ return op1 * op2;
+}
+
+inline jdouble BytecodeInterpreter::VMdoubleNeg(jdouble op) {
+ return -op;
+}
+
+inline jdouble BytecodeInterpreter::VMdoubleRem(jdouble op1, jdouble op2) {
+ return fmod(op1, op2);
+}
+
+inline jdouble BytecodeInterpreter::VMdoubleSub(jdouble op1, jdouble op2) {
+ return op1 - op2;
+}
+
+inline int32_t BytecodeInterpreter::VMdoubleCompare(jdouble op1,
+ jdouble op2,
+ int32_t direction) {
+ return ( op1 < op2 ? -1 :
+ op1 > op2 ? 1 :
+ op1 == op2 ? 0 :
+ (direction == -1 || direction == 1) ? direction : 0);
+}
+
+// Double Conversions
+
+inline jfloat BytecodeInterpreter::VMdouble2Float(jdouble val) {
+ return (jfloat) val;
+}
+
+// Float Conversions
+
+inline jdouble BytecodeInterpreter::VMfloat2Double(jfloat op) {
+ return (jdouble) op;
+}
+
+// Integer Arithmetic
+
+inline jint BytecodeInterpreter::VMintAdd(jint op1, jint op2) {
+ return op1 + op2;
+}
+
+inline jint BytecodeInterpreter::VMintAnd(jint op1, jint op2) {
+ return op1 & op2;
+}
+
+inline jint BytecodeInterpreter::VMintDiv(jint op1, jint op2) {
+ /* it's possible we could catch this special case implicitly */
+ if (op1 == (jint) 0x80000000 && op2 == -1) return op1;
+ else return op1 / op2;
+}
+
+inline jint BytecodeInterpreter::VMintMul(jint op1, jint op2) {
+ return op1 * op2;
+}
+
+inline jint BytecodeInterpreter::VMintNeg(jint op) {
+ return -op;
+}
+
+inline jint BytecodeInterpreter::VMintOr(jint op1, jint op2) {
+ return op1 | op2;
+}
+
+inline jint BytecodeInterpreter::VMintRem(jint op1, jint op2) {
+ /* it's possible we could catch this special case implicitly */
+ if (op1 == (jint) 0x80000000 && op2 == -1) return 0;
+ else return op1 % op2;
+}
+
+inline jint BytecodeInterpreter::VMintShl(jint op1, jint op2) {
+ return op1 << (op2 & 0x1F);
+}
+
+inline jint BytecodeInterpreter::VMintShr(jint op1, jint op2) {
+ return op1 >> (op2 & 0x1F);
+}
+
+inline jint BytecodeInterpreter::VMintSub(jint op1, jint op2) {
+ return op1 - op2;
+}
+
+inline jint BytecodeInterpreter::VMintUshr(jint op1, jint op2) {
+ return ((juint) op1) >> (op2 & 0x1F);
+}
+
+inline jint BytecodeInterpreter::VMintXor(jint op1, jint op2) {
+ return op1 ^ op2;
+}
+
+inline jdouble BytecodeInterpreter::VMint2Double(jint val) {
+ return (jdouble) val;
+}
+
+inline jfloat BytecodeInterpreter::VMint2Float(jint val) {
+ return (jfloat) val;
+}
+
+inline jlong BytecodeInterpreter::VMint2Long(jint val) {
+ return (jlong) val;
+}
+
+inline jchar BytecodeInterpreter::VMint2Char(jint val) {
+ return (jchar) val;
+}
+
+inline jshort BytecodeInterpreter::VMint2Short(jint val) {
+ return (jshort) val;
+}
+
+inline jbyte BytecodeInterpreter::VMint2Byte(jint val) {
+ return (jbyte) val;
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/bytecodes_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/bytecodes_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_bytecodes_zero.cpp.incl"
+
+void Bytecodes::pd_initialize() {
+ // No zero specific initialization
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/bytecodes_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/bytecodes_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/bytes_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/bytes_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,164 @@
+/*
+ * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+typedef union unaligned {
+ u4 u;
+ u2 us;
+ u8 ul;
+} __attribute__((packed)) unaligned;
+
+class Bytes: AllStatic {
+ public:
+ // Returns true if the byte ordering used by Java is different
+ // from the native byte ordering of the underlying machine.
+ static inline bool is_Java_byte_ordering_different() {
+#ifdef VM_LITTLE_ENDIAN
+ return true;
+#else
+ return false;
+#endif
+ }
+
+ // Efficient reading and writing of unaligned unsigned data in
+ // platform-specific byte ordering.
+ static inline u2 get_native_u2(address p){
+ unaligned *up = (unaligned *) p;
+ return up->us;
+ }
+
+ static inline u4 get_native_u4(address p) {
+ unaligned *up = (unaligned *) p;
+ return up->u;
+ }
+
+ static inline u8 get_native_u8(address p) {
+ unaligned *up = (unaligned *) p;
+ return up->ul;
+ }
+
+ static inline void put_native_u2(address p, u2 x) {
+ unaligned *up = (unaligned *) p;
+ up->us = x;
+ }
+
+ static inline void put_native_u4(address p, u4 x) {
+ unaligned *up = (unaligned *) p;
+ up->u = x;
+ }
+
+ static inline void put_native_u8(address p, u8 x) {
+ unaligned *up = (unaligned *) p;
+ up->ul = x;
+ }
+
+ // Efficient reading and writing of unaligned unsigned data in Java
+ // byte ordering (i.e. big-endian ordering).
+#ifdef VM_LITTLE_ENDIAN
+ // Byte-order reversal is needed
+ static inline u2 get_Java_u2(address p) {
+ return (u2(p[0]) << 8) |
+ (u2(p[1]) );
+ }
+ static inline u4 get_Java_u4(address p) {
+ return (u4(p[0]) << 24) |
+ (u4(p[1]) << 16) |
+ (u4(p[2]) << 8) |
+ (u4(p[3]) );
+ }
+ static inline u8 get_Java_u8(address p) {
+ u4 hi, lo;
+ hi = (u4(p[0]) << 24) |
+ (u4(p[1]) << 16) |
+ (u4(p[2]) << 8) |
+ (u4(p[3]) );
+ lo = (u4(p[4]) << 24) |
+ (u4(p[5]) << 16) |
+ (u4(p[6]) << 8) |
+ (u4(p[7]) );
+ return u8(lo) | (u8(hi) << 32);
+ }
+
+ static inline void put_Java_u2(address p, u2 x) {
+ p[0] = x >> 8;
+ p[1] = x;
+ }
+ static inline void put_Java_u4(address p, u4 x) {
+ p[0] = x >> 24;
+ p[1] = x >> 16;
+ p[2] = x >> 8;
+ p[3] = x;
+ }
+ static inline void put_Java_u8(address p, u8 x) {
+ u4 hi, lo;
+ lo = x;
+ hi = x >> 32;
+ p[0] = hi >> 24;
+ p[1] = hi >> 16;
+ p[2] = hi >> 8;
+ p[3] = hi;
+ p[4] = lo >> 24;
+ p[5] = lo >> 16;
+ p[6] = lo >> 8;
+ p[7] = lo;
+ }
+
+ // Efficient swapping of byte ordering
+ static inline u2 swap_u2(u2 x);
+ static inline u4 swap_u4(u4 x);
+ static inline u8 swap_u8(u8 x);
+#else
+ // No byte-order reversal is needed
+ static inline u2 get_Java_u2(address p) {
+ return get_native_u2(p);
+ }
+ static inline u4 get_Java_u4(address p) {
+ return get_native_u4(p);
+ }
+ static inline u8 get_Java_u8(address p) {
+ return get_native_u8(p);
+ }
+
+ static inline void put_Java_u2(address p, u2 x) {
+ put_native_u2(p, x);
+ }
+ static inline void put_Java_u4(address p, u4 x) {
+ put_native_u4(p, x);
+ }
+ static inline void put_Java_u8(address p, u8 x) {
+ put_native_u8(p, x);
+ }
+
+ // No byte-order reversal is needed
+ static inline u2 swap_u2(u2 x) { return x; }
+ static inline u4 swap_u4(u4 x) { return x; }
+ static inline u8 swap_u8(u8 x) { return x; }
+#endif // VM_LITTLE_ENDIAN
+};
+
+#ifdef VM_LITTLE_ENDIAN
+// The following header contains the implementations of swap_u2,
+// swap_u4, and swap_u8
+#include "incls/_bytes_pd.inline.hpp.incl"
+#endif // VM_LITTLE_ENDIAN
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/codeBuffer_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/codeBuffer_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ private:
+ void pd_initialize() {}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/copy_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/copy_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// Inline functions for memory copy and fill.
+
+static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+ memmove(to, from, count * HeapWordSize);
+}
+
+static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+ switch (count) {
+ case 8: to[7] = from[7];
+ case 7: to[6] = from[6];
+ case 6: to[5] = from[5];
+ case 5: to[4] = from[4];
+ case 4: to[3] = from[3];
+ case 3: to[2] = from[2];
+ case 2: to[1] = from[1];
+ case 1: to[0] = from[0];
+ case 0: break;
+ default:
+ memcpy(to, from, count * HeapWordSize);
+ break;
+ }
+}
+
+static void pd_disjoint_words_atomic(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ switch (count) {
+ case 8: to[7] = from[7];
+ case 7: to[6] = from[6];
+ case 6: to[5] = from[5];
+ case 5: to[4] = from[4];
+ case 4: to[3] = from[3];
+ case 3: to[2] = from[2];
+ case 2: to[1] = from[1];
+ case 1: to[0] = from[0];
+ case 0: break;
+ default:
+ while (count-- > 0) {
+ *to++ = *from++;
+ }
+ break;
+ }
+}
+
+static void pd_aligned_conjoint_words(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ memmove(to, from, count * HeapWordSize);
+}
+
+static void pd_aligned_disjoint_words(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ pd_disjoint_words(from, to, count);
+}
+
+static void pd_conjoint_bytes(void* from, void* to, size_t count) {
+ memmove(to, from, count);
+}
+
+static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
+ memmove(to, from, count);
+}
+
+static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+ _Copy_conjoint_jshorts_atomic(from, to, count);
+}
+
+static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+ _Copy_conjoint_jints_atomic(from, to, count);
+}
+
+static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+ _Copy_conjoint_jlongs_atomic(from, to, count);
+}
+
+static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
+#ifdef _LP64
+ assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
+ _Copy_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+#else
+ assert(BytesPerInt == BytesPerOop, "jints and oops must be the same size");
+ _Copy_conjoint_jints_atomic((jint*)from, (jint*)to, count);
+#endif // _LP64
+}
+
+static void pd_arrayof_conjoint_bytes(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ _Copy_arrayof_conjoint_bytes(from, to, count);
+}
+
+static void pd_arrayof_conjoint_jshorts(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ _Copy_arrayof_conjoint_jshorts(from, to, count);
+}
+
+static void pd_arrayof_conjoint_jints(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ _Copy_arrayof_conjoint_jints(from, to, count);
+}
+
+static void pd_arrayof_conjoint_jlongs(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ _Copy_arrayof_conjoint_jlongs(from, to, count);
+}
+
+static void pd_arrayof_conjoint_oops(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+#ifdef _LP64
+ assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
+ _Copy_arrayof_conjoint_jlongs(from, to, count);
+#else
+ assert(BytesPerInt == BytesPerOop, "jints and oops must be the same size");
+ _Copy_arrayof_conjoint_jints(from, to, count);
+#endif // _LP64
+}
+
+static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) {
+#ifdef _LP64
+ julong* to = (julong*) tohw;
+ julong v = ((julong) value << 32) | value;
+#else
+ juint* to = (juint*) tohw;
+ juint v = value;
+#endif // _LP64
+
+ while (count-- > 0) {
+ *to++ = v;
+ }
+}
+
+static void pd_fill_to_aligned_words(HeapWord* tohw,
+ size_t count,
+ juint value) {
+ pd_fill_to_words(tohw, count, value);
+}
+
+static void pd_fill_to_bytes(void* to, size_t count, jubyte value) {
+ memset(to, value, count);
+}
+
+static void pd_zero_to_words(HeapWord* tohw, size_t count) {
+ pd_fill_to_words(tohw, count, 0);
+}
+
+static void pd_zero_to_bytes(void* to, size_t count) {
+ memset(to, 0, count);
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ protected:
+ MacroAssembler* assembler() const {
+ return _masm;
+ }
+
+ protected:
+ address generate_entry(address entry_point) {
+ ZeroEntry *entry = (ZeroEntry *) assembler()->pc();
+ assembler()->advance(sizeof(ZeroEntry));
+ entry->set_entry_point(entry_point);
+ return (address) entry;
+ }
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/cppInterpreter_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,981 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_cppInterpreter_zero.cpp.incl"
+
+#ifdef CC_INTERP
+
+#define fixup_after_potential_safepoint() \
+ method = istate->method()
+
+#define CALL_VM_NOCHECK(func) \
+ thread->set_last_Java_frame(); \
+ func; \
+ thread->reset_last_Java_frame(); \
+ fixup_after_potential_safepoint()
+
+void CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) {
+ JavaThread *thread = (JavaThread *) THREAD;
+ ZeroStack *stack = thread->zero_stack();
+
+ // Adjust the caller's stack frame to accomodate any additional
+ // local variables we have contiguously with our parameters.
+ int extra_locals = method->max_locals() - method->size_of_parameters();
+ if (extra_locals > 0) {
+ if (extra_locals > stack->available_words()) {
+ Unimplemented();
+ }
+ for (int i = 0; i < extra_locals; i++)
+ stack->push(0);
+ }
+
+ // Allocate and initialize our frame.
+ InterpreterFrame *frame = InterpreterFrame::build(stack, method, thread);
+ thread->push_zero_frame(frame);
+
+ // Execute those bytecodes!
+ main_loop(0, THREAD);
+}
+
+void CppInterpreter::main_loop(int recurse, TRAPS) {
+ JavaThread *thread = (JavaThread *) THREAD;
+ ZeroStack *stack = thread->zero_stack();
+
+ // If we are entering from a deopt we may need to call
+ // ourself a few times in order to get to our frame.
+ if (recurse)
+ main_loop(recurse - 1, THREAD);
+
+ InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
+ interpreterState istate = frame->interpreter_state();
+ methodOop method = istate->method();
+
+ intptr_t *result = NULL;
+ int result_slots = 0;
+
+ // Check we're not about to run out of stack
+ if (stack_overflow_imminent(thread)) {
+ CALL_VM_NOCHECK(InterpreterRuntime::throw_StackOverflowError(thread));
+ goto unwind_and_return;
+ }
+
+ while (true) {
+ // We can set up the frame anchor with everything we want at
+ // this point as we are thread_in_Java and no safepoints can
+ // occur until we go to vm mode. We do have to clear flags
+ // on return from vm but that is it.
+ thread->set_last_Java_frame();
+
+ // Call the interpreter
+ if (JvmtiExport::can_post_interpreter_events())
+ BytecodeInterpreter::runWithChecks(istate);
+ else
+ BytecodeInterpreter::run(istate);
+ fixup_after_potential_safepoint();
+
+ // Clear the frame anchor
+ thread->reset_last_Java_frame();
+
+ // Examine the message from the interpreter to decide what to do
+ if (istate->msg() == BytecodeInterpreter::call_method) {
+ methodOop callee = istate->callee();
+
+ // Trim back the stack to put the parameters at the top
+ stack->set_sp(istate->stack() + 1);
+
+ // Make the call
+ Interpreter::invoke_method(callee, istate->callee_entry_point(), THREAD);
+ fixup_after_potential_safepoint();
+
+ // Convert the result
+ istate->set_stack(stack->sp() - 1);
+
+ // Restore the stack
+ stack->set_sp(istate->stack_limit() + 1);
+
+ // Resume the interpreter
+ istate->set_msg(BytecodeInterpreter::method_resume);
+ }
+ else if (istate->msg() == BytecodeInterpreter::more_monitors) {
+ int monitor_words = frame::interpreter_frame_monitor_size();
+
+ // Allocate the space
+ if (monitor_words > stack->available_words()) {
+ Unimplemented();
+ }
+ stack->alloc(monitor_words * wordSize);
+
+ // Move the expression stack contents
+ for (intptr_t *p = istate->stack() + 1; p < istate->stack_base(); p++)
+ *(p - monitor_words) = *p;
+
+ // Move the expression stack pointers
+ istate->set_stack_limit(istate->stack_limit() - monitor_words);
+ istate->set_stack(istate->stack() - monitor_words);
+ istate->set_stack_base(istate->stack_base() - monitor_words);
+
+ // Zero the new monitor so the interpreter can find it.
+ ((BasicObjectLock *) istate->stack_base())->set_obj(NULL);
+
+ // Resume the interpreter
+ istate->set_msg(BytecodeInterpreter::got_monitors);
+ }
+ else if (istate->msg() == BytecodeInterpreter::return_from_method) {
+ // Copy the result into the caller's frame
+ result_slots = type2size[result_type_of(method)];
+ assert(result_slots >= 0 && result_slots <= 2, "what?");
+ result = istate->stack() + result_slots;
+ break;
+ }
+ else if (istate->msg() == BytecodeInterpreter::throwing_exception) {
+ assert(HAS_PENDING_EXCEPTION, "should do");
+ break;
+ }
+ else if (istate->msg() == BytecodeInterpreter::do_osr) {
+ // Unwind the current frame
+ thread->pop_zero_frame();
+
+ // Remove any extension of the previous frame
+ int extra_locals = method->max_locals() - method->size_of_parameters();
+ stack->set_sp(stack->sp() + extra_locals);
+
+ // Jump into the OSR method
+ Interpreter::invoke_osr(
+ method, istate->osr_entry(), istate->osr_buf(), THREAD);
+ return;
+ }
+ else {
+ ShouldNotReachHere();
+ }
+ }
+
+ unwind_and_return:
+
+ // Unwind the current frame
+ thread->pop_zero_frame();
+
+ // Pop our local variables
+ stack->set_sp(stack->sp() + method->max_locals());
+
+ // Push our result
+ for (int i = 0; i < result_slots; i++)
+ stack->push(result[-i]);
+}
+
+void CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) {
+ // Make sure method is native and not abstract
+ assert(method->is_native() && !method->is_abstract(), "should be");
+
+ JavaThread *thread = (JavaThread *) THREAD;
+ ZeroStack *stack = thread->zero_stack();
+
+ // Allocate and initialize our frame
+ InterpreterFrame *frame = InterpreterFrame::build(stack, method, thread);
+ thread->push_zero_frame(frame);
+ interpreterState istate = frame->interpreter_state();
+ intptr_t *locals = istate->locals();
+
+ // Check we're not about to run out of stack
+ if (stack_overflow_imminent(thread)) {
+ CALL_VM_NOCHECK(InterpreterRuntime::throw_StackOverflowError(thread));
+ goto unwind_and_return;
+ }
+
+ // Update the invocation counter
+ if ((UseCompiler || CountCompiledCalls) && !method->is_synchronized()) {
+ thread->set_do_not_unlock();
+ InvocationCounter *counter = method->invocation_counter();
+ counter->increment();
+ if (counter->reached_InvocationLimit()) {
+ CALL_VM_NOCHECK(
+ InterpreterRuntime::frequency_counter_overflow(thread, NULL));
+ if (HAS_PENDING_EXCEPTION)
+ goto unwind_and_return;
+ }
+ thread->clr_do_not_unlock();
+ }
+
+ // Lock if necessary
+ BasicObjectLock *monitor;
+ monitor = NULL;
+ if (method->is_synchronized()) {
+ monitor = (BasicObjectLock*) istate->stack_base();
+ oop lockee = monitor->obj();
+ markOop disp = lockee->mark()->set_unlocked();
+
+ monitor->lock()->set_displaced_header(disp);
+ if (Atomic::cmpxchg_ptr(monitor, lockee->mark_addr(), disp) != disp) {
+ if (thread->is_lock_owned((address) disp->clear_lock_bits())) {
+ monitor->lock()->set_displaced_header(NULL);
+ }
+ else {
+ CALL_VM_NOCHECK(InterpreterRuntime::monitorenter(thread, monitor));
+ if (HAS_PENDING_EXCEPTION)
+ goto unwind_and_return;
+ }
+ }
+ }
+
+ // Get the signature handler
+ InterpreterRuntime::SignatureHandler *handler; {
+ address handlerAddr = method->signature_handler();
+ if (handlerAddr == NULL) {
+ CALL_VM_NOCHECK(InterpreterRuntime::prepare_native_call(thread, method));
+ if (HAS_PENDING_EXCEPTION)
+ goto unlock_unwind_and_return;
+
+ handlerAddr = method->signature_handler();
+ assert(handlerAddr != NULL, "eh?");
+ }
+ if (handlerAddr == (address) InterpreterRuntime::slow_signature_handler) {
+ CALL_VM_NOCHECK(handlerAddr =
+ InterpreterRuntime::slow_signature_handler(thread, method, NULL,NULL));
+ if (HAS_PENDING_EXCEPTION)
+ goto unlock_unwind_and_return;
+ }
+ handler = \
+ InterpreterRuntime::SignatureHandler::from_handlerAddr(handlerAddr);
+ }
+
+ // Get the native function entry point
+ address function;
+ function = method->native_function();
+ assert(function != NULL, "should be set if signature handler is");
+
+ // Build the argument list
+ if (handler->argument_count() * 2 > stack->available_words()) {
+ Unimplemented();
+ }
+ void **arguments;
+ void *mirror; {
+ arguments =
+ (void **) stack->alloc(handler->argument_count() * sizeof(void **));
+ void **dst = arguments;
+
+ void *env = thread->jni_environment();
+ *(dst++) = &env;
+
+ if (method->is_static()) {
+ istate->set_oop_temp(
+ method->constants()->pool_holder()->klass_part()->java_mirror());
+ mirror = istate->oop_temp_addr();
+ *(dst++) = &mirror;
+ }
+
+ intptr_t *src = locals;
+ for (int i = dst - arguments; i < handler->argument_count(); i++) {
+ ffi_type *type = handler->argument_type(i);
+ if (type == &ffi_type_pointer) {
+ if (*src) {
+ stack->push((intptr_t) src);
+ *(dst++) = stack->sp();
+ }
+ else {
+ *(dst++) = src;
+ }
+ src--;
+ }
+ else if (type->size == 4) {
+ *(dst++) = src--;
+ }
+ else if (type->size == 8) {
+ src--;
+ *(dst++) = src--;
+ }
+ else {
+ ShouldNotReachHere();
+ }
+ }
+ }
+
+ // Set up the Java frame anchor
+ thread->set_last_Java_frame();
+
+ // Change the thread state to _thread_in_native
+ ThreadStateTransition::transition_from_java(thread, _thread_in_native);
+
+ // Make the call
+ intptr_t result[4 - LogBytesPerWord];
+ ffi_call(handler->cif(), (void (*)()) function, result, arguments);
+
+ // Change the thread state back to _thread_in_Java.
+ // ThreadStateTransition::transition_from_native() cannot be used
+ // here because it does not check for asynchronous exceptions.
+ // We have to manage the transition ourself.
+ thread->set_thread_state(_thread_in_native_trans);
+
+ // Make sure new state is visible in the GC thread
+ if (os::is_MP()) {
+ if (UseMembar) {
+ OrderAccess::fence();
+ }
+ else {
+ InterfaceSupport::serialize_memory(thread);
+ }
+ }
+
+ // Handle safepoint operations, pending suspend requests,
+ // and pending asynchronous exceptions.
+ if (SafepointSynchronize::do_call_back() ||
+ thread->has_special_condition_for_native_trans()) {
+ JavaThread::check_special_condition_for_native_trans(thread);
+ CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops());
+ }
+
+ // Finally we can change the thread state to _thread_in_Java.
+ thread->set_thread_state(_thread_in_Java);
+ fixup_after_potential_safepoint();
+
+ // Clear the frame anchor
+ thread->reset_last_Java_frame();
+
+ // If the result was an oop then unbox it and store it in
+ // oop_temp where the garbage collector can see it before
+ // we release the handle it might be protected by.
+ if (handler->result_type() == &ffi_type_pointer) {
+ if (result[0])
+ istate->set_oop_temp(*(oop *) result[0]);
+ else
+ istate->set_oop_temp(NULL);
+ }
+
+ // Reset handle block
+ thread->active_handles()->clear();
+
+ unlock_unwind_and_return:
+
+ // Unlock if necessary
+ if (monitor) {
+ BasicLock *lock = monitor->lock();
+ markOop header = lock->displaced_header();
+ oop rcvr = monitor->obj();
+ monitor->set_obj(NULL);
+
+ if (header != NULL) {
+ if (Atomic::cmpxchg_ptr(header, rcvr->mark_addr(), lock) != lock) {
+ monitor->set_obj(rcvr); {
+ HandleMark hm(thread);
+ CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(thread, monitor));
+ }
+ }
+ }
+ }
+
+ unwind_and_return:
+
+ // Unwind the current activation
+ thread->pop_zero_frame();
+
+ // Pop our parameters
+ stack->set_sp(stack->sp() + method->size_of_parameters());
+
+ // Push our result
+ if (!HAS_PENDING_EXCEPTION) {
+ BasicType type = result_type_of(method);
+ stack->set_sp(stack->sp() - type2size[type]);
+
+ switch (type) {
+ case T_VOID:
+ break;
+
+ case T_BOOLEAN:
+#ifndef VM_LITTLE_ENDIAN
+ result[0] <<= (BitsPerWord - BitsPerByte);
+#endif
+ SET_LOCALS_INT(*(jboolean *) result != 0, 0);
+ break;
+
+ case T_CHAR:
+#ifndef VM_LITTLE_ENDIAN
+ result[0] <<= (BitsPerWord - BitsPerShort);
+#endif
+ SET_LOCALS_INT(*(jchar *) result, 0);
+ break;
+
+ case T_BYTE:
+#ifndef VM_LITTLE_ENDIAN
+ result[0] <<= (BitsPerWord - BitsPerByte);
+#endif
+ SET_LOCALS_INT(*(jbyte *) result, 0);
+ break;
+
+ case T_SHORT:
+#ifndef VM_LITTLE_ENDIAN
+ result[0] <<= (BitsPerWord - BitsPerShort);
+#endif
+ SET_LOCALS_INT(*(jshort *) result, 0);
+ break;
+
+ case T_INT:
+#ifndef VM_LITTLE_ENDIAN
+ result[0] <<= (BitsPerWord - BitsPerInt);
+#endif
+ SET_LOCALS_INT(*(jint *) result, 0);
+ break;
+
+ case T_LONG:
+ SET_LOCALS_LONG(*(jlong *) result, 0);
+ break;
+
+ case T_FLOAT:
+ SET_LOCALS_FLOAT(*(jfloat *) result, 0);
+ break;
+
+ case T_DOUBLE:
+ SET_LOCALS_DOUBLE(*(jdouble *) result, 0);
+ break;
+
+ case T_OBJECT:
+ case T_ARRAY:
+ SET_LOCALS_OBJECT(istate->oop_temp(), 0);
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+ }
+}
+
+void CppInterpreter::accessor_entry(methodOop method, intptr_t UNUSED, TRAPS) {
+ JavaThread *thread = (JavaThread *) THREAD;
+ ZeroStack *stack = thread->zero_stack();
+ intptr_t *locals = stack->sp();
+
+ // Drop into the slow path if we need a safepoint check
+ if (SafepointSynchronize::do_call_back()) {
+ normal_entry(method, 0, THREAD);
+ return;
+ }
+
+ // Load the object pointer and drop into the slow path
+ // if we have a NullPointerException
+ oop object = LOCALS_OBJECT(0);
+ if (object == NULL) {
+ normal_entry(method, 0, THREAD);
+ return;
+ }
+
+ // Read the field index from the bytecode, which looks like this:
+ // 0: aload_0
+ // 1: getfield
+ // 2: index
+ // 3: index
+ // 4: ireturn/areturn
+ // NB this is not raw bytecode: index is in machine order
+ u1 *code = method->code_base();
+ assert(code[0] == Bytecodes::_aload_0 &&
+ code[1] == Bytecodes::_getfield &&
+ (code[4] == Bytecodes::_ireturn ||
+ code[4] == Bytecodes::_areturn), "should do");
+ u2 index = Bytes::get_native_u2(&code[2]);
+
+ // Get the entry from the constant pool cache, and drop into
+ // the slow path if it has not been resolved
+ constantPoolCacheOop cache = method->constants()->cache();
+ ConstantPoolCacheEntry* entry = cache->entry_at(index);
+ if (!entry->is_resolved(Bytecodes::_getfield)) {
+ normal_entry(method, 0, THREAD);
+ return;
+ }
+
+ // Get the result and push it onto the stack
+ switch (entry->flag_state()) {
+ case ltos:
+ case dtos:
+ if (stack->available_words() < 1) {
+ Unimplemented();
+ }
+ stack->alloc(wordSize);
+ break;
+ }
+ if (entry->is_volatile()) {
+ switch (entry->flag_state()) {
+ case ctos:
+ SET_LOCALS_INT(object->char_field_acquire(entry->f2()), 0);
+ break;
+
+ case btos:
+ SET_LOCALS_INT(object->byte_field_acquire(entry->f2()), 0);
+ break;
+
+ case stos:
+ SET_LOCALS_INT(object->short_field_acquire(entry->f2()), 0);
+ break;
+
+ case itos:
+ SET_LOCALS_INT(object->int_field_acquire(entry->f2()), 0);
+ break;
+
+ case ltos:
+ SET_LOCALS_LONG(object->long_field_acquire(entry->f2()), 0);
+ break;
+
+ case ftos:
+ SET_LOCALS_FLOAT(object->float_field_acquire(entry->f2()), 0);
+ break;
+
+ case dtos:
+ SET_LOCALS_DOUBLE(object->double_field_acquire(entry->f2()), 0);
+ break;
+
+ case atos:
+ SET_LOCALS_OBJECT(object->obj_field_acquire(entry->f2()), 0);
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+ }
+ else {
+ switch (entry->flag_state()) {
+ case ctos:
+ SET_LOCALS_INT(object->char_field(entry->f2()), 0);
+ break;
+
+ case btos:
+ SET_LOCALS_INT(object->byte_field(entry->f2()), 0);
+ break;
+
+ case stos:
+ SET_LOCALS_INT(object->short_field(entry->f2()), 0);
+ break;
+
+ case itos:
+ SET_LOCALS_INT(object->int_field(entry->f2()), 0);
+ break;
+
+ case ltos:
+ SET_LOCALS_LONG(object->long_field(entry->f2()), 0);
+ break;
+
+ case ftos:
+ SET_LOCALS_FLOAT(object->float_field(entry->f2()), 0);
+ break;
+
+ case dtos:
+ SET_LOCALS_DOUBLE(object->double_field(entry->f2()), 0);
+ break;
+
+ case atos:
+ SET_LOCALS_OBJECT(object->obj_field(entry->f2()), 0);
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+ }
+}
+
+void CppInterpreter::empty_entry(methodOop method, intptr_t UNUSED, TRAPS) {
+ JavaThread *thread = (JavaThread *) THREAD;
+ ZeroStack *stack = thread->zero_stack();
+
+ // Drop into the slow path if we need a safepoint check
+ if (SafepointSynchronize::do_call_back()) {
+ normal_entry(method, 0, THREAD);
+ return;
+ }
+
+ // Pop our parameters
+ stack->set_sp(stack->sp() + method->size_of_parameters());
+}
+
+bool CppInterpreter::stack_overflow_imminent(JavaThread *thread) {
+ // How is the ABI stack?
+ address stack_top = thread->stack_base() - thread->stack_size();
+ int free_stack = os::current_stack_pointer() - stack_top;
+ if (free_stack < StackShadowPages * os::vm_page_size()) {
+ return true;
+ }
+
+ // How is the Zero stack?
+ // Throwing a StackOverflowError involves a VM call, which means
+ // we need a frame on the stack. We should be checking here to
+ // ensure that methods we call have enough room to install the
+ // largest possible frame, but that's more than twice the size
+ // of the entire Zero stack we get by default, so we just check
+ // we have *some* space instead...
+ free_stack = thread->zero_stack()->available_words() * wordSize;
+ if (free_stack < StackShadowPages * os::vm_page_size()) {
+ return true;
+ }
+
+ return false;
+}
+
+InterpreterFrame *InterpreterFrame::build(ZeroStack* stack,
+ const methodOop method,
+ JavaThread* thread) {
+ int monitor_words =
+ method->is_synchronized() ? frame::interpreter_frame_monitor_size() : 0;
+ int stack_words = method->is_native() ? 0 : method->max_stack();
+
+ if (header_words + monitor_words + stack_words > stack->available_words()) {
+ Unimplemented();
+ }
+
+ intptr_t *locals;
+ if (method->is_native())
+ locals = stack->sp() + (method->size_of_parameters() - 1);
+ else
+ locals = stack->sp() + (method->max_locals() - 1);
+
+ stack->push(0); // next_frame, filled in later
+ intptr_t *fp = stack->sp();
+ assert(fp - stack->sp() == next_frame_off, "should be");
+
+ stack->push(INTERPRETER_FRAME);
+ assert(fp - stack->sp() == frame_type_off, "should be");
+
+ interpreterState istate =
+ (interpreterState) stack->alloc(sizeof(BytecodeInterpreter));
+ assert(fp - stack->sp() == istate_off, "should be");
+
+ istate->set_locals(locals);
+ istate->set_method(method);
+ istate->set_self_link(istate);
+ istate->set_prev_link(NULL);
+ istate->set_thread(thread);
+ istate->set_bcp(method->is_native() ? NULL : method->code_base());
+ istate->set_constants(method->constants()->cache());
+ istate->set_msg(BytecodeInterpreter::method_entry);
+ istate->set_oop_temp(NULL);
+ istate->set_mdx(NULL);
+ istate->set_callee(NULL);
+
+ istate->set_monitor_base((BasicObjectLock *) stack->sp());
+ if (method->is_synchronized()) {
+ BasicObjectLock *monitor =
+ (BasicObjectLock *) stack->alloc(monitor_words * wordSize);
+ oop object;
+ if (method->is_static())
+ object = method->constants()->pool_holder()->klass_part()->java_mirror();
+ else
+ object = (oop) locals[0];
+ monitor->set_obj(object);
+ }
+
+ istate->set_stack_base(stack->sp());
+ istate->set_stack(stack->sp() - 1);
+ if (stack_words)
+ stack->alloc(stack_words * wordSize);
+ istate->set_stack_limit(stack->sp() - 1);
+
+ return (InterpreterFrame *) fp;
+}
+
+int AbstractInterpreter::BasicType_as_index(BasicType type) {
+ int i = 0;
+ switch (type) {
+ case T_BOOLEAN: i = 0; break;
+ case T_CHAR : i = 1; break;
+ case T_BYTE : i = 2; break;
+ case T_SHORT : i = 3; break;
+ case T_INT : i = 4; break;
+ case T_LONG : i = 5; break;
+ case T_VOID : i = 6; break;
+ case T_FLOAT : i = 7; break;
+ case T_DOUBLE : i = 8; break;
+ case T_OBJECT : i = 9; break;
+ case T_ARRAY : i = 9; break;
+ default : ShouldNotReachHere();
+ }
+ assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers,
+ "index out of bounds");
+ return i;
+}
+
+BasicType CppInterpreter::result_type_of(methodOop method) {
+ BasicType t;
+ switch (method->result_index()) {
+ case 0 : t = T_BOOLEAN; break;
+ case 1 : t = T_CHAR; break;
+ case 2 : t = T_BYTE; break;
+ case 3 : t = T_SHORT; break;
+ case 4 : t = T_INT; break;
+ case 5 : t = T_LONG; break;
+ case 6 : t = T_VOID; break;
+ case 7 : t = T_FLOAT; break;
+ case 8 : t = T_DOUBLE; break;
+ case 9 : t = T_OBJECT; break;
+ default: ShouldNotReachHere();
+ }
+ assert(AbstractInterpreter::BasicType_as_index(t) == method->result_index(),
+ "out of step with AbstractInterpreter::BasicType_as_index");
+ return t;
+}
+
+address InterpreterGenerator::generate_empty_entry() {
+ if (!UseFastEmptyMethods)
+ return NULL;
+
+ return generate_entry((address) CppInterpreter::empty_entry);
+}
+
+address InterpreterGenerator::generate_accessor_entry() {
+ if (!UseFastAccessorMethods)
+ return NULL;
+
+ return generate_entry((address) CppInterpreter::accessor_entry);
+}
+
+address InterpreterGenerator::generate_native_entry(bool synchronized) {
+ assert(synchronized == false, "should be");
+
+ return generate_entry((address) CppInterpreter::native_entry);
+}
+
+address InterpreterGenerator::generate_normal_entry(bool synchronized) {
+ assert(synchronized == false, "should be");
+
+ return generate_entry((address) CppInterpreter::normal_entry);
+}
+
+address AbstractInterpreterGenerator::generate_method_entry(
+ AbstractInterpreter::MethodKind kind) {
+ address entry_point = NULL;
+
+ switch (kind) {
+ case Interpreter::zerolocals:
+ case Interpreter::zerolocals_synchronized:
+ break;
+
+ case Interpreter::native:
+ entry_point = ((InterpreterGenerator*) this)->generate_native_entry(false);
+ break;
+
+ case Interpreter::native_synchronized:
+ entry_point = ((InterpreterGenerator*) this)->generate_native_entry(false);
+ break;
+
+ case Interpreter::empty:
+ entry_point = ((InterpreterGenerator*) this)->generate_empty_entry();
+ break;
+
+ case Interpreter::accessor:
+ entry_point = ((InterpreterGenerator*) this)->generate_accessor_entry();
+ break;
+
+ case Interpreter::abstract:
+ entry_point = ((InterpreterGenerator*) this)->generate_abstract_entry();
+ break;
+
+ case Interpreter::method_handle:
+ entry_point = ((InterpreterGenerator*) this)->generate_method_handle_entry();
+ break;
+
+ case Interpreter::java_lang_math_sin:
+ case Interpreter::java_lang_math_cos:
+ case Interpreter::java_lang_math_tan:
+ case Interpreter::java_lang_math_abs:
+ case Interpreter::java_lang_math_log:
+ case Interpreter::java_lang_math_log10:
+ case Interpreter::java_lang_math_sqrt:
+ entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind);
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+
+ if (entry_point == NULL)
+ entry_point = ((InterpreterGenerator*) this)->generate_normal_entry(false);
+
+ return entry_point;
+}
+
+InterpreterGenerator::InterpreterGenerator(StubQueue* code)
+ : CppInterpreterGenerator(code) {
+ generate_all();
+}
+
+// Deoptimization helpers
+
+InterpreterFrame *InterpreterFrame::build(ZeroStack* stack, int size) {
+ int size_in_words = size >> LogBytesPerWord;
+ assert(size_in_words * wordSize == size, "unaligned");
+ assert(size_in_words >= header_words, "too small");
+
+ if (size_in_words > stack->available_words()) {
+ Unimplemented();
+ }
+
+ stack->push(0); // next_frame, filled in later
+ intptr_t *fp = stack->sp();
+ assert(fp - stack->sp() == next_frame_off, "should be");
+
+ stack->push(INTERPRETER_FRAME);
+ assert(fp - stack->sp() == frame_type_off, "should be");
+
+ interpreterState istate =
+ (interpreterState) stack->alloc(sizeof(BytecodeInterpreter));
+ assert(fp - stack->sp() == istate_off, "should be");
+ istate->set_self_link(NULL); // mark invalid
+
+ stack->alloc((size_in_words - header_words) * wordSize);
+
+ return (InterpreterFrame *) fp;
+}
+
+int AbstractInterpreter::layout_activation(methodOop method,
+ int tempcount,
+ int popframe_extra_args,
+ int moncount,
+ int callee_param_count,
+ int callee_locals,
+ frame* caller,
+ frame* interpreter_frame,
+ bool is_top_frame) {
+ assert(popframe_extra_args == 0, "what to do?");
+ assert(!is_top_frame || (!callee_locals && !callee_param_count),
+ "top frame should have no caller")
+
+ // This code must exactly match what InterpreterFrame::build
+ // does (the full InterpreterFrame::build, that is, not the
+ // one that creates empty frames for the deoptimizer).
+ //
+ // If interpreter_frame is not NULL then it will be filled in.
+ // It's size is determined by a previous call to this method,
+ // so it should be correct.
+ //
+ // Note that tempcount is the current size of the expression
+ // stack. For top most frames we will allocate a full sized
+ // expression stack and not the trimmed version that non-top
+ // frames have.
+
+ int header_words = InterpreterFrame::header_words;
+ int monitor_words = moncount * frame::interpreter_frame_monitor_size();
+ int stack_words = is_top_frame ? method->max_stack() : tempcount;
+ int callee_extra_locals = callee_locals - callee_param_count;
+
+ if (interpreter_frame) {
+ intptr_t *locals = interpreter_frame->sp() + method->max_locals();
+ interpreterState istate = interpreter_frame->get_interpreterState();
+ intptr_t *monitor_base = (intptr_t*) istate;
+ intptr_t *stack_base = monitor_base - monitor_words;
+ intptr_t *stack = stack_base - tempcount - 1;
+
+ BytecodeInterpreter::layout_interpreterState(istate,
+ caller,
+ NULL,
+ method,
+ locals,
+ stack,
+ stack_base,
+ monitor_base,
+ NULL,
+ is_top_frame);
+ }
+ return header_words + monitor_words + stack_words + callee_extra_locals;
+}
+
+void BytecodeInterpreter::layout_interpreterState(interpreterState istate,
+ frame* caller,
+ frame* current,
+ methodOop method,
+ intptr_t* locals,
+ intptr_t* stack,
+ intptr_t* stack_base,
+ intptr_t* monitor_base,
+ intptr_t* frame_bottom,
+ bool is_top_frame) {
+ istate->set_locals(locals);
+ istate->set_method(method);
+ istate->set_self_link(istate);
+ istate->set_prev_link(NULL);
+ // thread will be set by a hacky repurposing of frame::patch_pc()
+ // bcp will be set by vframeArrayElement::unpack_on_stack()
+ istate->set_constants(method->constants()->cache());
+ istate->set_msg(BytecodeInterpreter::method_resume);
+ istate->set_bcp_advance(0);
+ istate->set_oop_temp(NULL);
+ istate->set_mdx(NULL);
+ if (caller->is_interpreted_frame()) {
+ interpreterState prev = caller->get_interpreterState();
+ prev->set_callee(method);
+ if (*prev->bcp() == Bytecodes::_invokeinterface)
+ prev->set_bcp_advance(5);
+ else
+ prev->set_bcp_advance(3);
+ }
+ istate->set_callee(NULL);
+ istate->set_monitor_base((BasicObjectLock *) monitor_base);
+ istate->set_stack_base(stack_base);
+ istate->set_stack(stack);
+ istate->set_stack_limit(stack_base - method->max_stack() - 1);
+}
+
+address CppInterpreter::return_entry(TosState state, int length) {
+ ShouldNotCallThis();
+}
+
+address CppInterpreter::deopt_entry(TosState state, int length) {
+ return NULL;
+}
+
+// Helper for (runtime) stack overflow checks
+
+int AbstractInterpreter::size_top_interpreter_activation(methodOop method) {
+ return 0;
+}
+
+// Helper for figuring out if frames are interpreter frames
+
+bool CppInterpreter::contains(address pc) {
+#ifdef PRODUCT
+ ShouldNotCallThis();
+#else
+ return false; // make frame::print_value_on work
+#endif // !PRODUCT
+}
+
+// Result handlers and convertors
+
+address CppInterpreterGenerator::generate_result_handler_for(
+ BasicType type) {
+ assembler()->advance(1);
+ return ShouldNotCallThisStub();
+}
+
+address CppInterpreterGenerator::generate_tosca_to_stack_converter(
+ BasicType type) {
+ assembler()->advance(1);
+ return ShouldNotCallThisStub();
+}
+
+address CppInterpreterGenerator::generate_stack_to_stack_converter(
+ BasicType type) {
+ assembler()->advance(1);
+ return ShouldNotCallThisStub();
+}
+
+address CppInterpreterGenerator::generate_stack_to_native_abi_converter(
+ BasicType type) {
+ assembler()->advance(1);
+ return ShouldNotCallThisStub();
+}
+
+#endif // CC_INTERP
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/cppInterpreter_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/cppInterpreter_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2010 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ protected:
+ // Size of interpreter code
+ const static int InterpreterCodeSize = 6 * K;
+
+ public:
+ // Method entries
+ static void normal_entry(methodOop method, intptr_t UNUSED, TRAPS);
+ static void native_entry(methodOop method, intptr_t UNUSED, TRAPS);
+ static void accessor_entry(methodOop method, intptr_t UNUSED, TRAPS);
+ static void empty_entry(methodOop method, intptr_t UNUSED, TRAPS);
+
+ public:
+ // Main loop of normal_entry
+ static void main_loop(int recurse, TRAPS);
+
+ private:
+ // Stack overflow checks
+ static bool stack_overflow_imminent(JavaThread *thread);
+
+ private:
+ // Fast result type determination
+ static BasicType result_type_of(methodOop method);
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/debug_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/debug_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_debug_zero.cpp.incl"
+
+void pd_ps(frame f) {
+ ShouldNotCallThis();
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/depChecker_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/depChecker_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/depChecker_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/depChecker_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/disassembler_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/disassembler_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/disassembler_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/disassembler_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// The disassembler prints out zero code annotated
+// with Java specific information.
+
+ static int pd_instruction_alignment() {
+ ShouldNotCallThis();
+ }
+
+ static const char* pd_cpu_opts() {
+ ShouldNotCallThis();
+ }
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/dump_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/dump_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_dump_zero.cpp.incl"
+
+void CompactingPermGenGen::generate_vtable_methods(void** vtbl_list,
+ void** vtable,
+ char** md_top,
+ char* md_end,
+ char** mc_top,
+ char* mc_end) {
+ ShouldNotCallThis();
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/entryFrame_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/entryFrame_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// | ... |
+// +--------------------+ ------------------
+// | parameter n-1 | low addresses
+// | ... |
+// | parameter 0 |
+// | call_wrapper |
+// | frame_type |
+// | next_frame | high addresses
+// +--------------------+ ------------------
+// | ... |
+
+class EntryFrame : public ZeroFrame {
+ private:
+ EntryFrame() : ZeroFrame() {
+ ShouldNotCallThis();
+ }
+
+ protected:
+ enum Layout {
+ call_wrapper_off = jf_header_words,
+ header_words
+ };
+
+ public:
+ static EntryFrame *build(ZeroStack* stack,
+ const intptr_t* parameters,
+ int parameter_words,
+ JavaCallWrapper* call_wrapper);
+ public:
+ JavaCallWrapper *call_wrapper() const {
+ return (JavaCallWrapper *) value_of_word(call_wrapper_off);
+ }
+
+ public:
+ void identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const;
+};
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/entry_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/entry_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+class ZeroEntry {
+ public:
+ ZeroEntry() {
+ ShouldNotCallThis();
+ }
+
+ private:
+ address _entry_point;
+
+ public:
+ address entry_point() const {
+ return _entry_point;
+ }
+ void set_entry_point(address entry_point) {
+ _entry_point = entry_point;
+ }
+
+ private:
+ typedef void (*NormalEntryFunc)(methodOop method,
+ intptr_t base_pc,
+ TRAPS);
+ typedef void (*OSREntryFunc)(methodOop method,
+ address osr_buf,
+ intptr_t base_pc,
+ TRAPS);
+
+ public:
+ void invoke(methodOop method, TRAPS) const {
+ ((NormalEntryFunc) entry_point())(method, (intptr_t) this, THREAD);
+ }
+ void invoke_osr(methodOop method, address osr_buf, TRAPS) const {
+ ((OSREntryFunc) entry_point())(method, osr_buf, (intptr_t) this, THREAD);
+ }
+
+ public:
+ static ByteSize entry_point_offset() {
+ return byte_offset_of(ZeroEntry, _entry_point);
+ }
+};
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/fakeStubFrame_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/fakeStubFrame_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// | ... |
+// +--------------------+ ------------------
+// | frame_type | low addresses
+// | next_frame | high addresses
+// +--------------------+ ------------------
+// | ... |
+
+class FakeStubFrame : public ZeroFrame {
+ private:
+ FakeStubFrame() : ZeroFrame() {
+ ShouldNotCallThis();
+ }
+
+ protected:
+ enum Layout {
+ header_words = jf_header_words
+ };
+
+ public:
+ static FakeStubFrame *build(ZeroStack* stack);
+
+ public:
+ void identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const {}
+};
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/frame_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/frame_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,397 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_frame_zero.cpp.incl"
+
+#ifdef ASSERT
+void RegisterMap::check_location_valid() {
+ ShouldNotCallThis();
+}
+#endif
+
+bool frame::is_interpreted_frame() const {
+ return zeroframe()->is_interpreter_frame();
+}
+
+frame frame::sender_for_entry_frame(RegisterMap *map) const {
+ assert(zeroframe()->is_entry_frame(), "wrong type of frame");
+ assert(map != NULL, "map must be set");
+ assert(!entry_frame_is_first(), "next Java fp must be non zero");
+ assert(entry_frame_call_wrapper()->anchor()->last_Java_sp() == sender_sp(),
+ "sender should be next Java frame");
+ map->clear();
+ assert(map->include_argument_oops(), "should be set by clear");
+ return frame(sender_sp(), sp() + 1);
+}
+
+frame frame::sender_for_nonentry_frame(RegisterMap *map) const {
+ assert(zeroframe()->is_interpreter_frame() ||
+ zeroframe()->is_shark_frame() ||
+ zeroframe()->is_fake_stub_frame(), "wrong type of frame");
+ return frame(sender_sp(), sp() + 1);
+}
+
+frame frame::sender(RegisterMap* map) const {
+ // Default is not to follow arguments; the various
+ // sender_for_xxx methods update this accordingly.
+ map->set_include_argument_oops(false);
+
+ if (is_entry_frame())
+ return sender_for_entry_frame(map);
+ else
+ return sender_for_nonentry_frame(map);
+}
+
+#ifdef CC_INTERP
+BasicObjectLock* frame::interpreter_frame_monitor_begin() const {
+ return get_interpreterState()->monitor_base();
+}
+
+BasicObjectLock* frame::interpreter_frame_monitor_end() const {
+ return (BasicObjectLock*) get_interpreterState()->stack_base();
+}
+#endif // CC_INTERP
+
+void frame::patch_pc(Thread* thread, address pc) {
+ // We borrow this call to set the thread pointer in the interpreter
+ // state; the hook to set up deoptimized frames isn't supplied it.
+ assert(pc == NULL, "should be");
+ get_interpreterState()->set_thread((JavaThread *) thread);
+}
+
+bool frame::safe_for_sender(JavaThread *thread) {
+ ShouldNotCallThis();
+}
+
+void frame::pd_gc_epilog() {
+}
+
+bool frame::is_interpreted_frame_valid(JavaThread *thread) const {
+ ShouldNotCallThis();
+}
+
+BasicType frame::interpreter_frame_result(oop* oop_result,
+ jvalue* value_result) {
+ assert(is_interpreted_frame(), "interpreted frame expected");
+ methodOop method = interpreter_frame_method();
+ BasicType type = method->result_type();
+ intptr_t* tos_addr = (intptr_t *) interpreter_frame_tos_address();
+ oop obj;
+
+ switch (type) {
+ case T_VOID:
+ break;
+ case T_BOOLEAN:
+ value_result->z = *(jboolean *) tos_addr;
+ break;
+ case T_BYTE:
+ value_result->b = *(jbyte *) tos_addr;
+ break;
+ case T_CHAR:
+ value_result->c = *(jchar *) tos_addr;
+ break;
+ case T_SHORT:
+ value_result->s = *(jshort *) tos_addr;
+ break;
+ case T_INT:
+ value_result->i = *(jint *) tos_addr;
+ break;
+ case T_LONG:
+ value_result->j = *(jlong *) tos_addr;
+ break;
+ case T_FLOAT:
+ value_result->f = *(jfloat *) tos_addr;
+ break;
+ case T_DOUBLE:
+ value_result->d = *(jdouble *) tos_addr;
+ break;
+
+ case T_OBJECT:
+ case T_ARRAY:
+ if (method->is_native()) {
+ obj = get_interpreterState()->oop_temp();
+ }
+ else {
+ oop* obj_p = (oop *) tos_addr;
+ obj = (obj_p == NULL) ? (oop) NULL : *obj_p;
+ }
+ assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");
+ *oop_result = obj;
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+
+ return type;
+}
+
+int frame::frame_size(RegisterMap* map) const {
+#ifdef PRODUCT
+ ShouldNotCallThis();
+#else
+ return 0; // make javaVFrame::print_value work
+#endif // PRODUCT
+}
+
+intptr_t* frame::interpreter_frame_tos_at(jint offset) const {
+ int index = (Interpreter::expr_offset_in_bytes(offset) / wordSize);
+ return &interpreter_frame_tos_address()[index];
+}
+
+void frame::zero_print_on_error(int frame_index,
+ outputStream* st,
+ char* buf,
+ int buflen) const {
+ // Divide the buffer between the field and the value
+ buflen >>= 1;
+ char *fieldbuf = buf;
+ char *valuebuf = buf + buflen;
+
+ // Print each word of the frame
+ for (intptr_t *addr = fp(); addr <= sp(); addr++) {
+ int offset = sp() - addr;
+
+ // Fill in default values, then try and improve them
+ snprintf(fieldbuf, buflen, "word[%d]", offset);
+ snprintf(valuebuf, buflen, PTR_FORMAT, *addr);
+ zeroframe()->identify_word(frame_index, offset, fieldbuf, valuebuf, buflen);
+ fieldbuf[buflen - 1] = '\0';
+ valuebuf[buflen - 1] = '\0';
+
+ // Print the result
+ st->print_cr(" " PTR_FORMAT ": %-21s = %s", addr, fieldbuf, valuebuf);
+ }
+}
+
+void ZeroFrame::identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const {
+ switch (offset) {
+ case next_frame_off:
+ strncpy(fieldbuf, "next_frame", buflen);
+ break;
+
+ case frame_type_off:
+ strncpy(fieldbuf, "frame_type", buflen);
+ if (is_entry_frame())
+ strncpy(valuebuf, "ENTRY_FRAME", buflen);
+ else if (is_interpreter_frame())
+ strncpy(valuebuf, "INTERPRETER_FRAME", buflen);
+ else if (is_shark_frame())
+ strncpy(valuebuf, "SHARK_FRAME", buflen);
+ else if (is_fake_stub_frame())
+ strncpy(valuebuf, "FAKE_STUB_FRAME", buflen);
+ break;
+
+ default:
+ if (is_entry_frame()) {
+ as_entry_frame()->identify_word(
+ frame_index, offset, fieldbuf, valuebuf, buflen);
+ }
+ else if (is_interpreter_frame()) {
+ as_interpreter_frame()->identify_word(
+ frame_index, offset, fieldbuf, valuebuf, buflen);
+ }
+ else if (is_shark_frame()) {
+ as_shark_frame()->identify_word(
+ frame_index, offset, fieldbuf, valuebuf, buflen);
+ }
+ else if (is_fake_stub_frame()) {
+ as_fake_stub_frame()->identify_word(
+ frame_index, offset, fieldbuf, valuebuf, buflen);
+ }
+ }
+}
+
+void EntryFrame::identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const {
+ switch (offset) {
+ case call_wrapper_off:
+ strncpy(fieldbuf, "call_wrapper", buflen);
+ break;
+
+ default:
+ snprintf(fieldbuf, buflen, "local[%d]", offset - 3);
+ }
+}
+
+void InterpreterFrame::identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const {
+ interpreterState istate = interpreter_state();
+ bool is_valid = istate->self_link() == istate;
+ intptr_t *addr = addr_of_word(offset);
+
+ // Fixed part
+ if (addr >= (intptr_t *) istate) {
+ const char *field = istate->name_of_field_at_address((address) addr);
+ if (field) {
+ if (is_valid && !strcmp(field, "_method")) {
+ istate->method()->name_and_sig_as_C_string(valuebuf, buflen);
+ }
+ else if (is_valid && !strcmp(field, "_bcp") && istate->bcp()) {
+ snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)",
+ (intptr_t) istate->bcp(),
+ istate->method()->bci_from(istate->bcp()));
+ }
+ snprintf(fieldbuf, buflen, "%sistate->%s",
+ field[strlen(field) - 1] == ')' ? "(": "", field);
+ }
+ else if (addr == (intptr_t *) istate) {
+ strncpy(fieldbuf, "(vtable for istate)", buflen);
+ }
+ return;
+ }
+
+ // Variable part
+ if (!is_valid)
+ return;
+
+ // JNI stuff
+ if (istate->method()->is_native() && addr < istate->stack_base()) {
+ address hA = istate->method()->signature_handler();
+ if (hA != NULL) {
+ if (hA != (address) InterpreterRuntime::slow_signature_handler) {
+ InterpreterRuntime::SignatureHandler *handler =
+ InterpreterRuntime::SignatureHandler::from_handlerAddr(hA);
+
+ intptr_t *params = istate->stack_base() - handler->argument_count();
+ if (addr >= params) {
+ int param = addr - params;
+ const char *desc = "";
+ if (param == 0)
+ desc = " (JNIEnv)";
+ else if (param == 1) {
+ if (istate->method()->is_static())
+ desc = " (mirror)";
+ else
+ desc = " (this)";
+ }
+ snprintf(fieldbuf, buflen, "parameter[%d]%s", param, desc);
+ return;
+ }
+
+ for (int i = 0; i < handler->argument_count(); i++) {
+ if (params[i] == (intptr_t) addr) {
+ snprintf(fieldbuf, buflen, "unboxed parameter[%d]", i);
+ return;
+ }
+ }
+ }
+ }
+ return;
+ }
+
+ // Monitors and stack
+ identify_vp_word(frame_index, addr,
+ (intptr_t *) istate->monitor_base(),
+ istate->stack_base(),
+ fieldbuf, buflen);
+}
+
+void SharkFrame::identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const {
+ // Fixed part
+ switch (offset) {
+ case pc_off:
+ strncpy(fieldbuf, "pc", buflen);
+ if (method()->is_oop()) {
+ nmethod *code = method()->code();
+ if (code && code->pc_desc_at(pc())) {
+ SimpleScopeDesc ssd(code, pc());
+ snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)",
+ (intptr_t) pc(), ssd.bci());
+ }
+ }
+ return;
+
+ case unextended_sp_off:
+ strncpy(fieldbuf, "unextended_sp", buflen);
+ return;
+
+ case method_off:
+ strncpy(fieldbuf, "method", buflen);
+ if (method()->is_oop()) {
+ method()->name_and_sig_as_C_string(valuebuf, buflen);
+ }
+ return;
+
+ case oop_tmp_off:
+ strncpy(fieldbuf, "oop_tmp", buflen);
+ return;
+ }
+
+ // Variable part
+ if (method()->is_oop()) {
+ identify_vp_word(frame_index, addr_of_word(offset),
+ addr_of_word(header_words + 1),
+ unextended_sp() + method()->max_stack(),
+ fieldbuf, buflen);
+ }
+}
+
+void ZeroFrame::identify_vp_word(int frame_index,
+ intptr_t* addr,
+ intptr_t* monitor_base,
+ intptr_t* stack_base,
+ char* fieldbuf,
+ int buflen) const {
+ // Monitors
+ if (addr >= stack_base && addr < monitor_base) {
+ int monitor_size = frame::interpreter_frame_monitor_size();
+ int last_index = (monitor_base - stack_base) / monitor_size - 1;
+ int index = last_index - (addr - stack_base) / monitor_size;
+ intptr_t monitor = (intptr_t) (
+ (BasicObjectLock *) monitor_base - 1 - index);
+ intptr_t offset = (intptr_t) addr - monitor;
+
+ if (offset == BasicObjectLock::obj_offset_in_bytes())
+ snprintf(fieldbuf, buflen, "monitor[%d]->_obj", index);
+ else if (offset == BasicObjectLock::lock_offset_in_bytes())
+ snprintf(fieldbuf, buflen, "monitor[%d]->_lock", index);
+
+ return;
+ }
+
+ // Expression stack
+ if (addr < stack_base) {
+ snprintf(fieldbuf, buflen, "%s[%d]",
+ frame_index == 0 ? "stack_word" : "local",
+ (int) (stack_base - addr - 1));
+ return;
+ }
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/frame_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/frame_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// A frame represents a physical stack frame on the Zero stack.
+
+ public:
+ enum {
+ pc_return_offset = 0
+ };
+
+ // Constructor
+ public:
+ frame(intptr_t* sp, intptr_t* fp);
+
+ // The sp of a Zero frame is the address of the highest word in
+ // that frame. We keep track of the lowest address too, so the
+ // boundaries of the frame are available for debug printing.
+ private:
+ intptr_t* _fp;
+
+ public:
+ intptr_t* fp() const {
+ return _fp;
+ }
+
+#ifdef CC_INTERP
+ inline interpreterState get_interpreterState() const;
+#endif // CC_INTERP
+
+ public:
+ const ZeroFrame *zeroframe() const {
+ return (ZeroFrame *) sp();
+ }
+
+ const EntryFrame *zero_entryframe() const {
+ return zeroframe()->as_entry_frame();
+ }
+ const InterpreterFrame *zero_interpreterframe() const {
+ return zeroframe()->as_interpreter_frame();
+ }
+ const SharkFrame *zero_sharkframe() const {
+ return zeroframe()->as_shark_frame();
+ }
+
+ public:
+ frame sender_for_nonentry_frame(RegisterMap* map) const;
+
+ public:
+ void zero_print_on_error(int index,
+ outputStream* st,
+ char* buf,
+ int buflen) const;
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/frame_zero.inline.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/frame_zero.inline.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// Constructors
+
+inline frame::frame() {
+ _sp = NULL;
+ _fp = NULL;
+ _pc = NULL;
+ _cb = NULL;
+ _deopt_state = unknown;
+}
+
+inline frame::frame(intptr_t* sp, intptr_t* fp) {
+ _sp = sp;
+ _fp = fp;
+ switch (zeroframe()->type()) {
+ case ZeroFrame::ENTRY_FRAME:
+ _pc = StubRoutines::call_stub_return_pc();
+ _cb = NULL;
+ break;
+
+ case ZeroFrame::INTERPRETER_FRAME:
+ _pc = NULL;
+ _cb = NULL;
+ break;
+
+ case ZeroFrame::SHARK_FRAME:
+ _pc = zero_sharkframe()->pc();
+ _cb = CodeCache::find_blob_unsafe(pc());
+ break;
+
+ case ZeroFrame::FAKE_STUB_FRAME:
+ _pc = NULL;
+ _cb = NULL;
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+ _deopt_state = not_deoptimized;
+}
+
+// Accessors
+
+inline intptr_t* frame::sender_sp() const {
+ return (intptr_t *) zeroframe()->next();
+}
+
+inline intptr_t* frame::link() const {
+ ShouldNotCallThis();
+}
+
+#ifdef CC_INTERP
+inline interpreterState frame::get_interpreterState() const {
+ return zero_interpreterframe()->interpreter_state();
+}
+
+inline intptr_t** frame::interpreter_frame_locals_addr() const {
+ return &(get_interpreterState()->_locals);
+}
+
+inline intptr_t* frame::interpreter_frame_bcx_addr() const {
+ return (intptr_t*) &(get_interpreterState()->_bcp);
+}
+
+inline constantPoolCacheOop* frame::interpreter_frame_cache_addr() const {
+ return &(get_interpreterState()->_constants);
+}
+
+inline methodOop* frame::interpreter_frame_method_addr() const {
+ return &(get_interpreterState()->_method);
+}
+
+inline intptr_t* frame::interpreter_frame_mdx_addr() const {
+ return (intptr_t*) &(get_interpreterState()->_mdx);
+}
+
+inline intptr_t* frame::interpreter_frame_tos_address() const {
+ return get_interpreterState()->_stack + 1;
+}
+#endif // CC_INTERP
+
+inline int frame::interpreter_frame_monitor_size() {
+ return BasicObjectLock::size();
+}
+
+inline intptr_t* frame::interpreter_frame_expression_stack() const {
+ intptr_t* monitor_end = (intptr_t*) interpreter_frame_monitor_end();
+ return monitor_end - 1;
+}
+
+inline jint frame::interpreter_frame_expression_stack_direction() {
+ return -1;
+}
+
+// Return a unique id for this frame. The id must have a value where
+// we can distinguish identity and younger/older relationship. NULL
+// represents an invalid (incomparable) frame.
+inline intptr_t* frame::id() const {
+ return sp();
+}
+
+inline JavaCallWrapper* frame::entry_frame_call_wrapper() const {
+ return zero_entryframe()->call_wrapper();
+}
+
+inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) {
+ ShouldNotCallThis();
+}
+
+inline oop frame::saved_oop_result(RegisterMap* map) const {
+ ShouldNotCallThis();
+}
+
+inline bool frame::is_older(intptr_t* id) const {
+ ShouldNotCallThis();
+}
+
+inline intptr_t* frame::entry_frame_argument_at(int offset) const {
+ ShouldNotCallThis();
+}
+
+inline intptr_t* frame::unextended_sp() const {
+ if (zeroframe()->is_shark_frame())
+ return zero_sharkframe()->unextended_sp();
+ else
+ return (intptr_t *) -1;
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/globalDefinitions_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/globalDefinitions_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/globals_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/globals_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// Set the default values for platform dependent flags used by the
+// runtime system. See globals.hpp for details of what they do.
+
+define_pd_global(bool, ConvertSleepToYield, true);
+define_pd_global(bool, ShareVtableStubs, true);
+define_pd_global(bool, CountInterpCalls, true);
+define_pd_global(bool, NeedsDeoptSuspend, false);
+
+define_pd_global(bool, ImplicitNullChecks, true);
+define_pd_global(bool, UncommonNullCast, true);
+
+define_pd_global(intx, CodeEntryAlignment, 32);
+define_pd_global(intx, InlineFrequencyCount, 100);
+define_pd_global(intx, PreInflateSpin, 10);
+
+define_pd_global(intx, StackYellowPages, 2);
+define_pd_global(intx, StackRedPages, 1);
+define_pd_global(intx, StackShadowPages, 5 LP64_ONLY(+1) DEBUG_ONLY(+3));
+
+define_pd_global(bool, RewriteBytecodes, true);
+define_pd_global(bool, RewriteFrequentPairs, true);
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/icBuffer_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/icBuffer_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_icBuffer_zero.cpp.incl"
+
+int InlineCacheBuffer::ic_stub_code_size() {
+ // NB set this once the functions below are implemented
+ return 4;
+}
+
+void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin,
+ oop cached_oop,
+ address entry_point) {
+ // NB ic_stub_code_size() must return the size of the code we generate
+ ShouldNotCallThis();
+}
+
+address InlineCacheBuffer::ic_buffer_entry_point(address code_begin) {
+ // NB ic_stub_code_size() must return the size of the code we generate
+ ShouldNotCallThis();
+}
+
+oop InlineCacheBuffer::ic_buffer_cached_oop(address code_begin) {
+ // NB ic_stub_code_size() must return the size of the code we generate
+ ShouldNotCallThis();
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/icache_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/icache_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_icache_zero.cpp.incl"
+
+void ICacheStubGenerator::generate_icache_flush(
+ ICache::flush_icache_stub_t* flush_icache_stub) {
+ ShouldNotCallThis();
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/icache_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/icache_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// Interface for updating the instruction cache. Whenever the VM
+// modifies code, part of the processor instruction cache potentially
+// has to be flushed. This implementation is empty: Zero never deals
+// with code, and LLVM handles cache flushing for Shark.
+
+class ICache : public AbstractICache {
+ public:
+ static void initialize() {}
+ static void invalidate_word(address addr) {}
+ static void invalidate_range(address start, int nbytes) {}
+};
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/interp_masm_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/interp_masm_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/interp_masm_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/interp_masm_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file specializes the assember with interpreter-specific macros
+
+class InterpreterMacroAssembler : public MacroAssembler {
+ public:
+ InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {}
+
+ public:
+ RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr,
+ Register tmp,
+ int offset) {
+ ShouldNotCallThis();
+ }
+};
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/interpreterFrame_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/interpreterFrame_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#ifdef CC_INTERP
+// | ... |
+// +--------------------+ ------------------
+// | stack slot n-1 | low addresses
+// | ... |
+// | stack slot 0 |
+// | monitor 0 (maybe) |
+// | ... |
+// | interpreter state |
+// | ... |
+// | frame_type |
+// | next_frame | high addresses
+// +--------------------+ ------------------
+// | ... |
+
+class InterpreterFrame : public ZeroFrame {
+ friend class AbstractInterpreter;
+
+ private:
+ InterpreterFrame() : ZeroFrame() {
+ ShouldNotCallThis();
+ }
+
+ protected:
+ enum Layout {
+ istate_off = jf_header_words +
+ (align_size_up_(sizeof(BytecodeInterpreter),
+ wordSize) >> LogBytesPerWord) - 1,
+ header_words
+ };
+
+ public:
+ static InterpreterFrame *build(ZeroStack* stack,
+ const methodOop method,
+ JavaThread* thread);
+ static InterpreterFrame *build(ZeroStack* stack, int size);
+
+ public:
+ interpreterState interpreter_state() const {
+ return (interpreterState) addr_of_word(istate_off);
+ }
+
+ public:
+ void identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const;
+};
+#endif // CC_INTERP
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/interpreterGenerator_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/interpreterGenerator_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ // Generation of Interpreter
+ //
+ friend class AbstractInterpreterGenerator;
+
+ private:
+ address generate_normal_entry(bool synchronized);
+ address generate_native_entry(bool synchronized);
+ address generate_abstract_entry();
+ address generate_math_entry(AbstractInterpreter::MethodKind kind);
+ address generate_empty_entry();
+ address generate_accessor_entry();
+ address generate_method_handle_entry();
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/interpreterRT_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/interpreterRT_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_interpreterRT_zero.cpp.incl"
+
+void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_int() {
+ push(T_INT);
+ _cif->nargs++;
+}
+
+void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_long() {
+ push(T_LONG);
+ _cif->nargs++;
+}
+
+void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_float() {
+ push(T_FLOAT);
+ _cif->nargs++;
+}
+
+void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_double() {
+ push(T_DOUBLE);
+ _cif->nargs++;
+}
+
+void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_object() {
+ push(T_OBJECT);
+ _cif->nargs++;
+}
+
+void InterpreterRuntime::SignatureHandlerGeneratorBase::push(BasicType type) {
+ ffi_type *ftype;
+ switch (type) {
+ case T_VOID:
+ ftype = &ffi_type_void;
+ break;
+
+ case T_BOOLEAN:
+ ftype = &ffi_type_uint8;
+ break;
+
+ case T_CHAR:
+ ftype = &ffi_type_uint16;
+ break;
+
+ case T_BYTE:
+ ftype = &ffi_type_sint8;
+ break;
+
+ case T_SHORT:
+ ftype = &ffi_type_sint16;
+ break;
+
+ case T_INT:
+ ftype = &ffi_type_sint32;
+ break;
+
+ case T_LONG:
+ ftype = &ffi_type_sint64;
+ break;
+
+ case T_FLOAT:
+ ftype = &ffi_type_float;
+ break;
+
+ case T_DOUBLE:
+ ftype = &ffi_type_double;
+ break;
+
+ case T_OBJECT:
+ case T_ARRAY:
+ ftype = &ffi_type_pointer;
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+ push((intptr_t) ftype);
+}
+
+// For fast signature handlers the "signature handler" is generated
+// into a temporary buffer. It is then copied to its final location,
+// and pd_set_handler is called on it. We have this two stage thing
+// to accomodate this.
+
+void InterpreterRuntime::SignatureHandlerGeneratorBase::generate(
+ uint64_t fingerprint) {
+
+ // Build the argument types list
+ pass_object();
+ if (method()->is_static())
+ pass_object();
+ iterate(fingerprint);
+
+ // Tack on the result type
+ push(method()->result_type());
+}
+
+void InterpreterRuntime::SignatureHandler::finalize() {
+ ffi_status status =
+ ffi_prep_cif(cif(),
+ FFI_DEFAULT_ABI,
+ argument_count(),
+ result_type(),
+ argument_types());
+
+ assert(status == FFI_OK, "should be");
+}
+
+IRT_ENTRY(address,
+ InterpreterRuntime::slow_signature_handler(JavaThread* thread,
+ methodOop method,
+ intptr_t* unused1,
+ intptr_t* unused2))
+ ZeroStack *stack = thread->zero_stack();
+
+ int required_words =
+ (align_size_up(sizeof(ffi_cif), wordSize) >> LogBytesPerWord) +
+ (method->is_static() ? 2 : 1) + method->size_of_parameters() + 1;
+ if (required_words > stack->available_words()) {
+ Unimplemented();
+ }
+
+ intptr_t *buf = (intptr_t *) stack->alloc(required_words * wordSize);
+ SlowSignatureHandlerGenerator sshg(methodHandle(thread, method), buf);
+ sshg.generate(UCONST64(-1));
+
+ SignatureHandler *handler = sshg.handler();
+ handler->finalize();
+
+ return (address) handler;
+IRT_END
+
+void SignatureHandlerLibrary::pd_set_handler(address handlerAddr) {
+ InterpreterRuntime::SignatureHandler *handler =
+ InterpreterRuntime::SignatureHandler::from_handlerAddr(handlerAddr);
+
+ handler->finalize();
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/interpreterRT_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/interpreterRT_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+class SignatureHandler {
+ public:
+ static SignatureHandler *from_handlerAddr(address handlerAddr) {
+ return (SignatureHandler *) handlerAddr;
+ }
+
+ public:
+ ffi_cif* cif() const {
+ return (ffi_cif *) this;
+ }
+
+ int argument_count() const {
+ return cif()->nargs;
+ }
+
+ ffi_type** argument_types() const {
+ return (ffi_type**) (cif() + 1);
+ }
+
+ ffi_type* argument_type(int i) const {
+ return argument_types()[i];
+ }
+
+ ffi_type* result_type() const {
+ return *(argument_types() + argument_count());
+ }
+
+ protected:
+ friend class InterpreterRuntime;
+ friend class SignatureHandlerLibrary;
+
+ void finalize();
+};
+
+class SignatureHandlerGeneratorBase : public NativeSignatureIterator {
+ private:
+ ffi_cif* _cif;
+
+ protected:
+ SignatureHandlerGeneratorBase(methodHandle method, ffi_cif *cif)
+ : NativeSignatureIterator(method), _cif(cif) {
+ _cif->nargs = 0;
+ }
+
+ ffi_cif *cif() const {
+ return _cif;
+ }
+
+ public:
+ void generate(uint64_t fingerprint);
+
+ private:
+ void pass_int();
+ void pass_long();
+ void pass_float();
+ void pass_double();
+ void pass_object();
+
+ private:
+ void push(BasicType type);
+ virtual void push(intptr_t value) = 0;
+};
+
+class SignatureHandlerGenerator : public SignatureHandlerGeneratorBase {
+ private:
+ CodeBuffer* _cb;
+
+ public:
+ SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer)
+ : SignatureHandlerGeneratorBase(method, (ffi_cif *) buffer->code_end()),
+ _cb(buffer) {
+ _cb->set_code_end((address) (cif() + 1));
+ }
+
+ private:
+ void push(intptr_t value) {
+ intptr_t *dst = (intptr_t *) _cb->code_end();
+ _cb->set_code_end((address) (dst + 1));
+ *dst = value;
+ }
+};
+
+class SlowSignatureHandlerGenerator : public SignatureHandlerGeneratorBase {
+ private:
+ intptr_t *_dst;
+
+ public:
+ SlowSignatureHandlerGenerator(methodHandle method, intptr_t* buf)
+ : SignatureHandlerGeneratorBase(method, (ffi_cif *) buf) {
+ _dst = (intptr_t *) (cif() + 1);
+ }
+
+ private:
+ void push(intptr_t value) {
+ *(_dst++) = value;
+ }
+
+ public:
+ SignatureHandler *handler() const {
+ return (SignatureHandler *) cif();
+ }
+};
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/interpreter_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/interpreter_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_interpreter_zero.cpp.incl"
+
+address AbstractInterpreterGenerator::generate_slow_signature_handler() {
+ _masm->advance(1);
+ return (address) InterpreterRuntime::slow_signature_handler;
+}
+
+address InterpreterGenerator::generate_math_entry(
+ AbstractInterpreter::MethodKind kind) {
+ if (!InlineIntrinsics)
+ return NULL;
+
+ Unimplemented();
+}
+
+address InterpreterGenerator::generate_abstract_entry() {
+ return ShouldNotCallThisEntry();
+}
+
+address InterpreterGenerator::generate_method_handle_entry() {
+ return ShouldNotCallThisEntry();
+}
+
+bool AbstractInterpreter::can_be_compiled(methodHandle m) {
+ return true;
+}
+
+int AbstractInterpreter::size_activation(methodOop method,
+ int tempcount,
+ int popframe_extra_args,
+ int moncount,
+ int callee_param_count,
+ int callee_locals,
+ bool is_top_frame) {
+ return layout_activation(method,
+ tempcount,
+ popframe_extra_args,
+ moncount,
+ callee_param_count,
+ callee_locals,
+ (frame*) NULL,
+ (frame*) NULL,
+ is_top_frame);
+}
+
+void Deoptimization::unwind_callee_save_values(frame* f,
+ vframeArray* vframe_array) {
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/interpreter_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/interpreter_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ public:
+ static void invoke_method(methodOop method, address entry_point, TRAPS) {
+ ((ZeroEntry *) entry_point)->invoke(method, THREAD);
+ }
+ static void invoke_osr(methodOop method,
+ address entry_point,
+ address osr_buf,
+ TRAPS) {
+ ((ZeroEntry *) entry_point)->invoke_osr(method, osr_buf, THREAD);
+ }
+
+ public:
+ static int expr_index_at(int i) {
+ return stackElementWords() * i;
+ }
+ static int expr_tag_index_at(int i) {
+ assert(TaggedStackInterpreter, "should not call this");
+ Unimplemented();
+ }
+
+ static int expr_offset_in_bytes(int i) {
+ return stackElementSize() * i;
+ }
+ static int expr_tag_offset_in_bytes(int i) {
+ assert(TaggedStackInterpreter, "should not call this");
+ Unimplemented();
+ }
+
+ static int local_index_at(int i) {
+ assert(i <= 0, "local direction already negated");
+ return stackElementWords() * i + (value_offset_in_bytes() / wordSize);
+ }
+ static int local_tag_index_at(int i) {
+ assert(TaggedStackInterpreter, "should not call this");
+ Unimplemented();
+ }
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/javaFrameAnchor_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/javaFrameAnchor_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ public:
+ // Each arch must define reset, save, restore
+ // These are used by objects that only care about:
+ // 1 - initializing a new state (thread creation, javaCalls)
+ // 2 - saving a current state (javaCalls)
+ // 3 - restoring an old state (javaCalls)
+
+ void clear() {
+ // clearing _last_Java_sp must be first
+ _last_Java_sp = NULL;
+ // fence?
+ _last_Java_pc = NULL;
+ }
+
+ void copy(JavaFrameAnchor* src) {
+ // In order to make sure the transition state is valid for "this"
+ // We must clear _last_Java_sp before copying the rest of the new
+ // data
+ //
+ // Hack Alert: Temporary bugfix for 4717480/4721647 To act like
+ // previous version (pd_cache_state) don't NULL _last_Java_sp
+ // unless the value is changing
+ //
+ if (_last_Java_sp != src->_last_Java_sp)
+ _last_Java_sp = NULL;
+
+ _last_Java_pc = src->_last_Java_pc;
+ // Must be last so profiler will always see valid frame if
+ // has_last_frame() is true
+ _last_Java_sp = src->_last_Java_sp;
+ }
+
+ bool walkable() {
+ return true;
+ }
+
+ void make_walkable(JavaThread* thread) {
+ // nothing to do
+ }
+
+ intptr_t* last_Java_sp() const {
+ return _last_Java_sp;
+ }
+
+ void set_last_Java_sp(intptr_t* sp) {
+ _last_Java_sp = sp;
+ }
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/jniFastGetField_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/jniFastGetField_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_jniFastGetField_zero.cpp.incl"
+
+address JNI_FastGetField::generate_fast_get_boolean_field() {
+ return (address) -1;
+}
+
+address JNI_FastGetField::generate_fast_get_byte_field() {
+ return (address) -1;
+}
+
+address JNI_FastGetField::generate_fast_get_char_field() {
+ return (address) -1;
+}
+
+address JNI_FastGetField::generate_fast_get_short_field() {
+ return (address) -1;
+}
+
+address JNI_FastGetField::generate_fast_get_int_field() {
+ return (address) -1;
+}
+
+address JNI_FastGetField::generate_fast_get_long_field() {
+ return (address) -1;
+}
+
+address JNI_FastGetField::generate_fast_get_float_field() {
+ return (address) -1;
+}
+
+address JNI_FastGetField::generate_fast_get_double_field() {
+ return (address) -1;
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/jniTypes_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/jniTypes_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,108 @@
+/*
+ * Copyright 1998-2002 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.
+ *
+ */
+
+// This file holds platform-dependent routines used to write primitive jni
+// types to the array of arguments passed into JavaCalls::call
+
+class JNITypes : AllStatic {
+ // These functions write a java primitive type (in native format)
+ // to a java stack slot array to be passed as an argument to JavaCalls:calls.
+ // I.e., they are functionally 'push' operations if they have a 'pos'
+ // formal parameter. Note that jlong's and jdouble's are written
+ // _in reverse_ of the order in which they appear in the interpreter
+ // stack. This is because call stubs (see stubGenerator_zero.cpp)
+ // reverse the argument list constructed by JavaCallArguments (see
+ // javaCalls.hpp).
+
+private:
+ // Helper routines.
+ static inline void put_int2 (jint *from, jint *to) { to[0] = from[0]; to[1] = from[1]; }
+ static inline void put_int2 (jint *from, jint *to, int& pos) { put_int2 (from, (jint *)((intptr_t *)to + pos)); pos += 2; }
+ static inline void put_int2r(jint *from, jint *to) { to[0] = from[1]; to[1] = from[0]; }
+ static inline void put_int2r(jint *from, jint *to, int& pos) { put_int2r(from, (jint *)((intptr_t *)to + pos)); pos += 2; }
+
+public:
+ // Ints are stored in native format in one JavaCallArgument slot at *to.
+ static inline void put_int(jint from, intptr_t *to) { *(jint *)(to + 0 ) = from; }
+ static inline void put_int(jint from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = from; }
+ static inline void put_int(jint *from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = *from; }
+
+#ifdef _LP64
+ // Longs are stored in native format in one JavaCallArgument slot at *(to+1).
+ static inline void put_long(jlong from, intptr_t *to) { *(jlong *)(to + 1 + 0) = from; }
+ static inline void put_long(jlong from, intptr_t *to, int& pos) { *(jlong *)(to + 1 + pos) = from; pos += 2; }
+ static inline void put_long(jlong *from, intptr_t *to, int& pos) { *(jlong *)(to + 1 + pos) = *from; pos += 2; }
+#else
+ // Longs are stored in reversed native word format in two JavaCallArgument slots at *to.
+ // The high half is in *(to+1) and the low half in *to.
+ static inline void put_long(jlong from, intptr_t *to) { put_int2r((jint *)&from, (jint *)to); }
+ static inline void put_long(jlong from, intptr_t *to, int& pos) { put_int2r((jint *)&from, (jint *)to, pos); }
+ static inline void put_long(jlong *from, intptr_t *to, int& pos) { put_int2r((jint *) from, (jint *)to, pos); }
+#endif
+
+ // Oops are stored in native format in one JavaCallArgument slot at *to.
+ static inline void put_obj(oop from, intptr_t *to) { *(oop *)(to + 0 ) = from; }
+ static inline void put_obj(oop from, intptr_t *to, int& pos) { *(oop *)(to + pos++) = from; }
+ static inline void put_obj(oop *from, intptr_t *to, int& pos) { *(oop *)(to + pos++) = *from; }
+
+ // Floats are stored in native format in one JavaCallArgument slot at *to.
+ static inline void put_float(jfloat from, intptr_t *to) { *(jfloat *)(to + 0 ) = from; }
+ static inline void put_float(jfloat from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = from; }
+ static inline void put_float(jfloat *from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = *from; }
+
+#ifdef _LP64
+ // Doubles are stored in native word format in one JavaCallArgument slot at *(to+1).
+ static inline void put_double(jdouble from, intptr_t *to) { *(jdouble *)(to + 1 + 0) = from; }
+ static inline void put_double(jdouble from, intptr_t *to, int& pos) { *(jdouble *)(to + 1 + pos) = from; pos += 2; }
+ static inline void put_double(jdouble *from, intptr_t *to, int& pos) { *(jdouble *)(to + 1 + pos) = *from; pos += 2; }
+#else
+ // Doubles are stored in reversed native word format in two JavaCallArgument slots at *to.
+ static inline void put_double(jdouble from, intptr_t *to) { put_int2r((jint *)&from, (jint *)to); }
+ static inline void put_double(jdouble from, intptr_t *to, int& pos) { put_int2r((jint *)&from, (jint *)to, pos); }
+ static inline void put_double(jdouble *from, intptr_t *to, int& pos) { put_int2r((jint *) from, (jint *)to, pos); }
+#endif
+
+ // The get_xxx routines, on the other hand, actually _do_ fetch
+ // java primitive types from the interpreter stack.
+ static inline jint get_int(intptr_t *from) { return *(jint *)from; }
+
+#ifdef _LP64
+ static inline jlong get_long(intptr_t *from) { return *(jlong *)from; }
+#else
+ static inline jlong get_long(intptr_t *from) { return ((jlong)(*( signed int *)((jint *)from )) << 32) |
+ ((jlong)(*(unsigned int *)((jint *)from + 1)) << 0); }
+#endif
+
+ static inline oop get_obj(intptr_t *from) { return *(oop *)from; }
+ static inline jfloat get_float(intptr_t *from) { return *(jfloat *)from; }
+
+#ifdef _LP64
+ static inline jdouble get_double(intptr_t *from) { return *(jdouble *)from; }
+#else
+ static inline jdouble get_double(intptr_t *from) { jlong jl = ((jlong)(*( signed int *)((jint *)from )) << 32) |
+ ((jlong)(*(unsigned int *)((jint *)from + 1)) << 0);
+ return *(jdouble *)&jl; }
+#endif
+
+};
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/jni_zero.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/jni_zero.h Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+#define JNIEXPORT
+#define JNIIMPORT
+#define JNICALL
+
+typedef int jint;
+typedef signed char jbyte;
+
+#ifdef _LP64
+typedef long jlong;
+#else
+typedef long long jlong;
+#endif
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/methodHandles_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/methodHandles_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/nativeInst_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/nativeInst_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_nativeInst_zero.cpp.incl"
+
+// This method is called by nmethod::make_not_entrant_or_zombie to
+// insert a jump to SharedRuntime::get_handle_wrong_method_stub()
+// (dest) at the start of a compiled method (verified_entry) to avoid
+// a race where a method is invoked while being made non-entrant.
+//
+// In Shark, verified_entry is a pointer to a SharkEntry. We can
+// handle this simply by changing it's entry point to point at the
+// interpreter. This only works because the interpreter and Shark
+// calling conventions are the same.
+
+void NativeJump::patch_verified_entry(address entry,
+ address verified_entry,
+ address dest) {
+ assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "should be");
+
+#ifdef CC_INTERP
+ ((ZeroEntry*) verified_entry)->set_entry_point(
+ (address) CppInterpreter::normal_entry);
+#else
+ Unimplemented();
+#endif // CC_INTERP
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/nativeInst_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/nativeInst_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// We have interfaces for the following instructions:
+// - NativeInstruction
+// - - NativeCall
+// - - NativeMovConstReg
+// - - NativeMovConstRegPatching
+// - - NativeJump
+// - - NativeIllegalOpCode
+// - - NativeReturn
+// - - NativeReturnX (return with argument)
+// - - NativePushConst
+// - - NativeTstRegMem
+
+// The base class for different kinds of native instruction abstractions.
+// Provides the primitive operations to manipulate code relative to this.
+
+class NativeInstruction VALUE_OBJ_CLASS_SPEC {
+ public:
+ bool is_jump() {
+ ShouldNotCallThis();
+ }
+
+ bool is_safepoint_poll() {
+ ShouldNotCallThis();
+ }
+};
+
+inline NativeInstruction* nativeInstruction_at(address address) {
+ ShouldNotCallThis();
+}
+
+class NativeCall : public NativeInstruction {
+ public:
+ enum zero_specific_constants {
+ instruction_size = 0 // not used within the interpreter
+ };
+
+ address instruction_address() const {
+ ShouldNotCallThis();
+ }
+
+ address next_instruction_address() const {
+ ShouldNotCallThis();
+ }
+
+ address return_address() const {
+ ShouldNotCallThis();
+ }
+
+ address destination() const {
+ ShouldNotCallThis();
+ }
+
+ void set_destination_mt_safe(address dest) {
+ ShouldNotCallThis();
+ }
+
+ void verify_alignment() {
+ ShouldNotCallThis();
+ }
+
+ void verify() {
+ ShouldNotCallThis();
+ }
+
+ static bool is_call_before(address return_address) {
+ ShouldNotCallThis();
+ }
+};
+
+inline NativeCall* nativeCall_before(address return_address) {
+ ShouldNotCallThis();
+}
+
+inline NativeCall* nativeCall_at(address address) {
+ ShouldNotCallThis();
+}
+
+class NativeMovConstReg : public NativeInstruction {
+ public:
+ address next_instruction_address() const {
+ ShouldNotCallThis();
+ }
+
+ intptr_t data() const {
+ ShouldNotCallThis();
+ }
+
+ void set_data(intptr_t x) {
+ ShouldNotCallThis();
+ }
+};
+
+inline NativeMovConstReg* nativeMovConstReg_at(address address) {
+ ShouldNotCallThis();
+}
+
+class NativeMovRegMem : public NativeInstruction {
+ public:
+ int offset() const {
+ ShouldNotCallThis();
+ }
+
+ void set_offset(intptr_t x) {
+ ShouldNotCallThis();
+ }
+
+ void add_offset_in_bytes(int add_offset) {
+ ShouldNotCallThis();
+ }
+};
+
+inline NativeMovRegMem* nativeMovRegMem_at(address address) {
+ ShouldNotCallThis();
+}
+
+class NativeJump : public NativeInstruction {
+ public:
+ enum zero_specific_constants {
+ instruction_size = 0 // not used within the interpreter
+ };
+
+ address jump_destination() const {
+ ShouldNotCallThis();
+ }
+
+ void set_jump_destination(address dest) {
+ ShouldNotCallThis();
+ }
+
+ static void check_verified_entry_alignment(address entry,
+ address verified_entry) {
+ }
+
+ static void patch_verified_entry(address entry,
+ address verified_entry,
+ address dest);
+};
+
+inline NativeJump* nativeJump_at(address address) {
+ ShouldNotCallThis();
+}
+
+class NativeGeneralJump : public NativeInstruction {
+ public:
+ address jump_destination() const {
+ ShouldNotCallThis();
+ }
+
+ static void insert_unconditional(address code_pos, address entry) {
+ ShouldNotCallThis();
+ }
+
+ static void replace_mt_safe(address instr_addr, address code_buffer) {
+ ShouldNotCallThis();
+ }
+};
+
+inline NativeGeneralJump* nativeGeneralJump_at(address address) {
+ ShouldNotCallThis();
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/registerMap_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/registerMap_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1998-2007 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.
+ *
+ */
+
+ // machine-dependent implemention for register maps
+ friend class frame;
+
+ private:
+ // This is the hook for finding a register in an "well-known" location,
+ // such as a register block of a predetermined format.
+ // Since there is none, we just return NULL.
+ // See registerMap_sparc.hpp for an example of grabbing registers
+ // from register save areas of a standard layout.
+ address pd_location(VMReg reg) const { return NULL; }
+
+ // no PD state to clear or copy:
+ void pd_clear() {}
+ void pd_initialize() {}
+ void pd_initialize_from(const RegisterMap* map) {}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/register_definitions_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/register_definitions_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/register_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/register_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_register_zero.cpp.incl"
+
+const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers;
+const int ConcreteRegisterImpl::max_fpr =
+ ConcreteRegisterImpl::max_gpr + FloatRegisterImpl::number_of_registers;
+
+const char* RegisterImpl::name() const {
+ ShouldNotCallThis();
+}
+
+const char* FloatRegisterImpl::name() const {
+ ShouldNotCallThis();
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/register_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/register_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+class VMRegImpl;
+typedef VMRegImpl* VMReg;
+
+// Use Register as shortcut
+class RegisterImpl;
+typedef RegisterImpl* Register;
+
+inline Register as_Register(int encoding) {
+ return (Register)(intptr_t) encoding;
+}
+
+// The implementation of integer registers for the zero architecture
+class RegisterImpl : public AbstractRegisterImpl {
+ public:
+ enum {
+ number_of_registers = 0
+ };
+
+ // construction
+ inline friend Register as_Register(int encoding);
+ VMReg as_VMReg();
+
+ // derived registers, offsets, and addresses
+ Register successor() const {
+ return as_Register(encoding() + 1);
+ }
+
+ // accessors
+ int encoding() const {
+ assert(is_valid(), "invalid register");
+ return (intptr_t)this;
+ }
+ bool is_valid() const {
+ return 0 <= (intptr_t) this && (intptr_t)this < number_of_registers;
+ }
+ const char* name() const;
+};
+
+// Use FloatRegister as shortcut
+class FloatRegisterImpl;
+typedef FloatRegisterImpl* FloatRegister;
+
+inline FloatRegister as_FloatRegister(int encoding) {
+ return (FloatRegister)(intptr_t) encoding;
+}
+
+// The implementation of floating point registers for the zero architecture
+class FloatRegisterImpl : public AbstractRegisterImpl {
+ public:
+ enum {
+ number_of_registers = 0
+ };
+
+ // construction
+ inline friend FloatRegister as_FloatRegister(int encoding);
+ VMReg as_VMReg();
+
+ // derived registers, offsets, and addresses
+ FloatRegister successor() const {
+ return as_FloatRegister(encoding() + 1);
+ }
+
+ // accessors
+ int encoding() const {
+ assert(is_valid(), "invalid register");
+ return (intptr_t)this;
+ }
+ bool is_valid() const {
+ return 0 <= (intptr_t) this && (intptr_t)this < number_of_registers;
+ }
+ const char* name() const;
+};
+
+class ConcreteRegisterImpl : public AbstractRegisterImpl {
+ public:
+ enum {
+ number_of_registers = RegisterImpl::number_of_registers +
+ FloatRegisterImpl::number_of_registers
+ };
+
+ static const int max_gpr;
+ static const int max_fpr;
+};
+
+CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1));
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/relocInfo_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/relocInfo_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_relocInfo_zero.cpp.incl"
+
+void Relocation::pd_set_data_value(address x, intptr_t o) {
+ ShouldNotCallThis();
+}
+
+address Relocation::pd_call_destination(address orig_addr) {
+ ShouldNotCallThis();
+}
+
+void Relocation::pd_set_call_destination(address x) {
+ ShouldNotCallThis();
+}
+
+address Relocation::pd_get_address_from_code() {
+ ShouldNotCallThis();
+}
+
+address* Relocation::pd_address_in_code() {
+ // Relocations in Shark are just stored directly
+ return (address *) addr();
+}
+
+int Relocation::pd_breakpoint_size() {
+ ShouldNotCallThis();
+}
+
+void Relocation::pd_swap_in_breakpoint(address x,
+ short* instrs,
+ int instrlen) {
+ ShouldNotCallThis();
+}
+
+void Relocation::pd_swap_out_breakpoint(address x,
+ short* instrs,
+ int instrlen) {
+ ShouldNotCallThis();
+}
+
+void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src,
+ CodeBuffer* dst) {
+ ShouldNotCallThis();
+}
+
+void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src,
+ CodeBuffer* dst) {
+ ShouldNotCallThis();
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/relocInfo_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/relocInfo_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ // machine-dependent parts of class relocInfo
+ private:
+ enum {
+ // these constants mean nothing without an assembler
+ offset_unit = 1,
+ format_width = 1
+ };
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/sharedRuntime_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/sharedRuntime_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharedRuntime_zero.cpp.incl"
+
+DeoptimizationBlob *SharedRuntime::_deopt_blob;
+SafepointBlob *SharedRuntime::_polling_page_safepoint_handler_blob;
+SafepointBlob *SharedRuntime::_polling_page_return_handler_blob;
+RuntimeStub *SharedRuntime::_wrong_method_blob;
+RuntimeStub *SharedRuntime::_ic_miss_blob;
+RuntimeStub *SharedRuntime::_resolve_opt_virtual_call_blob;
+RuntimeStub *SharedRuntime::_resolve_virtual_call_blob;
+RuntimeStub *SharedRuntime::_resolve_static_call_blob;
+
+int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
+ VMRegPair *regs,
+ int total_args_passed,
+ int is_outgoing) {
+ return 0;
+}
+
+AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(
+ MacroAssembler *masm,
+ int total_args_passed,
+ int comp_args_on_stack,
+ const BasicType *sig_bt,
+ const VMRegPair *regs,
+ AdapterFingerPrint *fingerprint) {
+ return AdapterHandlerLibrary::new_entry(
+ fingerprint,
+ ShouldNotCallThisStub(),
+ ShouldNotCallThisStub(),
+ ShouldNotCallThisStub());
+}
+
+nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
+ methodHandle method,
+ int total_in_args,
+ int comp_args_on_stack,
+ BasicType *in_sig_bt,
+ VMRegPair *in_regs,
+ BasicType ret_type) {
+#ifdef SHARK
+ return SharkCompiler::compiler()->generate_native_wrapper(masm,
+ method,
+ in_sig_bt,
+ ret_type);
+#else
+ ShouldNotCallThis();
+#endif // SHARK
+}
+
+int Deoptimization::last_frame_adjust(int callee_parameters,
+ int callee_locals) {
+ return 0;
+}
+
+uint SharedRuntime::out_preserve_stack_slots() {
+ ShouldNotCallThis();
+}
+
+static RuntimeStub* generate_empty_runtime_stub(const char* name) {
+ CodeBuffer buffer(name, 0, 0);
+ return RuntimeStub::new_runtime_stub(name, &buffer, 0, 0, NULL, false);
+}
+
+static SafepointBlob* generate_empty_safepoint_blob() {
+ CodeBuffer buffer("handler_blob", 0, 0);
+ return SafepointBlob::create(&buffer, NULL, 0);
+}
+
+void SharedRuntime::generate_stubs() {
+ _wrong_method_blob =
+ generate_empty_runtime_stub("wrong_method_stub");
+ _ic_miss_blob =
+ generate_empty_runtime_stub("ic_miss_stub");
+ _resolve_opt_virtual_call_blob =
+ generate_empty_runtime_stub("resolve_opt_virtual_call");
+ _resolve_virtual_call_blob =
+ generate_empty_runtime_stub("resolve_virtual_call");
+ _resolve_static_call_blob =
+ generate_empty_runtime_stub("resolve_static_call");
+
+ _polling_page_safepoint_handler_blob =
+ generate_empty_safepoint_blob();
+ _polling_page_return_handler_blob =
+ generate_empty_safepoint_blob();
+}
+
+int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
+ VMRegPair *regs,
+ int total_args_passed) {
+ ShouldNotCallThis();
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/sharkFrame_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/sharkFrame_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// | ... |
+// +--------------------+ ------------------
+// | stack slot n-1 | low addresses
+// | ... |
+// | stack slot 0 |
+// | monitor m-1 |
+// | ... |
+// | monitor 0 |
+// | oop_tmp |
+// | method |
+// | unextended_sp |
+// | pc |
+// | frame_type |
+// | next_frame | high addresses
+// +--------------------+ ------------------
+// | ... |
+
+class SharkFrame : public ZeroFrame {
+ friend class SharkStack;
+
+ private:
+ SharkFrame() : ZeroFrame() {
+ ShouldNotCallThis();
+ }
+
+ protected:
+ enum Layout {
+ pc_off = jf_header_words,
+ unextended_sp_off,
+ method_off,
+ oop_tmp_off,
+ header_words
+ };
+
+ public:
+ address pc() const {
+ return (address) value_of_word(pc_off);
+ }
+
+ intptr_t* unextended_sp() const {
+ return (intptr_t *) value_of_word(unextended_sp_off);
+ }
+
+ methodOop method() const {
+ return (methodOop) value_of_word(method_off);
+ }
+
+ public:
+ void identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const;
+};
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/stack_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/stack_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+class ZeroStack {
+ private:
+ intptr_t *_base; // the last available word
+ intptr_t *_top; // the word past the end of the stack
+ intptr_t *_sp; // the top word on the stack
+
+ public:
+ ZeroStack()
+ : _base(NULL), _top(NULL), _sp(NULL) {}
+
+ bool needs_setup() const {
+ return _base == NULL;
+ }
+
+ void setup(void *mem, size_t size) {
+ assert(needs_setup(), "already set up");
+ assert(!(size & WordAlignmentMask), "unaligned");
+
+ _base = (intptr_t *) mem;
+ _top = _base + (size >> LogBytesPerWord);
+ _sp = _top;
+ }
+ void teardown() {
+ assert(!needs_setup(), "not set up");
+ assert(_sp == _top, "stuff on stack at teardown");
+
+ _base = NULL;
+ _top = NULL;
+ _sp = NULL;
+ }
+
+ intptr_t *sp() const {
+ return _sp;
+ }
+ void set_sp(intptr_t *new_sp) {
+ assert(_top >= new_sp && new_sp >= _base, "bad stack pointer");
+ _sp = new_sp;
+ }
+
+ int available_words() const {
+ return _sp - _base;
+ }
+
+ void push(intptr_t value) {
+ assert(_sp > _base, "stack overflow");
+ *(--_sp) = value;
+ }
+ intptr_t pop() {
+ assert(_sp < _top, "stack underflow");
+ return *(_sp++);
+ }
+
+ void *alloc(size_t size) {
+ int count = align_size_up(size, wordSize) >> LogBytesPerWord;
+ assert(count <= available_words(), "stack overflow");
+ return _sp -= count;
+ }
+
+ public:
+ static ByteSize base_offset() {
+ return byte_offset_of(ZeroStack, _base);
+ }
+ static ByteSize top_offset() {
+ return byte_offset_of(ZeroStack, _top);
+ }
+ static ByteSize sp_offset() {
+ return byte_offset_of(ZeroStack, _sp);
+ }
+};
+
+
+class EntryFrame;
+class InterpreterFrame;
+class SharkFrame;
+class FakeStubFrame;
+
+//
+// | ... |
+// +--------------------+ ------------------
+// | ... | low addresses
+// | frame_type |
+// | next_frame | high addresses
+// +--------------------+ ------------------
+// | ... |
+
+class ZeroFrame {
+ friend class frame;
+ friend class ZeroStackPrinter;
+
+ protected:
+ ZeroFrame() {
+ ShouldNotCallThis();
+ }
+
+ enum Layout {
+ next_frame_off,
+ frame_type_off,
+ jf_header_words
+ };
+
+ enum FrameType {
+ ENTRY_FRAME = 1,
+ INTERPRETER_FRAME,
+ SHARK_FRAME,
+ FAKE_STUB_FRAME
+ };
+
+ protected:
+ intptr_t *addr_of_word(int offset) const {
+ return (intptr_t *) this - offset;
+ }
+ intptr_t value_of_word(int offset) const {
+ return *addr_of_word(offset);
+ }
+
+ public:
+ ZeroFrame *next() const {
+ return (ZeroFrame *) value_of_word(next_frame_off);
+ }
+
+ protected:
+ FrameType type() const {
+ return (FrameType) value_of_word(frame_type_off);
+ }
+
+ public:
+ bool is_entry_frame() const {
+ return type() == ENTRY_FRAME;
+ }
+ bool is_interpreter_frame() const {
+ return type() == INTERPRETER_FRAME;
+ }
+ bool is_shark_frame() const {
+ return type() == SHARK_FRAME;
+ }
+ bool is_fake_stub_frame() const {
+ return type() == FAKE_STUB_FRAME;
+ }
+
+ public:
+ EntryFrame *as_entry_frame() const {
+ assert(is_entry_frame(), "should be");
+ return (EntryFrame *) this;
+ }
+ InterpreterFrame *as_interpreter_frame() const {
+ assert(is_interpreter_frame(), "should be");
+ return (InterpreterFrame *) this;
+ }
+ SharkFrame *as_shark_frame() const {
+ assert(is_shark_frame(), "should be");
+ return (SharkFrame *) this;
+ }
+ FakeStubFrame *as_fake_stub_frame() const {
+ assert(is_fake_stub_frame(), "should be");
+ return (FakeStubFrame *) this;
+ }
+
+ public:
+ void identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const;
+
+ protected:
+ void identify_vp_word(int frame_index,
+ intptr_t* addr,
+ intptr_t* monitor_base,
+ intptr_t* stack_base,
+ char* fieldbuf,
+ int buflen) const;
+};
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/stubGenerator_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/stubGenerator_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_stubGenerator_zero.cpp.incl"
+
+// Declaration and definition of StubGenerator (no .hpp file).
+// For a more detailed description of the stub routine structure
+// see the comment in stubRoutines.hpp
+
+class StubGenerator: public StubCodeGenerator {
+ private:
+ // The call stub is used to call Java from C
+ static void call_stub(
+ JavaCallWrapper *call_wrapper,
+ intptr_t* result,
+ BasicType result_type,
+ methodOop method,
+ address entry_point,
+ intptr_t* parameters,
+ int parameter_words,
+ TRAPS) {
+ JavaThread *thread = (JavaThread *) THREAD;
+ ZeroStack *stack = thread->zero_stack();
+
+ // Make sure we have no pending exceptions
+ assert(!HAS_PENDING_EXCEPTION, "call_stub called with pending exception");
+
+ // Set up the stack if necessary
+ bool stack_needs_teardown = false;
+ if (stack->needs_setup()) {
+ size_t stack_used = thread->stack_base() - (address) &stack_used;
+ size_t stack_free = thread->stack_size() - stack_used;
+ size_t zero_stack_size = align_size_down(stack_free / 2, wordSize);
+
+ stack->setup(alloca(zero_stack_size), zero_stack_size);
+ stack_needs_teardown = true;
+ }
+
+ // Allocate and initialize our frame
+ thread->push_zero_frame(
+ EntryFrame::build(stack, parameters, parameter_words, call_wrapper));
+
+ // Make the call
+ Interpreter::invoke_method(method, entry_point, THREAD);
+
+ // Store result depending on type
+ if (!HAS_PENDING_EXCEPTION) {
+ switch (result_type) {
+ case T_INT:
+ *(jint *) result = *(jint *) stack->sp();
+ break;
+ case T_LONG:
+ *(jlong *) result = *(jlong *) stack->sp();
+ break;
+ case T_FLOAT:
+ *(jfloat *) result = *(jfloat *) stack->sp();
+ break;
+ case T_DOUBLE:
+ *(jdouble *) result = *(jdouble *) stack->sp();
+ break;
+ case T_OBJECT:
+ *(oop *) result = *(oop *) stack->sp();
+ break;
+ default:
+ ShouldNotReachHere();
+ }
+ }
+
+ // Unwind our frame
+ thread->pop_zero_frame();
+
+ // Tear down the stack if necessary
+ if (stack_needs_teardown)
+ stack->teardown();
+ }
+
+ // These stubs get called from some dumb test routine.
+ // I'll write them properly when they're called from
+ // something that's actually doing something.
+ static void fake_arraycopy_stub(address src, address dst, int count) {
+ assert(count == 0, "huh?");
+ }
+
+ void generate_arraycopy_stubs() {
+ // Call the conjoint generation methods immediately after
+ // the disjoint ones so that short branches from the former
+ // to the latter can be generated.
+ StubRoutines::_jbyte_disjoint_arraycopy = (address) fake_arraycopy_stub;
+ StubRoutines::_jbyte_arraycopy = (address) fake_arraycopy_stub;
+
+ StubRoutines::_jshort_disjoint_arraycopy = (address) fake_arraycopy_stub;
+ StubRoutines::_jshort_arraycopy = (address) fake_arraycopy_stub;
+
+ StubRoutines::_jint_disjoint_arraycopy = (address) fake_arraycopy_stub;
+ StubRoutines::_jint_arraycopy = (address) fake_arraycopy_stub;
+
+ StubRoutines::_jlong_disjoint_arraycopy = (address) fake_arraycopy_stub;
+ StubRoutines::_jlong_arraycopy = (address) fake_arraycopy_stub;
+
+ StubRoutines::_oop_disjoint_arraycopy = ShouldNotCallThisStub();
+ StubRoutines::_oop_arraycopy = ShouldNotCallThisStub();
+
+ StubRoutines::_checkcast_arraycopy = ShouldNotCallThisStub();
+ StubRoutines::_unsafe_arraycopy = ShouldNotCallThisStub();
+ StubRoutines::_generic_arraycopy = ShouldNotCallThisStub();
+
+ // We don't generate specialized code for HeapWord-aligned source
+ // arrays, so just use the code we've already generated
+ StubRoutines::_arrayof_jbyte_disjoint_arraycopy =
+ StubRoutines::_jbyte_disjoint_arraycopy;
+ StubRoutines::_arrayof_jbyte_arraycopy =
+ StubRoutines::_jbyte_arraycopy;
+
+ StubRoutines::_arrayof_jshort_disjoint_arraycopy =
+ StubRoutines::_jshort_disjoint_arraycopy;
+ StubRoutines::_arrayof_jshort_arraycopy =
+ StubRoutines::_jshort_arraycopy;
+
+ StubRoutines::_arrayof_jint_disjoint_arraycopy =
+ StubRoutines::_jint_disjoint_arraycopy;
+ StubRoutines::_arrayof_jint_arraycopy =
+ StubRoutines::_jint_arraycopy;
+
+ StubRoutines::_arrayof_jlong_disjoint_arraycopy =
+ StubRoutines::_jlong_disjoint_arraycopy;
+ StubRoutines::_arrayof_jlong_arraycopy =
+ StubRoutines::_jlong_arraycopy;
+
+ StubRoutines::_arrayof_oop_disjoint_arraycopy =
+ StubRoutines::_oop_disjoint_arraycopy;
+ StubRoutines::_arrayof_oop_arraycopy =
+ StubRoutines::_oop_arraycopy;
+ }
+
+ void generate_initial() {
+ // Generates all stubs and initializes the entry points
+
+ // entry points that exist in all platforms Note: This is code
+ // that could be shared among different platforms - however the
+ // benefit seems to be smaller than the disadvantage of having a
+ // much more complicated generator structure. See also comment in
+ // stubRoutines.hpp.
+
+ StubRoutines::_forward_exception_entry = ShouldNotCallThisStub();
+ StubRoutines::_call_stub_entry = (address) call_stub;
+ StubRoutines::_catch_exception_entry = ShouldNotCallThisStub();
+
+ // atomic calls
+ StubRoutines::_atomic_xchg_entry = ShouldNotCallThisStub();
+ StubRoutines::_atomic_xchg_ptr_entry = ShouldNotCallThisStub();
+ StubRoutines::_atomic_cmpxchg_entry = ShouldNotCallThisStub();
+ StubRoutines::_atomic_cmpxchg_ptr_entry = ShouldNotCallThisStub();
+ StubRoutines::_atomic_cmpxchg_long_entry = ShouldNotCallThisStub();
+ StubRoutines::_atomic_add_entry = ShouldNotCallThisStub();
+ StubRoutines::_atomic_add_ptr_entry = ShouldNotCallThisStub();
+ StubRoutines::_fence_entry = ShouldNotCallThisStub();
+
+ // amd64 does this here, sparc does it in generate_all()
+ StubRoutines::_handler_for_unsafe_access_entry =
+ ShouldNotCallThisStub();
+ }
+
+ void generate_all() {
+ // Generates all stubs and initializes the entry points
+
+ // These entry points require SharedInfo::stack0 to be set up in
+ // non-core builds and need to be relocatable, so they each
+ // fabricate a RuntimeStub internally.
+ StubRoutines::_throw_AbstractMethodError_entry =
+ ShouldNotCallThisStub();
+
+ StubRoutines::_throw_ArithmeticException_entry =
+ ShouldNotCallThisStub();
+
+ StubRoutines::_throw_NullPointerException_entry =
+ ShouldNotCallThisStub();
+
+ StubRoutines::_throw_NullPointerException_at_call_entry =
+ ShouldNotCallThisStub();
+
+ StubRoutines::_throw_StackOverflowError_entry =
+ ShouldNotCallThisStub();
+
+ // support for verify_oop (must happen after universe_init)
+ StubRoutines::_verify_oop_subroutine_entry =
+ ShouldNotCallThisStub();
+
+ // arraycopy stubs used by compilers
+ generate_arraycopy_stubs();
+ }
+
+ public:
+ StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) {
+ if (all) {
+ generate_all();
+ } else {
+ generate_initial();
+ }
+ }
+};
+
+void StubGenerator_generate(CodeBuffer* code, bool all) {
+ StubGenerator g(code, all);
+}
+
+EntryFrame *EntryFrame::build(ZeroStack* stack,
+ const intptr_t* parameters,
+ int parameter_words,
+ JavaCallWrapper* call_wrapper) {
+ if (header_words + parameter_words > stack->available_words()) {
+ Unimplemented();
+ }
+
+ stack->push(0); // next_frame, filled in later
+ intptr_t *fp = stack->sp();
+ assert(fp - stack->sp() == next_frame_off, "should be");
+
+ stack->push(ENTRY_FRAME);
+ assert(fp - stack->sp() == frame_type_off, "should be");
+
+ stack->push((intptr_t) call_wrapper);
+ assert(fp - stack->sp() == call_wrapper_off, "should be");
+
+ for (int i = 0; i < parameter_words; i++)
+ stack->push(parameters[i]);
+
+ return (EntryFrame *) fp;
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/stubRoutines_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/stubRoutines_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_stubRoutines_zero.cpp.incl"
+
+#ifdef IA32
+address StubRoutines::x86::_call_stub_compiled_return = NULL;
+#endif // IA32
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/stubRoutines_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/stubRoutines_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ // This file holds the platform specific parts of the StubRoutines
+ // definition. See stubRoutines.hpp for a description on how to
+ // extend it.
+
+ public:
+ static address call_stub_return_pc() {
+ return (address) -1;
+ }
+
+ static bool returns_to_call_stub(address return_pc) {
+ return return_pc == call_stub_return_pc();
+ }
+
+ enum platform_dependent_constants {
+ code_size1 = 0, // The assembler will fail with a guarantee
+ code_size2 = 0 // if these are too small. Simply increase
+ }; // them if that happens.
+
+#ifdef IA32
+ class x86 {
+ friend class VMStructs;
+
+ private:
+ static address _call_stub_compiled_return;
+ };
+#endif // IA32
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/templateInterpreterGenerator_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/templateInterpreterGenerator_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/templateInterpreter_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/templateInterpreter_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/templateInterpreter_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/templateInterpreter_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/templateTable_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/templateTable_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/templateTable_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/templateTable_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/vmStructs_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/vmStructs_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// These are the CPU-specific fields, types and integer
+// constants required by the Serviceability Agent. This file is
+// referenced by vmStructs.cpp.
+
+#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
+
+ /* NOTE that we do not use the last_entry() macro here; it is used */
+ /* in vmStructs__.hpp's VM_STRUCTS_OS_CPU macro (and must */
+ /* be present there) */
+
+#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
+
+ /* NOTE that we do not use the last_entry() macro here; it is used */
+ /* in vmStructs__.hpp's VM_TYPES_OS_CPU macro (and must */
+ /* be present there) */
+
+#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
+
+ /* NOTE that we do not use the last_entry() macro here; it is used */
+ /* in vmStructs__.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */
+ /* be present there) */
+
+#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
+
+ /* NOTE that we do not use the last_entry() macro here; it is used */
+ /* in vmStructs__.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */
+ /* be present there) */
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/vm_version_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/vm_version_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/vm_version_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/vm_version_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+class VM_Version : public Abstract_VM_Version {
+ public:
+ static const char* cpu_features() {
+ return "";
+ }
+};
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/vmreg_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/vmreg_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_vmreg_zero.cpp.incl"
+
+void VMRegImpl::set_regName() {
+ int i = 0;
+ Register reg = ::as_Register(0);
+ for ( ; i < ConcreteRegisterImpl::max_gpr ; ) {
+ regName[i++] = reg->name();
+ reg = reg->successor();
+ }
+ FloatRegister freg = ::as_FloatRegister(0);
+ for ( ; i < ConcreteRegisterImpl::max_fpr ; ) {
+ regName[i++] = freg->name();
+ freg = freg->successor();
+ }
+ assert(i == ConcreteRegisterImpl::number_of_registers, "fix this");
+}
+
+bool VMRegImpl::is_Register() {
+ return value() >= 0 &&
+ value() < ConcreteRegisterImpl::max_gpr;
+}
+
+bool VMRegImpl::is_FloatRegister() {
+ return value() >= ConcreteRegisterImpl::max_gpr &&
+ value() < ConcreteRegisterImpl::max_fpr;
+}
+
+Register VMRegImpl::as_Register() {
+ assert(is_Register(), "must be");
+ return ::as_Register(value());
+}
+
+FloatRegister VMRegImpl::as_FloatRegister() {
+ assert(is_FloatRegister(), "must be" );
+ return ::as_FloatRegister(value() - ConcreteRegisterImpl::max_gpr);
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/vmreg_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/vmreg_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2006 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.
+ *
+ */
+
+ bool is_Register();
+ Register as_Register();
+
+ bool is_FloatRegister();
+ FloatRegister as_FloatRegister();
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/vmreg_zero.inline.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/vmreg_zero.inline.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+inline VMReg RegisterImpl::as_VMReg() {
+ return VMRegImpl::as_VMReg(encoding());
+}
+
+inline VMReg FloatRegisterImpl::as_VMReg() {
+ return VMRegImpl::as_VMReg(encoding() + ConcreteRegisterImpl::max_gpr);
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/cpu/zero/vm/vtableStubs_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/zero/vm/vtableStubs_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_vtableStubs_zero.cpp.incl"
+
+VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
+ ShouldNotCallThis();
+}
+
+VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
+ ShouldNotCallThis();
+}
+
+int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
+ ShouldNotCallThis();
+}
+
+int VtableStub::pd_code_alignment() {
+ ShouldNotCallThis();
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/os/linux/vm/os_linux.cpp
--- a/src/os/linux/vm/os_linux.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/os/linux/vm/os_linux.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -22,6 +22,8 @@
*
*/
+# define __STDC_FORMAT_MACROS
+
// do not include precompiled header file
# include "incls/_os_linux.cpp.incl"
@@ -53,6 +55,8 @@
# include
# include
# include
+# include
+# include
#define MAX_PATH (2 * K)
@@ -176,7 +180,9 @@
#endif
// Cpu architecture string
-#if defined(IA64)
+#if defined(ZERO)
+static char cpu_arch[] = ZERO_LIBARCH;
+#elif defined(IA64)
static char cpu_arch[] = "ia64";
#elif defined(IA32)
static char cpu_arch[] = "i386";
@@ -221,8 +227,8 @@
"environment on Linux when /proc filesystem is not mounted.";
void os::Linux::initialize_system_info() {
- _processor_count = sysconf(_SC_NPROCESSORS_CONF);
- if (_processor_count == 1) {
+ set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
+ if (processor_count() == 1) {
pid_t pid = os::Linux::gettid();
char fname[32];
jio_snprintf(fname, sizeof(fname), "/proc/%d", pid);
@@ -234,7 +240,7 @@
}
}
_physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
- assert(_processor_count > 0, "linux error");
+ assert(processor_count() > 0, "linux error");
}
void os::init_system_properties_values() {
@@ -1743,7 +1749,14 @@
{EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
{EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"},
{EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},
- {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"}
+ {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
+ {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"},
+ {EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"},
+ {EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"},
+ {EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"},
+ {EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"},
+ {EM_PARISC, EM_PARISC, ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"},
+ {EM_68K, EM_68K, ELFCLASS32, ELFDATA2MSB, (char*)"M68k"}
};
#if (defined IA32)
@@ -1760,9 +1773,23 @@
static Elf32_Half running_arch_code=EM_PPC64;
#elif (defined __powerpc__)
static Elf32_Half running_arch_code=EM_PPC;
+ #elif (defined ARM)
+ static Elf32_Half running_arch_code=EM_ARM;
+ #elif (defined S390)
+ static Elf32_Half running_arch_code=EM_S390;
+ #elif (defined ALPHA)
+ static Elf32_Half running_arch_code=EM_ALPHA;
+ #elif (defined MIPSEL)
+ static Elf32_Half running_arch_code=EM_MIPS_RS3_LE;
+ #elif (defined PARISC)
+ static Elf32_Half running_arch_code=EM_PARISC;
+ #elif (defined MIPS)
+ static Elf32_Half running_arch_code=EM_MIPS;
+ #elif (defined M68K)
+ static Elf32_Half running_arch_code=EM_68K;
#else
#error Method os::dll_load requires that one of following is defined:\
- IA32, AMD64, IA64, __sparc, __powerpc__
+ IA32, AMD64, IA64, __sparc, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K
#endif
// Identify compatability class for VM's architecture and library's architecture
@@ -1794,10 +1821,12 @@
return NULL;
}
+#ifndef S390
if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");
return NULL;
}
+#endif // !S390
if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
if ( lib_arch.name!=NULL ) {
@@ -2467,6 +2496,91 @@
!= MAP_FAILED;
}
+// Linux uses a growable mapping for the stack, and if the mapping for
+// the stack guard pages is not removed when we detach a thread the
+// stack cannot grow beyond the pages where the stack guard was
+// mapped. If at some point later in the process the stack expands to
+// that point, the Linux kernel cannot expand the stack any further
+// because the guard pages are in the way, and a segfault occurs.
+//
+// However, it's essential not to split the stack region by unmapping
+// a region (leaving a hole) that's already part of the stack mapping,
+// so if the stack mapping has already grown beyond the guard pages at
+// the time we create them, we have to truncate the stack mapping.
+// So, we need to know the extent of the stack mapping when
+// create_stack_guard_pages() is called.
+
+// Find the bounds of the stack mapping. Return true for success.
+//
+// We only need this for stacks that are growable: at the time of
+// writing thread stacks don't use growable mappings (i.e. those
+// creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this
+// only applies to the main thread.
+static bool
+get_stack_bounds(uintptr_t *bottom, uintptr_t *top)
+{
+ FILE *f = fopen("/proc/self/maps", "r");
+ if (f == NULL)
+ return false;
+
+ while (!feof(f)) {
+ size_t dummy;
+ char *str = NULL;
+ ssize_t len = getline(&str, &dummy, f);
+ if (len == -1) {
+ fclose(f);
+ return false;
+ }
+
+ if (len > 0 && str[len-1] == '\n') {
+ str[len-1] = 0;
+ len--;
+ }
+
+ static const char *stack_str = "[stack]";
+ if (len > (ssize_t)strlen(stack_str)
+ && (strcmp(str + len - strlen(stack_str), stack_str) == 0)) {
+ if (sscanf(str, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) {
+ uintptr_t sp = (uintptr_t)__builtin_frame_address(0);
+ if (sp >= *bottom && sp <= *top) {
+ free(str);
+ fclose(f);
+ return true;
+ }
+ }
+ }
+ free(str);
+ }
+ fclose(f);
+ return false;
+}
+
+// If the (growable) stack mapping already extends beyond the point
+// where we're going to put our guard pages, truncate the mapping at
+// that point by munmap()ping it. This ensures that when we later
+// munmap() the guard pages we don't leave a hole in the stack
+// mapping.
+bool os::create_stack_guard_pages(char* addr, size_t size) {
+ uintptr_t stack_extent, stack_base;
+ if (get_stack_bounds(&stack_extent, &stack_base)) {
+ if (stack_extent < (uintptr_t)addr)
+ ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent);
+ }
+
+ return os::commit_memory(addr, size);
+}
+
+// If this is a growable mapping, remove the guard pages entirely by
+// munmap()ping them. If not, just call uncommit_memory().
+bool os::remove_stack_guard_pages(char* addr, size_t size) {
+ uintptr_t stack_extent, stack_base;
+ if (get_stack_bounds(&stack_extent, &stack_base)) {
+ return ::munmap(addr, size) == 0;
+ }
+
+ return os::uncommit_memory(addr, size);
+}
+
static address _highest_vm_reserved_address = NULL;
// If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory
@@ -2586,7 +2700,9 @@
// format has been changed), we'll use the largest page size supported by
// the processor.
+#ifndef ZERO
_large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M);
+#endif // ZERO
FILE *fp = fopen("/proc/meminfo", "r");
if (fp) {
@@ -4656,6 +4772,7 @@
// Return immediately if a permit is available.
if (_counter > 0) {
_counter = 0 ;
+ OrderAccess::fence();
return ;
}
@@ -4698,6 +4815,7 @@
_counter = 0;
status = pthread_mutex_unlock(_mutex);
assert (status == 0, "invariant") ;
+ OrderAccess::fence();
return;
}
@@ -4738,6 +4856,7 @@
jt->java_suspend_self();
}
+ OrderAccess::fence();
}
void Parker::unpark() {
diff -r 39e409a664b3 -r 84043c7507b9 src/os/solaris/dtrace/hotspot.d
--- a/src/os/solaris/dtrace/hotspot.d Thu Mar 25 16:27:12 2010 -0700
+++ b/src/os/solaris/dtrace/hotspot.d Thu Mar 25 16:54:59 2010 -0700
@@ -25,9 +25,20 @@
provider hotspot {
probe class__loaded(char*, uintptr_t, void*, uintptr_t);
probe class__unloaded(char*, uintptr_t, void*, uintptr_t);
+ probe class__initialization__required(char*, uintptr_t, void*, intptr_t,int);
+ probe class__initialization__recursive(char*, uintptr_t, void*, intptr_t,int);
+ probe class__initialization__concurrent(char*, uintptr_t, void*, intptr_t,int);
+ probe class__initialization__erroneous(char*, uintptr_t, void*, intptr_t, int);
+ probe class__initialization__super__failed(char*, uintptr_t, void*, intptr_t,int);
+ probe class__initialization__clinit(char*, uintptr_t, void*, intptr_t,int);
+ probe class__initialization__error(char*, uintptr_t, void*, intptr_t,int);
+ probe class__initialization__end(char*, uintptr_t, void*, intptr_t,int);
probe vm__init__begin();
probe vm__init__end();
probe vm__shutdown();
+ probe vmops__request(char*, uintptr_t, int);
+ probe vmops__begin(char*, uintptr_t, int);
+ probe vmops__end(char*, uintptr_t, int);
probe gc__begin(uintptr_t);
probe gc__end();
probe mem__pool__gc__begin(
@@ -38,6 +49,12 @@
uintptr_t, uintptr_t, uintptr_t, uintptr_t);
probe thread__start(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
probe thread__stop(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+ probe thread__sleep__begin(long long);
+ probe thread__sleep__end(int);
+ probe thread__yield();
+ probe thread__park__begin(uintptr_t, int, long long);
+ probe thread__park__end(uintptr_t);
+ probe thread__unpark(uintptr_t);
probe method__compile__begin(
char*, uintptr_t, char*, uintptr_t, char*, uintptr_t, char*, uintptr_t);
probe method__compile__end(
diff -r 39e409a664b3 -r 84043c7507b9 src/os/solaris/dtrace/libjvm_db.c
--- a/src/os/solaris/dtrace/libjvm_db.c Thu Mar 25 16:27:12 2010 -0700
+++ b/src/os/solaris/dtrace/libjvm_db.c Thu Mar 25 16:54:59 2010 -0700
@@ -937,54 +937,56 @@
return err;
}
-static int
-scopeDesc_chain(Nmethod_t *N)
-{
+static int scopeDesc_chain(Nmethod_t *N) {
int32_t decode_offset = 0;
int32_t err;
- if (debug > 2)
- fprintf(stderr, "\t scopeDesc_chain: BEGIN\n");
+ if (debug > 2) {
+ fprintf(stderr, "\t scopeDesc_chain: BEGIN\n");
+ }
err = ps_pread(N->J->P, N->pc_desc + OFFSET_PcDesc_scope_decode_offset,
&decode_offset, SZ32);
CHECK_FAIL(err);
while (decode_offset > 0) {
- if (debug > 2)
- fprintf(stderr, "\t scopeDesc_chain: decode_offset: %#x\n", decode_offset);
+ Vframe_t *vf = &N->vframes[N->vf_cnt];
- Vframe_t *vf = &N->vframes[N->vf_cnt];
+ if (debug > 2) {
+ fprintf(stderr, "\t scopeDesc_chain: decode_offset: %#x\n", decode_offset);
+ }
+
+ err = scope_desc_at(N, decode_offset, vf);
+ CHECK_FAIL(err);
- err = scope_desc_at(N, decode_offset, vf);
- CHECK_FAIL(err);
+ if (vf->methodIdx > N->oops_len) {
+ fprintf(stderr, "\t scopeDesc_chain: (methodIdx > oops_len) !\n");
+ return -1;
+ }
+ err = read_pointer(N->J, N->nm + N->oops_beg + (vf->methodIdx-1)*POINTER_SIZE,
+ &vf->methodOop);
+ CHECK_FAIL(err);
- if (vf->methodIdx > N->oops_len) {
- fprintf(stderr, "\t scopeDesc_chain: (methodIdx > oops_len) !\n");
- return -1;
- }
- err = read_pointer(N->J, N->nm + N->oops_beg + (vf->methodIdx-1)*POINTER_SIZE,
- &vf->methodOop);
+ if (vf->methodOop) {
+ N->vf_cnt++;
+ err = line_number_from_bci(N->J, vf);
CHECK_FAIL(err);
-
- if (vf->methodOop) {
- N->vf_cnt++;
- err = line_number_from_bci(N->J, vf);
- CHECK_FAIL(err);
- if (debug > 2) {
- fprintf(stderr, "\t scopeDesc_chain: methodOop: %#8llx, line: %ld\n",
- vf->methodOop, vf->line);
- }
+ if (debug > 2) {
+ fprintf(stderr, "\t scopeDesc_chain: methodOop: %#8llx, line: %ld\n",
+ vf->methodOop, vf->line);
}
- decode_offset = vf->sender_decode_offset;
+ }
+ decode_offset = vf->sender_decode_offset;
}
- if (debug > 2)
- fprintf(stderr, "\t scopeDesc_chain: END \n\n");
+ if (debug > 2) {
+ fprintf(stderr, "\t scopeDesc_chain: END \n\n");
+ }
return PS_OK;
fail:
- if (debug)
- fprintf(stderr, "\t scopeDesc_chain: FAIL \n\n");
+ if (debug) {
+ fprintf(stderr, "\t scopeDesc_chain: FAIL \n\n");
+ }
return err;
}
diff -r 39e409a664b3 -r 84043c7507b9 src/os/solaris/vm/attachListener_solaris.cpp
--- a/src/os/solaris/vm/attachListener_solaris.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/os/solaris/vm/attachListener_solaris.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -668,13 +668,18 @@
}
}
- if (strcmp(name, "ExtendedDTraceProbes") != 0) {
- out->print_cr("flag '%s' cannot be changed", name);
- return JNI_ERR;
+ if (strcmp(name, "ExtendedDTraceProbes") == 0) {
+ DTrace::set_extended_dprobes(flag);
+ return JNI_OK;
}
- DTrace::set_extended_dprobes(flag);
- return JNI_OK;
+ if (strcmp(name, "DTraceMonitorProbes") == 0) {
+ DTrace::set_monitor_dprobes(flag);
+ return JNI_OK;
+ }
+
+ out->print_cr("flag '%s' cannot be changed", name);
+ return JNI_ERR;
}
void AttachListener::pd_detachall() {
diff -r 39e409a664b3 -r 84043c7507b9 src/os/solaris/vm/os_solaris.cpp
--- a/src/os/solaris/vm/os_solaris.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/os/solaris/vm/os_solaris.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -457,7 +457,7 @@
void os::Solaris::initialize_system_info() {
- _processor_count = sysconf(_SC_NPROCESSORS_CONF);
+ set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
_processors_online = sysconf (_SC_NPROCESSORS_ONLN);
_physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
}
@@ -2698,6 +2698,14 @@
}
}
+bool os::create_stack_guard_pages(char* addr, size_t size) {
+ return os::commit_memory(addr, size);
+}
+
+bool os::remove_stack_guard_pages(char* addr, size_t size) {
+ return os::uncommit_memory(addr, size);
+}
+
// Change the page size in a given range.
void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned.");
@@ -5803,6 +5811,7 @@
// Return immediately if a permit is available.
if (_counter > 0) {
_counter = 0 ;
+ OrderAccess::fence();
return ;
}
@@ -5846,6 +5855,7 @@
_counter = 0;
status = os::Solaris::mutex_unlock(_mutex);
assert (status == 0, "invariant") ;
+ OrderAccess::fence();
return;
}
@@ -5892,6 +5902,7 @@
jt->java_suspend_self();
}
+ OrderAccess::fence();
}
void Parker::unpark() {
diff -r 39e409a664b3 -r 84043c7507b9 src/os/windows/vm/os_windows.cpp
--- a/src/os/windows/vm/os_windows.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/os/windows/vm/os_windows.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -142,6 +142,9 @@
}
#ifndef _WIN64
+// previous UnhandledExceptionFilter, if there is one
+static LPTOP_LEVEL_EXCEPTION_FILTER prev_uef_handler = NULL;
+
LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo);
#endif
void os::init_system_properties_values() {
@@ -260,7 +263,8 @@
}
#ifndef _WIN64
- SetUnhandledExceptionFilter(Handle_FLT_Exception);
+ // set our UnhandledExceptionFilter and save any previous one
+ prev_uef_handler = SetUnhandledExceptionFilter(Handle_FLT_Exception);
#endif
// Done
@@ -1526,7 +1530,8 @@
case 5000: st->print(" Windows 2000"); break;
case 5001: st->print(" Windows XP"); break;
case 5002:
- case 6000: {
+ case 6000:
+ case 6001: {
// Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
// find out whether we are running on 64 bit processor or not.
SYSTEM_INFO si;
@@ -1549,13 +1554,27 @@
st->print(" Windows XP x64 Edition");
else
st->print(" Windows Server 2003 family");
- } else { // os_vers == 6000
+ } else if (os_vers == 6000) {
if (osvi.wProductType == VER_NT_WORKSTATION)
st->print(" Windows Vista");
else
st->print(" Windows Server 2008");
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
st->print(" , 64 bit");
+ } else if (os_vers == 6001) {
+ if (osvi.wProductType == VER_NT_WORKSTATION) {
+ st->print(" Windows 7");
+ } else {
+ // Unrecognized windows, print out its major and minor versions
+ st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
+ }
+ if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+ st->print(" , 64 bit");
+ } else { // future os
+ // Unrecognized windows, print out its major and minor versions
+ st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
+ if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+ st->print(" , 64 bit");
}
break;
}
@@ -1954,7 +1973,7 @@
#ifndef _WIN64
//-----------------------------------------------------------------------------
LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
- // handle exception caused by native mothod modifying control word
+ // handle exception caused by native method modifying control word
PCONTEXT ctx = exceptionInfo->ContextRecord;
DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
@@ -1975,6 +1994,13 @@
return EXCEPTION_CONTINUE_EXECUTION;
}
}
+
+ if (prev_uef_handler != NULL) {
+ // We didn't handle this exception so pass it to the previous
+ // UnhandledExceptionFilter.
+ return (prev_uef_handler)(exceptionInfo);
+ }
+
return EXCEPTION_CONTINUE_SEARCH;
}
#else //_WIN64
@@ -2777,6 +2803,14 @@
return VirtualFree(addr, 0, MEM_RELEASE) != 0;
}
+bool os::create_stack_guard_pages(char* addr, size_t size) {
+ return os::commit_memory(addr, size);
+}
+
+bool os::remove_stack_guard_pages(char* addr, size_t size) {
+ return os::uncommit_memory(addr, size);
+}
+
// Set protections specified
bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
bool is_committed) {
@@ -3135,7 +3169,7 @@
_vm_allocation_granularity = si.dwAllocationGranularity;
_processor_type = si.dwProcessorType;
_processor_level = si.wProcessorLevel;
- _processor_count = si.dwNumberOfProcessors;
+ set_processor_count(si.dwNumberOfProcessors);
MEMORYSTATUSEX ms;
ms.dwLength = sizeof(ms);
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/linux_x86/vm/globals_linux_x86.hpp
--- a/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -22,10 +22,9 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the runtime system.
// (see globals.hpp)
-//
+
define_pd_global(bool, DontYieldALot, false);
#ifdef AMD64
define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default
@@ -39,11 +38,10 @@
#endif // AMD64
define_pd_global(intx, CompilerThreadStackSize, 0);
-define_pd_global(intx, SurvivorRatio, 8);
-define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
+define_pd_global(uintx,JVMInvokeMethodSlack, 8192);
// Only used on 64 bit platforms
-define_pd_global(uintx, HeapBaseMinAddress, 2*G);
+define_pd_global(uintx,HeapBaseMinAddress, 2*G);
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/linux_zero/vm/assembler_linux_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_cpu/linux_zero/vm/assembler_linux_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// Implementation of class atomic
+
+#ifdef M68K
+
+/*
+ * __m68k_cmpxchg
+ *
+ * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
+ * Returns newval on success and oldval if no exchange happened.
+ * This implementation is processor specific and works on
+ * 68020 68030 68040 and 68060.
+ *
+ * It will not work on ColdFire, 68000 and 68010 since they lack the CAS
+ * instruction.
+ * Using a kernelhelper would be better for arch complete implementation.
+ *
+ */
+
+static inline int __m68k_cmpxchg(int oldval, int newval, volatile int *ptr) {
+ int ret;
+ __asm __volatile ("cas%.l %0,%2,%1"
+ : "=d" (ret), "+m" (*(ptr))
+ : "d" (newval), "0" (oldval));
+ return ret;
+}
+
+/* Perform an atomic compare and swap: if the current value of `*PTR'
+ is OLDVAL, then write NEWVAL into `*PTR'. Return the contents of
+ `*PTR' before the operation.*/
+static inline int m68k_compare_and_swap(volatile int *ptr,
+ int oldval,
+ int newval) {
+ for (;;) {
+ int prev = *ptr;
+ if (prev != oldval)
+ return prev;
+
+ if (__m68k_cmpxchg (prev, newval, ptr) == newval)
+ // Success.
+ return prev;
+
+ // We failed even though prev == oldval. Try again.
+ }
+}
+
+/* Atomically add an int to memory. */
+static inline int m68k_add_and_fetch(volatile int *ptr, int add_value) {
+ for (;;) {
+ // Loop until success.
+
+ int prev = *ptr;
+
+ if (__m68k_cmpxchg (prev, prev + add_value, ptr) == prev + add_value)
+ return prev + add_value;
+ }
+}
+
+/* Atomically write VALUE into `*PTR' and returns the previous
+ contents of `*PTR'. */
+static inline int m68k_lock_test_and_set(volatile int *ptr, int newval) {
+ for (;;) {
+ // Loop until success.
+ int prev = *ptr;
+
+ if (__m68k_cmpxchg (prev, newval, ptr) == prev)
+ return prev;
+ }
+}
+#endif // M68K
+
+#ifdef ARM
+
+/*
+ * __kernel_cmpxchg
+ *
+ * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
+ * Return zero if *ptr was changed or non-zero if no exchange happened.
+ * The C flag is also set if *ptr was changed to allow for assembly
+ * optimization in the calling code.
+ *
+ */
+
+typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
+#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0)
+
+
+
+/* Perform an atomic compare and swap: if the current value of `*PTR'
+ is OLDVAL, then write NEWVAL into `*PTR'. Return the contents of
+ `*PTR' before the operation.*/
+static inline int arm_compare_and_swap(volatile int *ptr,
+ int oldval,
+ int newval) {
+ for (;;) {
+ int prev = *ptr;
+ if (prev != oldval)
+ return prev;
+
+ if (__kernel_cmpxchg (prev, newval, ptr) == 0)
+ // Success.
+ return prev;
+
+ // We failed even though prev == oldval. Try again.
+ }
+}
+
+/* Atomically add an int to memory. */
+static inline int arm_add_and_fetch(volatile int *ptr, int add_value) {
+ for (;;) {
+ // Loop until a __kernel_cmpxchg succeeds.
+
+ int prev = *ptr;
+
+ if (__kernel_cmpxchg (prev, prev + add_value, ptr) == 0)
+ return prev + add_value;
+ }
+}
+
+/* Atomically write VALUE into `*PTR' and returns the previous
+ contents of `*PTR'. */
+static inline int arm_lock_test_and_set(volatile int *ptr, int newval) {
+ for (;;) {
+ // Loop until a __kernel_cmpxchg succeeds.
+ int prev = *ptr;
+
+ if (__kernel_cmpxchg (prev, newval, ptr) == 0)
+ return prev;
+ }
+}
+#endif // ARM
+
+inline void Atomic::store(jint store_value, volatile jint* dest) {
+ *dest = store_value;
+}
+
+inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) {
+ *dest = store_value;
+}
+
+inline jint Atomic::add(jint add_value, volatile jint* dest) {
+#ifdef ARM
+ return arm_add_and_fetch(dest, add_value);
+#else
+#ifdef M68K
+ return m68k_add_and_fetch(dest, add_value);
+#else
+ return __sync_add_and_fetch(dest, add_value);
+#endif // M68K
+#endif // ARM
+}
+
+inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
+#ifdef ARM
+ return arm_add_and_fetch(dest, add_value);
+#else
+#ifdef M68K
+ return m68k_add_and_fetch(dest, add_value);
+#else
+ return __sync_add_and_fetch(dest, add_value);
+#endif // M68K
+#endif // ARM
+}
+
+inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
+ return (void *) add_ptr(add_value, (volatile intptr_t *) dest);
+}
+
+inline void Atomic::inc(volatile jint* dest) {
+ add(1, dest);
+}
+
+inline void Atomic::inc_ptr(volatile intptr_t* dest) {
+ add_ptr(1, dest);
+}
+
+inline void Atomic::inc_ptr(volatile void* dest) {
+ add_ptr(1, dest);
+}
+
+inline void Atomic::dec(volatile jint* dest) {
+ add(-1, dest);
+}
+
+inline void Atomic::dec_ptr(volatile intptr_t* dest) {
+ add_ptr(-1, dest);
+}
+
+inline void Atomic::dec_ptr(volatile void* dest) {
+ add_ptr(-1, dest);
+}
+
+inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) {
+#ifdef ARM
+ return arm_lock_test_and_set(dest, exchange_value);
+#else
+#ifdef M68K
+ return m68k_lock_test_and_set(dest, exchange_value);
+#else
+ // __sync_lock_test_and_set is a bizarrely named atomic exchange
+ // operation. Note that some platforms only support this with the
+ // limitation that the only valid value to store is the immediate
+ // constant 1. There is a test for this in JNI_CreateJavaVM().
+ return __sync_lock_test_and_set (dest, exchange_value);
+#endif // M68K
+#endif // ARM
+}
+
+inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value,
+ volatile intptr_t* dest) {
+#ifdef ARM
+ return arm_lock_test_and_set(dest, exchange_value);
+#else
+#ifdef M68K
+ return m68k_lock_test_and_set(dest, exchange_value);
+#else
+ return __sync_lock_test_and_set (dest, exchange_value);
+#endif // M68K
+#endif // ARM
+}
+
+inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) {
+ return (void *) xchg_ptr((intptr_t) exchange_value,
+ (volatile intptr_t*) dest);
+}
+
+inline jint Atomic::cmpxchg(jint exchange_value,
+ volatile jint* dest,
+ jint compare_value) {
+#ifdef ARM
+ return arm_compare_and_swap(dest, compare_value, exchange_value);
+#else
+#ifdef M68K
+ return m68k_compare_and_swap(dest, compare_value, exchange_value);
+#else
+ return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
+#endif // M68K
+#endif // ARM
+}
+
+inline jlong Atomic::cmpxchg(jlong exchange_value,
+ volatile jlong* dest,
+ jlong compare_value) {
+
+ return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
+}
+
+inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value,
+ volatile intptr_t* dest,
+ intptr_t compare_value) {
+#ifdef ARM
+ return arm_compare_and_swap(dest, compare_value, exchange_value);
+#else
+#ifdef M68K
+ return m68k_compare_and_swap(dest, compare_value, exchange_value);
+#else
+ return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
+#endif // M68K
+#endif // ARM
+}
+
+inline void* Atomic::cmpxchg_ptr(void* exchange_value,
+ volatile void* dest,
+ void* compare_value) {
+
+ return (void *) cmpxchg_ptr((intptr_t) exchange_value,
+ (volatile intptr_t*) dest,
+ (intptr_t) compare_value);
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/linux_zero/vm/bytes_linux_zero.inline.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_cpu/linux_zero/vm/bytes_linux_zero.inline.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2003 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.
+ *
+ */
+
+// Efficient swapping of data bytes from Java byte
+// ordering to native byte ordering and vice versa.
+
+#include
+
+inline u2 Bytes::swap_u2(u2 x) {
+ return bswap_16(x);
+}
+
+inline u4 Bytes::swap_u4(u4 x) {
+ return bswap_32(x);
+}
+
+inline u8 Bytes::swap_u8(u8 x) {
+ return bswap_64(x);
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/linux_zero/vm/globals_linux_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+//
+// Set the default values for platform dependent flags used by the
+// runtime system. See globals.hpp for details of what they do.
+//
+
+define_pd_global(bool, DontYieldALot, false);
+#ifdef _LP64
+define_pd_global(intx, ThreadStackSize, 1536);
+define_pd_global(intx, VMThreadStackSize, 1024);
+#else
+define_pd_global(intx, ThreadStackSize, 1024);
+define_pd_global(intx, VMThreadStackSize, 512);
+#endif // _LP64
+define_pd_global(intx, SurvivorRatio, 8);
+define_pd_global(intx, CompilerThreadStackSize, 0);
+define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
+
+define_pd_global(bool, UseVectoredExceptions, false);
+// Only used on 64 bit platforms
+define_pd_global(uintx, HeapBaseMinAddress, 2*G);
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#ifdef ARM
+
+/*
+ * ARM Kernel helper for memory barrier.
+ * Using __asm __volatile ("":::"memory") does not work reliable on ARM
+ * and gcc __sync_synchronize(); implementation does not use the kernel
+ * helper for all gcc versions so it is unreliable to use as well.
+ */
+typedef void (__kernel_dmb_t) (void);
+#define __kernel_dmb (*(__kernel_dmb_t *) 0xffff0fa0)
+
+#define FULL_MEM_BARRIER __kernel_dmb()
+#define READ_MEM_BARRIER __kernel_dmb()
+#define WRITE_MEM_BARRIER __kernel_dmb()
+
+#else // ARM
+
+#define FULL_MEM_BARRIER __sync_synchronize()
+
+#ifdef PPC
+
+#define READ_MEM_BARRIER __asm __volatile ("isync":::"memory")
+#ifdef __NO_LWSYNC__
+#define WRITE_MEM_BARRIER __asm __volatile ("sync":::"memory")
+#else
+#define WRITE_MEM_BARRIER __asm __volatile ("lwsync":::"memory")
+#endif
+
+#else // PPC
+
+#define READ_MEM_BARRIER __asm __volatile ("":::"memory")
+#define WRITE_MEM_BARRIER __asm __volatile ("":::"memory")
+
+#endif // PPC
+
+#endif // ARM
+
+
+inline void OrderAccess::loadload() { acquire(); }
+inline void OrderAccess::storestore() { release(); }
+inline void OrderAccess::loadstore() { acquire(); }
+inline void OrderAccess::storeload() { fence(); }
+
+inline void OrderAccess::acquire() {
+ READ_MEM_BARRIER;
+}
+
+inline void OrderAccess::release() {
+ WRITE_MEM_BARRIER;
+}
+
+inline void OrderAccess::fence() {
+ FULL_MEM_BARRIER;
+}
+
+inline jbyte OrderAccess::load_acquire(volatile jbyte* p) { jbyte data = *p; acquire(); return data; }
+inline jshort OrderAccess::load_acquire(volatile jshort* p) { jshort data = *p; acquire(); return data; }
+inline jint OrderAccess::load_acquire(volatile jint* p) { jint data = *p; acquire(); return data; }
+inline jlong OrderAccess::load_acquire(volatile jlong* p) {
+ jlong tmp;
+ os::atomic_copy64(p, &tmp);
+ acquire();
+ return tmp;
+}
+inline jubyte OrderAccess::load_acquire(volatile jubyte* p) { jubyte data = *p; acquire(); return data; }
+inline jushort OrderAccess::load_acquire(volatile jushort* p) { jushort data = *p; acquire(); return data; }
+inline juint OrderAccess::load_acquire(volatile juint* p) { juint data = *p; acquire(); return data; }
+inline julong OrderAccess::load_acquire(volatile julong* p) {
+ julong tmp;
+ os::atomic_copy64(p, &tmp);
+ acquire();
+ return tmp;
+}
+inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { jfloat data = *p; acquire(); return data; }
+inline jdouble OrderAccess::load_acquire(volatile jdouble* p) {
+ jdouble tmp;
+ os::atomic_copy64(p, &tmp);
+ acquire();
+ return tmp;
+}
+
+inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) {
+ intptr_t data = *p;
+ acquire();
+ return data;
+}
+inline void* OrderAccess::load_ptr_acquire(volatile void* p) {
+ void *data = *(void* volatile *)p;
+ acquire();
+ return data;
+}
+inline void* OrderAccess::load_ptr_acquire(const volatile void* p) {
+ void *data = *(void* const volatile *)p;
+ acquire();
+ return data;
+}
+
+inline void OrderAccess::release_store(volatile jbyte* p, jbyte v) { release(); *p = v; }
+inline void OrderAccess::release_store(volatile jshort* p, jshort v) { release(); *p = v; }
+inline void OrderAccess::release_store(volatile jint* p, jint v) { release(); *p = v; }
+inline void OrderAccess::release_store(volatile jlong* p, jlong v)
+{ release(); os::atomic_copy64(&v, p); }
+inline void OrderAccess::release_store(volatile jubyte* p, jubyte v) { release(); *p = v; }
+inline void OrderAccess::release_store(volatile jushort* p, jushort v) { release(); *p = v; }
+inline void OrderAccess::release_store(volatile juint* p, juint v) { release(); *p = v; }
+inline void OrderAccess::release_store(volatile julong* p, julong v)
+{ release(); os::atomic_copy64(&v, p); }
+inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { release(); *p = v; }
+inline void OrderAccess::release_store(volatile jdouble* p, jdouble v)
+{ release(); os::atomic_copy64(&v, p); }
+
+inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { release(); *p = v; }
+inline void OrderAccess::release_store_ptr(volatile void* p, void* v)
+{ release(); *(void* volatile *)p = v; }
+
+inline void OrderAccess::store_fence(jbyte* p, jbyte v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(jshort* p, jshort v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(jint* p, jint v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(jlong* p, jlong v) { os::atomic_copy64(&v, p); fence(); }
+inline void OrderAccess::store_fence(jubyte* p, jubyte v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(jushort* p, jushort v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(juint* p, juint v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(julong* p, julong v) { os::atomic_copy64(&v, p); fence(); }
+inline void OrderAccess::store_fence(jfloat* p, jfloat v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(jdouble* p, jdouble v) { os::atomic_copy64(&v, p); fence(); }
+
+inline void OrderAccess::store_ptr_fence(intptr_t* p, intptr_t v) { *p = v; fence(); }
+inline void OrderAccess::store_ptr_fence(void** p, void* v) { *p = v; fence(); }
+
+inline void OrderAccess::release_store_fence(volatile jbyte* p, jbyte v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile jshort* p, jshort v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile jint* p, jint v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile jlong* p, jlong v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile jubyte* p, jubyte v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile jushort* p, jushort v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile juint* p, juint v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { release_store(p, v); fence(); }
+
+inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) { release_store_ptr(p, v); fence(); }
+inline void OrderAccess::release_store_ptr_fence(volatile void* p, void* v) { release_store_ptr(p, v); fence(); }
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/linux_zero/vm/os_linux_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,470 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// do not include precompiled header file
+#include "incls/_os_linux_zero.cpp.incl"
+
+address os::current_stack_pointer() {
+ address dummy = (address) &dummy;
+ return dummy;
+}
+
+frame os::get_sender_for_C_frame(frame* fr) {
+ ShouldNotCallThis();
+}
+
+frame os::current_frame() {
+ // The only thing that calls this is the stack printing code in
+ // VMError::report:
+ // - Step 110 (printing stack bounds) uses the sp in the frame
+ // to determine the amount of free space on the stack. We
+ // set the sp to a close approximation of the real value in
+ // order to allow this step to complete.
+ // - Step 120 (printing native stack) tries to walk the stack.
+ // The frame we create has a NULL pc, which is ignored as an
+ // invalid frame.
+ frame dummy = frame();
+ dummy.set_sp((intptr_t *) current_stack_pointer());
+ return dummy;
+}
+
+char* os::non_memory_address_word() {
+ // Must never look like an address returned by reserve_memory,
+ // even in its subfields (as defined by the CPU immediate fields,
+ // if the CPU splits constants across multiple instructions).
+#ifdef SPARC
+ // On SPARC, 0 != %hi(any real address), because there is no
+ // allocation in the first 1Kb of the virtual address space.
+ return (char *) 0;
+#else
+ // This is the value for x86; works pretty well for PPC too.
+ return (char *) -1;
+#endif // SPARC
+}
+
+void os::initialize_thread() {
+ // Nothing to do.
+}
+
+address os::Linux::ucontext_get_pc(ucontext_t* uc) {
+ ShouldNotCallThis();
+}
+
+ExtendedPC os::fetch_frame_from_context(void* ucVoid,
+ intptr_t** ret_sp,
+ intptr_t** ret_fp) {
+ ShouldNotCallThis();
+}
+
+frame os::fetch_frame_from_context(void* ucVoid) {
+ ShouldNotCallThis();
+}
+
+extern "C" int
+JVM_handle_linux_signal(int sig,
+ siginfo_t* info,
+ void* ucVoid,
+ int abort_if_unrecognized) {
+ ucontext_t* uc = (ucontext_t*) ucVoid;
+
+ Thread* t = ThreadLocalStorage::get_thread_slow();
+
+ SignalHandlerMark shm(t);
+
+ // Note: it's not uncommon that JNI code uses signal/sigset to
+ // install then restore certain signal handler (e.g. to temporarily
+ // block SIGPIPE, or have a SIGILL handler when detecting CPU
+ // type). When that happens, JVM_handle_linux_signal() might be
+ // invoked with junk info/ucVoid. To avoid unnecessary crash when
+ // libjsig is not preloaded, try handle signals that do not require
+ // siginfo/ucontext first.
+
+ if (sig == SIGPIPE || sig == SIGXFSZ) {
+ // allow chained handler to go first
+ if (os::Linux::chained_handler(sig, info, ucVoid)) {
+ return true;
+ } else {
+ if (PrintMiscellaneous && (WizardMode || Verbose)) {
+ char buf[64];
+ warning("Ignoring %s - see bugs 4229104 or 646499219",
+ os::exception_name(sig, buf, sizeof(buf)));
+ }
+ return true;
+ }
+ }
+
+ JavaThread* thread = NULL;
+ VMThread* vmthread = NULL;
+ if (os::Linux::signal_handlers_are_installed) {
+ if (t != NULL ){
+ if(t->is_Java_thread()) {
+ thread = (JavaThread*)t;
+ }
+ else if(t->is_VM_thread()){
+ vmthread = (VMThread *)t;
+ }
+ }
+ }
+
+ if (info != NULL && thread != NULL) {
+ // Handle ALL stack overflow variations here
+ if (sig == SIGSEGV) {
+ address addr = (address) info->si_addr;
+
+ // check if fault address is within thread stack
+ if (addr < thread->stack_base() &&
+ addr >= thread->stack_base() - thread->stack_size()) {
+ // stack overflow
+ if (thread->in_stack_yellow_zone(addr)) {
+ thread->disable_stack_yellow_zone();
+ ShouldNotCallThis();
+ }
+ else if (thread->in_stack_red_zone(addr)) {
+ thread->disable_stack_red_zone();
+ ShouldNotCallThis();
+ }
+ else {
+ // Accessing stack address below sp may cause SEGV if
+ // current thread has MAP_GROWSDOWN stack. This should
+ // only happen when current thread was created by user
+ // code with MAP_GROWSDOWN flag and then attached to VM.
+ // See notes in os_linux.cpp.
+ if (thread->osthread()->expanding_stack() == 0) {
+ thread->osthread()->set_expanding_stack();
+ if (os::Linux::manually_expand_stack(thread, addr)) {
+ thread->osthread()->clear_expanding_stack();
+ return true;
+ }
+ thread->osthread()->clear_expanding_stack();
+ }
+ else {
+ fatal("recursive segv. expanding stack.");
+ }
+ }
+ }
+ }
+
+ /*if (thread->thread_state() == _thread_in_Java) {
+ ShouldNotCallThis();
+ }
+ else*/ if (thread->thread_state() == _thread_in_vm &&
+ sig == SIGBUS && thread->doing_unsafe_access()) {
+ ShouldNotCallThis();
+ }
+
+ // jni_fast_GetField can trap at certain pc's if a GC
+ // kicks in and the heap gets shrunk before the field access.
+ /*if (sig == SIGSEGV || sig == SIGBUS) {
+ address addr = JNI_FastGetField::find_slowcase_pc(pc);
+ if (addr != (address)-1) {
+ stub = addr;
+ }
+ }*/
+
+ // Check to see if we caught the safepoint code in the process
+ // of write protecting the memory serialization page. It write
+ // enables the page immediately after protecting it so we can
+ // just return to retry the write.
+ if (sig == SIGSEGV &&
+ os::is_memory_serialize_page(thread, (address) info->si_addr)) {
+ // Block current thread until permission is restored.
+ os::block_on_serialize_page_trap();
+ return true;
+ }
+ }
+
+ // signal-chaining
+ if (os::Linux::chained_handler(sig, info, ucVoid)) {
+ return true;
+ }
+
+ if (!abort_if_unrecognized) {
+ // caller wants another chance, so give it to him
+ return false;
+ }
+
+#ifndef PRODUCT
+ if (sig == SIGSEGV) {
+ fatal("\n#"
+ "\n# /--------------------\\"
+ "\n# | segmentation fault |"
+ "\n# \\---\\ /--------------/"
+ "\n# /"
+ "\n# [-] |\\_/| "
+ "\n# (+)=C |o o|__ "
+ "\n# | | =-*-=__\\ "
+ "\n# OOO c_c_(___)");
+ }
+#endif // !PRODUCT
+
+ const char *fmt = "caught unhandled signal %d";
+ char buf[64];
+
+ sprintf(buf, fmt, sig);
+ fatal(buf);
+}
+
+void os::Linux::init_thread_fpu_state(void) {
+ // Nothing to do
+}
+
+int os::Linux::get_fpu_control_word() {
+ ShouldNotCallThis();
+}
+
+void os::Linux::set_fpu_control_word(int fpu) {
+ ShouldNotCallThis();
+}
+
+bool os::is_allocatable(size_t bytes) {
+#ifdef _LP64
+ return true;
+#else
+ if (bytes < 2 * G) {
+ return true;
+ }
+
+ char* addr = reserve_memory(bytes, NULL);
+
+ if (addr != NULL) {
+ release_memory(addr, bytes);
+ }
+
+ return addr != NULL;
+#endif // _LP64
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// thread stack
+
+size_t os::Linux::min_stack_allowed = 64 * K;
+
+bool os::Linux::supports_variable_stack_size() {
+ return true;
+}
+
+size_t os::Linux::default_stack_size(os::ThreadType thr_type) {
+#ifdef _LP64
+ size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
+#else
+ size_t s = (thr_type == os::compiler_thread ? 2 * M : 512 * K);
+#endif // _LP64
+ return s;
+}
+
+size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
+ // Only enable glibc guard pages for non-Java threads
+ // (Java threads have HotSpot guard pages)
+ return (thr_type == java_thread ? 0 : page_size());
+}
+
+static void current_stack_region(address *bottom, size_t *size) {
+ pthread_attr_t attr;
+ int res = pthread_getattr_np(pthread_self(), &attr);
+ if (res != 0) {
+ if (res == ENOMEM) {
+ vm_exit_out_of_memory(0, "pthread_getattr_np");
+ }
+ else {
+ fatal1("pthread_getattr_np failed with errno = %d", res);
+ }
+ }
+
+ address stack_bottom;
+ size_t stack_bytes;
+ res = pthread_attr_getstack(&attr, (void **) &stack_bottom, &stack_bytes);
+ if (res != 0) {
+ fatal1("pthread_attr_getstack failed with errno = %d", res);
+ }
+ address stack_top = stack_bottom + stack_bytes;
+
+ // The block of memory returned by pthread_attr_getstack() includes
+ // guard pages where present. We need to trim these off.
+ size_t page_bytes = os::Linux::page_size();
+ assert(((intptr_t) stack_bottom & (page_bytes - 1)) == 0, "unaligned stack");
+
+ size_t guard_bytes;
+ res = pthread_attr_getguardsize(&attr, &guard_bytes);
+ if (res != 0) {
+ fatal1("pthread_attr_getguardsize failed with errno = %d", res);
+ }
+ int guard_pages = align_size_up(guard_bytes, page_bytes) / page_bytes;
+ assert(guard_bytes == guard_pages * page_bytes, "unaligned guard");
+
+#ifdef IA64
+ // IA64 has two stacks sharing the same area of memory, a normal
+ // stack growing downwards and a register stack growing upwards.
+ // Guard pages, if present, are in the centre. This code splits
+ // the stack in two even without guard pages, though in theory
+ // there's nothing to stop us allocating more to the normal stack
+ // or more to the register stack if one or the other were found
+ // to grow faster.
+ int total_pages = align_size_down(stack_bytes, page_bytes) / page_bytes;
+ stack_bottom += (total_pages - guard_pages) / 2 * page_bytes;
+#endif // IA64
+
+ stack_bottom += guard_bytes;
+
+ pthread_attr_destroy(&attr);
+
+ // The initial thread has a growable stack, and the size reported
+ // by pthread_attr_getstack is the maximum size it could possibly
+ // be given what currently mapped. This can be huge, so we cap it.
+ if (os::Linux::is_initial_thread()) {
+ stack_bytes = stack_top - stack_bottom;
+
+ if (stack_bytes > JavaThread::stack_size_at_create())
+ stack_bytes = JavaThread::stack_size_at_create();
+
+ stack_bottom = stack_top - stack_bytes;
+ }
+
+ assert(os::current_stack_pointer() >= stack_bottom, "should do");
+ assert(os::current_stack_pointer() < stack_top, "should do");
+
+ *bottom = stack_bottom;
+ *size = stack_top - stack_bottom;
+}
+
+address os::current_stack_base() {
+ address bottom;
+ size_t size;
+ current_stack_region(&bottom, &size);
+ return bottom + size;
+}
+
+size_t os::current_stack_size() {
+ // stack size includes normal stack and HotSpot guard pages
+ address bottom;
+ size_t size;
+ current_stack_region(&bottom, &size);
+ return size;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// helper functions for fatal error handler
+
+void os::print_context(outputStream* st, void* context) {
+ ShouldNotCallThis();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Stubs for things that would be in linux_zero.s if it existed.
+// You probably want to disassemble these monkeys to check they're ok.
+
+extern "C" {
+ int SpinPause() {
+ }
+
+ int SafeFetch32(int *adr, int errValue) {
+ int value = errValue;
+ value = *adr;
+ return value;
+ }
+ intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) {
+ intptr_t value = errValue;
+ value = *adr;
+ return value;
+ }
+
+ void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+ if (from > to) {
+ jshort *end = from + count;
+ while (from < end)
+ *(to++) = *(from++);
+ }
+ else if (from < to) {
+ jshort *end = from;
+ from += count - 1;
+ to += count - 1;
+ while (from >= end)
+ *(to--) = *(from--);
+ }
+ }
+ void _Copy_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+ if (from > to) {
+ jint *end = from + count;
+ while (from < end)
+ *(to++) = *(from++);
+ }
+ else if (from < to) {
+ jint *end = from;
+ from += count - 1;
+ to += count - 1;
+ while (from >= end)
+ *(to--) = *(from--);
+ }
+ }
+ void _Copy_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+ if (from > to) {
+ jlong *end = from + count;
+ while (from < end)
+ os::atomic_copy64(from++, to++);
+ }
+ else if (from < to) {
+ jlong *end = from;
+ from += count - 1;
+ to += count - 1;
+ while (from >= end)
+ os::atomic_copy64(from--, to--);
+ }
+ }
+
+ void _Copy_arrayof_conjoint_bytes(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ ShouldNotCallThis();
+ }
+ void _Copy_arrayof_conjoint_jshorts(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ ShouldNotCallThis();
+ }
+ void _Copy_arrayof_conjoint_jints(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ ShouldNotCallThis();
+ }
+ void _Copy_arrayof_conjoint_jlongs(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ ShouldNotCallThis();
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Implementations of atomic operations not supported by processors.
+// -- http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Atomic-Builtins.html
+
+#ifndef _LP64
+extern "C" {
+ long long unsigned int __sync_val_compare_and_swap_8(
+ volatile void *ptr,
+ long long unsigned int oldval,
+ long long unsigned int newval) {
+ ShouldNotCallThis();
+ }
+};
+#endif // !_LP64
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/linux_zero/vm/os_linux_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_cpu/linux_zero/vm/os_linux_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2010 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ static void setup_fpu() {}
+
+ static bool is_allocatable(size_t bytes);
+
+ // Used to register dynamic code cache area with the OS
+ // Note: Currently only used in 64 bit Windows implementations
+ static bool register_code_area(char *low, char *high) { return true; }
+
+ // Atomically copy 64 bits of data
+ static void atomic_copy64(volatile void *src, volatile void *dst) {
+#if defined(PPC) && !defined(_LP64)
+ double tmp;
+ asm volatile ("lfd %0, 0(%1)\n"
+ "stfd %0, 0(%2)\n"
+ : "=f"(tmp)
+ : "b"(src), "b"(dst));
+#elif defined(S390) && !defined(_LP64)
+ double tmp;
+ asm volatile ("ld %0, 0(%1)\n"
+ "std %0, 0(%2)\n"
+ : "=r"(tmp)
+ : "a"(src), "a"(dst));
+#else
+ *(jlong *) dst = *(jlong *) src;
+#endif
+ }
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/linux_zero/vm/prefetch_linux_zero.inline.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_cpu/linux_zero/vm/prefetch_linux_zero.inline.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+inline void Prefetch::read(void* loc, intx interval) {
+}
+
+inline void Prefetch::write(void* loc, intx interval) {
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_threadLS_linux_zero.cpp.incl"
+
+void ThreadLocalStorage::generate_code_for_get_thread() {
+ // nothing to do
+}
+
+void ThreadLocalStorage::pd_init() {
+ // nothing to do
+}
+
+void ThreadLocalStorage::pd_set_thread(Thread* thread) {
+ os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
+}
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/linux_zero/vm/threadLS_linux_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_cpu/linux_zero/vm/threadLS_linux_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2003 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.
+ *
+ */
+
+// Processor dependent parts of ThreadLocalStorage
+
+ public:
+ static Thread* thread() {
+ return (Thread*) os::thread_local_storage_at(thread_index());
+ }
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/linux_zero/vm/thread_linux_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/linux_zero/vm/thread_linux_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ private:
+ ZeroStack _zero_stack;
+ ZeroFrame* _top_zero_frame;
+
+ void pd_initialize() {
+ _top_zero_frame = NULL;
+ }
+
+ public:
+ ZeroStack *zero_stack() {
+ return &_zero_stack;
+ }
+
+ public:
+ ZeroFrame *top_zero_frame() {
+ return _top_zero_frame;
+ }
+ void push_zero_frame(ZeroFrame *frame) {
+ *(ZeroFrame **) frame = _top_zero_frame;
+ _top_zero_frame = frame;
+ }
+ void pop_zero_frame() {
+ zero_stack()->set_sp((intptr_t *) _top_zero_frame + 1);
+ _top_zero_frame = *(ZeroFrame **) _top_zero_frame;
+ }
+
+ public:
+ static ByteSize zero_stack_offset() {
+ return byte_offset_of(JavaThread, _zero_stack);
+ }
+ static ByteSize top_zero_frame_offset() {
+ return byte_offset_of(JavaThread, _top_zero_frame);
+ }
+
+ public:
+ void record_base_of_stack_pointer() {
+ assert(top_zero_frame() == NULL, "junk on stack prior to Java call");
+ }
+ void set_base_of_stack_pointer(intptr_t* base_sp) {
+ assert(base_sp == NULL, "should be");
+ assert(top_zero_frame() == NULL, "junk on stack after Java call");
+ }
+
+ public:
+ void set_last_Java_frame() {
+ JavaFrameAnchor *jfa = frame_anchor();
+ jfa->set_last_Java_sp((intptr_t *) top_zero_frame());
+ }
+ void reset_last_Java_frame() {
+ JavaFrameAnchor *jfa = frame_anchor();
+ jfa->set_last_Java_sp(NULL);
+ }
+
+ private:
+ frame pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+ return frame(last_Java_sp(), zero_stack()->sp());
+ }
+
+ public:
+ // Check for pending suspend requests and pending asynchronous
+ // exceptions. There are separate accessors for these, but
+ // _suspend_flags is volatile so using them would be unsafe.
+ bool has_special_condition_for_native_trans() {
+ return _suspend_flags != 0;
+ }
+
+ public:
+ bool pd_get_top_frame_for_signal_handler(frame* fr_addr,
+ void* ucontext,
+ bool isInJava) {
+ ShouldNotCallThis();
+ }
+
+ // These routines are only used on cpu architectures that
+ // have separate register stacks (Itanium).
+ static bool register_stack_overflow() { return false; }
+ static void enable_register_stack_guard() {}
+ static void disable_register_stack_guard() {}
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// These are the OS and CPU-specific fields, types and integer
+// constants required by the Serviceability Agent. This file is
+// referenced by vmStructs.cpp.
+
+#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
+ /* This must be the last entry, and must be present */ \
+ last_entry()
+
+
+#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
+ /* This must be the last entry, and must be present */ \
+ last_entry()
+
+#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
+ /* This must be the last entry, and must be present */ \
+ last_entry()
+
+#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
+ /* This must be the last entry, and must be present */ \
+ last_entry()
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/linux_zero/vm/vm_version_linux_zero.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_cpu/linux_zero/vm/vm_version_linux_zero.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp
--- a/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2009 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
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp
--- a/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2009 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
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp
--- a/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -22,31 +22,25 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the runtime system.
// (see globals.hpp)
-//
+
define_pd_global(bool, DontYieldALot, true); // Determined in the design center
#ifdef AMD64
define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default
define_pd_global(intx, VMThreadStackSize, 1024);
-define_pd_global(intx, SurvivorRatio, 6);
-define_pd_global(uintx, JVMInvokeMethodSlack, 8*K);
+define_pd_global(uintx,JVMInvokeMethodSlack, 8*K);
#else
-// UseStackBanging is not pd
-// define_pd_global(bool, UseStackBanging, true);
-
// ThreadStackSize 320 allows TaggedStackInterpreter and a couple of test cases
// to run while keeping the number of threads that can be created high.
define_pd_global(intx, ThreadStackSize, 320);
define_pd_global(intx, VMThreadStackSize, 512);
-define_pd_global(intx, SurvivorRatio, 8);
-define_pd_global(uintx, JVMInvokeMethodSlack, 10*K);
+define_pd_global(uintx,JVMInvokeMethodSlack, 10*K);
#endif // AMD64
define_pd_global(intx, CompilerThreadStackSize, 0);
// Only used on 64 bit platforms
-define_pd_global(uintx, HeapBaseMinAddress, 256*M);
+define_pd_global(uintx,HeapBaseMinAddress, 256*M);
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
--- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -730,11 +730,12 @@
st->print(", RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]);
st->print(", RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]);
st->cr();
- st->print(", R8=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]);
+ st->print( "R8=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]);
st->print(", R9=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]);
st->print(", R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]);
st->print(", R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]);
- st->print(", R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]);
+ st->cr();
+ st->print( "R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]);
st->print(", R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]);
st->print(", R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]);
st->print(", R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]);
diff -r 39e409a664b3 -r 84043c7507b9 src/os_cpu/windows_x86/vm/globals_windows_x86.hpp
--- a/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -22,10 +22,9 @@
*
*/
-//
// Sets the default values for platform dependent flags used by the runtime system.
// (see globals.hpp)
-//
+
define_pd_global(bool, DontYieldALot, false);
// Default stack size on Windows is determined by the executable (java.exe
@@ -35,8 +34,6 @@
define_pd_global(intx, ThreadStackSize, 0); // 0 => use system default
define_pd_global(intx, VMThreadStackSize, 0); // 0 => use system default
-define_pd_global(intx, SurvivorRatio, 8);
-
#ifdef ASSERT
define_pd_global(intx, CompilerThreadStackSize, 1024);
#else
diff -r 39e409a664b3 -r 84043c7507b9 src/share/vm/adlc/archDesc.cpp
--- a/src/share/vm/adlc/archDesc.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/share/vm/adlc/archDesc.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1031,7 +1031,8 @@
//---------------------------addSUNcopyright-------------------------------
// output SUN copyright info
void ArchDesc::addSunCopyright(char* legal, int size, FILE *fp) {
- fwrite(legal, size, 1, fp);
+ size_t count = fwrite(legal, 1, size, fp);
+ assert(count == (size_t) size, "copyright info truncated");
fprintf(fp,"\n");
fprintf(fp,"// Machine Generated File. Do Not Edit!\n");
fprintf(fp,"\n");
diff -r 39e409a664b3 -r 84043c7507b9 src/share/vm/adlc/formssel.cpp
--- a/src/share/vm/adlc/formssel.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/share/vm/adlc/formssel.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -828,11 +828,13 @@
return AdlcVMDeps::Parms; // Skip the machine-state edges
if( _matrule->_rChild &&
- ( strcmp(_matrule->_rChild->_opType,"StrComp" )==0 ||
+ ( strcmp(_matrule->_rChild->_opType,"AryEq" )==0 ||
+ strcmp(_matrule->_rChild->_opType,"StrComp" )==0 ||
strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 ||
strcmp(_matrule->_rChild->_opType,"StrIndexOf")==0 )) {
- // String.(compareTo/equals/indexOf) take 1 control and 4 memory edges.
- return 5;
+ // String.(compareTo/equals/indexOf) and Arrays.equals
+ // take 1 control and 1 memory edges.
+ return 2;
}
// Check for handling of 'Memory' input/edge in the ideal world.
diff -r 39e409a664b3 -r 84043c7507b9 src/share/vm/adlc/output_c.cpp
--- a/src/share/vm/adlc/output_c.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/share/vm/adlc/output_c.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2010 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
@@ -1496,7 +1496,7 @@
unsigned i;
// Generate Expand function header
- fprintf(fp,"MachNode *%sNode::Expand(State *state, Node_List &proj_list) {\n", node->_ident);
+ fprintf(fp,"MachNode *%sNode::Expand(State *state, Node_List &proj_list, Node* mem) {\n", node->_ident);
fprintf(fp,"Compile* C = Compile::current();\n");
// Generate expand code
if( node->expands() ) {
@@ -1546,15 +1546,16 @@
// Build a mapping from operand index to input edges
fprintf(fp," unsigned idx0 = oper_input_base();\n");
- // The order in which inputs are added to a node is very
+ // The order in which the memory input is added to a node is very
// strange. Store nodes get a memory input before Expand is
- // called and all other nodes get it afterwards so
- // oper_input_base is wrong during expansion. This code adjusts
- // is so that expansion will work correctly.
- bool missing_memory_edge = node->_matrule->needs_ideal_memory_edge(_globalNames) &&
- node->is_ideal_store() == Form::none;
- if (missing_memory_edge) {
- fprintf(fp," idx0--; // Adjust base because memory edge hasn't been inserted yet\n");
+ // called and other nodes get it afterwards or before depending on
+ // match order so oper_input_base is wrong during expansion. This
+ // code adjusts it so that expansion will work correctly.
+ int has_memory_edge = node->_matrule->needs_ideal_memory_edge(_globalNames);
+ if (has_memory_edge) {
+ fprintf(fp," if (mem == (Node*)1) {\n");
+ fprintf(fp," idx0--; // Adjust base because memory edge hasn't been inserted yet\n");
+ fprintf(fp," }\n");
}
for( i = 0; i < node->num_opnds(); i++ ) {
@@ -1611,9 +1612,11 @@
int node_mem_op = node->memory_operand(_globalNames);
assert( node_mem_op != InstructForm::NO_MEMORY_OPERAND,
"expand rule member needs memory but top-level inst doesn't have any" );
- if (!missing_memory_edge) {
+ if (has_memory_edge) {
// Copy memory edge
- fprintf(fp," n%d->add_req(_in[1]);\t// Add memory edge\n", cnt);
+ fprintf(fp," if (mem != (Node*)1) {\n");
+ fprintf(fp," n%d->add_req(_in[1]);\t// Add memory edge\n", cnt);
+ fprintf(fp," }\n");
}
}
@@ -1689,7 +1692,7 @@
} // done iterating over a new instruction's operands
// Invoke Expand() for the newly created instruction.
- fprintf(fp," result = n%d->Expand( state, proj_list );\n", cnt);
+ fprintf(fp," result = n%d->Expand( state, proj_list, mem );\n", cnt);
assert( !new_inst->expands(), "Do not have complete support for recursive expansion");
} // done iterating over new instructions
fprintf(fp,"\n");
diff -r 39e409a664b3 -r 84043c7507b9 src/share/vm/adlc/output_h.cpp
--- a/src/share/vm/adlc/output_h.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/share/vm/adlc/output_h.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2010 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
@@ -1754,7 +1754,7 @@
instr->has_temps() ||
instr->_matrule != NULL &&
instr->num_opnds() != instr->num_unique_opnds() ) {
- fprintf(fp," virtual MachNode *Expand(State *state, Node_List &proj_list);\n");
+ fprintf(fp," virtual MachNode *Expand(State *state, Node_List &proj_list, Node* mem);\n");
}
if (instr->is_pinned(_globalNames)) {
diff -r 39e409a664b3 -r 84043c7507b9 src/share/vm/asm/codeBuffer.hpp
--- a/src/share/vm/asm/codeBuffer.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/share/vm/asm/codeBuffer.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -39,6 +39,7 @@
Dtrace_trap = OSR_Entry, // dtrace probes can never have an OSR entry so reuse it
Exceptions, // Offset where exception handler lives
Deopt, // Offset where deopt handler lives
+ DeoptMH, // Offset where MethodHandle deopt handler lives
max_Entries };
// special value to note codeBlobs where profile (forte) stack walking is
@@ -51,12 +52,13 @@
public:
CodeOffsets() {
- _values[Entry] = 0;
+ _values[Entry ] = 0;
_values[Verified_Entry] = 0;
_values[Frame_Complete] = frame_never_safe;
- _values[OSR_Entry] = 0;
- _values[Exceptions] = -1;
- _values[Deopt] = -1;
+ _values[OSR_Entry ] = 0;
+ _values[Exceptions ] = -1;
+ _values[Deopt ] = -1;
+ _values[DeoptMH ] = -1;
}
int value(Entries e) { return _values[e]; }
diff -r 39e409a664b3 -r 84043c7507b9 src/share/vm/c1/c1_Compilation.cpp
--- a/src/share/vm/c1/c1_Compilation.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/share/vm/c1/c1_Compilation.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -205,6 +205,8 @@
void Compilation::emit_code_epilog(LIR_Assembler* assembler) {
CHECK_BAILOUT();
+ CodeOffsets* code_offsets = assembler->offsets();
+
// generate code or slow cases
assembler->emit_slow_case_stubs();
CHECK_BAILOUT();
@@ -213,10 +215,18 @@
assembler->emit_exception_entries(exception_info_list());
CHECK_BAILOUT();
- // generate code for exception handler
- assembler->emit_exception_handler();
+ // Generate code for exception handler.
+ code_offsets->set_value(CodeOffsets::Exceptions, assembler->emit_exception_handler());
CHECK_BAILOUT();
- assembler->emit_deopt_handler();
+
+ // Generate code for deopt handler.
+ code_offsets->set_value(CodeOffsets::Deopt, assembler->emit_deopt_handler());
+ CHECK_BAILOUT();
+
+ // Generate code for MethodHandle deopt handler. We can use the
+ // same code as for the normal deopt handler, we just need a
+ // different entry point address.
+ code_offsets->set_value(CodeOffsets::DeoptMH, assembler->emit_deopt_handler());
CHECK_BAILOUT();
// done
diff -r 39e409a664b3 -r 84043c7507b9 src/share/vm/c1/c1_GraphBuilder.cpp
--- a/src/share/vm/c1/c1_GraphBuilder.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/share/vm/c1/c1_GraphBuilder.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -365,7 +365,7 @@
if (_next_loop_index < 31) _next_loop_index++;
} else {
// block already marked as loop header
- assert(is_power_of_2(_loop_map.at(block->block_id())), "exactly one bit must be set");
+ assert(is_power_of_2((unsigned int)_loop_map.at(block->block_id())), "exactly one bit must be set");
}
}
@@ -1442,7 +1442,7 @@
switch (field_type) {
case T_ARRAY:
case T_OBJECT:
- if (field_val.as_object()->has_encoding()) {
+ if (field_val.as_object()->should_be_constant()) {
constant = new Constant(as_ValueType(field_val));
}
break;
diff -r 39e409a664b3 -r 84043c7507b9 src/share/vm/c1/c1_IR.cpp
--- a/src/share/vm/c1/c1_IR.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/share/vm/c1/c1_IR.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2009 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
diff -r 39e409a664b3 -r 84043c7507b9 src/share/vm/c1/c1_IR.hpp
--- a/src/share/vm/c1/c1_IR.hpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/share/vm/c1/c1_IR.hpp Thu Mar 25 16:54:59 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2009 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
@@ -251,8 +251,10 @@
DebugToken* expvals = recorder->create_scope_values(expressions());
DebugToken* monvals = recorder->create_monitor_values(monitors());
// reexecute allowed only for the topmost frame
- bool reexecute = topmost ? should_reexecute() : false;
- recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, locvals, expvals, monvals);
+ bool reexecute = topmost ? should_reexecute() : false;
+ bool is_method_handle_invoke = false;
+ bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis.
+ recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
}
};
diff -r 39e409a664b3 -r 84043c7507b9 src/share/vm/c1/c1_InstructionPrinter.cpp
--- a/src/share/vm/c1/c1_InstructionPrinter.cpp Thu Mar 25 16:27:12 2010 -0700
+++ b/src/share/vm/c1/c1_InstructionPrinter.cpp Thu Mar 25 16:54:59 2010 -0700
@@ -133,12 +133,12 @@
ciMethod* m = (ciMethod*)value;
output()->print("", m->holder()->name()->as_utf8(), m->name()->as_utf8());
} else {
- output()->print("