This commit is contained in:
Lana Steuck 2011-09-09 17:22:03 -07:00
commit 4ade26a0ee
1589 changed files with 119067 additions and 36512 deletions

View File

@ -122,3 +122,6 @@ f4298bc3f4b6baa315643be06966f09684290068 jdk7-b140
8294c99e685a1f6d1d37c45cd97854cf74be771e jdk7-b145 8294c99e685a1f6d1d37c45cd97854cf74be771e jdk7-b145
dca1e8a87e8f756f95b99bac8fe795750d42e1b0 jdk7-b146 dca1e8a87e8f756f95b99bac8fe795750d42e1b0 jdk7-b146
a2a589fc29543ed32919c78a1810ad93a6fcf5bc jdk7-b147 a2a589fc29543ed32919c78a1810ad93a6fcf5bc jdk7-b147
de9223c94f9c710b3eebb599cd3586f36c8b94a9 jdk8-b01
1b9d19620eb4606a25b1e28f86d66c8bfa867e06 jdk8-b02
6815e85bf96d6d3875954f9777660372cd70d065 jdk8-b03

View File

@ -122,3 +122,6 @@ cfbbdb77eac0397b03eb99ee2e07ea00e0a7b81e jdk7-b142
55e9ebf032186c333e5964ed044419830ac02693 jdk7-b145 55e9ebf032186c333e5964ed044419830ac02693 jdk7-b145
2d38c2a79c144c30cd04d143d83ee7ec6af40771 jdk7-b146 2d38c2a79c144c30cd04d143d83ee7ec6af40771 jdk7-b146
d91364304d7c4ecd34caffdba2b840aeb0d10b51 jdk7-b147 d91364304d7c4ecd34caffdba2b840aeb0d10b51 jdk7-b147
f42e3d9394b40a423d345b8da22687b5462e5f25 jdk8-b01
69f592185747226a9c765a9fe139c1d34d616f9c jdk8-b02
587bb549dff83131b65f40aa51864f69562f34a7 jdk8-b03

15
README
View File

@ -9,11 +9,14 @@ README:
will be needed. will be needed.
This one root repository can be obtained with something like: This one root repository can be obtained with something like:
hg clone http://hg.openjdk.java.net/jdk7/jdk7 openjdk7
To make sure you have all the nested repositories, you can run: hg clone http://hg.openjdk.java.net/jdk8/jdk8 openjdk8
cd openjdk7 && sh ./get_source.sh
(This is identical to using the Mercurial Forest Extension command To make sure you have all the nested repositories, you can run the
'hg fclone http://hg.openjdk.java.net/jdk7/jdk7 openjdk7'). get_source.sh script located in the same respository as this file:
cd openjdk8 && sh ./get_source.sh
People unfamiliar with Mercurial should read the first few chapters of People unfamiliar with Mercurial should read the first few chapters of
the Mercurial book: http://hgbook.red-bean.com/read/ the Mercurial book: http://hgbook.red-bean.com/read/
@ -22,7 +25,7 @@ README:
Simple Build Instructions: Simple Build Instructions:
0. Get the necessary system software/packages installed on your system, see 0. Get the necessary system software/packages installed on your system, see
http://hg.openjdk.java.net/jdk7/build/raw-file/tip/README-builds.html http://hg.openjdk.java.net/jdk8/build/raw-file/tip/README-builds.html
1. If you don't have a jdk6 installed, download and install a JDK 6 from 1. If you don't have a jdk6 installed, download and install a JDK 6 from
http://java.sun.com/javase/downloads/index.jsp http://java.sun.com/javase/downloads/index.jsp

View File

@ -126,38 +126,15 @@
<a href="http://openjdk.java.net/guide/repositories.html#installConfig"> <a href="http://openjdk.java.net/guide/repositories.html#installConfig">
Developer Guide: Installing and Configuring Mercurial</a> Developer Guide: Installing and Configuring Mercurial</a>
section for more information. section for more information.
The Forest Extension is not part of the Mercurial install,
and is optional,
but can be obtained with the following commands:
<blockquote>
<tt>
hg clone https://bitbucket.org/pmezard/hgforest-crew/overview/ <i>YourHgForest</i>
</tt>
</blockquote>
Once you have the file <tt>forest.py</tt>, you need to add these
lines to your <tt>${HOME}/.hgrc</tt> file:
<blockquote>
<tt>
[extensions]
<br>forest = <i>YourHgForest</i>/forest.py
</tt>
</blockquote>
<!-- ------------------------------------------------------ --> <!-- ------------------------------------------------------ -->
<h3><a name="get_source">Getting the Source</a></h3> <h3><a name="get_source">Getting the Source</a></h3>
<blockquote> <blockquote>
To get the entire set of OpenJDK Mercurial repositories To get the entire set of OpenJDK Mercurial repositories
using the Forest Extension: use the script <code>get_source.sh</code> located in the root repository:
<blockquote> <blockquote>
<tt> <tt>
hg fclone http://hg.openjdk.java.net/jdk7/jdk7 <i>YourOpenJDK</i> hg clone http://hg.openjdk.java.net/jdk8/jdk8 <i>YourOpenJDK</i>
</tt>
</blockquote>
To get the entire set of OpenJDK Mercurial repositories
without using the Forest Extension:
<blockquote>
<tt>
hg clone http://hg.openjdk.java.net/jdk7/jdk7 <i>YourOpenJDK</i>
<br>cd <i>YourOpenJDK</i> <br>cd <i>YourOpenJDK</i>
<br>sh ./get_source.sh <br>sh ./get_source.sh
</tt> </tt>
@ -172,9 +149,6 @@
<br>sh ./make/scripts/hgforest.sh pull -u <br>sh ./make/scripts/hgforest.sh pull -u
</tt> </tt>
</blockquote> </blockquote>
You may find this script <tt>make/scripts/hgforest.sh</tt> faster
than the <tt>hg</tt> forest commands provided by the
Forest Extension.
</blockquote> </blockquote>
</blockquote> </blockquote>
@ -558,7 +532,7 @@
understood that this is not ideal for the open source community. understood that this is not ideal for the open source community.
It is possible this process could change in the future. It is possible this process could change in the future.
<br> <br>
<b>NOTE:</b> The <a href="http://download.java.net/openjdk/jdk7/"> <b>NOTE:</b> The <a href="http://download.java.net/openjdk/jdk8/">
Complete OpenJDK Source Bundles</a> <u>will</u> contain the JAXP and Complete OpenJDK Source Bundles</a> <u>will</u> contain the JAXP and
JAX-WS sources. JAX-WS sources.
</p> </p>
@ -578,7 +552,7 @@
</li> </li>
<li> <li>
The OpenJDK team copies this new bundle into shared The OpenJDK team copies this new bundle into shared
area (e.g. <tt>/java/devtools/share/jdk7-drops</tt>). area (e.g. <tt>/java/devtools/share/jdk8-drops</tt>).
Older bundles are never deleted so we retain the history. Older bundles are never deleted so we retain the history.
</li> </li>
<li> <li>
@ -1726,7 +1700,7 @@
The location of any source drop bundles The location of any source drop bundles
(see <a href="#drops">Managing the Source Drops</a>). (see <a href="#drops">Managing the Source Drops</a>).
The default will be The default will be
<tt>$(ALT_JDK_DEVTOOLS_PATH)/share/jdk7-drops</tt>. <tt>$(ALT_JDK_DEVTOOLS_PATH)/share/jdk8-drops</tt>.
</dd> </dd>
<dt><a name="ALT_UNIXCCS_PATH"><tt>ALT_UNIXCCS_PATH</tt></a></dt> <dt><a name="ALT_UNIXCCS_PATH"><tt>ALT_UNIXCCS_PATH</tt></a></dt>
<dd> <dd>
@ -1931,7 +1905,7 @@
PATH, INCLUDE, LIB, LIBPATH, and WINDOWSSDKDIR PATH, INCLUDE, LIB, LIBPATH, and WINDOWSSDKDIR
variables set in your shell environment. variables set in your shell environment.
These bat files are not easy to use from a shell environment. These bat files are not easy to use from a shell environment.
However, there is a script placed in the root jdk7 repository called However, there is a script placed in the root jdk8 repository called
vsvars.sh that can help, it should only be done once in a shell vsvars.sh that can help, it should only be done once in a shell
that will be doing the build, e.g.<br> that will be doing the build, e.g.<br>
<tt>sh ./make/scripts/vsvars.sh -v10 > settings<br> <tt>sh ./make/scripts/vsvars.sh -v10 > settings<br>

View File

@ -122,3 +122,6 @@ a2f340a048c88d10cbedc0504f5cf03d39925a40 jdk7-b142
77ec0541aa2aa4da27e9e385a118a2e51e7fca24 jdk7-b145 77ec0541aa2aa4da27e9e385a118a2e51e7fca24 jdk7-b145
770227a4087e4e401fe87ccd19738440111c3948 jdk7-b146 770227a4087e4e401fe87ccd19738440111c3948 jdk7-b146
73323cb3396260d93e0ab731fd2d431096ceed0f jdk7-b147 73323cb3396260d93e0ab731fd2d431096ceed0f jdk7-b147
949fb60ca830364571e7c4c9964e6b351ca929ec jdk8-b01
ed8d94519a87b4adac270c3eec9134ff1f62bff5 jdk8-b02
cd0da00694fbce642db9be936d3e4909a71d911d jdk8-b03

View File

@ -174,3 +174,6 @@ d283b82966712b353fa307845a1316da42a355f4 hs21-b10
9ad1548c6b63d596c411afc35147ffd5254426d9 hs21-b12 9ad1548c6b63d596c411afc35147ffd5254426d9 hs21-b12
c149193c768b8b7233da4c3a3fdc0756b975848e hs21-b13 c149193c768b8b7233da4c3a3fdc0756b975848e hs21-b13
c149193c768b8b7233da4c3a3fdc0756b975848e jdk7-b143 c149193c768b8b7233da4c3a3fdc0756b975848e jdk7-b143
0cc8a70952c368e06de2adab1f2649a408f5e577 jdk8-b01
31e253c1da429124bb87570ab095d9bc89850d0a jdk8-b02
3a2fb61165dfc72e398179a2796d740c8da5b8c0 jdk8-b03

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,7 @@ package sun.jvm.hotspot.interpreter;
import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.utilities.*; import sun.jvm.hotspot.utilities.*;
import sun.jvm.hotspot.runtime.VM;
public class Bytecode { public class Bytecode {
Method method; Method method;
@ -45,6 +46,23 @@ public class Bytecode {
return Bits.roundTo(bci + offset, jintSize) - bci; return Bits.roundTo(bci + offset, jintSize) - bci;
} }
public int getIndexU1() { return method.getBytecodeOrBPAt(bci() + 1) & 0xFF; }
public int getIndexU2(int bc, boolean isWide) {
if (can_use_native_byte_order(bc, isWide)) {
return method.getNativeShortArg(bci() + (isWide ? 2 : 1)) & 0xFFFF;
}
return method.getBytecodeShortArg(bci() + (isWide ? 2 : 1)) & 0xFFFF;
}
public int getIndexU4() { return method.getNativeIntArg(bci() + 1); }
public boolean hasIndexU4() { return code() == Bytecodes._invokedynamic; }
public int getIndexU1Cpcache() { return method.getBytecodeOrBPAt(bci() + 1) & 0xFF; }
public int getIndexU2Cpcache() { return method.getNativeShortArg(bci() + 1) & 0xFFFF; }
static boolean can_use_native_byte_order(int bc, boolean is_wide) {
return (VM.getVM().isBigEndian() || Bytecodes.native_byte_order(bc /*, is_wide*/));
}
int javaSignedWordAt(int offset) { int javaSignedWordAt(int offset) {
return method.getBytecodeIntArg(bci + offset); return method.getBytecodeIntArg(bci + offset);
} }

View File

@ -1,78 +0,0 @@
/*
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.interpreter;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.utilities.*;
public class BytecodeFastAAccess0 extends BytecodeGetPut {
BytecodeFastAAccess0(Method method, int bci) {
super(method, bci);
}
public int index() {
return (int) (0xFF & javaShortAt(2));
}
public boolean isStatic() {
return false;
}
public void verify() {
if (Assert.ASSERTS_ENABLED) {
Assert.that(isValid(), "check fast_aaccess_0");
}
}
public boolean isValid() {
return code() == Bytecodes._fast_aaccess_0;
}
public static BytecodeFastAAccess0 at(Method method, int bci) {
BytecodeFastAAccess0 b = new BytecodeFastAAccess0(method, bci);
if (Assert.ASSERTS_ENABLED) {
b.verify();
}
return b;
}
/** Like at, but returns null if the BCI is not at fast_aaccess_0 */
public static BytecodeFastAAccess0 atCheck(Method method, int bci) {
BytecodeFastAAccess0 b = new BytecodeFastAAccess0(method, bci);
return (b.isValid() ? b : null);
}
public static BytecodeFastAAccess0 at(BytecodeStream bcs) {
return new BytecodeFastAAccess0(bcs.method(), bcs.bci());
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("aload_0");
buf.append(spaces);
buf.append(super.toString());
return buf.toString();
}
}

View File

@ -1,78 +0,0 @@
/*
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.interpreter;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.utilities.*;
public class BytecodeFastIAccess0 extends BytecodeGetPut {
BytecodeFastIAccess0(Method method, int bci) {
super(method, bci);
}
public int index() {
return (int) (0xFF & javaShortAt(2));
}
public boolean isStatic() {
return false;
}
public void verify() {
if (Assert.ASSERTS_ENABLED) {
Assert.that(isValid(), "check fast_iaccess_0");
}
}
public boolean isValid() {
return code() == Bytecodes._fast_iaccess_0;
}
public static BytecodeFastIAccess0 at(Method method, int bci) {
BytecodeFastIAccess0 b = new BytecodeFastIAccess0(method, bci);
if (Assert.ASSERTS_ENABLED) {
b.verify();
}
return b;
}
/** Like at, but returns null if the BCI is not at fast_iaccess_0 */
public static BytecodeFastIAccess0 atCheck(Method method, int bci) {
BytecodeFastIAccess0 b = new BytecodeFastIAccess0(method, bci);
return (b.isValid() ? b : null);
}
public static BytecodeFastIAccess0 at(BytecodeStream bcs) {
return new BytecodeFastIAccess0(bcs.method(), bcs.bci());
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("aload_0");
buf.append(spaces);
buf.append(super.toString());
return buf.toString();
}
}

View File

@ -28,29 +28,25 @@ import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.utilities.*; import sun.jvm.hotspot.utilities.*;
public class BytecodeLoadConstant extends BytecodeWithCPIndex { public class BytecodeLoadConstant extends Bytecode {
BytecodeLoadConstant(Method method, int bci) { BytecodeLoadConstant(Method method, int bci) {
super(method, bci); super(method, bci);
} }
public boolean hasCacheIndex() { public boolean hasCacheIndex() {
// normal ldc uses CP index, but fast_aldc uses swapped CP cache index // normal ldc uses CP index, but fast_aldc uses swapped CP cache index
return javaCode() != code(); return code() >= Bytecodes.number_of_java_codes;
} }
public int index() { int rawIndex() {
int i = javaCode() == Bytecodes._ldc ? if (javaCode() == Bytecodes._ldc)
(int) (0xFF & javaByteAt(1)) return getIndexU1();
: (int) (0xFFFF & javaShortAt(1)); else
if (hasCacheIndex()) { return getIndexU2(code(), false);
return (0xFFFF & VM.getVM().getBytes().swapShort((short) i));
} else {
return i;
}
} }
public int poolIndex() { public int poolIndex() {
int i = index(); int i = rawIndex();
if (hasCacheIndex()) { if (hasCacheIndex()) {
ConstantPoolCache cpCache = method().getConstants().getCache(); ConstantPoolCache cpCache = method().getConstants().getCache();
return cpCache.getEntryAt(i).getConstantPoolIndex(); return cpCache.getEntryAt(i).getConstantPoolIndex();
@ -61,12 +57,18 @@ public class BytecodeLoadConstant extends BytecodeWithCPIndex {
public int cacheIndex() { public int cacheIndex() {
if (hasCacheIndex()) { if (hasCacheIndex()) {
return index(); return rawIndex();
} else { } else {
return -1; // no cache index return -1; // no cache index
} }
} }
public BasicType resultType() {
int index = poolIndex();
ConstantTag tag = method().getConstants().getTagAt(index);
return tag.basicType();
}
private Oop getCachedConstant() { private Oop getCachedConstant() {
int i = cacheIndex(); int i = cacheIndex();
if (i >= 0) { if (i >= 0) {
@ -88,7 +90,7 @@ public class BytecodeLoadConstant extends BytecodeWithCPIndex {
jcode == Bytecodes._ldc2_w; jcode == Bytecodes._ldc2_w;
if (! codeOk) return false; if (! codeOk) return false;
ConstantTag ctag = method().getConstants().getTagAt(index()); ConstantTag ctag = method().getConstants().getTagAt(rawIndex());
if (jcode == Bytecodes._ldc2_w) { if (jcode == Bytecodes._ldc2_w) {
// has to be double or long // has to be double or long
return (ctag.isDouble() || ctag.isLong()) ? true: false; return (ctag.isDouble() || ctag.isLong()) ? true: false;
@ -107,7 +109,7 @@ public class BytecodeLoadConstant extends BytecodeWithCPIndex {
return false; return false;
} }
ConstantTag ctag = method().getConstants().getTagAt(index()); ConstantTag ctag = method().getConstants().getTagAt(poolIndex());
return ctag.isKlass() || ctag.isUnresolvedKlass(); return ctag.isKlass() || ctag.isUnresolvedKlass();
} }
@ -120,7 +122,7 @@ public class BytecodeLoadConstant extends BytecodeWithCPIndex {
// We just look at the object at the corresponding index and // We just look at the object at the corresponding index and
// decide based on the oop type. // decide based on the oop type.
ConstantPool cpool = method().getConstants(); ConstantPool cpool = method().getConstants();
int cpIndex = index(); int cpIndex = poolIndex();
ConstantPool.CPSlot oop = cpool.getSlotAt(cpIndex); ConstantPool.CPSlot oop = cpool.getSlotAt(cpIndex);
if (oop.isOop()) { if (oop.isOop()) {
return (Klass) oop.getOop(); return (Klass) oop.getOop();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -130,7 +130,13 @@ public class BytecodeStream {
public int getIndex() { return (isWide()) public int getIndex() { return (isWide())
? (_method.getBytecodeShortArg(bci() + 2) & 0xFFFF) ? (_method.getBytecodeShortArg(bci() + 2) & 0xFFFF)
: (_method.getBytecodeOrBPAt(bci() + 1) & 0xFF); } : (_method.getBytecodeOrBPAt(bci() + 1) & 0xFF); }
public int getIndexBig() { return _method.getBytecodeShortArg(bci() + 1); } public int getIndexU1() { return _method.getBytecodeOrBPAt(bci() + 1) & 0xFF; }
public int getIndexU2() { return _method.getBytecodeShortArg(bci() + 1) & 0xFFFF; }
public int getIndexU4() { return _method.getNativeIntArg(bci() + 1); }
public boolean hasIndexU4() { return code() == Bytecodes._invokedynamic; }
public int getIndexU1Cpcache() { return _method.getBytecodeOrBPAt(bci() + 1) & 0xFF; }
public int getIndexU2Cpcache() { return _method.getNativeShortArg(bci() + 1) & 0xFFFF; }
// Fetch at absolute BCI (for manual parsing of certain bytecodes) // Fetch at absolute BCI (for manual parsing of certain bytecodes)
public int codeAt(int bci) { public int codeAt(int bci) {

View File

@ -38,7 +38,6 @@ public abstract class BytecodeWideable extends Bytecode {
// the local variable index // the local variable index
public int getLocalVarIndex() { public int getLocalVarIndex() {
return (isWide()) ? (int) (0xFFFF & javaShortAt(1)) return (isWide()) ? getIndexU2(code(), true) : getIndexU1();
: (int) (0xFF & javaByteAt(1));
} }
} }

View File

@ -35,7 +35,7 @@ public abstract class BytecodeWithCPIndex extends Bytecode {
} }
// the constant pool index for this bytecode // the constant pool index for this bytecode
public int index() { return 0xFFFF & javaShortAt(1); } public int index() { return getIndexU2(code(), false); }
public int getSecondaryIndex() { public int getSecondaryIndex() {
throw new IllegalArgumentException("must be invokedynamic"); throw new IllegalArgumentException("must be invokedynamic");

View File

@ -276,6 +276,34 @@ public class Bytecodes {
public static final int number_of_codes = 233; public static final int number_of_codes = 233;
// Flag bits derived from format strings, can_trap, can_rewrite, etc.:
// semantic flags:
static final int _bc_can_trap = 1<<0; // bytecode execution can trap or block
static final int _bc_can_rewrite = 1<<1; // bytecode execution has an alternate form
// format bits (determined only by the format string):
static final int _fmt_has_c = 1<<2; // constant, such as sipush "bcc"
static final int _fmt_has_j = 1<<3; // constant pool cache index, such as getfield "bjj"
static final int _fmt_has_k = 1<<4; // constant pool index, such as ldc "bk"
static final int _fmt_has_i = 1<<5; // local index, such as iload
static final int _fmt_has_o = 1<<6; // offset, such as ifeq
static final int _fmt_has_nbo = 1<<7; // contains native-order field(s)
static final int _fmt_has_u2 = 1<<8; // contains double-byte field(s)
static final int _fmt_has_u4 = 1<<9; // contains quad-byte field
static final int _fmt_not_variable = 1<<10; // not of variable length (simple or wide)
static final int _fmt_not_simple = 1<<11; // either wide or variable length
static final int _all_fmt_bits = (_fmt_not_simple*2 - _fmt_has_c);
// Example derived format syndromes:
static final int _fmt_b = _fmt_not_variable;
static final int _fmt_bc = _fmt_b | _fmt_has_c;
static final int _fmt_bi = _fmt_b | _fmt_has_i;
static final int _fmt_bkk = _fmt_b | _fmt_has_k | _fmt_has_u2;
static final int _fmt_bJJ = _fmt_b | _fmt_has_j | _fmt_has_u2 | _fmt_has_nbo;
static final int _fmt_bo2 = _fmt_b | _fmt_has_o | _fmt_has_u2;
static final int _fmt_bo4 = _fmt_b | _fmt_has_o | _fmt_has_u4;
public static int specialLengthAt(Method method, int bci) { public static int specialLengthAt(Method method, int bci) {
int code = codeAt(method, bci); int code = codeAt(method, bci);
switch (code) { switch (code) {
@ -337,18 +365,20 @@ public class Bytecodes {
// static Code non_breakpoint_code_at(address bcp, methodOop method = null); // static Code non_breakpoint_code_at(address bcp, methodOop method = null);
// Bytecode attributes // Bytecode attributes
public static boolean isDefined (int code) { return 0 <= code && code < number_of_codes && _format[code] != null; } public static boolean isDefined (int code) { return 0 <= code && code < number_of_codes && flags(code, false) != 0; }
public static boolean wideIsDefined(int code) { return isDefined(code) && _wide_format[code] != null; } public static boolean wideIsDefined(int code) { return isDefined(code) && flags(code, true) != 0; }
public static String name (int code) { check(code); return _name [code]; } public static String name (int code) { check(code); return _name [code]; }
public static String format (int code) { check(code); return _format [code]; } public static String format (int code) { check(code); return _format [code]; }
public static String wideFormat (int code) { wideCheck(code); return _wide_format [code]; } public static String wideFormat (int code) { wideCheck(code); return _wide_format [code]; }
public static int resultType (int code) { check(code); return _result_type [code]; } public static int resultType (int code) { check(code); return _result_type [code]; }
public static int depth (int code) { check(code); return _depth [code]; } public static int depth (int code) { check(code); return _depth [code]; }
public static int lengthFor (int code) { check(code); return _length [code]; } public static int lengthFor (int code) { check(code); return _lengths [code] & 0xF; }
public static boolean canTrap (int code) { check(code); return _can_trap [code]; } public static int wideLengthFor(int code) { check(code); return _lengths [code] >> 4; }
public static boolean canTrap (int code) { check(code); return has_all_flags(code, _bc_can_trap, false); }
public static int javaCode (int code) { check(code); return _java_code [code]; } public static int javaCode (int code) { check(code); return _java_code [code]; }
public static boolean canRewrite (int code) { check(code); return _can_rewrite [code]; } public static boolean canRewrite (int code) { check(code); return has_all_flags(code, _bc_can_rewrite, false); }
public static int wideLengthFor(int code) { wideCheck(code); return wideFormat(code).length(); } public static boolean native_byte_order(int code) { check(code); return has_all_flags(code, _fmt_has_nbo, false); }
public static boolean uses_cp_cache (int code) { check(code); return has_all_flags(code, _fmt_has_j, false); }
public static int lengthAt (Method method, int bci) { int l = lengthFor(codeAt(method, bci)); return l > 0 ? l : specialLengthAt(method, bci); } public static int lengthAt (Method method, int bci) { int l = lengthFor(codeAt(method, bci)); return l > 0 ? l : specialLengthAt(method, bci); }
public static int javaLengthAt (Method method, int bci) { int l = lengthFor(javaCode(codeAt(method, bci))); return l > 0 ? l : specialLengthAt(method, bci); } public static int javaLengthAt (Method method, int bci) { int l = lengthFor(javaCode(codeAt(method, bci))); return l > 0 ? l : specialLengthAt(method, bci); }
public static boolean isJavaCode (int code) { return 0 <= code && code < number_of_java_codes; } public static boolean isJavaCode (int code) { return 0 <= code && code < number_of_java_codes; }
@ -362,6 +392,92 @@ public class Bytecodes {
public static boolean isZeroConst (int code) { return (code == _aconst_null || code == _iconst_0 public static boolean isZeroConst (int code) { return (code == _aconst_null || code == _iconst_0
|| code == _fconst_0 || code == _dconst_0); } || code == _fconst_0 || code == _dconst_0); }
static int flags (int code, boolean is_wide) {
assert code == (code & 0xff) : "must be a byte";
return _flags[code + (is_wide ? 256 : 0)];
}
static int format_bits (int code, boolean is_wide) { return flags(code, is_wide) & _all_fmt_bits; }
static boolean has_all_flags (int code, int test_flags, boolean is_wide) {
return (flags(code, is_wide) & test_flags) == test_flags;
}
static char compute_flags(String format) {
return compute_flags(format, 0);
}
static char compute_flags(String format, int more_flags) {
if (format == null) return 0; // not even more_flags
int flags = more_flags;
int fp = 0;
if (format.length() == 0) {
flags |= _fmt_not_simple; // but variable
} else {
switch (format.charAt(fp)) {
case 'b':
flags |= _fmt_not_variable; // but simple
++fp; // skip 'b'
break;
case 'w':
flags |= _fmt_not_variable | _fmt_not_simple;
++fp; // skip 'w'
assert(format.charAt(fp) == 'b') : "wide format must start with 'wb'";
++fp; // skip 'b'
break;
}
}
boolean has_nbo = false, has_jbo = false;
int has_size = 0;
while (fp < format.length()) {
int this_flag = 0;
char fc = format.charAt(fp++);
switch (fc) {
case '_': continue; // ignore these
case 'j': this_flag = _fmt_has_j; has_jbo = true; break;
case 'k': this_flag = _fmt_has_k; has_jbo = true; break;
case 'i': this_flag = _fmt_has_i; has_jbo = true; break;
case 'c': this_flag = _fmt_has_c; has_jbo = true; break;
case 'o': this_flag = _fmt_has_o; has_jbo = true; break;
// uppercase versions mark native byte order (from Rewriter)
// actually, only the 'J' case happens currently
case 'J': this_flag = _fmt_has_j; has_nbo = true; break;
case 'K': this_flag = _fmt_has_k; has_nbo = true; break;
case 'I': this_flag = _fmt_has_i; has_nbo = true; break;
case 'C': this_flag = _fmt_has_c; has_nbo = true; break;
case 'O': this_flag = _fmt_has_o; has_nbo = true; break;
default: assert false : "bad char in format";
}
flags |= this_flag;
assert !(has_jbo && has_nbo) : "mixed byte orders in format";
if (has_nbo)
flags |= _fmt_has_nbo;
int this_size = 1;
if (fp < format.length() && format.charAt(fp) == fc) {
// advance beyond run of the same characters
this_size = 2;
while (fp + 1 < format.length() && format.charAt(++fp) == fc) this_size++;
switch (this_size) {
case 2: flags |= _fmt_has_u2; break;
case 4: flags |= _fmt_has_u4; break;
default: assert false : "bad rep count in format";
}
}
assert has_size == 0 || // no field yet
this_size == has_size || // same size
this_size < has_size && fp == format.length() : // last field can be short
"mixed field sizes in format";
has_size = this_size;
}
assert flags == (char)flags : "change _format_flags";
return (char)flags;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Internals only below this point // Internals only below this point
// //
@ -371,10 +487,9 @@ public class Bytecodes {
private static String[] _wide_format; private static String[] _wide_format;
private static int[] _result_type; private static int[] _result_type;
private static byte[] _depth; private static byte[] _depth;
private static byte[] _length; private static byte[] _lengths;
private static boolean[] _can_trap;
private static int[] _java_code; private static int[] _java_code;
private static boolean[] _can_rewrite; private static char[] _flags;
static { static {
_name = new String [number_of_codes]; _name = new String [number_of_codes];
@ -382,10 +497,9 @@ public class Bytecodes {
_wide_format = new String [number_of_codes]; _wide_format = new String [number_of_codes];
_result_type = new int [number_of_codes]; // See BasicType.java _result_type = new int [number_of_codes]; // See BasicType.java
_depth = new byte [number_of_codes]; _depth = new byte [number_of_codes];
_length = new byte [number_of_codes]; _lengths = new byte [number_of_codes];
_can_trap = new boolean[number_of_codes];
_java_code = new int [number_of_codes]; _java_code = new int [number_of_codes];
_can_rewrite = new boolean[number_of_codes]; _flags = new char[256 * 2]; // all second page for wide formats
// In case we want to fetch this information from the VM in the // In case we want to fetch this information from the VM in the
// future // future
@ -712,18 +826,19 @@ public class Bytecodes {
if (Assert.ASSERTS_ENABLED) { if (Assert.ASSERTS_ENABLED) {
Assert.that(wide_format == null || format != null, "short form must exist if there's a wide form"); Assert.that(wide_format == null || format != null, "short form must exist if there's a wide form");
} }
int len = (format != null ? format.length() : 0);
int wlen = (wide_format != null ? wide_format.length() : 0);
_name [code] = name; _name [code] = name;
_format [code] = format;
_wide_format [code] = wide_format;
_result_type [code] = result_type; _result_type [code] = result_type;
_depth [code] = (byte) depth; _depth [code] = (byte) depth;
_can_trap [code] = can_trap; _lengths [code] = (byte)((wlen << 4) | (len & 0xF));
_length [code] = (byte) (format != null ? format.length() : 0);
_java_code [code] = java_code; _java_code [code] = java_code;
if (java_code != code) { _format [code] = format;
_can_rewrite[java_code] = true; _wide_format [code] = wide_format;
} else { int bc_flags = 0;
_can_rewrite[java_code] = false; if (can_trap) bc_flags |= _bc_can_trap;
} if (java_code != code) bc_flags |= _bc_can_rewrite;
_flags[code+0*256] = compute_flags(format, bc_flags);
_flags[code+1*256] = compute_flags(wide_format, bc_flags);
} }
} }

View File

@ -164,6 +164,18 @@ public class ConstMethod extends Oop {
return (short) ((hi << 8) | lo); return (short) ((hi << 8) | lo);
} }
/** Fetches a 16-bit native ordered value from the
bytecode stream */
public short getNativeShortArg(int bci) {
int hi = getBytecodeOrBPAt(bci);
int lo = getBytecodeOrBPAt(bci + 1);
if (VM.getVM().isBigEndian()) {
return (short) ((hi << 8) | lo);
} else {
return (short) ((lo << 8) | hi);
}
}
/** Fetches a 32-bit big-endian ("Java ordered") value from the /** Fetches a 32-bit big-endian ("Java ordered") value from the
bytecode stream */ bytecode stream */
public int getBytecodeIntArg(int bci) { public int getBytecodeIntArg(int bci) {
@ -175,6 +187,21 @@ public class ConstMethod extends Oop {
return (b4 << 24) | (b3 << 16) | (b2 << 8) | b1; return (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;
} }
/** Fetches a 32-bit native ordered value from the
bytecode stream */
public int getNativeIntArg(int bci) {
int b4 = getBytecodeOrBPAt(bci);
int b3 = getBytecodeOrBPAt(bci + 1);
int b2 = getBytecodeOrBPAt(bci + 2);
int b1 = getBytecodeOrBPAt(bci + 3);
if (VM.getVM().isBigEndian()) {
return (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;
} else {
return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
}
}
public byte[] getByteCode() { public byte[] getByteCode() {
byte[] bc = new byte[ (int) getCodeSize() ]; byte[] bc = new byte[ (int) getCodeSize() ];
for( int i=0; i < bc.length; i++ ) for( int i=0; i < bc.length; i++ )

View File

@ -212,13 +212,60 @@ public class ConstantPool extends Oop implements ClassConstants {
} }
public Symbol getNameRefAt(int which) { public Symbol getNameRefAt(int which) {
int nameIndex = getNameAndTypeAt(getNameAndTypeRefIndexAt(which))[0]; return implGetNameRefAt(which, false);
return getSymbolAt(nameIndex); }
private Symbol implGetNameRefAt(int which, boolean uncached) {
int signatureIndex = getNameRefIndexAt(implNameAndTypeRefIndexAt(which, uncached));
return getSymbolAt(signatureIndex);
} }
public Symbol getSignatureRefAt(int which) { public Symbol getSignatureRefAt(int which) {
int sigIndex = getNameAndTypeAt(getNameAndTypeRefIndexAt(which))[1]; return implGetSignatureRefAt(which, false);
return getSymbolAt(sigIndex); }
private Symbol implGetSignatureRefAt(int which, boolean uncached) {
int signatureIndex = getSignatureRefIndexAt(implNameAndTypeRefIndexAt(which, uncached));
return getSymbolAt(signatureIndex);
}
private int implNameAndTypeRefIndexAt(int which, boolean uncached) {
int i = which;
if (!uncached && getCache() != null) {
if (ConstantPoolCache.isSecondaryIndex(which)) {
// Invokedynamic index.
int pool_index = getCache().getMainEntryAt(which).getConstantPoolIndex();
pool_index = invokeDynamicNameAndTypeRefIndexAt(pool_index);
// assert(tagAt(pool_index).isNameAndType(), "");
return pool_index;
}
// change byte-ordering and go via cache
i = remapInstructionOperandFromCache(which);
} else {
if (getTagAt(which).isInvokeDynamic()) {
int pool_index = invokeDynamicNameAndTypeRefIndexAt(which);
// assert(tag_at(pool_index).is_name_and_type(), "");
return pool_index;
}
}
// assert(tag_at(i).is_field_or_method(), "Corrupted constant pool");
// assert(!tag_at(i).is_invoke_dynamic(), "Must be handled above");
int ref_index = getIntAt(i);
return extractHighShortFromInt(ref_index);
}
private int remapInstructionOperandFromCache(int operand) {
int cpc_index = operand;
// DEBUG_ONLY(cpc_index -= CPCACHE_INDEX_TAG);
// assert((int)(u2)cpc_index == cpc_index, "clean u2");
int member_index = getCache().getEntryAt(cpc_index).getConstantPoolIndex();
return member_index;
}
int invokeDynamicNameAndTypeRefIndexAt(int which) {
// assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
return extractHighShortFromInt(getIntAt(which));
} }
// returns null, if not resolved. // returns null, if not resolved.
@ -253,15 +300,7 @@ public class ConstantPool extends Oop implements ClassConstants {
} }
public int getNameAndTypeRefIndexAt(int index) { public int getNameAndTypeRefIndexAt(int index) {
int refIndex = getFieldOrMethodAt(index); return implNameAndTypeRefIndexAt(index, false);
if (DEBUG) {
System.err.println("ConstantPool.getNameAndTypeRefIndexAt(" + index + "): refIndex = " + refIndex);
}
int i = extractHighShortFromInt(refIndex);
if (DEBUG) {
System.err.println("ConstantPool.getNameAndTypeRefIndexAt(" + index + "): result = " + i);
}
return i;
} }
/** Lookup for entries consisting of (name_index, signature_index) */ /** Lookup for entries consisting of (name_index, signature_index) */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -72,9 +72,7 @@ public class ConstantPoolCache extends Oop {
} }
public ConstantPoolCacheEntry getEntryAt(int i) { public ConstantPoolCacheEntry getEntryAt(int i) {
if (Assert.ASSERTS_ENABLED) { if (i < 0 || i >= getLength()) throw new IndexOutOfBoundsException(i + " " + getLength());
Assert.that(0 <= i && i < getLength(), "index out of bounds");
}
return new ConstantPoolCacheEntry(this, i); return new ConstantPoolCacheEntry(this, i);
} }
@ -84,21 +82,27 @@ public class ConstantPoolCache extends Oop {
// secondary entries hold invokedynamic call site bindings // secondary entries hold invokedynamic call site bindings
public ConstantPoolCacheEntry getSecondaryEntryAt(int i) { public ConstantPoolCacheEntry getSecondaryEntryAt(int i) {
ConstantPoolCacheEntry e = new ConstantPoolCacheEntry(this, decodeSecondaryIndex(i)); int rawIndex = i;
if (isSecondaryIndex(i)) {
rawIndex = decodeSecondaryIndex(i);
}
ConstantPoolCacheEntry e = getEntryAt(rawIndex);
if (Assert.ASSERTS_ENABLED) { if (Assert.ASSERTS_ENABLED) {
Assert.that(e.isSecondaryEntry(), "must be a secondary entry"); Assert.that(e.isSecondaryEntry(), "must be a secondary entry:" + rawIndex);
} }
return e; return e;
} }
public ConstantPoolCacheEntry getMainEntryAt(int i) { public ConstantPoolCacheEntry getMainEntryAt(int i) {
int primaryIndex = i;
if (isSecondaryIndex(i)) { if (isSecondaryIndex(i)) {
// run through an extra level of indirection: // run through an extra level of indirection:
i = getSecondaryEntryAt(i).getMainEntryIndex(); int rawIndex = decodeSecondaryIndex(i);
primaryIndex = getEntryAt(rawIndex).getMainEntryIndex();
} }
ConstantPoolCacheEntry e = new ConstantPoolCacheEntry(this, i); ConstantPoolCacheEntry e = getEntryAt(primaryIndex);
if (Assert.ASSERTS_ENABLED) { if (Assert.ASSERTS_ENABLED) {
Assert.that(!e.isSecondaryEntry(), "must not be a secondary entry"); Assert.that(!e.isSecondaryEntry(), "must not be a secondary entry:" + primaryIndex);
} }
return e; return e;
} }

View File

@ -569,10 +569,10 @@ public class GenerateOopMap {
case Bytecodes._invokedynamic: case Bytecodes._invokedynamic:
// FIXME: print signature of referenced method (need more // FIXME: print signature of referenced method (need more
// accessors in ConstantPool and ConstantPoolCache) // accessors in ConstantPool and ConstantPoolCache)
int idx = currentBC.getIndexBig(); int idx = currentBC.hasIndexU4() ? currentBC.getIndexU4() : currentBC.getIndexU2();
tty.print(" idx " + idx); tty.print(" idx " + idx);
/* /*
int idx = currentBC.getIndexBig(); int idx = currentBC.getIndexU2();
ConstantPool cp = method().getConstants(); ConstantPool cp = method().getConstants();
int nameAndTypeIdx = cp.name_and_type_ref_index_at(idx); int nameAndTypeIdx = cp.name_and_type_ref_index_at(idx);
int signatureIdx = cp.signature_ref_index_at(nameAndTypeIdx); int signatureIdx = cp.signature_ref_index_at(nameAndTypeIdx);
@ -609,10 +609,10 @@ public class GenerateOopMap {
case Bytecodes._invokedynamic: case Bytecodes._invokedynamic:
// FIXME: print signature of referenced method (need more // FIXME: print signature of referenced method (need more
// accessors in ConstantPool and ConstantPoolCache) // accessors in ConstantPool and ConstantPoolCache)
int idx = currentBC.getIndexBig(); int idx = currentBC.hasIndexU4() ? currentBC.getIndexU4() : currentBC.getIndexU2();
tty.print(" idx " + idx); tty.print(" idx " + idx);
/* /*
int idx = currentBC.getIndexBig(); int idx = currentBC.getIndexU2();
constantPoolOop cp = method().constants(); constantPoolOop cp = method().constants();
int nameAndTypeIdx = cp.name_and_type_ref_index_at(idx); int nameAndTypeIdx = cp.name_and_type_ref_index_at(idx);
int signatureIdx = cp.signature_ref_index_at(nameAndTypeIdx); int signatureIdx = cp.signature_ref_index_at(nameAndTypeIdx);
@ -1118,7 +1118,8 @@ public class GenerateOopMap {
current instruction, starting in the current state. */ current instruction, starting in the current state. */
void interp1 (BytecodeStream itr) { void interp1 (BytecodeStream itr) {
if (DEBUG) { if (DEBUG) {
System.err.println(" - bci " + itr.bci()); System.err.println(" - bci " + itr.bci() + " " + itr.code());
printCurrentState(System.err, itr, false);
} }
// if (TraceNewOopMapGeneration) { // if (TraceNewOopMapGeneration) {
@ -1179,8 +1180,8 @@ public class GenerateOopMap {
case Bytecodes._ldc2_w: ppush(vvCTS); break; case Bytecodes._ldc2_w: ppush(vvCTS); break;
case Bytecodes._ldc: doLdc(itr.getIndex(), itr.bci()); break; case Bytecodes._ldc: doLdc(itr.bci()); break;
case Bytecodes._ldc_w: doLdc(itr.getIndexBig(), itr.bci());break; case Bytecodes._ldc_w: doLdc(itr.bci()); break;
case Bytecodes._iload: case Bytecodes._iload:
case Bytecodes._fload: ppload(vCTS, itr.getIndex()); break; case Bytecodes._fload: ppload(vCTS, itr.getIndex()); break;
@ -1372,18 +1373,16 @@ public class GenerateOopMap {
case Bytecodes._jsr: doJsr(itr.dest()); break; case Bytecodes._jsr: doJsr(itr.dest()); break;
case Bytecodes._jsr_w: doJsr(itr.dest_w()); break; case Bytecodes._jsr_w: doJsr(itr.dest_w()); break;
case Bytecodes._getstatic: doField(true, true, case Bytecodes._getstatic: doField(true, true, itr.getIndexU2Cpcache(), itr.bci()); break;
itr.getIndexBig(), case Bytecodes._putstatic: doField(false, true, itr.getIndexU2Cpcache(), itr.bci()); break;
itr.bci()); break; case Bytecodes._getfield: doField(true, false, itr.getIndexU2Cpcache(), itr.bci()); break;
case Bytecodes._putstatic: doField(false, true, itr.getIndexBig(), itr.bci()); break; case Bytecodes._putfield: doField(false, false, itr.getIndexU2Cpcache(), itr.bci()); break;
case Bytecodes._getfield: doField(true, false, itr.getIndexBig(), itr.bci()); break;
case Bytecodes._putfield: doField(false, false, itr.getIndexBig(), itr.bci()); break;
case Bytecodes._invokevirtual: case Bytecodes._invokevirtual:
case Bytecodes._invokespecial: doMethod(false, false, itr.getIndexBig(), itr.bci()); break; case Bytecodes._invokespecial: doMethod(false, false, itr.getIndexU2Cpcache(), itr.bci()); break;
case Bytecodes._invokestatic: doMethod(true, false, itr.getIndexBig(), itr.bci()); break; case Bytecodes._invokestatic: doMethod(true, false, itr.getIndexU2Cpcache(), itr.bci()); break;
case Bytecodes._invokedynamic: doMethod(false, true, itr.getIndexBig(), itr.bci()); break; case Bytecodes._invokedynamic: doMethod(true, false, itr.getIndexU4(), itr.bci()); break;
case Bytecodes._invokeinterface: doMethod(false, true, itr.getIndexBig(), itr.bci()); break; case Bytecodes._invokeinterface: doMethod(false, true, itr.getIndexU2Cpcache(), itr.bci()); break;
case Bytecodes._newarray: case Bytecodes._newarray:
case Bytecodes._anewarray: ppNewRef(vCTS, itr.bci()); break; case Bytecodes._anewarray: ppNewRef(vCTS, itr.bci()); break;
case Bytecodes._checkcast: doCheckcast(); break; case Bytecodes._checkcast: doCheckcast(); break;
@ -1665,13 +1664,11 @@ public class GenerateOopMap {
} }
} }
void doLdc (int idx, int bci) { void doLdc (int bci) {
BytecodeLoadConstant ldc = BytecodeLoadConstant.at(_method, bci);
ConstantPool cp = method().getConstants(); ConstantPool cp = method().getConstants();
ConstantTag tag = cp.getTagAt(idx); BasicType bt = ldc.resultType();
CellTypeState cts = (tag.isString() || tag.isUnresolvedString() || CellTypeState cts = (bt == BasicType.T_OBJECT) ? CellTypeState.makeLineRef(bci) : valCTS;
tag.isKlass() || tag.isUnresolvedKlass())
? CellTypeState.makeLineRef(bci)
: valCTS;
ppush1(cts); ppush1(cts);
} }
@ -1729,15 +1726,7 @@ public class GenerateOopMap {
void doMethod (boolean is_static, boolean is_interface, int idx, int bci) { void doMethod (boolean is_static, boolean is_interface, int idx, int bci) {
// Dig up signature for field in constant pool // Dig up signature for field in constant pool
ConstantPool cp = _method.getConstants(); ConstantPool cp = _method.getConstants();
int nameAndTypeIdx = cp.getTagAt(idx).isNameAndType() ? idx : cp.getNameAndTypeRefIndexAt(idx); Symbol signature = cp.getSignatureRefAt(idx);
int signatureIdx = cp.getSignatureRefIndexAt(nameAndTypeIdx);
Symbol signature = cp.getSymbolAt(signatureIdx);
if (DEBUG) {
System.err.println("doMethod: signature = " + signature.asString() + ", idx = " + idx +
", nameAndTypeIdx = " + nameAndTypeIdx + ", signatureIdx = " + signatureIdx +
", bci = " + bci);
}
// Parse method signature // Parse method signature
CellTypeStateList out = new CellTypeStateList(4); CellTypeStateList out = new CellTypeStateList(4);

View File

@ -180,12 +180,24 @@ public class Method extends Oop {
return getConstMethod().getBytecodeShortArg(bci); return getConstMethod().getBytecodeShortArg(bci);
} }
/** Fetches a 16-bit native ordered value from the
bytecode stream */
public short getNativeShortArg(int bci) {
return getConstMethod().getNativeShortArg(bci);
}
/** Fetches a 32-bit big-endian ("Java ordered") value from the /** Fetches a 32-bit big-endian ("Java ordered") value from the
bytecode stream */ bytecode stream */
public int getBytecodeIntArg(int bci) { public int getBytecodeIntArg(int bci) {
return getConstMethod().getBytecodeIntArg(bci); return getConstMethod().getBytecodeIntArg(bci);
} }
/** Fetches a 32-bit native ordered value from the
bytecode stream */
public int getNativeIntArg(int bci) {
return getConstMethod().getNativeIntArg(bci);
}
public byte[] getByteCode() { public byte[] getByteCode() {
return getConstMethod().getByteCode(); return getConstMethod().getByteCode();
} }

View File

@ -53,6 +53,9 @@ public class TypeArray extends Array {
public boolean isTypeArray() { return true; } public boolean isTypeArray() { return true; }
public byte getByteAt(long index) { public byte getByteAt(long index) {
if (index < 0 || index >= getLength()) {
throw new ArrayIndexOutOfBoundsException(index + " " + getLength());
}
long offset = baseOffsetInBytes(BasicType.T_BYTE) + index * getHeap().getByteSize(); long offset = baseOffsetInBytes(BasicType.T_BYTE) + index * getHeap().getByteSize();
return getHandle().getJByteAt(offset); return getHandle().getJByteAt(offset);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,31 +24,33 @@
package sun.jvm.hotspot.utilities; package sun.jvm.hotspot.utilities;
import sun.jvm.hotspot.runtime.BasicType;
public class ConstantTag { public class ConstantTag {
// These replicated from the VM to save space // These replicated from the VM to save space
private static int JVM_CONSTANT_Utf8 = 1; private static final int JVM_CONSTANT_Utf8 = 1;
private static int JVM_CONSTANT_Unicode = 2; // unused private static final int JVM_CONSTANT_Unicode = 2; // unused
private static int JVM_CONSTANT_Integer = 3; private static final int JVM_CONSTANT_Integer = 3;
private static int JVM_CONSTANT_Float = 4; private static final int JVM_CONSTANT_Float = 4;
private static int JVM_CONSTANT_Long = 5; private static final int JVM_CONSTANT_Long = 5;
private static int JVM_CONSTANT_Double = 6; private static final int JVM_CONSTANT_Double = 6;
private static int JVM_CONSTANT_Class = 7; private static final int JVM_CONSTANT_Class = 7;
private static int JVM_CONSTANT_String = 8; private static final int JVM_CONSTANT_String = 8;
private static int JVM_CONSTANT_Fieldref = 9; private static final int JVM_CONSTANT_Fieldref = 9;
private static int JVM_CONSTANT_Methodref = 10; private static final int JVM_CONSTANT_Methodref = 10;
private static int JVM_CONSTANT_InterfaceMethodref = 11; private static final int JVM_CONSTANT_InterfaceMethodref = 11;
private static int JVM_CONSTANT_NameAndType = 12; private static final int JVM_CONSTANT_NameAndType = 12;
private static int JVM_CONSTANT_MethodHandle = 15; // JSR 292 private static final int JVM_CONSTANT_MethodHandle = 15; // JSR 292
private static int JVM_CONSTANT_MethodType = 16; // JSR 292 private static final int JVM_CONSTANT_MethodType = 16; // JSR 292
// static int JVM_CONSTANT_(unused) = 17; // JSR 292 early drafts only // static final int JVM_CONSTANT_(unused) = 17; // JSR 292 early drafts only
private static int JVM_CONSTANT_InvokeDynamic = 18; // JSR 292 private static final int JVM_CONSTANT_InvokeDynamic = 18; // JSR 292
private static int JVM_CONSTANT_Invalid = 0; // For bad value initialization private static final int JVM_CONSTANT_Invalid = 0; // For bad value initialization
private static int JVM_CONSTANT_UnresolvedClass = 100; // Temporary tag until actual use private static final int JVM_CONSTANT_UnresolvedClass = 100; // Temporary tag until actual use
private static int JVM_CONSTANT_ClassIndex = 101; // Temporary tag while constructing constant pool private static final int JVM_CONSTANT_ClassIndex = 101; // Temporary tag while constructing constant pool
private static int JVM_CONSTANT_UnresolvedString = 102; // Temporary tag until actual use private static final int JVM_CONSTANT_UnresolvedString = 102; // Temporary tag until actual use
private static int JVM_CONSTANT_StringIndex = 103; // Temporary tag while constructing constant pool private static final int JVM_CONSTANT_StringIndex = 103; // Temporary tag while constructing constant pool
private static int JVM_CONSTANT_UnresolvedClassInError = 104; // Resolution failed private static final int JVM_CONSTANT_UnresolvedClassInError = 104; // Resolution failed
private static int JVM_CONSTANT_Object = 105; // Required for BoundMethodHandle arguments. private static final int JVM_CONSTANT_Object = 105; // Required for BoundMethodHandle arguments.
// JVM_CONSTANT_MethodHandle subtypes //FIXME: connect these to data structure // JVM_CONSTANT_MethodHandle subtypes //FIXME: connect these to data structure
private static int JVM_REF_getField = 1; private static int JVM_REF_getField = 1;
@ -99,4 +101,31 @@ public class ConstantTag {
public boolean isKlassReference() { return isKlassIndex() || isUnresolvedKlass(); } public boolean isKlassReference() { return isKlassIndex() || isUnresolvedKlass(); }
public boolean isFieldOrMethod() { return isField() || isMethod() || isInterfaceMethod(); } public boolean isFieldOrMethod() { return isField() || isMethod() || isInterfaceMethod(); }
public boolean isSymbol() { return isUtf8(); } public boolean isSymbol() { return isUtf8(); }
public BasicType basicType() {
switch (tag) {
case JVM_CONSTANT_Integer :
return BasicType.T_INT;
case JVM_CONSTANT_Float :
return BasicType.T_FLOAT;
case JVM_CONSTANT_Long :
return BasicType.T_LONG;
case JVM_CONSTANT_Double :
return BasicType.T_DOUBLE;
case JVM_CONSTANT_Class :
case JVM_CONSTANT_String :
case JVM_CONSTANT_UnresolvedClass :
case JVM_CONSTANT_UnresolvedClassInError :
case JVM_CONSTANT_ClassIndex :
case JVM_CONSTANT_UnresolvedString :
case JVM_CONSTANT_StringIndex :
case JVM_CONSTANT_MethodHandle :
case JVM_CONSTANT_MethodType :
case JVM_CONSTANT_Object :
return BasicType.T_OBJECT;
default:
throw new InternalError("unexpected tag: " + tag);
}
}
} }

View File

@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2011
HS_MAJOR_VER=22 HS_MAJOR_VER=22
HS_MINOR_VER=0 HS_MINOR_VER=0
HS_BUILD_NUMBER=01 HS_BUILD_NUMBER=03
JDK_MAJOR_VER=1 JDK_MAJOR_VER=1
JDK_MINOR_VER=8 JDK_MINOR_VER=8

View File

@ -34,13 +34,13 @@ else
endif endif
jprt_build_productEmb: jprt_build_productEmb:
$(MAKE) JAVASE_EMBEDDED=true jprt_build_product $(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_product
jprt_build_debugEmb: jprt_build_debugEmb:
$(MAKE) JAVASE_EMBEDDED=true jprt_build_debug $(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_debug
jprt_build_fastdebugEmb: jprt_build_fastdebugEmb:
$(MAKE) JAVASE_EMBEDDED=true jprt_build_fastdebug $(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_fastdebug
jprt_build_productOpen: jprt_build_productOpen:
$(MAKE) OPENJDK=true jprt_build_product $(MAKE) OPENJDK=true jprt_build_product

View File

@ -230,7 +230,7 @@ checks: check_os_version check_j2se_version
# Solaris 2.5.1, 2.6). # Solaris 2.5.1, 2.6).
# Disable this check by setting DISABLE_HOTSPOT_OS_VERSION_CHECK=ok. # Disable this check by setting DISABLE_HOTSPOT_OS_VERSION_CHECK=ok.
SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 2.7% SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 3%
OS_VERSION := $(shell uname -r) OS_VERSION := $(shell uname -r)
EMPTY_IF_NOT_SUPPORTED = $(filter $(SUPPORTED_OS_VERSION),$(OS_VERSION)) EMPTY_IF_NOT_SUPPORTED = $(filter $(SUPPORTED_OS_VERSION),$(OS_VERSION))

View File

@ -1,4 +1,4 @@
Copyright (c) 2007 Oracle and/or its affiliates. All rights reserved. Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it This code is free software; you can redistribute it and/or modify it

View File

@ -124,6 +124,7 @@ EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
# client and server subdirectories have symbolic links to ../libjsig.so # client and server subdirectories have symbolic links to ../libjsig.so
EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so
EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
ifndef BUILD_CLIENT_ONLY ifndef BUILD_CLIENT_ONLY
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
@ -132,7 +133,6 @@ endif
ifneq ($(ZERO_BUILD), true) ifneq ($(ZERO_BUILD), true)
ifeq ($(ARCH_DATA_MODEL), 32) 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)/Xusage.txt
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so
endif endif

View File

@ -70,6 +70,8 @@ EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so
EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
ifneq ($(BUILD_CLIENT_ONLY),true) ifneq ($(BUILD_CLIENT_ONLY),true)
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so
@ -77,7 +79,6 @@ EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.so
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.so EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.so
endif endif
ifeq ($(ARCH_DATA_MODEL), 32) 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)/Xusage.txt
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.so EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.so

View File

@ -72,9 +72,9 @@ $(shell uname -r -v \
-e '/^[0-4]\. /b' \ -e '/^[0-4]\. /b' \
-e '/^5\.[0-9] /b' \ -e '/^5\.[0-9] /b' \
-e '/^5\.10 /b' \ -e '/^5\.10 /b' \
-e '/ snv_[0-9][0-9]$/b' \ -e '/ snv_[0-9][0-9]$$/b' \
-e '/ snv_[01][0-4][0-9]$/b' \ -e '/ snv_[01][0-4][0-9]$$/b' \
-e '/ snv_15[0-8]$/b' \ -e '/ snv_15[0-8]$$/b' \
-e 's/.*/-DSOLARIS_11_B159_OR_LATER/' \ -e 's/.*/-DSOLARIS_11_B159_OR_LATER/' \
-e 'p' \ -e 'p' \
) )

View File

@ -81,7 +81,6 @@ CPP=ARCH_ERROR
!endif !endif
CPP_FLAGS=$(CPP_FLAGS) /D "WIN32" /D "_WINDOWS" CPP_FLAGS=$(CPP_FLAGS) /D "WIN32" /D "_WINDOWS"
# Must specify this for sharedRuntimeTrig.cpp # Must specify this for sharedRuntimeTrig.cpp
CPP_FLAGS=$(CPP_FLAGS) /D "VM_LITTLE_ENDIAN" CPP_FLAGS=$(CPP_FLAGS) /D "VM_LITTLE_ENDIAN"
@ -232,6 +231,11 @@ LINK_FLAGS= $(LINK_FLAGS) kernel32.lib user32.lib gdi32.lib winspool.lib \
uuid.lib Wsock32.lib winmm.lib /nologo /machine:$(MACHINE) /opt:REF \ uuid.lib Wsock32.lib winmm.lib /nologo /machine:$(MACHINE) /opt:REF \
/opt:ICF,8 /map /debug /opt:ICF,8 /map /debug
!if $(MSC_VER) >= 1600
LINK_FLAGS= $(LINK_FLAGS) psapi.lib
!endif
# Resource compiler settings # Resource compiler settings
RC=rc.exe RC=rc.exe
RC_FLAGS=/D "HS_VER=$(HS_VER)" \ RC_FLAGS=/D "HS_VER=$(HS_VER)" \

View File

@ -171,19 +171,20 @@ ifeq ($(BUILD_WIN_SA), 1)
endif endif
EXPORT_SERVER_DIR = $(EXPORT_JRE_BIN_DIR)/server EXPORT_SERVER_DIR = $(EXPORT_JRE_BIN_DIR)/server
EXPORT_CLIENT_DIR = $(EXPORT_JRE_BIN_DIR)/client
EXPORT_KERNEL_DIR = $(EXPORT_JRE_BIN_DIR)/kernel
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.dll EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.dll
EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.pdb EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.pdb
EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.map EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.map
EXPORT_LIST += $(EXPORT_LIB_DIR)/jvm.lib EXPORT_LIST += $(EXPORT_LIB_DIR)/jvm.lib
ifeq ($(ARCH_DATA_MODEL), 32) ifeq ($(ARCH_DATA_MODEL), 32)
EXPORT_CLIENT_DIR = $(EXPORT_JRE_BIN_DIR)/client
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.dll EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.dll
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.pdb EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.pdb
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.map EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.map
# kernel vm # kernel vm
EXPORT_KERNEL_DIR = $(EXPORT_JRE_BIN_DIR)/kernel
EXPORT_LIST += $(EXPORT_KERNEL_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_KERNEL_DIR)/Xusage.txt
EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.dll EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.dll
EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.pdb EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.pdb

View File

@ -66,7 +66,7 @@ $(GENERATED)\sa-jdi.jar: $(AGENT_FILES1:/=\) $(AGENT_FILES2:/=\)
$(QUIETLY) mkdir $(SA_CLASSDIR)\sun\jvm\hotspot\ui\resources $(QUIETLY) mkdir $(SA_CLASSDIR)\sun\jvm\hotspot\ui\resources
$(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources $(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources
$(QUIETLY) cp -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR) $(QUIETLY) cp -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)
$(RUN_JAR) cf $@ -C saclasses . $(RUN_JAR) cf $@ -C $(SA_CLASSDIR) .
$(RUN_JAR) uf $@ -C $(AGENT_SRC_DIR:/=\) META-INF\services\com.sun.jdi.connect.Connector $(RUN_JAR) uf $@ -C $(AGENT_SRC_DIR:/=\) META-INF\services\com.sun.jdi.connect.Connector
$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal $(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal
$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext $(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2007, 2010 Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it

File diff suppressed because it is too large Load Diff

View File

@ -761,7 +761,7 @@ class Assembler : public AbstractAssembler {
mwtos_opf = 0x119 mwtos_opf = 0x119
}; };
enum RCondition { rc_z = 1, rc_lez = 2, rc_lz = 3, rc_nz = 5, rc_gz = 6, rc_gez = 7 }; enum RCondition { rc_z = 1, rc_lez = 2, rc_lz = 3, rc_nz = 5, rc_gz = 6, rc_gez = 7, rc_last = rc_gez };
enum Condition { enum Condition {
// for FBfcc & FBPfcc instruction // for FBfcc & FBPfcc instruction
@ -866,9 +866,18 @@ class Assembler : public AbstractAssembler {
return is_simm(d, nbits + 2); return is_simm(d, nbits + 2);
} }
address target_distance(Label& L) {
// Assembler::target(L) should be called only when
// a branch instruction is emitted since non-bound
// labels record current pc() as a branch address.
if (L.is_bound()) return target(L);
// Return current address for non-bound labels.
return pc();
}
// test if label is in simm16 range in words (wdisp16). // test if label is in simm16 range in words (wdisp16).
bool is_in_wdisp16_range(Label& L) { bool is_in_wdisp16_range(Label& L) {
return is_in_wdisp_range(target(L), pc(), 16); return is_in_wdisp_range(target_distance(L), pc(), 16);
} }
// test if the distance between two addresses fits in simm30 range in words // test if the distance between two addresses fits in simm30 range in words
static bool is_in_wdisp30_range(address a, address b) { static bool is_in_wdisp30_range(address a, address b) {
@ -877,7 +886,11 @@ class Assembler : public AbstractAssembler {
enum ASIs { // page 72, v9 enum ASIs { // page 72, v9
ASI_PRIMARY = 0x80, ASI_PRIMARY = 0x80,
ASI_PRIMARY_LITTLE = 0x88 ASI_PRIMARY_LITTLE = 0x88,
// Block initializing store
ASI_ST_BLKINIT_PRIMARY = 0xE2,
// Most-Recently-Used (MRU) BIS variant
ASI_ST_BLKINIT_MRU_PRIMARY = 0xF2
// add more from book as needed // add more from book as needed
}; };
@ -975,6 +988,20 @@ class Assembler : public AbstractAssembler {
static int sx( int i) { return u_field(i, 12, 12); } // shift x=1 means 64-bit static int sx( int i) { return u_field(i, 12, 12); } // shift x=1 means 64-bit
static int opf( int x) { return u_field(x, 13, 5); } static int opf( int x) { return u_field(x, 13, 5); }
static bool is_cbcond( int x ) {
return (VM_Version::has_cbcond() && (inv_cond(x) > rc_last) &&
inv_op(x) == branch_op && inv_op2(x) == bpr_op2);
}
static bool is_cxb( int x ) {
assert(is_cbcond(x), "wrong instruction");
return (x & (1<<21)) != 0;
}
static int cond_cbcond( int x) { return u_field((((x & 8)<<1) + 8 + (x & 7)), 29, 25); }
static int inv_cond_cbcond(int x) {
assert(is_cbcond(x), "wrong instruction");
return inv_u_field(x, 27, 25) | (inv_u_field(x, 29, 29)<<3);
}
static int opf_cc( CC c, bool useFloat ) { return u_field((useFloat ? 0 : 4) + c, 13, 11); } static int opf_cc( CC c, bool useFloat ) { return u_field((useFloat ? 0 : 4) + c, 13, 11); }
static int mov_cc( CC c, bool useFloat ) { return u_field(useFloat ? 0 : 1, 18, 18) | u_field(c, 12, 11); } static int mov_cc( CC c, bool useFloat ) { return u_field(useFloat ? 0 : 1, 18, 18) | u_field(c, 12, 11); }
@ -1026,6 +1053,26 @@ class Assembler : public AbstractAssembler {
return r; return r;
} }
// compute inverse of wdisp10
static intptr_t inv_wdisp10(int x, intptr_t pos) {
assert(is_cbcond(x), "wrong instruction");
int lo = inv_u_field(x, 12, 5);
int hi = (x >> 19) & 3;
if (hi >= 2) hi |= ~1;
return (((hi << 8) | lo) << 2) + pos;
}
// word offset for cbcond, 8 bits at [B12,B5], 2 bits at [B20,B19]
static int wdisp10(intptr_t x, intptr_t off) {
assert(VM_Version::has_cbcond(), "This CPU does not have CBCOND instruction");
intptr_t xx = x - off;
assert_signed_word_disp_range(xx, 10);
int r = ( ( (xx >> 2 ) & ((1 << 8) - 1) ) << 5 )
| ( ( (xx >> (2+8)) & 3 ) << 19 );
// Have to fake cbcond instruction to pass assert in inv_wdisp10()
assert(inv_wdisp10((r | op(branch_op) | cond_cbcond(rc_last+1) | op2(bpr_op2)), off) == x, "inverse is not inverse");
return r;
}
// word displacement in low-order nbits bits // word displacement in low-order nbits bits
@ -1138,7 +1185,26 @@ class Assembler : public AbstractAssembler {
#endif #endif
} }
// cbcond instruction should not be generated one after an other
bool cbcond_before() {
if (offset() == 0) return false; // it is first instruction
int x = *(int*)(intptr_t(pc()) - 4); // previous instruction
return is_cbcond(x);
}
void no_cbcond_before() {
assert(offset() == 0 || !cbcond_before(), "cbcond should not follow an other cbcond");
}
public: public:
bool use_cbcond(Label& L) {
if (!UseCBCond || cbcond_before()) return false;
intptr_t x = intptr_t(target_distance(L)) - intptr_t(pc());
assert( (x & 3) == 0, "not word aligned");
return is_simm(x, 12);
}
// Tells assembler you know that next instruction is delayed // Tells assembler you know that next instruction is delayed
Assembler* delayed() { Assembler* delayed() {
#ifdef CHECK_DELAY #ifdef CHECK_DELAY
@ -1181,10 +1247,15 @@ public:
void addccc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } void addccc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
void addccc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } void addccc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
// pp 136 // pp 136
inline void bpr( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt = relocInfo::none ); inline void bpr(RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt = relocInfo::none);
inline void bpr( RCondition c, bool a, Predict p, Register s1, Label& L); inline void bpr(RCondition c, bool a, Predict p, Register s1, Label& L);
// compare and branch
inline void cbcond(Condition c, CC cc, Register s1, Register s2, Label& L);
inline void cbcond(Condition c, CC cc, Register s1, int simm5, Label& L);
protected: // use MacroAssembler::br instead protected: // use MacroAssembler::br instead
@ -1198,8 +1269,6 @@ public:
inline void fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none ); inline void fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
inline void fbp( Condition c, bool a, CC cc, Predict p, Label& L ); inline void fbp( Condition c, bool a, CC cc, Predict p, Label& L );
public:
// pp 144 // pp 144
inline void br( Condition c, bool a, address d, relocInfo::relocType rt = relocInfo::none ); inline void br( Condition c, bool a, address d, relocInfo::relocType rt = relocInfo::none );
@ -1220,6 +1289,8 @@ public:
inline void call( address d, relocInfo::relocType rt = relocInfo::runtime_call_type ); inline void call( address d, relocInfo::relocType rt = relocInfo::runtime_call_type );
inline void call( Label& L, relocInfo::relocType rt = relocInfo::runtime_call_type ); inline void call( Label& L, relocInfo::relocType rt = relocInfo::runtime_call_type );
public:
// pp 150 // pp 150
// These instructions compare the contents of s2 with the contents of // These instructions compare the contents of s2 with the contents of
@ -1862,8 +1933,8 @@ class MacroAssembler: public Assembler {
inline void fb( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none ); inline void fb( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
inline void fb( Condition c, bool a, Predict p, Label& L ); inline void fb( Condition c, bool a, Predict p, Label& L );
// compares register with zero and branches (V9 and V8 instructions) // compares register with zero (32 bit) and branches (V9 and V8 instructions)
void br_zero( Condition c, bool a, Predict p, Register s1, Label& L); void cmp_zero_and_br( Condition c, Register s1, Label& L, bool a = false, Predict p = pn );
// Compares a pointer register with zero and branches on (not)null. // Compares a pointer register with zero and branches on (not)null.
// Does a test & branch on 32-bit systems and a register-branch on 64-bit. // Does a test & branch on 32-bit systems and a register-branch on 64-bit.
void br_null ( Register s1, bool a, Predict p, Label& L ); void br_null ( Register s1, bool a, Predict p, Label& L );
@ -1875,6 +1946,26 @@ class MacroAssembler: public Assembler {
void br_on_reg_cond( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt = relocInfo::none ); void br_on_reg_cond( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt = relocInfo::none );
void br_on_reg_cond( RCondition c, bool a, Predict p, Register s1, Label& L); void br_on_reg_cond( RCondition c, bool a, Predict p, Register s1, Label& L);
//
// Compare registers and branch with nop in delay slot or cbcond without delay slot.
//
// ATTENTION: use these instructions with caution because cbcond instruction
// has very short distance: 512 instructions (2Kbyte).
// Compare integer (32 bit) values (icc only).
void cmp_and_br_short(Register s1, Register s2, Condition c, Predict p, Label& L);
void cmp_and_br_short(Register s1, int simm13a, Condition c, Predict p, Label& L);
// Platform depending version for pointer compare (icc on !LP64 and xcc on LP64).
void cmp_and_brx_short(Register s1, Register s2, Condition c, Predict p, Label& L);
void cmp_and_brx_short(Register s1, int simm13a, Condition c, Predict p, Label& L);
// Short branch version for compares a pointer pwith zero.
void br_null_short ( Register s1, Predict p, Label& L );
void br_notnull_short( Register s1, Predict p, Label& L );
// unconditional short branch
void ba_short(Label& L);
inline void bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none ); inline void bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
inline void bp( Condition c, bool a, CC cc, Predict p, Label& L ); inline void bp( Condition c, bool a, CC cc, Predict p, Label& L );
@ -1882,8 +1973,8 @@ class MacroAssembler: public Assembler {
inline void brx( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none ); inline void brx( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
inline void brx( Condition c, bool a, Predict p, Label& L ); inline void brx( Condition c, bool a, Predict p, Label& L );
// unconditional short branch // unconditional branch
inline void ba( bool a, Label& L ); inline void ba( Label& L );
// Branch that tests fp condition codes // Branch that tests fp condition codes
inline void fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none ); inline void fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
@ -2167,7 +2258,6 @@ public:
inline void stbool(Register d, const Address& a) { stb(d, a); } inline void stbool(Register d, const Address& a) { stb(d, a); }
inline void ldbool(const Address& a, Register d) { ldsb(a, d); } inline void ldbool(const Address& a, Register d) { ldsb(a, d); }
inline void tstbool( Register s ) { tst(s); }
inline void movbool( bool boolconst, Register d) { mov( (int) boolconst, d); } inline void movbool( bool boolconst, Register d) { mov( (int) boolconst, d); }
// klass oop manipulations if compressed // klass oop manipulations if compressed
@ -2469,8 +2559,7 @@ public:
Label* L_success, Label* L_success,
Label* L_failure, Label* L_failure,
Label* L_slow_path, Label* L_slow_path,
RegisterOrConstant super_check_offset = RegisterOrConstant(-1), RegisterOrConstant super_check_offset = RegisterOrConstant(-1));
Register instanceof_hack = noreg);
// The rest of the type check; must be wired to a corresponding fast path. // The rest of the type check; must be wired to a corresponding fast path.
// It does not repeat the fast path logic, so don't use it standalone. // It does not repeat the fast path logic, so don't use it standalone.

View File

@ -80,32 +80,36 @@ inline void Assembler::add(Register s1, Register s2, Register d )
inline void Assembler::add(Register s1, int simm13a, Register d, relocInfo::relocType rtype ) { emit_data( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rtype ); } inline void Assembler::add(Register s1, int simm13a, Register d, relocInfo::relocType rtype ) { emit_data( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rtype ); }
inline void Assembler::add(Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { emit_data( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec ); } inline void Assembler::add(Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { emit_data( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec ); }
inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt ) { v9_only(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(bpr_op2) | wdisp16(intptr_t(d), intptr_t(pc())) | predict(p) | rs1(s1), rt); has_delay_slot(); } inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt ) { v9_only(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(bpr_op2) | wdisp16(intptr_t(d), intptr_t(pc())) | predict(p) | rs1(s1), rt); has_delay_slot(); }
inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, Label& L) { bpr( c, a, p, s1, target(L)); } inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, Label& L) { bpr( c, a, p, s1, target(L)); }
inline void Assembler::fb( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(fb_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); } inline void Assembler::fb( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(fb_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); }
inline void Assembler::fb( Condition c, bool a, Label& L ) { fb(c, a, target(L)); } inline void Assembler::fb( Condition c, bool a, Label& L ) { fb(c, a, target(L)); }
inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(fbp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); has_delay_slot(); } inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(fbp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); has_delay_slot(); }
inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, Label& L ) { fbp(c, a, cc, p, target(L)); } inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, Label& L ) { fbp(c, a, cc, p, target(L)); }
inline void Assembler::cb( Condition c, bool a, address d, relocInfo::relocType rt ) { v8_only(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(cb_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); } inline void Assembler::cb( Condition c, bool a, address d, relocInfo::relocType rt ) { v8_only(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(cb_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); }
inline void Assembler::cb( Condition c, bool a, Label& L ) { cb(c, a, target(L)); } inline void Assembler::cb( Condition c, bool a, Label& L ) { cb(c, a, target(L)); }
inline void Assembler::br( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(br_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); } inline void Assembler::br( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(br_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); }
inline void Assembler::br( Condition c, bool a, Label& L ) { br(c, a, target(L)); } inline void Assembler::br( Condition c, bool a, Label& L ) { br(c, a, target(L)); }
inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(bp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); has_delay_slot(); } inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(bp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); has_delay_slot(); }
inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, Label& L ) { bp(c, a, cc, p, target(L)); } inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, Label& L ) { bp(c, a, cc, p, target(L)); }
inline void Assembler::call( address d, relocInfo::relocType rt ) { emit_data( op(call_op) | wdisp(intptr_t(d), intptr_t(pc()), 30), rt); has_delay_slot(); assert(rt != relocInfo::virtual_call_type, "must use virtual_call_Relocation::spec"); } // compare and branch
inline void Assembler::cbcond(Condition c, CC cc, Register s1, Register s2, Label& L) { cti(); no_cbcond_before(); emit_data(op(branch_op) | cond_cbcond(c) | op2(bpr_op2) | branchcc(cc) | wdisp10(intptr_t(target(L)), intptr_t(pc())) | rs1(s1) | rs2(s2)); }
inline void Assembler::cbcond(Condition c, CC cc, Register s1, int simm5, Label& L) { cti(); no_cbcond_before(); emit_data(op(branch_op) | cond_cbcond(c) | op2(bpr_op2) | branchcc(cc) | wdisp10(intptr_t(target(L)), intptr_t(pc())) | rs1(s1) | immed(true) | simm(simm5, 5)); }
inline void Assembler::call( address d, relocInfo::relocType rt ) { cti(); emit_data( op(call_op) | wdisp(intptr_t(d), intptr_t(pc()), 30), rt); has_delay_slot(); assert(rt != relocInfo::virtual_call_type, "must use virtual_call_Relocation::spec"); }
inline void Assembler::call( Label& L, relocInfo::relocType rt ) { call( target(L), rt); } inline void Assembler::call( Label& L, relocInfo::relocType rt ) { call( target(L), rt); }
inline void Assembler::flush( Register s1, Register s2) { emit_long( op(arith_op) | op3(flush_op3) | rs1(s1) | rs2(s2)); } inline void Assembler::flush( Register s1, Register s2) { emit_long( op(arith_op) | op3(flush_op3) | rs1(s1) | rs2(s2)); }
inline void Assembler::flush( Register s1, int simm13a) { emit_data( op(arith_op) | op3(flush_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } inline void Assembler::flush( Register s1, int simm13a) { emit_data( op(arith_op) | op3(flush_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
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, Register s2, Register d ) { cti(); 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::jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { cti(); 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) { inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, RegisterOrConstant s2, FloatRegister d) {
if (s2.is_register()) ldf(w, s1, s2.as_register(), d); if (s2.is_register()) ldf(w, s1, s2.as_register(), d);
@ -240,8 +244,8 @@ inline void Assembler::prefetch(Register s1, int simm13a, PrefetchFcn f) { v9_on
inline void Assembler::prefetch(const Address& a, PrefetchFcn f, int offset) { v9_only(); relocate(a.rspec(offset)); prefetch(a.base(), a.disp() + offset, f); } inline void Assembler::prefetch(const Address& a, PrefetchFcn f, int offset) { v9_only(); relocate(a.rspec(offset)); prefetch(a.base(), a.disp() + offset, f); }
inline void Assembler::rett( Register s1, Register s2 ) { emit_long( op(arith_op) | op3(rett_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); } inline void Assembler::rett( Register s1, Register s2 ) { cti(); emit_long( op(arith_op) | op3(rett_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); }
inline void Assembler::rett( Register s1, int simm13a, relocInfo::relocType rt) { emit_data( op(arith_op) | op3(rett_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rt); has_delay_slot(); } inline void Assembler::rett( Register s1, int simm13a, relocInfo::relocType rt) { cti(); emit_data( op(arith_op) | op3(rett_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rt); has_delay_slot(); }
inline void Assembler::sethi( int imm22a, Register d, RelocationHolder const& rspec ) { emit_data( op(branch_op) | rd(d) | op2(sethi_op2) | hi22(imm22a), rspec); } inline void Assembler::sethi( int imm22a, Register d, RelocationHolder const& rspec ) { emit_data( op(branch_op) | rd(d) | op2(sethi_op2) | hi22(imm22a), rspec); }
@ -557,8 +561,8 @@ inline void MacroAssembler::brx( Condition c, bool a, Predict p, Label& L ) {
brx(c, a, p, target(L)); brx(c, a, p, target(L));
} }
inline void MacroAssembler::ba( bool a, Label& L ) { inline void MacroAssembler::ba( Label& L ) {
br(always, a, pt, L); br(always, false, pt, L);
} }
// Warning: V9 only functions // Warning: V9 only functions

View File

@ -303,9 +303,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) {
assert(_oop_index >= 0, "must have oop index"); assert(_oop_index >= 0, "must have oop index");
__ load_heap_oop(_obj, java_lang_Class::klass_offset_in_bytes(), G3); __ load_heap_oop(_obj, java_lang_Class::klass_offset_in_bytes(), G3);
__ ld_ptr(G3, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc), G3); __ ld_ptr(G3, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc), G3);
__ cmp(G2_thread, G3); __ cmp_and_brx_short(G2_thread, G3, Assembler::notEqual, Assembler::pn, call_patch);
__ br(Assembler::notEqual, false, Assembler::pn, call_patch);
__ delayed()->nop();
// load_klass patches may execute the patched code before it's // load_klass patches may execute the patched code before it's
// copied back into place so we need to jump back into the main // copied back into place so we need to jump back into the main

View File

@ -217,9 +217,7 @@ void LIR_Assembler::osr_entry() {
{ {
Label L; Label L;
__ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7); __ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7);
__ cmp(G0, O7); __ cmp_and_br_short(O7, G0, Assembler::notEqual, Assembler::pt, L);
__ br(Assembler::notEqual, false, Assembler::pt, L);
__ delayed()->nop();
__ stop("locked object is NULL"); __ stop("locked object is NULL");
__ bind(L); __ bind(L);
} }
@ -2096,10 +2094,10 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
__ xor3(O0, -1, tmp); __ xor3(O0, -1, tmp);
__ sub(length, tmp, length); __ sub(length, tmp, length);
__ add(src_pos, tmp, src_pos); __ add(src_pos, tmp, src_pos);
__ br_zero(Assembler::less, false, Assembler::pn, O0, *stub->entry()); __ cmp_zero_and_br(Assembler::less, O0, *stub->entry());
__ delayed()->add(dst_pos, tmp, dst_pos); __ delayed()->add(dst_pos, tmp, dst_pos);
} else { } else {
__ br_zero(Assembler::less, false, Assembler::pn, O0, *stub->entry()); __ cmp_zero_and_br(Assembler::less, O0, *stub->entry());
__ delayed()->nop(); __ delayed()->nop();
} }
__ bind(*stub->continuation()); __ bind(*stub->continuation());
@ -2123,22 +2121,19 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
if (flags & LIR_OpArrayCopy::src_pos_positive_check) { if (flags & LIR_OpArrayCopy::src_pos_positive_check) {
// test src_pos register // test src_pos register
__ tst(src_pos); __ cmp_zero_and_br(Assembler::less, src_pos, *stub->entry());
__ br(Assembler::less, false, Assembler::pn, *stub->entry());
__ delayed()->nop(); __ delayed()->nop();
} }
if (flags & LIR_OpArrayCopy::dst_pos_positive_check) { if (flags & LIR_OpArrayCopy::dst_pos_positive_check) {
// test dst_pos register // test dst_pos register
__ tst(dst_pos); __ cmp_zero_and_br(Assembler::less, dst_pos, *stub->entry());
__ br(Assembler::less, false, Assembler::pn, *stub->entry());
__ delayed()->nop(); __ delayed()->nop();
} }
if (flags & LIR_OpArrayCopy::length_positive_check) { if (flags & LIR_OpArrayCopy::length_positive_check) {
// make sure length isn't negative // make sure length isn't negative
__ tst(length); __ cmp_zero_and_br(Assembler::less, length, *stub->entry());
__ br(Assembler::less, false, Assembler::pn, *stub->entry());
__ delayed()->nop(); __ delayed()->nop();
} }
@ -2261,8 +2256,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
#ifndef PRODUCT #ifndef PRODUCT
if (PrintC1Statistics) { if (PrintC1Statistics) {
Label failed; Label failed;
__ br_notnull(O0, false, Assembler::pn, failed); __ br_notnull_short(O0, Assembler::pn, failed);
__ delayed()->nop();
__ inc_counter((address)&Runtime1::_arraycopy_checkcast_cnt, G1, G3); __ inc_counter((address)&Runtime1::_arraycopy_checkcast_cnt, G1, G3);
__ bind(failed); __ bind(failed);
} }
@ -2314,9 +2308,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
__ br(Assembler::notEqual, false, Assembler::pn, halt); __ br(Assembler::notEqual, false, Assembler::pn, halt);
// load the raw value of the src klass. // load the raw value of the src klass.
__ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2); __ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2);
__ cmp(tmp, tmp2); __ cmp_and_br_short(tmp, tmp2, Assembler::equal, Assembler::pn, known_ok);
__ br(Assembler::equal, false, Assembler::pn, known_ok);
__ delayed()->nop();
} else { } else {
__ cmp(tmp, tmp2); __ cmp(tmp, tmp2);
__ br(Assembler::equal, false, Assembler::pn, known_ok); __ br(Assembler::equal, false, Assembler::pn, known_ok);
@ -2330,9 +2322,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
__ cmp(tmp, tmp2); __ cmp(tmp, tmp2);
__ brx(Assembler::notEqual, false, Assembler::pn, halt); __ brx(Assembler::notEqual, false, Assembler::pn, halt);
__ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2); __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2);
__ cmp(tmp, tmp2); __ cmp_and_brx_short(tmp, tmp2, Assembler::equal, Assembler::pn, known_ok);
__ brx(Assembler::equal, false, Assembler::pn, known_ok);
__ delayed()->nop();
} else { } else {
__ cmp(tmp, tmp2); __ cmp(tmp, tmp2);
__ brx(Assembler::equal, false, Assembler::pn, known_ok); __ brx(Assembler::equal, false, Assembler::pn, known_ok);
@ -2530,15 +2520,13 @@ void LIR_Assembler::type_profile_helper(Register mdo, int mdo_offset_bias,
mdo_offset_bias); mdo_offset_bias);
__ ld_ptr(receiver_addr, tmp1); __ ld_ptr(receiver_addr, tmp1);
__ verify_oop(tmp1); __ verify_oop(tmp1);
__ cmp(recv, tmp1); __ cmp_and_brx_short(recv, tmp1, Assembler::notEqual, Assembler::pt, next_test);
__ brx(Assembler::notEqual, false, Assembler::pt, next_test);
__ delayed()->nop();
Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) - Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) -
mdo_offset_bias); mdo_offset_bias);
__ ld_ptr(data_addr, tmp1); __ ld_ptr(data_addr, tmp1);
__ add(tmp1, DataLayout::counter_increment, tmp1); __ add(tmp1, DataLayout::counter_increment, tmp1);
__ st_ptr(tmp1, data_addr); __ st_ptr(tmp1, data_addr);
__ ba(false, *update_done); __ ba(*update_done);
__ delayed()->nop(); __ delayed()->nop();
__ bind(next_test); __ bind(next_test);
} }
@ -2549,13 +2537,12 @@ void LIR_Assembler::type_profile_helper(Register mdo, int mdo_offset_bias,
Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) - Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) -
mdo_offset_bias); mdo_offset_bias);
__ ld_ptr(recv_addr, tmp1); __ ld_ptr(recv_addr, tmp1);
__ br_notnull(tmp1, false, Assembler::pt, next_test); __ br_notnull_short(tmp1, Assembler::pt, next_test);
__ delayed()->nop();
__ st_ptr(recv, recv_addr); __ st_ptr(recv, recv_addr);
__ set(DataLayout::counter_increment, tmp1); __ set(DataLayout::counter_increment, tmp1);
__ st_ptr(tmp1, mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) - __ st_ptr(tmp1, mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) -
mdo_offset_bias); mdo_offset_bias);
__ ba(false, *update_done); __ ba(*update_done);
__ delayed()->nop(); __ delayed()->nop();
__ bind(next_test); __ bind(next_test);
} }
@ -2601,8 +2588,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
setup_md_access(method, op->profiled_bci(), md, data, mdo_offset_bias); setup_md_access(method, op->profiled_bci(), md, data, mdo_offset_bias);
Label not_null; Label not_null;
__ br_notnull(obj, false, Assembler::pn, not_null); __ br_notnull_short(obj, Assembler::pn, not_null);
__ delayed()->nop();
Register mdo = k_RInfo; Register mdo = k_RInfo;
Register data_val = Rtmp1; Register data_val = Rtmp1;
jobject2reg(md->constant_encoding(), mdo); jobject2reg(md->constant_encoding(), mdo);
@ -2614,7 +2600,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
__ ldub(flags_addr, data_val); __ ldub(flags_addr, data_val);
__ or3(data_val, BitData::null_seen_byte_constant(), data_val); __ or3(data_val, BitData::null_seen_byte_constant(), data_val);
__ stb(data_val, flags_addr); __ stb(data_val, flags_addr);
__ ba(false, *obj_is_null); __ ba(*obj_is_null);
__ delayed()->nop(); __ delayed()->nop();
__ bind(not_null); __ bind(not_null);
} else { } else {
@ -2682,7 +2668,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
__ load_klass(obj, recv); __ load_klass(obj, recv);
type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success); type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success);
// Jump over the failure case // Jump over the failure case
__ ba(false, *success); __ ba(*success);
__ delayed()->nop(); __ delayed()->nop();
// Cast failure case // Cast failure case
__ bind(profile_cast_failure); __ bind(profile_cast_failure);
@ -2695,10 +2681,10 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
__ ld_ptr(data_addr, tmp1); __ ld_ptr(data_addr, tmp1);
__ sub(tmp1, DataLayout::counter_increment, tmp1); __ sub(tmp1, DataLayout::counter_increment, tmp1);
__ st_ptr(tmp1, data_addr); __ st_ptr(tmp1, data_addr);
__ ba(false, *failure); __ ba(*failure);
__ delayed()->nop(); __ delayed()->nop();
} }
__ ba(false, *success); __ ba(*success);
__ delayed()->nop(); __ delayed()->nop();
} }
@ -2728,8 +2714,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
if (op->should_profile()) { if (op->should_profile()) {
Label not_null; Label not_null;
__ br_notnull(value, false, Assembler::pn, not_null); __ br_notnull_short(value, Assembler::pn, not_null);
__ delayed()->nop();
Register mdo = k_RInfo; Register mdo = k_RInfo;
Register data_val = Rtmp1; Register data_val = Rtmp1;
jobject2reg(md->constant_encoding(), mdo); jobject2reg(md->constant_encoding(), mdo);
@ -2741,12 +2726,10 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
__ ldub(flags_addr, data_val); __ ldub(flags_addr, data_val);
__ or3(data_val, BitData::null_seen_byte_constant(), data_val); __ or3(data_val, BitData::null_seen_byte_constant(), data_val);
__ stb(data_val, flags_addr); __ stb(data_val, flags_addr);
__ ba(false, done); __ ba_short(done);
__ delayed()->nop();
__ bind(not_null); __ bind(not_null);
} else { } else {
__ br_null(value, false, Assembler::pn, done); __ br_null_short(value, Assembler::pn, done);
__ delayed()->nop();
} }
add_debug_info_for_null_check_here(op->info_for_exception()); add_debug_info_for_null_check_here(op->info_for_exception());
__ load_klass(array, k_RInfo); __ load_klass(array, k_RInfo);
@ -2777,8 +2760,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
} }
__ load_klass(value, recv); __ load_klass(value, recv);
type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done); type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done);
__ ba(false, done); __ ba_short(done);
__ delayed()->nop();
// Cast failure case // Cast failure case
__ bind(profile_cast_failure); __ bind(profile_cast_failure);
jobject2reg(md->constant_encoding(), mdo); jobject2reg(md->constant_encoding(), mdo);
@ -2790,7 +2772,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
__ ld_ptr(data_addr, tmp1); __ ld_ptr(data_addr, tmp1);
__ sub(tmp1, DataLayout::counter_increment, tmp1); __ sub(tmp1, DataLayout::counter_increment, tmp1);
__ st_ptr(tmp1, data_addr); __ st_ptr(tmp1, data_addr);
__ ba(false, *stub->entry()); __ ba(*stub->entry());
__ delayed()->nop(); __ delayed()->nop();
} }
__ bind(done); __ bind(done);
@ -2808,8 +2790,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
emit_typecheck_helper(op, &success, &failure, &failure); emit_typecheck_helper(op, &success, &failure, &failure);
__ bind(failure); __ bind(failure);
__ set(0, dst); __ set(0, dst);
__ ba(false, done); __ ba_short(done);
__ delayed()->nop();
__ bind(success); __ bind(success);
__ set(1, dst); __ set(1, dst);
__ bind(done); __ bind(done);

View File

@ -41,9 +41,7 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
// Note: needs more testing of out-of-line vs. inline slow case // Note: needs more testing of out-of-line vs. inline slow case
verify_oop(receiver); verify_oop(receiver);
load_klass(receiver, temp_reg); load_klass(receiver, temp_reg);
cmp(temp_reg, iCache); cmp_and_brx_short(temp_reg, iCache, Assembler::equal, Assembler::pt, L);
brx(Assembler::equal, true, Assembler::pt, L);
delayed()->nop();
AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub()); AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub());
jump_to(ic_miss, temp_reg); jump_to(ic_miss, temp_reg);
delayed()->nop(); delayed()->nop();
@ -142,8 +140,7 @@ void C1_MacroAssembler::unlock_object(Register Rmark, Register Roop, Register Rb
} }
// Test first it it is a fast recursive unlock // Test first it it is a fast recursive unlock
ld_ptr(Rbox, BasicLock::displaced_header_offset_in_bytes(), Rmark); ld_ptr(Rbox, BasicLock::displaced_header_offset_in_bytes(), Rmark);
br_null(Rmark, false, Assembler::pt, done); br_null_short(Rmark, Assembler::pt, done);
delayed()->nop();
if (!UseBiasedLocking) { if (!UseBiasedLocking) {
// load object // load object
ld_ptr(Rbox, BasicObjectLock::obj_offset_in_bytes(), Roop); ld_ptr(Rbox, BasicObjectLock::obj_offset_in_bytes(), Roop);
@ -231,7 +228,7 @@ void C1_MacroAssembler::allocate_object(
if (!is_simm13(obj_size * wordSize)) { if (!is_simm13(obj_size * wordSize)) {
// would need to use extra register to load // would need to use extra register to load
// object size => go the slow case for now // object size => go the slow case for now
br(Assembler::always, false, Assembler::pt, slow_case); ba(slow_case);
delayed()->nop(); delayed()->nop();
return; return;
} }
@ -257,12 +254,10 @@ void C1_MacroAssembler::initialize_object(
Label ok; Label ok;
ld(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), t1); ld(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), t1);
if (var_size_in_bytes != noreg) { if (var_size_in_bytes != noreg) {
cmp(t1, var_size_in_bytes); cmp_and_brx_short(t1, var_size_in_bytes, Assembler::equal, Assembler::pt, ok);
} else { } else {
cmp(t1, con_size_in_bytes); cmp_and_brx_short(t1, con_size_in_bytes, Assembler::equal, Assembler::pt, ok);
} }
brx(Assembler::equal, false, Assembler::pt, ok);
delayed()->nop();
stop("bad size in initialize_object"); stop("bad size in initialize_object");
should_not_reach_here(); should_not_reach_here();
@ -387,8 +382,7 @@ void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
void C1_MacroAssembler::verify_not_null_oop(Register r) { void C1_MacroAssembler::verify_not_null_oop(Register r) {
Label not_null; Label not_null;
br_notnull(r, false, Assembler::pt, not_null); br_notnull_short(r, Assembler::pt, not_null);
delayed()->nop();
stop("non-null oop required"); stop("non-null oop required");
bind(not_null); bind(not_null);
if (!VerifyOops) return; if (!VerifyOops) return;

View File

@ -71,8 +71,7 @@ int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address e
{ Label L; { Label L;
Address exception_addr(G2_thread, Thread::pending_exception_offset()); Address exception_addr(G2_thread, Thread::pending_exception_offset());
ld_ptr(exception_addr, Gtemp); ld_ptr(exception_addr, Gtemp);
br_null(Gtemp, false, pt, L); br_null_short(Gtemp, pt, L);
delayed()->nop();
Address vm_result_addr(G2_thread, JavaThread::vm_result_offset()); Address vm_result_addr(G2_thread, JavaThread::vm_result_offset());
st_ptr(G0, vm_result_addr); st_ptr(G0, vm_result_addr);
Address vm_result_addr_2(G2_thread, JavaThread::vm_result_2_offset()); Address vm_result_addr_2(G2_thread, JavaThread::vm_result_2_offset());
@ -333,9 +332,7 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) {
assert(deopt_blob != NULL, "deoptimization blob must have been created"); assert(deopt_blob != NULL, "deoptimization blob must have been created");
Label no_deopt; Label no_deopt;
__ tst(O0); __ br_null_short(O0, Assembler::pt, no_deopt);
__ brx(Assembler::equal, false, Assembler::pt, no_deopt);
__ delayed()->nop();
// return to the deoptimization handler entry for unpacking and rexecute // return to the deoptimization handler entry for unpacking and rexecute
// if we simply returned the we'd deopt as if any call we patched had just // if we simply returned the we'd deopt as if any call we patched had just
@ -402,18 +399,15 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
if (id == fast_new_instance_init_check_id) { if (id == fast_new_instance_init_check_id) {
// make sure the klass is initialized // make sure the klass is initialized
__ ld(G5_klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_t1); __ ld(G5_klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_t1);
__ cmp(G3_t1, instanceKlass::fully_initialized); __ cmp_and_br_short(G3_t1, instanceKlass::fully_initialized, Assembler::notEqual, Assembler::pn, slow_path);
__ br(Assembler::notEqual, false, Assembler::pn, slow_path);
__ delayed()->nop();
} }
#ifdef ASSERT #ifdef ASSERT
// assert object can be fast path allocated // assert object can be fast path allocated
{ {
Label ok, not_ok; Label ok, not_ok;
__ ld(G5_klass, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc), G1_obj_size); __ ld(G5_klass, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc), G1_obj_size);
__ cmp(G1_obj_size, 0); // make sure it's an instance (LH > 0) // make sure it's an instance (LH > 0)
__ br(Assembler::lessEqual, false, Assembler::pn, not_ok); __ cmp_and_br_short(G1_obj_size, 0, Assembler::lessEqual, Assembler::pn, not_ok);
__ delayed()->nop();
__ btst(Klass::_lh_instance_slow_path_bit, G1_obj_size); __ btst(Klass::_lh_instance_slow_path_bit, G1_obj_size);
__ br(Assembler::zero, false, Assembler::pn, ok); __ br(Assembler::zero, false, Assembler::pn, ok);
__ delayed()->nop(); __ delayed()->nop();
@ -501,9 +495,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
int tag = ((id == new_type_array_id) int tag = ((id == new_type_array_id)
? Klass::_lh_array_tag_type_value ? Klass::_lh_array_tag_type_value
: Klass::_lh_array_tag_obj_value); : Klass::_lh_array_tag_obj_value);
__ cmp(G3_t1, tag); __ cmp_and_brx_short(G3_t1, tag, Assembler::equal, Assembler::pt, ok);
__ brx(Assembler::equal, false, Assembler::pt, ok);
__ delayed()->nop();
__ stop("assert(is an array klass)"); __ stop("assert(is an array klass)");
__ should_not_reach_here(); __ should_not_reach_here();
__ bind(ok); __ bind(ok);
@ -519,9 +511,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
// check that array length is small enough for fast path // check that array length is small enough for fast path
__ set(C1_MacroAssembler::max_array_allocation_length, G3_t1); __ set(C1_MacroAssembler::max_array_allocation_length, G3_t1);
__ cmp(G4_length, G3_t1); __ cmp_and_br_short(G4_length, G3_t1, Assembler::greaterUnsigned, Assembler::pn, slow_path);
__ br(Assembler::greaterUnsigned, false, Assembler::pn, slow_path);
__ delayed()->nop();
// if we got here then the TLAB allocation failed, so try // if we got here then the TLAB allocation failed, so try
// refilling the TLAB or allocating directly from eden. // refilling the TLAB or allocating directly from eden.

View File

@ -544,7 +544,7 @@ address InterpreterGenerator::generate_accessor_entry(void) {
// Generate regular method entry // Generate regular method entry
__ bind(slow_path); __ bind(slow_path);
__ ba(false, fast_accessor_slow_entry_path); __ ba(fast_accessor_slow_entry_path);
__ delayed()->nop(); __ delayed()->nop();
return entry; return entry;
} }
@ -719,8 +719,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
Address exception_addr(G2_thread, 0, in_bytes(Thread::pending_exception_offset())); Address exception_addr(G2_thread, 0, in_bytes(Thread::pending_exception_offset()));
__ ld_ptr(exception_addr, G3_scratch); __ ld_ptr(exception_addr, G3_scratch);
__ br_notnull(G3_scratch, false, Assembler::pn, pending_exception_present); __ br_notnull_short(G3_scratch, Assembler::pn, pending_exception_present);
__ delayed()->nop();
__ ld_ptr(Address(G5_method, 0, in_bytes(methodOopDesc::signature_handler_offset())), G3_scratch); __ ld_ptr(Address(G5_method, 0, in_bytes(methodOopDesc::signature_handler_offset())), G3_scratch);
__ bind(L); __ bind(L);
} }
@ -1292,7 +1291,7 @@ void CppInterpreterGenerator::generate_deopt_handling() {
deopt_frame_manager_return_atos = __ pc(); deopt_frame_manager_return_atos = __ pc();
// O0/O1 live // O0/O1 live
__ ba(false, return_from_deopt_common); __ ba(return_from_deopt_common);
__ delayed()->set(AbstractInterpreter::BasicType_as_index(T_OBJECT), L3_scratch); // Result stub address array index __ delayed()->set(AbstractInterpreter::BasicType_as_index(T_OBJECT), L3_scratch); // Result stub address array index
@ -1300,14 +1299,14 @@ void CppInterpreterGenerator::generate_deopt_handling() {
deopt_frame_manager_return_btos = __ pc(); deopt_frame_manager_return_btos = __ pc();
// O0/O1 live // O0/O1 live
__ ba(false, return_from_deopt_common); __ ba(return_from_deopt_common);
__ delayed()->set(AbstractInterpreter::BasicType_as_index(T_BOOLEAN), L3_scratch); // Result stub address array index __ delayed()->set(AbstractInterpreter::BasicType_as_index(T_BOOLEAN), L3_scratch); // Result stub address array index
// deopt needs to jump to here to enter the interpreter (return a result) // deopt needs to jump to here to enter the interpreter (return a result)
deopt_frame_manager_return_itos = __ pc(); deopt_frame_manager_return_itos = __ pc();
// O0/O1 live // O0/O1 live
__ ba(false, return_from_deopt_common); __ ba(return_from_deopt_common);
__ delayed()->set(AbstractInterpreter::BasicType_as_index(T_INT), L3_scratch); // Result stub address array index __ delayed()->set(AbstractInterpreter::BasicType_as_index(T_INT), L3_scratch); // Result stub address array index
// deopt needs to jump to here to enter the interpreter (return a result) // deopt needs to jump to here to enter the interpreter (return a result)
@ -1327,21 +1326,21 @@ void CppInterpreterGenerator::generate_deopt_handling() {
__ srlx(G1,32,O0); __ srlx(G1,32,O0);
#endif /* !_LP64 && COMPILER2 */ #endif /* !_LP64 && COMPILER2 */
// O0/O1 live // O0/O1 live
__ ba(false, return_from_deopt_common); __ ba(return_from_deopt_common);
__ delayed()->set(AbstractInterpreter::BasicType_as_index(T_LONG), L3_scratch); // Result stub address array index __ delayed()->set(AbstractInterpreter::BasicType_as_index(T_LONG), L3_scratch); // Result stub address array index
// deopt needs to jump to here to enter the interpreter (return a result) // deopt needs to jump to here to enter the interpreter (return a result)
deopt_frame_manager_return_ftos = __ pc(); deopt_frame_manager_return_ftos = __ pc();
// O0/O1 live // O0/O1 live
__ ba(false, return_from_deopt_common); __ ba(return_from_deopt_common);
__ delayed()->set(AbstractInterpreter::BasicType_as_index(T_FLOAT), L3_scratch); // Result stub address array index __ delayed()->set(AbstractInterpreter::BasicType_as_index(T_FLOAT), L3_scratch); // Result stub address array index
// deopt needs to jump to here to enter the interpreter (return a result) // deopt needs to jump to here to enter the interpreter (return a result)
deopt_frame_manager_return_dtos = __ pc(); deopt_frame_manager_return_dtos = __ pc();
// O0/O1 live // O0/O1 live
__ ba(false, return_from_deopt_common); __ ba(return_from_deopt_common);
__ delayed()->set(AbstractInterpreter::BasicType_as_index(T_DOUBLE), L3_scratch); // Result stub address array index __ delayed()->set(AbstractInterpreter::BasicType_as_index(T_DOUBLE), L3_scratch); // Result stub address array index
// deopt needs to jump to here to enter the interpreter (return a result) // deopt needs to jump to here to enter the interpreter (return a result)
@ -1398,7 +1397,7 @@ void CppInterpreterGenerator::generate_more_monitors() {
__ ld_ptr(STATE(_stack), L1_scratch); // Get current stack top __ ld_ptr(STATE(_stack), L1_scratch); // Get current stack top
__ sub(L1_scratch, entry_size, L1_scratch); __ sub(L1_scratch, entry_size, L1_scratch);
__ st_ptr(L1_scratch, STATE(_stack)); __ st_ptr(L1_scratch, STATE(_stack));
__ ba(false, entry); __ ba(entry);
__ delayed()->add(L1_scratch, wordSize, L1_scratch); // first real entry (undo prepush) __ delayed()->add(L1_scratch, wordSize, L1_scratch); // first real entry (undo prepush)
// 2. move expression stack // 2. move expression stack
@ -1651,7 +1650,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
__ set((int)BytecodeInterpreter::got_monitors, L1_scratch); __ set((int)BytecodeInterpreter::got_monitors, L1_scratch);
VALIDATE_STATE(G3_scratch, 5); VALIDATE_STATE(G3_scratch, 5);
__ ba(false, call_interpreter); __ ba(call_interpreter);
__ delayed()->st(L1_scratch, STATE(_msg)); __ delayed()->st(L1_scratch, STATE(_msg));
// uncommon trap needs to jump to here to enter the interpreter (re-execute current bytecode) // uncommon trap needs to jump to here to enter the interpreter (re-execute current bytecode)
@ -1659,7 +1658,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
// QQQ what message do we send // QQQ what message do we send
__ ba(false, call_interpreter); __ ba(call_interpreter);
__ delayed()->ld_ptr(STATE(_frame_bottom), SP); // restore to full stack frame __ delayed()->ld_ptr(STATE(_frame_bottom), SP); // restore to full stack frame
//============================================================================= //=============================================================================
@ -1675,7 +1674,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
// ready to resume the interpreter // ready to resume the interpreter
__ set((int)BytecodeInterpreter::deopt_resume, L1_scratch); __ set((int)BytecodeInterpreter::deopt_resume, L1_scratch);
__ ba(false, call_interpreter); __ ba(call_interpreter);
__ delayed()->st(L1_scratch, STATE(_msg)); __ delayed()->st(L1_scratch, STATE(_msg));
// Current frame has caught an exception we need to dispatch to the // Current frame has caught an exception we need to dispatch to the
@ -1763,7 +1762,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
// L1_scratch points to top of stack (prepushed) // L1_scratch points to top of stack (prepushed)
__ ba(false, resume_interpreter); __ ba(resume_interpreter);
__ delayed()->mov(L1_scratch, O1); __ delayed()->mov(L1_scratch, O1);
// An exception is being caught on return to a vanilla interpreter frame. // An exception is being caught on return to a vanilla interpreter frame.
@ -1773,7 +1772,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
__ ld_ptr(STATE(_frame_bottom), SP); // restore to full stack frame __ ld_ptr(STATE(_frame_bottom), SP); // restore to full stack frame
__ ld_ptr(STATE(_stack_base), O1); // empty java expression stack __ ld_ptr(STATE(_stack_base), O1); // empty java expression stack
__ ba(false, resume_interpreter); __ ba(resume_interpreter);
__ delayed()->sub(O1, wordSize, O1); // account for prepush __ delayed()->sub(O1, wordSize, O1); // account for prepush
// Return from interpreted method we return result appropriate to the caller (i.e. "recursive" // Return from interpreted method we return result appropriate to the caller (i.e. "recursive"
@ -1852,7 +1851,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
__ set((int)BytecodeInterpreter::method_resume, L1_scratch); __ set((int)BytecodeInterpreter::method_resume, L1_scratch);
__ st(L1_scratch, STATE(_msg)); __ st(L1_scratch, STATE(_msg));
__ ba(false, call_interpreter_2); __ ba(call_interpreter_2);
__ delayed()->st_ptr(O1, STATE(_stack)); __ delayed()->st_ptr(O1, STATE(_stack));
@ -1867,8 +1866,8 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
__ cmp(Gtmp1, O7); // returning to interpreter? __ cmp(Gtmp1, O7); // returning to interpreter?
__ brx(Assembler::equal, true, Assembler::pt, re_dispatch); // yep __ brx(Assembler::equal, true, Assembler::pt, re_dispatch); // yep
__ delayed()->nop(); __ delayed()->nop();
__ ba(false, re_dispatch); __ ba(re_dispatch);
__ delayed()->mov(G0, prevState); // initial entry __ delayed()->mov(G0, prevState); // initial entry
} }
@ -2031,8 +2030,8 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
__ brx(Assembler::zero, false, Assembler::pt, unwind_and_forward); __ brx(Assembler::zero, false, Assembler::pt, unwind_and_forward);
__ delayed()->nop(); __ delayed()->nop();
__ ld_ptr(STATE(_locals), O1); // get result of popping callee's args __ ld_ptr(STATE(_locals), O1); // get result of popping callee's args
__ ba(false, unwind_recursive_activation); __ ba(unwind_recursive_activation);
__ delayed()->nop(); __ delayed()->nop();
interpreter_frame_manager = entry_point; interpreter_frame_manager = entry_point;

View File

@ -236,17 +236,13 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register scratch_reg)
Label L; Label L;
Register thr_state = G3_scratch; Register thr_state = G3_scratch;
ld_ptr(G2_thread, JavaThread::jvmti_thread_state_offset(), thr_state); ld_ptr(G2_thread, JavaThread::jvmti_thread_state_offset(), thr_state);
tst(thr_state); br_null_short(thr_state, pt, L); // if (thread->jvmti_thread_state() == NULL) exit;
br(zero, false, pt, L); // if (thread->jvmti_thread_state() == NULL) exit;
delayed()->nop();
// Initiate earlyret handling only if it is not already being processed. // Initiate earlyret handling only if it is not already being processed.
// If the flag has the earlyret_processing bit set, it means that this code // If the flag has the earlyret_processing bit set, it means that this code
// is called *during* earlyret handling - we don't want to reenter. // is called *during* earlyret handling - we don't want to reenter.
ld(thr_state, JvmtiThreadState::earlyret_state_offset(), G4_scratch); ld(thr_state, JvmtiThreadState::earlyret_state_offset(), G4_scratch);
cmp(G4_scratch, JvmtiThreadState::earlyret_pending); cmp_and_br_short(G4_scratch, JvmtiThreadState::earlyret_pending, Assembler::notEqual, pt, L);
br(Assembler::notEqual, false, pt, L);
delayed()->nop();
// Call Interpreter::remove_activation_early_entry() to get the address of the // Call Interpreter::remove_activation_early_entry() to get the address of the
// same-named entrypoint in the generated interpreter code // same-named entrypoint in the generated interpreter code
@ -566,9 +562,7 @@ void InterpreterMacroAssembler::verify_sp(Register Rsp, Register Rtemp) {
#ifdef _LP64 #ifdef _LP64
sub(Rtemp, STACK_BIAS, Rtemp); // Bias Rtemp before cmp to FP sub(Rtemp, STACK_BIAS, Rtemp); // Bias Rtemp before cmp to FP
#endif #endif
cmp(Rtemp, FP); cmp_and_brx_short(Rtemp, FP, Assembler::greaterUnsigned, Assembler::pn, Bad);
brx(Assembler::greaterUnsigned, false, Assembler::pn, Bad);
delayed()->nop();
// Saved SP must not be ridiculously below current SP. // Saved SP must not be ridiculously below current SP.
size_t maxstack = MAX2(JavaThread::stack_size_at_create(), (size_t) 4*K*K); size_t maxstack = MAX2(JavaThread::stack_size_at_create(), (size_t) 4*K*K);
@ -577,12 +571,9 @@ void InterpreterMacroAssembler::verify_sp(Register Rsp, Register Rtemp) {
#ifdef _LP64 #ifdef _LP64
add(Rtemp, STACK_BIAS, Rtemp); // Unbias Rtemp before cmp to Rsp add(Rtemp, STACK_BIAS, Rtemp); // Unbias Rtemp before cmp to Rsp
#endif #endif
cmp(Rsp, Rtemp); cmp_and_brx_short(Rsp, Rtemp, Assembler::lessUnsigned, Assembler::pn, Bad);
brx(Assembler::lessUnsigned, false, Assembler::pn, Bad);
delayed()->nop();
br(Assembler::always, false, Assembler::pn, OK); ba_short(OK);
delayed()->nop();
bind(Bad); bind(Bad);
stop("on return to interpreted call, restored SP is corrupted"); stop("on return to interpreted call, restored SP is corrupted");
@ -630,8 +621,7 @@ void InterpreterMacroAssembler::call_from_interpreter(Register target, Register
const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset()); const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
ld(interp_only, scratch); ld(interp_only, scratch);
tst(scratch); cmp_zero_and_br(Assembler::notZero, scratch, skip_compiled_code, true, Assembler::pn);
br(Assembler::notZero, true, Assembler::pn, skip_compiled_code);
delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), target); delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), target);
bind(skip_compiled_code); bind(skip_compiled_code);
} }
@ -641,8 +631,7 @@ void InterpreterMacroAssembler::call_from_interpreter(Register target, Register
#ifdef ASSERT #ifdef ASSERT
{ {
Label ok; Label ok;
br_notnull(target, false, Assembler::pt, ok); br_notnull_short(target, Assembler::pt, ok);
delayed()->nop();
stop("null entry point"); stop("null entry point");
bind(ok); bind(ok);
} }
@ -769,6 +758,20 @@ void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Regis
} }
void InterpreterMacroAssembler::get_cache_and_index_and_bytecode_at_bcp(Register cache,
Register temp,
Register bytecode,
int byte_no,
int bcp_offset,
size_t index_size) {
get_cache_and_index_at_bcp(cache, temp, bcp_offset, index_size);
ld_ptr(cache, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset(), bytecode);
const int shift_count = (1 + byte_no) * BitsPerByte;
srl( bytecode, shift_count, bytecode);
and3(bytecode, 0xFF, bytecode);
}
void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, Register tmp, void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, Register tmp,
int bcp_offset, size_t index_size) { int bcp_offset, size_t index_size) {
assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
@ -982,8 +985,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
// Don't unlock anything if the _do_not_unlock_if_synchronized flag // Don't unlock anything if the _do_not_unlock_if_synchronized flag
// is set. // is set.
tstbool(G1_scratch); cmp_zero_and_br(Assembler::notZero, G1_scratch, no_unlock);
br(Assembler::notZero, false, pn, no_unlock);
delayed()->nop(); delayed()->nop();
// BasicObjectLock will be first in list, since this is a synchronized method. However, need // BasicObjectLock will be first in list, since this is a synchronized method. However, need
@ -997,8 +999,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
add( top_most_monitor(), O1 ); add( top_most_monitor(), O1 );
ld_ptr(O1, BasicObjectLock::obj_offset_in_bytes(), G3_scratch); ld_ptr(O1, BasicObjectLock::obj_offset_in_bytes(), G3_scratch);
br_notnull(G3_scratch, false, pt, unlock); br_notnull_short(G3_scratch, pt, unlock);
delayed()->nop();
if (throw_monitor_exception) { if (throw_monitor_exception) {
// Entry already unlocked need to throw an exception // Entry already unlocked need to throw an exception
@ -1011,8 +1012,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
if (install_monitor_exception) { if (install_monitor_exception) {
MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::new_illegal_monitor_state_exception)); MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::new_illegal_monitor_state_exception));
} }
ba(false, unlocked); ba_short(unlocked);
delayed()->nop();
} }
bind(unlock); bind(unlock);
@ -1037,15 +1037,13 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
add(top_most_monitor(), Rmptr, delta); add(top_most_monitor(), Rmptr, delta);
{ Label L; { Label L;
// ensure that Rmptr starts out above (or at) Rlimit // ensure that Rmptr starts out above (or at) Rlimit
cmp(Rmptr, Rlimit); cmp_and_brx_short(Rmptr, Rlimit, Assembler::greaterEqualUnsigned, pn, L);
brx(Assembler::greaterEqualUnsigned, false, pn, L);
delayed()->nop();
stop("monitor stack has negative size"); stop("monitor stack has negative size");
bind(L); bind(L);
} }
#endif #endif
bind(restart); bind(restart);
ba(false, entry); ba(entry);
delayed()-> delayed()->
add(top_most_monitor(), Rmptr, delta); // points to current entry, starting with bottom-most entry add(top_most_monitor(), Rmptr, delta); // points to current entry, starting with bottom-most entry
@ -1061,8 +1059,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
if (install_monitor_exception) { if (install_monitor_exception) {
MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::new_illegal_monitor_state_exception)); MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::new_illegal_monitor_state_exception));
} }
ba(false, restart); ba_short(restart);
delayed()->nop();
} }
bind(loop); bind(loop);
@ -1073,9 +1070,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
#ifdef ASSERT #ifdef ASSERT
{ Label L; { Label L;
// ensure that Rmptr has not somehow stepped below Rlimit // ensure that Rmptr has not somehow stepped below Rlimit
cmp(Rmptr, Rlimit); cmp_and_brx_short(Rmptr, Rlimit, Assembler::greaterEqualUnsigned, pn, L);
brx(Assembler::greaterEqualUnsigned, false, pn, L);
delayed()->nop();
stop("ran off the end of the monitor stack"); stop("ran off the end of the monitor stack");
bind(L); bind(L);
} }
@ -1196,9 +1191,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg, Register Object)
(address)StubRoutines::Sparc::atomic_memory_operation_lock_addr()); (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
// if the compare and exchange succeeded we are done (we saw an unlocked object) // if the compare and exchange succeeded we are done (we saw an unlocked object)
cmp(mark_reg, temp_reg); cmp_and_brx_short(mark_reg, temp_reg, Assembler::equal, Assembler::pt, done);
brx(Assembler::equal, true, Assembler::pt, done);
delayed()->nop();
// We did not see an unlocked object so try the fast recursive case // We did not see an unlocked object so try the fast recursive case
@ -1324,13 +1317,7 @@ void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {
void InterpreterMacroAssembler::test_method_data_pointer(Label& zero_continue) { void InterpreterMacroAssembler::test_method_data_pointer(Label& zero_continue) {
assert(ProfileInterpreter, "must be profiling interpreter"); assert(ProfileInterpreter, "must be profiling interpreter");
#ifdef _LP64 br_null_short(ImethodDataPtr, Assembler::pn, zero_continue);
bpr(Assembler::rc_z, false, Assembler::pn, ImethodDataPtr, zero_continue);
#else
tst(ImethodDataPtr);
br(Assembler::zero, false, Assembler::pn, zero_continue);
#endif
delayed()->nop();
} }
void InterpreterMacroAssembler::verify_method_data_pointer() { void InterpreterMacroAssembler::verify_method_data_pointer() {
@ -1376,31 +1363,18 @@ void InterpreterMacroAssembler::test_invocation_counter_for_mdp(Register invocat
Label done; Label done;
// if no method data exists, and the counter is high enough, make one // if no method data exists, and the counter is high enough, make one
#ifdef _LP64 br_notnull_short(ImethodDataPtr, Assembler::pn, done);
bpr(Assembler::rc_nz, false, Assembler::pn, ImethodDataPtr, done);
#else
tst(ImethodDataPtr);
br(Assembler::notZero, false, Assembler::pn, done);
#endif
// Test to see if we should create a method data oop // Test to see if we should create a method data oop
AddressLiteral profile_limit((address) &InvocationCounter::InterpreterProfileLimit); AddressLiteral profile_limit((address) &InvocationCounter::InterpreterProfileLimit);
#ifdef _LP64
delayed()->nop();
sethi(profile_limit, Rtmp); sethi(profile_limit, Rtmp);
#else
delayed()->sethi(profile_limit, Rtmp);
#endif
ld(Rtmp, profile_limit.low10(), Rtmp); ld(Rtmp, profile_limit.low10(), Rtmp);
cmp(invocation_count, Rtmp); cmp_and_br_short(invocation_count, Rtmp, Assembler::lessUnsigned, Assembler::pn, profile_continue);
br(Assembler::lessUnsigned, false, Assembler::pn, profile_continue);
delayed()->nop();
// Build it now. // Build it now.
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method)); call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
set_method_data_pointer_for_bcp(); set_method_data_pointer_for_bcp();
ba(false, profile_continue); ba_short(profile_continue);
delayed()->nop();
bind(done); bind(done);
} }
@ -1632,13 +1606,10 @@ void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
Label skip_receiver_profile; Label skip_receiver_profile;
if (receiver_can_be_null) { if (receiver_can_be_null) {
Label not_null; Label not_null;
tst(receiver); br_notnull_short(receiver, Assembler::pt, not_null);
brx(Assembler::notZero, false, Assembler::pt, not_null);
delayed()->nop();
// We are making a call. Increment the count for null receiver. // We are making a call. Increment the count for null receiver.
increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch); increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
ba(false, skip_receiver_profile); ba_short(skip_receiver_profile);
delayed()->nop();
bind(not_null); bind(not_null);
} }
@ -1682,8 +1653,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
// The receiver is receiver[n]. Increment count[n]. // The receiver is receiver[n]. Increment count[n].
int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row)); int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row));
increment_mdp_data_at(count_offset, scratch); increment_mdp_data_at(count_offset, scratch);
ba(false, done); ba_short(done);
delayed()->nop();
bind(next_test); bind(next_test);
if (test_for_null_also) { if (test_for_null_also) {
@ -1697,8 +1667,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
// Receiver did not match any saved receiver and there is no empty row for it. // Receiver did not match any saved receiver and there is no empty row for it.
// Increment total counter to indicate polymorphic case. // Increment total counter to indicate polymorphic case.
increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch); increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
ba(false, done); ba_short(done);
delayed()->nop();
bind(found_null); bind(found_null);
} else { } else {
brx(Assembler::notZero, false, Assembler::pt, done); brx(Assembler::notZero, false, Assembler::pt, done);
@ -1729,8 +1698,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
mov(DataLayout::counter_increment, scratch); mov(DataLayout::counter_increment, scratch);
set_mdp_data_at(count_offset, scratch); set_mdp_data_at(count_offset, scratch);
if (start_row > 0) { if (start_row > 0) {
ba(false, done); ba_short(done);
delayed()->nop();
} }
} }
@ -1772,8 +1740,7 @@ void InterpreterMacroAssembler::profile_ret(TosState state,
// The method data pointer needs to be updated to reflect the new target. // The method data pointer needs to be updated to reflect the new target.
update_mdp_by_offset(in_bytes(RetData::bci_displacement_offset(row)), scratch); update_mdp_by_offset(in_bytes(RetData::bci_displacement_offset(row)), scratch);
ba(false, profile_continue); ba_short(profile_continue);
delayed()->nop();
bind(next_test); bind(next_test);
} }
@ -1922,8 +1889,8 @@ void InterpreterMacroAssembler::add_monitor_to_stack( bool stack_is_empty,
// untested("monitor stack expansion"); // untested("monitor stack expansion");
compute_stack_base(Rtemp); compute_stack_base(Rtemp);
ba( false, start_copying ); ba(start_copying);
delayed()->cmp( Rtemp, Rlimit); // done? duplicated below delayed()->cmp(Rtemp, Rlimit); // done? duplicated below
// note: must copy from low memory upwards // note: must copy from low memory upwards
// On entry to loop, // On entry to loop,
@ -2010,9 +1977,7 @@ void InterpreterMacroAssembler::check_for_regarea_stomp(Register Rindex, int off
// untested("reg area corruption"); // untested("reg area corruption");
add(Rindex, offset, Rscratch); add(Rindex, offset, Rscratch);
add(Rlimit, 64 + STACK_BIAS, Rscratch1); add(Rlimit, 64 + STACK_BIAS, Rscratch1);
cmp(Rscratch, Rscratch1); cmp_and_brx_short(Rscratch, Rscratch1, Assembler::greaterEqualUnsigned, pn, L);
brx(Assembler::greaterEqualUnsigned, false, pn, L);
delayed()->nop();
stop("regsave area is being clobbered"); stop("regsave area is being clobbered");
bind(L); bind(L);
} }
@ -2174,9 +2139,7 @@ void InterpreterMacroAssembler::test_backedge_count_for_osr( Register backedge_c
AddressLiteral limit(&InvocationCounter::InterpreterBackwardBranchLimit); AddressLiteral limit(&InvocationCounter::InterpreterBackwardBranchLimit);
load_contents(limit, Rtmp); load_contents(limit, Rtmp);
cmp(backedge_count, Rtmp); cmp_and_br_short(backedge_count, Rtmp, Assembler::lessUnsigned, Assembler::pt, did_not_overflow);
br(Assembler::lessUnsigned, false, Assembler::pt, did_not_overflow);
delayed()->nop();
// When ProfileInterpreter is on, the backedge_count comes from the // When ProfileInterpreter is on, the backedge_count comes from the
// methodDataOop, which value does not get reset on the call to // methodDataOop, which value does not get reset on the call to
@ -2196,15 +2159,11 @@ void InterpreterMacroAssembler::test_backedge_count_for_osr( Register backedge_c
// Was an OSR adapter generated? // Was an OSR adapter generated?
// O0 = osr nmethod // O0 = osr nmethod
tst(O0); br_null_short(O0, Assembler::pn, overflow_with_error);
brx(Assembler::zero, false, Assembler::pn, overflow_with_error);
delayed()->nop();
// Has the nmethod been invalidated already? // Has the nmethod been invalidated already?
ld(O0, nmethod::entry_bci_offset(), O2); ld(O0, nmethod::entry_bci_offset(), O2);
cmp(O2, InvalidOSREntryBci); cmp_and_br_short(O2, InvalidOSREntryBci, Assembler::equal, Assembler::pn, overflow_with_error);
br(Assembler::equal, false, Assembler::pn, overflow_with_error);
delayed()->nop();
// migrate the interpreter frame off of the stack // migrate the interpreter frame off of the stack
@ -2270,8 +2229,7 @@ void InterpreterMacroAssembler::verify_oop_or_return_address(Register reg, Regis
mov(reg, Rtmp); mov(reg, Rtmp);
const int log2_bytecode_size_limit = 16; const int log2_bytecode_size_limit = 16;
srl(Rtmp, log2_bytecode_size_limit, Rtmp); srl(Rtmp, log2_bytecode_size_limit, Rtmp);
br_notnull( Rtmp, false, pt, test ); br_notnull_short( Rtmp, pt, test );
delayed()->nop();
// %%% should use call_VM_leaf here? // %%% should use call_VM_leaf here?
save_frame_and_mov(0, Lmethod, O0, reg, O1); save_frame_and_mov(0, Lmethod, O0, reg, O1);
@ -2320,9 +2278,7 @@ void InterpreterMacroAssembler::notify_method_entry() {
Register temp_reg = O5; Register temp_reg = O5;
const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset()); const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
ld(interp_only, temp_reg); ld(interp_only, temp_reg);
tst(temp_reg); cmp_and_br_short(temp_reg, 0, equal, pt, L);
br(zero, false, pt, L);
delayed()->nop();
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_entry)); call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_entry));
bind(L); bind(L);
} }
@ -2372,9 +2328,7 @@ void InterpreterMacroAssembler::notify_method_exit(bool is_native_method,
Register temp_reg = O5; Register temp_reg = O5;
const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset()); const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
ld(interp_only, temp_reg); ld(interp_only, temp_reg);
tst(temp_reg); cmp_and_br_short(temp_reg, 0, equal, pt, L);
br(zero, false, pt, L);
delayed()->nop();
// Note: frame::interpreter_frame_result has a dependency on how the // Note: frame::interpreter_frame_result has a dependency on how the
// method result is saved across the call to post_method_exit. For // method result is saved across the call to post_method_exit. For

View File

@ -189,6 +189,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
setCCOrNot should_set_CC = dont_set_CC ); setCCOrNot should_set_CC = dont_set_CC );
void get_cache_and_index_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2)); void get_cache_and_index_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register temp, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2)); void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_index_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2)); void get_cache_index_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));

View File

@ -191,22 +191,19 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() {
// Optimization, see if there are any more args and get out prior to checking // Optimization, see if there are any more args and get out prior to checking
// all 16 float registers. My guess is that this is rare. // all 16 float registers. My guess is that this is rare.
// If is_register is false, then we are done the first six integer args. // If is_register is false, then we are done the first six integer args.
__ tst(G4_scratch); __ br_null_short(G4_scratch, Assembler::pt, done);
__ brx(Assembler::zero, false, Assembler::pt, done);
__ delayed()->nop();
} }
__ ba(false, NextArg); __ ba(NextArg);
__ delayed()->srl( G4_scratch, 2, G4_scratch ); __ delayed()->srl( G4_scratch, 2, G4_scratch );
__ bind(LoadFloatArg); __ bind(LoadFloatArg);
__ ldf( FloatRegisterImpl::S, a, ldarg.as_float_register(), 4); __ ldf( FloatRegisterImpl::S, a, ldarg.as_float_register(), 4);
__ ba(false, NextArg); __ ba(NextArg);
__ delayed()->srl( G4_scratch, 2, G4_scratch ); __ delayed()->srl( G4_scratch, 2, G4_scratch );
__ bind(LoadDoubleArg); __ bind(LoadDoubleArg);
__ ldf( FloatRegisterImpl::D, a, ldarg.as_double_register() ); __ ldf( FloatRegisterImpl::D, a, ldarg.as_double_register() );
__ ba(false, NextArg); __ ba(NextArg);
__ delayed()->srl( G4_scratch, 2, G4_scratch ); __ delayed()->srl( G4_scratch, 2, G4_scratch );
__ bind(NextArg); __ bind(NextArg);
@ -234,8 +231,7 @@ void InterpreterGenerator::generate_counter_overflow(Label& Lcontinue) {
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), O2, O2, true); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), O2, O2, true);
// returns verified_entry_point or NULL // returns verified_entry_point or NULL
// we ignore it in any case // we ignore it in any case
__ ba(false, Lcontinue); __ ba_short(Lcontinue);
__ delayed()->nop();
} }

View File

@ -287,9 +287,7 @@ void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
BLOCK_COMMENT("verify_clean {"); BLOCK_COMMENT("verify_clean {");
// Magic numbers must check out: // Magic numbers must check out:
__ set((int32_t) MAGIC_NUMBER_1, O7_temp); __ set((int32_t) MAGIC_NUMBER_1, O7_temp);
__ cmp(O7_temp, L0_magic_number_1); __ cmp_and_br_short(O7_temp, L0_magic_number_1, Assembler::equal, Assembler::pt, L_ok_1);
__ br(Assembler::equal, false, Assembler::pt, L_ok_1);
__ delayed()->nop();
__ stop("damaged ricochet frame: MAGIC_NUMBER_1 not found"); __ stop("damaged ricochet frame: MAGIC_NUMBER_1 not found");
__ BIND(L_ok_1); __ BIND(L_ok_1);
@ -301,9 +299,7 @@ void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
#else #else
Register FP_temp = FP; Register FP_temp = FP;
#endif #endif
__ cmp(L4_saved_args_base, FP_temp); __ cmp_and_brx_short(L4_saved_args_base, FP_temp, Assembler::greaterEqualUnsigned, Assembler::pt, L_ok_2);
__ br(Assembler::greaterEqualUnsigned, false, Assembler::pt, L_ok_2);
__ delayed()->nop();
__ stop("damaged ricochet frame: L4 < FP"); __ stop("damaged ricochet frame: L4 < FP");
__ BIND(L_ok_2); __ BIND(L_ok_2);
@ -316,15 +312,11 @@ void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
__ BIND(L_ok_3); __ BIND(L_ok_3);
extract_conversion_dest_type(_masm, L5_conversion, O7_temp); extract_conversion_dest_type(_masm, L5_conversion, O7_temp);
__ cmp(O7_temp, T_VOID); __ cmp_and_br_short(O7_temp, T_VOID, Assembler::equal, Assembler::pt, L_ok_4);
__ br(Assembler::equal, false, Assembler::pt, L_ok_4);
__ delayed()->nop();
extract_conversion_vminfo(_masm, L5_conversion, O5_temp); extract_conversion_vminfo(_masm, L5_conversion, O5_temp);
__ ld_ptr(L4_saved_args_base, __ argument_offset(O5_temp, O5_temp), O7_temp); __ ld_ptr(L4_saved_args_base, __ argument_offset(O5_temp, O5_temp), O7_temp);
assert(__ is_simm13(RETURN_VALUE_PLACEHOLDER), "must be simm13"); assert(__ is_simm13(RETURN_VALUE_PLACEHOLDER), "must be simm13");
__ cmp(O7_temp, (int32_t) RETURN_VALUE_PLACEHOLDER); __ cmp_and_brx_short(O7_temp, (int32_t) RETURN_VALUE_PLACEHOLDER, Assembler::equal, Assembler::pt, L_ok_4);
__ brx(Assembler::equal, false, Assembler::pt, L_ok_4);
__ delayed()->nop();
__ stop("damaged ricochet frame: RETURN_VALUE_PLACEHOLDER not found"); __ stop("damaged ricochet frame: RETURN_VALUE_PLACEHOLDER not found");
__ BIND(L_ok_4); __ BIND(L_ok_4);
BLOCK_COMMENT("} verify_clean"); BLOCK_COMMENT("} verify_clean");
@ -363,9 +355,7 @@ void MethodHandles::load_stack_move(MacroAssembler* _masm,
if (VerifyMethodHandles) { if (VerifyMethodHandles) {
Label L_ok, L_bad; Label L_ok, L_bad;
int32_t stack_move_limit = 0x0800; // extra-large int32_t stack_move_limit = 0x0800; // extra-large
__ cmp(stack_move_reg, stack_move_limit); __ cmp_and_br_short(stack_move_reg, stack_move_limit, Assembler::greaterEqual, Assembler::pn, L_bad);
__ br(Assembler::greaterEqual, false, Assembler::pn, L_bad);
__ delayed()->nop();
__ cmp(stack_move_reg, -stack_move_limit); __ cmp(stack_move_reg, -stack_move_limit);
__ br(Assembler::greater, false, Assembler::pt, L_ok); __ br(Assembler::greater, false, Assembler::pt, L_ok);
__ delayed()->nop(); __ delayed()->nop();
@ -401,13 +391,9 @@ void MethodHandles::verify_argslot(MacroAssembler* _masm, Register argslot_reg,
// Verify that argslot lies within (Gargs, FP]. // Verify that argslot lies within (Gargs, FP].
Label L_ok, L_bad; Label L_ok, L_bad;
BLOCK_COMMENT("verify_argslot {"); BLOCK_COMMENT("verify_argslot {");
__ cmp_and_brx_short(Gargs, argslot_reg, Assembler::greaterUnsigned, Assembler::pn, L_bad);
__ add(FP, STACK_BIAS, temp_reg); // STACK_BIAS is zero on !_LP64 __ add(FP, STACK_BIAS, temp_reg); // STACK_BIAS is zero on !_LP64
__ cmp(argslot_reg, temp_reg); __ cmp_and_brx_short(argslot_reg, temp_reg, Assembler::lessEqualUnsigned, Assembler::pt, L_ok);
__ brx(Assembler::greaterUnsigned, false, Assembler::pn, L_bad);
__ delayed()->nop();
__ cmp(Gargs, argslot_reg);
__ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ BIND(L_bad); __ BIND(L_bad);
__ stop(error_message); __ stop(error_message);
__ BIND(L_ok); __ BIND(L_ok);
@ -434,14 +420,10 @@ void MethodHandles::verify_argslots(MacroAssembler* _masm,
} }
__ add(arg_slot_base_reg, __ argument_offset(arg_slots, temp_reg), temp_reg); __ add(arg_slot_base_reg, __ argument_offset(arg_slots, temp_reg), temp_reg);
__ add(FP, STACK_BIAS, temp2_reg); // STACK_BIAS is zero on !_LP64 __ add(FP, STACK_BIAS, temp2_reg); // STACK_BIAS is zero on !_LP64
__ cmp(temp_reg, temp2_reg); __ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::greaterUnsigned, Assembler::pn, L_bad);
__ brx(Assembler::greaterUnsigned, false, Assembler::pn, L_bad);
__ delayed()->nop();
// Gargs points to the first word so adjust by BytesPerWord // Gargs points to the first word so adjust by BytesPerWord
__ add(arg_slot_base_reg, BytesPerWord, temp_reg); __ add(arg_slot_base_reg, BytesPerWord, temp_reg);
__ cmp(Gargs, temp_reg); __ cmp_and_brx_short(Gargs, temp_reg, Assembler::lessEqualUnsigned, Assembler::pt, L_ok);
__ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ BIND(L_bad); __ BIND(L_bad);
__ stop(error_message); __ stop(error_message);
__ BIND(L_ok); __ BIND(L_ok);
@ -502,21 +484,16 @@ void MethodHandles::verify_klass(MacroAssembler* _masm,
Label L_ok, L_bad; Label L_ok, L_bad;
BLOCK_COMMENT("verify_klass {"); BLOCK_COMMENT("verify_klass {");
__ verify_oop(obj_reg); __ verify_oop(obj_reg);
__ br_null(obj_reg, false, Assembler::pn, L_bad); __ br_null_short(obj_reg, Assembler::pn, L_bad);
__ delayed()->nop();
__ load_klass(obj_reg, temp_reg); __ load_klass(obj_reg, temp_reg);
__ set(ExternalAddress(klass_addr), temp2_reg); __ set(ExternalAddress(klass_addr), temp2_reg);
__ ld_ptr(Address(temp2_reg, 0), temp2_reg); __ ld_ptr(Address(temp2_reg, 0), temp2_reg);
__ cmp(temp_reg, temp2_reg); __ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::equal, Assembler::pt, L_ok);
__ brx(Assembler::equal, false, Assembler::pt, L_ok);
__ delayed()->nop();
intptr_t super_check_offset = klass->super_check_offset(); intptr_t super_check_offset = klass->super_check_offset();
__ ld_ptr(Address(temp_reg, super_check_offset), temp_reg); __ ld_ptr(Address(temp_reg, super_check_offset), temp_reg);
__ set(ExternalAddress(klass_addr), temp2_reg); __ set(ExternalAddress(klass_addr), temp2_reg);
__ ld_ptr(Address(temp2_reg, 0), temp2_reg); __ ld_ptr(Address(temp2_reg, 0), temp2_reg);
__ cmp(temp_reg, temp2_reg); __ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::equal, Assembler::pt, L_ok);
__ brx(Assembler::equal, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ BIND(L_bad); __ BIND(L_bad);
__ stop(error_message); __ stop(error_message);
__ BIND(L_ok); __ BIND(L_ok);
@ -671,9 +648,7 @@ static RegisterOrConstant adjust_SP_and_Gargs_down_by_slots(MacroAssembler* _mas
#ifdef ASSERT #ifdef ASSERT
{ {
Label L_ok; Label L_ok;
__ cmp(arg_slots.as_register(), 0); __ cmp_and_br_short(arg_slots.as_register(), 0, Assembler::greaterEqual, Assembler::pt, L_ok);
__ br(Assembler::greaterEqual, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ stop("negative arg_slots"); __ stop("negative arg_slots");
__ bind(L_ok); __ bind(L_ok);
} }
@ -748,9 +723,7 @@ void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
__ ld_ptr( Address(temp_reg, 0 ), temp2_reg); __ ld_ptr( Address(temp_reg, 0 ), temp2_reg);
__ st_ptr(temp2_reg, Address(temp_reg, offset) ); __ st_ptr(temp2_reg, Address(temp_reg, offset) );
__ add(temp_reg, wordSize, temp_reg); __ add(temp_reg, wordSize, temp_reg);
__ cmp(temp_reg, argslot_reg); __ cmp_and_brx_short(temp_reg, argslot_reg, Assembler::lessUnsigned, Assembler::pt, loop);
__ brx(Assembler::lessUnsigned, false, Assembler::pt, loop);
__ delayed()->nop(); // FILLME
} }
// Now move the argslot down, to point to the opened-up space. // Now move the argslot down, to point to the opened-up space.
@ -797,9 +770,7 @@ void MethodHandles::remove_arg_slots(MacroAssembler* _masm,
__ ld_ptr( Address(temp_reg, 0 ), temp2_reg); __ ld_ptr( Address(temp_reg, 0 ), temp2_reg);
__ st_ptr(temp2_reg, Address(temp_reg, offset) ); __ st_ptr(temp2_reg, Address(temp_reg, offset) );
__ sub(temp_reg, wordSize, temp_reg); __ sub(temp_reg, wordSize, temp_reg);
__ cmp(temp_reg, Gargs); __ cmp_and_brx_short(temp_reg, Gargs, Assembler::greaterEqualUnsigned, Assembler::pt, L_loop);
__ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, L_loop);
__ delayed()->nop(); // FILLME
} }
// And adjust the argslot address to point at the deletion point. // And adjust the argslot address to point at the deletion point.
@ -848,8 +819,7 @@ void MethodHandles::push_arg_slots(MacroAssembler* _masm,
__ delayed()->nop(); __ delayed()->nop();
__ ld_ptr( Address(argslot_reg, 0), temp_reg); __ ld_ptr( Address(argslot_reg, 0), temp_reg);
__ st_ptr(temp_reg, Address(Gargs, 0)); __ st_ptr(temp_reg, Address(Gargs, 0));
__ ba(false, L_break); __ ba_short(L_break);
__ delayed()->nop(); // FILLME
__ BIND(L_plural); __ BIND(L_plural);
// Loop for 2 or more: // Loop for 2 or more:
@ -863,9 +833,7 @@ void MethodHandles::push_arg_slots(MacroAssembler* _masm,
__ sub(Gargs, wordSize, Gargs ); __ sub(Gargs, wordSize, Gargs );
__ ld_ptr( Address(top_reg, 0), temp2_reg); __ ld_ptr( Address(top_reg, 0), temp2_reg);
__ st_ptr(temp2_reg, Address(Gargs, 0)); __ st_ptr(temp2_reg, Address(Gargs, 0));
__ cmp(top_reg, argslot_reg); __ cmp_and_brx_short(top_reg, argslot_reg, Assembler::greaterUnsigned, Assembler::pt, L_loop);
__ brx(Assembler::greaterUnsigned, false, Assembler::pt, L_loop);
__ delayed()->nop(); // FILLME
__ BIND(L_break); __ BIND(L_break);
} }
BLOCK_COMMENT("} push_arg_slots"); BLOCK_COMMENT("} push_arg_slots");
@ -897,17 +865,13 @@ void MethodHandles::move_arg_slots_up(MacroAssembler* _masm,
__ br(Assembler::lessEqual, false, Assembler::pn, L_bad); __ br(Assembler::lessEqual, false, Assembler::pn, L_bad);
__ delayed()->nop(); __ delayed()->nop();
} }
__ cmp(bottom_reg, top_reg); __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::lessUnsigned, Assembler::pt, L_ok);
__ brx(Assembler::lessUnsigned, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ BIND(L_bad); __ BIND(L_bad);
__ stop("valid bounds (copy up)"); __ stop("valid bounds (copy up)");
__ BIND(L_ok); __ BIND(L_ok);
} }
#endif #endif
__ cmp(bottom_reg, top_reg); __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::greaterEqualUnsigned, Assembler::pn, L_break);
__ brx(Assembler::greaterEqualUnsigned, false, Assembler::pn, L_break);
__ delayed()->nop();
// work top down to bottom, copying contiguous data upwards // work top down to bottom, copying contiguous data upwards
// In pseudo-code: // In pseudo-code:
// while (--top >= bottom) *(top + distance) = *(top + 0); // while (--top >= bottom) *(top + distance) = *(top + 0);
@ -916,9 +880,7 @@ void MethodHandles::move_arg_slots_up(MacroAssembler* _masm,
__ sub(top_reg, wordSize, top_reg); __ sub(top_reg, wordSize, top_reg);
__ ld_ptr( Address(top_reg, 0 ), temp2_reg); __ ld_ptr( Address(top_reg, 0 ), temp2_reg);
__ st_ptr(temp2_reg, Address(top_reg, offset) ); __ st_ptr(temp2_reg, Address(top_reg, offset) );
__ cmp(top_reg, bottom_reg); __ cmp_and_brx_short(top_reg, bottom_reg, Assembler::greaterUnsigned, Assembler::pt, L_loop);
__ brx(Assembler::greaterUnsigned, false, Assembler::pt, L_loop);
__ delayed()->nop(); // FILLME
assert(Interpreter::stackElementSize == wordSize, "else change loop"); assert(Interpreter::stackElementSize == wordSize, "else change loop");
__ BIND(L_break); __ BIND(L_break);
BLOCK_COMMENT("} move_arg_slots_up"); BLOCK_COMMENT("} move_arg_slots_up");
@ -951,17 +913,13 @@ void MethodHandles::move_arg_slots_down(MacroAssembler* _masm,
__ br(Assembler::greaterEqual, false, Assembler::pn, L_bad); __ br(Assembler::greaterEqual, false, Assembler::pn, L_bad);
__ delayed()->nop(); __ delayed()->nop();
} }
__ cmp(bottom_reg, top_reg); __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::lessUnsigned, Assembler::pt, L_ok);
__ brx(Assembler::lessUnsigned, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ BIND(L_bad); __ BIND(L_bad);
__ stop("valid bounds (copy down)"); __ stop("valid bounds (copy down)");
__ BIND(L_ok); __ BIND(L_ok);
} }
#endif #endif
__ cmp(bottom_reg, top_reg); __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::greaterEqualUnsigned, Assembler::pn, L_break);
__ brx(Assembler::greaterEqualUnsigned, false, Assembler::pn, L_break);
__ delayed()->nop();
// work bottom up to top, copying contiguous data downwards // work bottom up to top, copying contiguous data downwards
// In pseudo-code: // In pseudo-code:
// while (bottom < top) *(bottom - distance) = *(bottom + 0), bottom++; // while (bottom < top) *(bottom - distance) = *(bottom + 0), bottom++;
@ -970,9 +928,7 @@ void MethodHandles::move_arg_slots_down(MacroAssembler* _masm,
__ ld_ptr( Address(bottom_reg, 0 ), temp2_reg); __ ld_ptr( Address(bottom_reg, 0 ), temp2_reg);
__ st_ptr(temp2_reg, Address(bottom_reg, offset) ); __ st_ptr(temp2_reg, Address(bottom_reg, offset) );
__ add(bottom_reg, wordSize, bottom_reg); __ add(bottom_reg, wordSize, bottom_reg);
__ cmp(bottom_reg, top_reg); __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::lessUnsigned, Assembler::pt, L_loop);
__ brx(Assembler::lessUnsigned, false, Assembler::pt, L_loop);
__ delayed()->nop(); // FILLME
assert(Interpreter::stackElementSize == wordSize, "else change loop"); assert(Interpreter::stackElementSize == wordSize, "else change loop");
__ BIND(L_break); __ BIND(L_break);
BLOCK_COMMENT("} move_arg_slots_down"); BLOCK_COMMENT("} move_arg_slots_down");
@ -1170,7 +1126,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
adjust_SP_and_Gargs_down_by_slots(_masm, 3, noreg, noreg); adjust_SP_and_Gargs_down_by_slots(_masm, 3, noreg, noreg);
__ st_ptr(O0_code, __ argument_address(constant(2), noreg, 0)); __ st (O0_code, __ argument_address(constant(2), noreg, 0));
__ st_ptr(O1_actual, __ argument_address(constant(1), noreg, 0)); __ st_ptr(O1_actual, __ argument_address(constant(1), noreg, 0));
__ st_ptr(O2_required, __ argument_address(constant(0), noreg, 0)); __ st_ptr(O2_required, __ argument_address(constant(0), noreg, 0));
jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch); jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch);
@ -1329,9 +1285,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
Label L_done; Label L_done;
__ ld_ptr(vmarg, O2_scratch); __ ld_ptr(vmarg, O2_scratch);
__ tst(O2_scratch); __ br_null_short(O2_scratch, Assembler::pn, L_done); // No cast if null.
__ brx(Assembler::zero, false, Assembler::pn, L_done); // No cast if null.
__ delayed()->nop();
__ load_klass(O2_scratch, O2_scratch); __ load_klass(O2_scratch, O2_scratch);
// Live at this point: // Live at this point:
@ -1436,8 +1390,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
// this path is taken for int->byte, int->short // this path is taken for int->byte, int->short
__ sra(O1_scratch, G5_vminfo, O1_scratch); __ sra(O1_scratch, G5_vminfo, O1_scratch);
__ ba(false, done); __ ba_short(done);
__ delayed()->nop();
__ bind(zero_extend); __ bind(zero_extend);
// this is taken for int->char // this is taken for int->char
@ -1860,9 +1813,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
BLOCK_COMMENT("verify collect_count_constant {"); BLOCK_COMMENT("verify collect_count_constant {");
__ load_method_handle_vmslots(O3_scratch, G3_method_handle, O2_scratch); __ load_method_handle_vmslots(O3_scratch, G3_method_handle, O2_scratch);
Label L_count_ok; Label L_count_ok;
__ cmp(O3_scratch, collect_count_constant); __ cmp_and_br_short(O3_scratch, collect_count_constant, Assembler::equal, Assembler::pt, L_count_ok);
__ br(Assembler::equal, false, Assembler::pt, L_count_ok);
__ delayed()->nop();
__ stop("bad vminfo in AMH.conv"); __ stop("bad vminfo in AMH.conv");
__ BIND(L_count_ok); __ BIND(L_count_ok);
BLOCK_COMMENT("} verify collect_count_constant"); BLOCK_COMMENT("} verify collect_count_constant");
@ -1909,9 +1860,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
BLOCK_COMMENT("verify dest_slot_constant {"); BLOCK_COMMENT("verify dest_slot_constant {");
extract_conversion_vminfo(_masm, RicochetFrame::L5_conversion, O3_scratch); extract_conversion_vminfo(_masm, RicochetFrame::L5_conversion, O3_scratch);
Label L_vminfo_ok; Label L_vminfo_ok;
__ cmp(O3_scratch, dest_slot_constant); __ cmp_and_br_short(O3_scratch, dest_slot_constant, Assembler::equal, Assembler::pt, L_vminfo_ok);
__ br(Assembler::equal, false, Assembler::pt, L_vminfo_ok);
__ delayed()->nop();
__ stop("bad vminfo in AMH.conv"); __ stop("bad vminfo in AMH.conv");
__ BIND(L_vminfo_ok); __ BIND(L_vminfo_ok);
BLOCK_COMMENT("} verify dest_slot_constant"); BLOCK_COMMENT("} verify dest_slot_constant");
@ -1951,14 +1900,10 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
// If there are variable parameters, use dynamic checks to skip around the whole mess. // If there are variable parameters, use dynamic checks to skip around the whole mess.
Label L_done; Label L_done;
if (keep3_count.is_register()) { if (keep3_count.is_register()) {
__ tst(keep3_count.as_register()); __ cmp_and_br_short(keep3_count.as_register(), 0, Assembler::equal, Assembler::pn, L_done);
__ br(Assembler::zero, false, Assembler::pn, L_done);
__ delayed()->nop();
} }
if (close_count.is_register()) { if (close_count.is_register()) {
__ cmp(close_count.as_register(), open_count); __ cmp_and_br_short(close_count.as_register(), open_count, Assembler::equal, Assembler::pn, L_done);
__ br(Assembler::equal, false, Assembler::pn, L_done);
__ delayed()->nop();
} }
if (move_keep3 && fix_arg_base) { if (move_keep3 && fix_arg_base) {
@ -1999,8 +1944,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
} }
if (emit_guard) { if (emit_guard) {
__ ba(false, L_done); // assumes emit_move_up is true also __ ba_short(L_done); // assumes emit_move_up is true also
__ delayed()->nop();
__ BIND(L_move_up); __ BIND(L_move_up);
} }
@ -2133,8 +2077,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
#ifdef ASSERT #ifdef ASSERT
{ Label L_ok; { Label L_ok;
__ br_notnull(O7_temp, false, Assembler::pt, L_ok); __ br_notnull_short(O7_temp, Assembler::pt, L_ok);
__ delayed()->nop();
__ stop("bad method handle return"); __ stop("bad method handle return");
__ BIND(L_ok); __ BIND(L_ok);
} }
@ -2192,11 +2135,10 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
Label L_skip; Label L_skip;
if (length_constant < 0) { if (length_constant < 0) {
load_conversion_vminfo(_masm, G3_amh_conversion, O3_scratch); load_conversion_vminfo(_masm, G3_amh_conversion, O3_scratch);
__ br_zero(Assembler::notZero, false, Assembler::pn, O3_scratch, L_skip); __ cmp_zero_and_br(Assembler::notZero, O3_scratch, L_skip);
__ delayed()->nop(); __ delayed()->nop(); // to avoid back-to-back cbcond instructions
} }
__ br_null(O1_array, false, Assembler::pn, L_array_is_empty); __ br_null_short(O1_array, Assembler::pn, L_array_is_empty);
__ delayed()->nop();
__ BIND(L_skip); __ BIND(L_skip);
} }
__ null_check(O1_array, oopDesc::klass_offset_in_bytes()); __ null_check(O1_array, oopDesc::klass_offset_in_bytes());
@ -2210,8 +2152,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
Label L_ok_array_klass, L_bad_array_klass, L_bad_array_length; Label L_ok_array_klass, L_bad_array_klass, L_bad_array_length;
__ check_klass_subtype(O2_array_klass, O3_klass, O4_scratch, G5_scratch, L_ok_array_klass); __ check_klass_subtype(O2_array_klass, O3_klass, O4_scratch, G5_scratch, L_ok_array_klass);
// If we get here, the type check failed! // If we get here, the type check failed!
__ ba(false, L_bad_array_klass); __ ba_short(L_bad_array_klass);
__ delayed()->nop();
__ BIND(L_ok_array_klass); __ BIND(L_ok_array_klass);
// Check length. // Check length.
@ -2247,8 +2188,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
__ BIND(L_array_is_empty); __ BIND(L_array_is_empty);
remove_arg_slots(_masm, -stack_move_unit() * array_slots, remove_arg_slots(_masm, -stack_move_unit() * array_slots,
O0_argslot, O1_scratch, O2_scratch, O3_scratch); O0_argslot, O1_scratch, O2_scratch, O3_scratch);
__ ba(false, L_args_done); // no spreading to do __ ba_short(L_args_done); // no spreading to do
__ delayed()->nop();
__ BIND(L_insert_arg_space); __ BIND(L_insert_arg_space);
// come here in the usual case, stack_move < 0 (2 or more spread arguments) // come here in the usual case, stack_move < 0 (2 or more spread arguments)
// Live: O1_array, O2_argslot_limit, O3_stack_move // Live: O1_array, O2_argslot_limit, O3_stack_move
@ -2289,9 +2229,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
Address(O1_source, 0), Address(O4_fill_ptr, 0), Address(O1_source, 0), Address(O4_fill_ptr, 0),
O2_scratch); // must be an even register for !_LP64 long moves (uses O2/O3) O2_scratch); // must be an even register for !_LP64 long moves (uses O2/O3)
__ add(O1_source, type2aelembytes(elem_type), O1_source); __ add(O1_source, type2aelembytes(elem_type), O1_source);
__ cmp(O4_fill_ptr, O0_argslot); __ cmp_and_brx_short(O4_fill_ptr, O0_argslot, Assembler::greaterUnsigned, Assembler::pt, L_loop);
__ brx(Assembler::greaterUnsigned, false, Assembler::pt, L_loop);
__ delayed()->nop(); // FILLME
} else if (length_constant == 0) { } else if (length_constant == 0) {
// nothing to copy // nothing to copy
} else { } else {

View File

@ -600,7 +600,7 @@ class AdapterGenerator {
void AdapterGenerator::patch_callers_callsite() { void AdapterGenerator::patch_callers_callsite() {
Label L; Label L;
__ ld_ptr(G5_method, in_bytes(methodOopDesc::code_offset()), G3_scratch); __ ld_ptr(G5_method, in_bytes(methodOopDesc::code_offset()), G3_scratch);
__ br_null(G3_scratch, false, __ pt, L); __ br_null(G3_scratch, false, Assembler::pt, L);
// Schedule the branch target address early. // Schedule the branch target address early.
__ delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), G3_scratch); __ delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), G3_scratch);
// Call into the VM to patch the caller, then jump to compiled callee // Call into the VM to patch the caller, then jump to compiled callee
@ -1127,8 +1127,7 @@ void AdapterGenerator::gen_i2c_adapter(
Label loop; Label loop;
__ bind(loop); __ bind(loop);
__ sub(L0, 1, L0); __ sub(L0, 1, L0);
__ br_null(L0, false, Assembler::pt, loop); __ br_null_short(L0, Assembler::pt, loop);
__ delayed()->nop();
__ restore(); __ restore();
} }
@ -1202,7 +1201,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
// the call site corrected. // the call site corrected.
__ ld_ptr(G5_method, in_bytes(methodOopDesc::code_offset()), G3_scratch); __ ld_ptr(G5_method, in_bytes(methodOopDesc::code_offset()), G3_scratch);
__ bind(ok2); __ bind(ok2);
__ br_null(G3_scratch, false, __ pt, skip_fixup); __ br_null(G3_scratch, false, Assembler::pt, skip_fixup);
__ delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), G3_scratch); __ delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), G3_scratch);
__ jump_to(ic_miss, G3_scratch); __ jump_to(ic_miss, G3_scratch);
__ delayed()->nop(); __ delayed()->nop();
@ -1779,9 +1778,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub()); AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub());
__ verify_oop(O0); __ verify_oop(O0);
__ load_klass(O0, temp_reg); __ load_klass(O0, temp_reg);
__ cmp(temp_reg, G5_inline_cache_reg); __ cmp_and_brx_short(temp_reg, G5_inline_cache_reg, Assembler::equal, Assembler::pt, L);
__ brx(Assembler::equal, true, Assembler::pt, L);
__ delayed()->nop();
__ jump_to(ic_miss, temp_reg); __ jump_to(ic_miss, temp_reg);
__ delayed()->nop(); __ delayed()->nop();
@ -2182,8 +2179,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
#ifdef ASSERT #ifdef ASSERT
{ Label L; { Label L;
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O0); __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O0);
__ br_null(O0, false, Assembler::pt, L); __ br_null_short(O0, Assembler::pt, L);
__ delayed()->nop();
__ stop("no pending exception allowed on exit from IR::monitorenter"); __ stop("no pending exception allowed on exit from IR::monitorenter");
__ bind(L); __ bind(L);
} }
@ -2298,9 +2294,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
Address suspend_state(G2_thread, JavaThread::suspend_flags_offset()); Address suspend_state(G2_thread, JavaThread::suspend_flags_offset());
__ br(Assembler::notEqual, false, Assembler::pn, L); __ br(Assembler::notEqual, false, Assembler::pn, L);
__ delayed()->ld(suspend_state, G3_scratch); __ delayed()->ld(suspend_state, G3_scratch);
__ cmp(G3_scratch, 0); __ cmp_and_br_short(G3_scratch, 0, Assembler::equal, Assembler::pt, no_block);
__ br(Assembler::equal, false, Assembler::pt, no_block);
__ delayed()->nop();
__ bind(L); __ bind(L);
// Block. Save any potential method result value before the operation and // Block. Save any potential method result value before the operation and
@ -2328,9 +2322,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
Label no_reguard; Label no_reguard;
__ ld(G2_thread, JavaThread::stack_guard_state_offset(), G3_scratch); __ ld(G2_thread, JavaThread::stack_guard_state_offset(), G3_scratch);
__ cmp(G3_scratch, JavaThread::stack_guard_yellow_disabled); __ cmp_and_br_short(G3_scratch, JavaThread::stack_guard_yellow_disabled, Assembler::notEqual, Assembler::pt, no_reguard);
__ br(Assembler::notEqual, false, Assembler::pt, no_reguard);
__ delayed()->nop();
save_native_result(masm, ret_type, stack_slots); save_native_result(masm, ret_type, stack_slots);
__ call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages)); __ call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages));
@ -2382,8 +2374,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
#ifdef ASSERT #ifdef ASSERT
{ Label L; { Label L;
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O0); __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O0);
__ br_null(O0, false, Assembler::pt, L); __ br_null_short(O0, Assembler::pt, L);
__ delayed()->nop();
__ stop("no pending exception allowed on exit from IR::monitorexit"); __ stop("no pending exception allowed on exit from IR::monitorexit");
__ bind(L); __ bind(L);
} }
@ -2639,9 +2630,7 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub()); AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub());
__ verify_oop(O0); __ verify_oop(O0);
__ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), temp_reg); __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), temp_reg);
__ cmp(temp_reg, G5_inline_cache_reg); __ cmp_and_brx_short(temp_reg, G5_inline_cache_reg, Assembler::equal, Assembler::pt, L);
__ brx(Assembler::equal, true, Assembler::pt, L);
__ delayed()->nop();
__ jump_to(ic_miss, temp_reg); __ jump_to(ic_miss, temp_reg);
__ delayed()->nop(); __ delayed()->nop();
@ -3143,8 +3132,7 @@ static void make_new_frames(MacroAssembler* masm, bool deopt) {
gen_new_frame(masm, deopt); // allocate an interpreter frame gen_new_frame(masm, deopt); // allocate an interpreter frame
__ tst(O4array_size); __ cmp_zero_and_br(Assembler::notZero, O4array_size, loop);
__ br(Assembler::notZero, false, Assembler::pn, loop);
__ delayed()->add(O3array, wordSize, O3array); __ delayed()->add(O3array, wordSize, O3array);
__ ld_ptr(G3pcs, 0, O7); // load final frame new pc __ ld_ptr(G3pcs, 0, O7); // load final frame new pc
@ -3221,7 +3209,7 @@ void SharedRuntime::generate_deopt_blob() {
// pc is now in O7. Return values are still in the expected places // pc is now in O7. Return values are still in the expected places
map = RegisterSaver::save_live_registers(masm, 0, &frame_size_words); map = RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
__ ba(false, cont); __ ba(cont);
__ delayed()->mov(Deoptimization::Unpack_deopt, L0deopt_mode); __ delayed()->mov(Deoptimization::Unpack_deopt, L0deopt_mode);
int exception_offset = __ offset() - start; int exception_offset = __ offset() - start;
@ -3256,8 +3244,7 @@ void SharedRuntime::generate_deopt_blob() {
// verify that there is really an exception oop in exception_oop // verify that there is really an exception oop in exception_oop
Label has_exception; Label has_exception;
__ ld_ptr(G2_thread, JavaThread::exception_oop_offset(), Oexception); __ ld_ptr(G2_thread, JavaThread::exception_oop_offset(), Oexception);
__ br_notnull(Oexception, false, Assembler::pt, has_exception); __ br_notnull_short(Oexception, Assembler::pt, has_exception);
__ delayed()-> nop();
__ stop("no exception in thread"); __ stop("no exception in thread");
__ bind(has_exception); __ bind(has_exception);
@ -3265,14 +3252,13 @@ void SharedRuntime::generate_deopt_blob() {
Label no_pending_exception; Label no_pending_exception;
Address exception_addr(G2_thread, Thread::pending_exception_offset()); Address exception_addr(G2_thread, Thread::pending_exception_offset());
__ ld_ptr(exception_addr, Oexception); __ ld_ptr(exception_addr, Oexception);
__ br_null(Oexception, false, Assembler::pt, no_pending_exception); __ br_null_short(Oexception, Assembler::pt, no_pending_exception);
__ delayed()->nop();
__ stop("must not have pending exception here"); __ stop("must not have pending exception here");
__ bind(no_pending_exception); __ bind(no_pending_exception);
} }
#endif #endif
__ ba(false, cont); __ ba(cont);
__ delayed()->mov(Deoptimization::Unpack_exception, L0deopt_mode);; __ delayed()->mov(Deoptimization::Unpack_exception, L0deopt_mode);;
// //
@ -3313,9 +3299,7 @@ void SharedRuntime::generate_deopt_blob() {
RegisterSaver::restore_result_registers(masm); RegisterSaver::restore_result_registers(masm);
Label noException; Label noException;
__ cmp(G4deopt_mode, Deoptimization::Unpack_exception); // Was exception pending? __ cmp_and_br_short(G4deopt_mode, Deoptimization::Unpack_exception, Assembler::notEqual, Assembler::pt, noException);
__ br(Assembler::notEqual, false, Assembler::pt, noException);
__ delayed()->nop();
// Move the pending exception from exception_oop to Oexception so // Move the pending exception from exception_oop to Oexception so
// the pending exception will be picked up the interpreter. // the pending exception will be picked up the interpreter.
@ -3359,9 +3343,7 @@ void SharedRuntime::generate_deopt_blob() {
// In 32 bit, C2 returns longs in G1 so restore the saved G1 into // In 32 bit, C2 returns longs in G1 so restore the saved G1 into
// I0/I1 if the return value is long. // I0/I1 if the return value is long.
Label not_long; Label not_long;
__ cmp(O0,T_LONG); __ cmp_and_br_short(O0,T_LONG, Assembler::notEqual, Assembler::pt, not_long);
__ br(Assembler::notEqual, false, Assembler::pt, not_long);
__ delayed()->nop();
__ ldd(saved_Greturn1_addr,I0); __ ldd(saved_Greturn1_addr,I0);
__ bind(not_long); __ bind(not_long);
#endif #endif
@ -3534,9 +3516,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause
Label pending; Label pending;
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O1); __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O1);
__ tst(O1); __ br_notnull_short(O1, Assembler::pn, pending);
__ brx(Assembler::notEqual, true, Assembler::pn, pending);
__ delayed()->nop();
RegisterSaver::restore_live_registers(masm); RegisterSaver::restore_live_registers(masm);
@ -3623,9 +3603,7 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const cha
Label pending; Label pending;
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O1); __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O1);
__ tst(O1); __ br_notnull_short(O1, Assembler::pn, pending);
__ brx(Assembler::notEqual, true, Assembler::pn, pending);
__ delayed()->nop();
// get the returned methodOop // get the returned methodOop

File diff suppressed because it is too large Load Diff

View File

@ -150,8 +150,7 @@ class StubGenerator: public StubCodeGenerator {
{ const Register t = G3_scratch; { const Register t = G3_scratch;
Label L; Label L;
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), t); __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), t);
__ br_null(t, false, Assembler::pt, L); __ br_null_short(t, Assembler::pt, L);
__ delayed()->nop();
__ stop("StubRoutines::call_stub: entered with pending exception"); __ stop("StubRoutines::call_stub: entered with pending exception");
__ bind(L); __ bind(L);
} }
@ -207,8 +206,7 @@ class StubGenerator: public StubCodeGenerator {
Label exit; Label exit;
__ ld_ptr(parameter_size.as_in().as_address(), cnt); // parameter counter __ ld_ptr(parameter_size.as_in().as_address(), cnt); // parameter counter
__ add( FP, STACK_BIAS, dst ); __ add( FP, STACK_BIAS, dst );
__ tst(cnt); __ cmp_zero_and_br(Assembler::zero, cnt, exit);
__ br(Assembler::zero, false, Assembler::pn, exit);
__ delayed()->sub(dst, BytesPerWord, dst); // setup Lentry_args __ delayed()->sub(dst, BytesPerWord, dst); // setup Lentry_args
// copy parameters if any // copy parameters if any
@ -282,20 +280,20 @@ class StubGenerator: public StubCodeGenerator {
__ delayed()->restore(); __ delayed()->restore();
__ BIND(is_object); __ BIND(is_object);
__ ba(false, exit); __ ba(exit);
__ delayed()->st_ptr(O0, addr, G0); __ delayed()->st_ptr(O0, addr, G0);
__ BIND(is_float); __ BIND(is_float);
__ ba(false, exit); __ ba(exit);
__ delayed()->stf(FloatRegisterImpl::S, F0, addr, G0); __ delayed()->stf(FloatRegisterImpl::S, F0, addr, G0);
__ BIND(is_double); __ BIND(is_double);
__ ba(false, exit); __ ba(exit);
__ delayed()->stf(FloatRegisterImpl::D, F0, addr, G0); __ delayed()->stf(FloatRegisterImpl::D, F0, addr, G0);
__ BIND(is_long); __ BIND(is_long);
#ifdef _LP64 #ifdef _LP64
__ ba(false, exit); __ ba(exit);
__ delayed()->st_long(O0, addr, G0); // store entire long __ delayed()->st_long(O0, addr, G0); // store entire long
#else #else
#if defined(COMPILER2) #if defined(COMPILER2)
@ -307,11 +305,11 @@ class StubGenerator: public StubCodeGenerator {
// do this here. Unfortunately if we did a rethrow we'd see an machepilog node // do this here. Unfortunately if we did a rethrow we'd see an machepilog node
// first which would move g1 -> O0/O1 and destroy the exception we were throwing. // first which would move g1 -> O0/O1 and destroy the exception we were throwing.
__ ba(false, exit); __ ba(exit);
__ delayed()->stx(G1, addr, G0); // store entire long __ delayed()->stx(G1, addr, G0); // store entire long
#else #else
__ st(O1, addr, BytesPerInt); __ st(O1, addr, BytesPerInt);
__ ba(false, exit); __ ba(exit);
__ delayed()->st(O0, addr, G0); __ delayed()->st(O0, addr, G0);
#endif /* COMPILER2 */ #endif /* COMPILER2 */
#endif /* _LP64 */ #endif /* _LP64 */
@ -382,8 +380,7 @@ class StubGenerator: public StubCodeGenerator {
// make sure that this code is only executed if there is a pending exception // make sure that this code is only executed if there is a pending exception
{ Label L; { Label L;
__ ld_ptr(exception_addr, Gtemp); __ ld_ptr(exception_addr, Gtemp);
__ br_notnull(Gtemp, false, Assembler::pt, L); __ br_notnull_short(Gtemp, Assembler::pt, L);
__ delayed()->nop();
__ stop("StubRoutines::forward exception: no pending exception (1)"); __ stop("StubRoutines::forward exception: no pending exception (1)");
__ bind(L); __ bind(L);
} }
@ -406,8 +403,7 @@ class StubGenerator: public StubCodeGenerator {
#ifdef ASSERT #ifdef ASSERT
// make sure exception is set // make sure exception is set
{ Label L; { Label L;
__ br_notnull(Oexception, false, Assembler::pt, L); __ br_notnull_short(Oexception, Assembler::pt, L);
__ delayed()->nop();
__ stop("StubRoutines::forward exception: no pending exception (2)"); __ stop("StubRoutines::forward exception: no pending exception (2)");
__ bind(L); __ bind(L);
} }
@ -501,8 +497,7 @@ class StubGenerator: public StubCodeGenerator {
Address exception_addr(G2_thread, Thread::pending_exception_offset()); Address exception_addr(G2_thread, Thread::pending_exception_offset());
Register scratch_reg = Gtemp; Register scratch_reg = Gtemp;
__ ld_ptr(exception_addr, scratch_reg); __ ld_ptr(exception_addr, scratch_reg);
__ br_notnull(scratch_reg, false, Assembler::pt, L); __ br_notnull_short(scratch_reg, Assembler::pt, L);
__ delayed()->nop();
__ should_not_reach_here(); __ should_not_reach_here();
__ bind(L); __ bind(L);
#endif // ASSERT #endif // ASSERT
@ -614,9 +609,7 @@ class StubGenerator: public StubCodeGenerator {
__ mov(G0,yield_reg); __ mov(G0,yield_reg);
__ BIND(retry); __ BIND(retry);
__ cmp(yield_reg, V8AtomicOperationUnderLockSpinCount); __ cmp_and_br_short(yield_reg, V8AtomicOperationUnderLockSpinCount, Assembler::less, Assembler::pt, dontyield);
__ br(Assembler::less, false, Assembler::pt, dontyield);
__ delayed()->nop();
// This code can only be called from inside the VM, this // This code can only be called from inside the VM, this
// stub is only invoked from Atomic::add(). We do not // stub is only invoked from Atomic::add(). We do not
@ -676,9 +669,7 @@ class StubGenerator: public StubCodeGenerator {
// try to replace O2 with O3 // try to replace O2 with O3
__ cas_under_lock(O1, O2, O3, __ cas_under_lock(O1, O2, O3,
(address)StubRoutines::Sparc::atomic_memory_operation_lock_addr(),false); (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr(),false);
__ cmp(O2, O3); __ cmp_and_br_short(O2, O3, Assembler::notEqual, Assembler::pn, retry);
__ br(Assembler::notEqual, false, Assembler::pn, retry);
__ delayed()->nop();
__ retl(false); __ retl(false);
__ delayed()->mov(O2, O0); // report previous value to caller __ delayed()->mov(O2, O0); // report previous value to caller
@ -798,11 +789,9 @@ class StubGenerator: public StubCodeGenerator {
__ BIND(retry); __ BIND(retry);
__ lduw(O1, 0, O2); __ lduw(O1, 0, O2);
__ add(O0, O2, O3); __ add(O0, O2, O3);
__ cas(O1, O2, O3); __ cas(O1, O2, O3);
__ cmp( O2, O3); __ cmp_and_br_short(O2, O3, Assembler::notEqual, Assembler::pn, retry);
__ br(Assembler::notEqual, false, Assembler::pn, retry);
__ delayed()->nop();
__ retl(false); __ retl(false);
__ delayed()->add(O0, O2, O0); // note that cas made O2==O3 __ delayed()->add(O0, O2, O0); // note that cas made O2==O3
} else { } else {
@ -1370,8 +1359,7 @@ class StubGenerator: public StubCodeGenerator {
// copy tailing bytes // copy tailing bytes
__ BIND(L_copy_byte); __ BIND(L_copy_byte);
__ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit); __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
__ delayed()->nop();
__ align(OptoLoopAlignment); __ align(OptoLoopAlignment);
__ BIND(L_copy_byte_loop); __ BIND(L_copy_byte_loop);
__ ldub(from, offset, O3); __ ldub(from, offset, O3);
@ -1482,8 +1470,7 @@ class StubGenerator: public StubCodeGenerator {
// copy 1 element (2 bytes) at a time // copy 1 element (2 bytes) at a time
__ BIND(L_copy_byte); __ BIND(L_copy_byte);
__ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit); __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
__ delayed()->nop();
__ align(OptoLoopAlignment); __ align(OptoLoopAlignment);
__ BIND(L_copy_byte_loop); __ BIND(L_copy_byte_loop);
__ dec(end_from); __ dec(end_from);
@ -1600,8 +1587,7 @@ class StubGenerator: public StubCodeGenerator {
// copy 1 element at a time // copy 1 element at a time
__ BIND(L_copy_2_bytes); __ BIND(L_copy_2_bytes);
__ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit); __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
__ delayed()->nop();
__ align(OptoLoopAlignment); __ align(OptoLoopAlignment);
__ BIND(L_copy_2_bytes_loop); __ BIND(L_copy_2_bytes_loop);
__ lduh(from, offset, O3); __ lduh(from, offset, O3);
@ -1946,8 +1932,7 @@ class StubGenerator: public StubCodeGenerator {
// copy 1 element (2 bytes) at a time // copy 1 element (2 bytes) at a time
__ BIND(L_copy_2_bytes); __ BIND(L_copy_2_bytes);
__ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit); __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
__ delayed()->nop();
__ BIND(L_copy_2_bytes_loop); __ BIND(L_copy_2_bytes_loop);
__ dec(end_from, 2); __ dec(end_from, 2);
__ dec(end_to, 2); __ dec(end_to, 2);
@ -2060,8 +2045,7 @@ class StubGenerator: public StubCodeGenerator {
// copy 1 element at a time // copy 1 element at a time
__ BIND(L_copy_4_bytes); __ BIND(L_copy_4_bytes);
__ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit); __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
__ delayed()->nop();
__ BIND(L_copy_4_bytes_loop); __ BIND(L_copy_4_bytes_loop);
__ ld(from, offset, O3); __ ld(from, offset, O3);
__ deccc(count); __ deccc(count);
@ -2193,8 +2177,7 @@ class StubGenerator: public StubCodeGenerator {
// copy 1 element (4 bytes) at a time // copy 1 element (4 bytes) at a time
__ BIND(L_copy_4_bytes); __ BIND(L_copy_4_bytes);
__ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit); __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
__ delayed()->nop();
__ BIND(L_copy_4_bytes_loop); __ BIND(L_copy_4_bytes_loop);
__ dec(end_from, 4); __ dec(end_from, 4);
__ dec(end_to, 4); __ dec(end_to, 4);
@ -2576,7 +2559,7 @@ class StubGenerator: public StubCodeGenerator {
super_klass->after_save(), super_klass->after_save(),
L0, L1, L2, L4, L0, L1, L2, L4,
NULL, &L_pop_to_miss); NULL, &L_pop_to_miss);
__ ba(false, L_success); __ ba(L_success);
__ delayed()->restore(); __ delayed()->restore();
__ bind(L_pop_to_miss); __ bind(L_pop_to_miss);
@ -2673,8 +2656,7 @@ class StubGenerator: public StubCodeGenerator {
// ======== loop entry is here ======== // ======== loop entry is here ========
__ BIND(load_element); __ BIND(load_element);
__ load_heap_oop(O0_from, O5_offset, G3_oop); // load the oop __ load_heap_oop(O0_from, O5_offset, G3_oop); // load the oop
__ br_null(G3_oop, true, Assembler::pt, store_element); __ br_null_short(G3_oop, Assembler::pt, store_element);
__ delayed()->nop();
__ load_klass(G3_oop, G4_klass); // query the object klass __ load_klass(G3_oop, G4_klass); // query the object klass
@ -2896,8 +2878,7 @@ class StubGenerator: public StubCodeGenerator {
// assert(src->klass() != NULL); // assert(src->klass() != NULL);
BLOCK_COMMENT("assert klasses not null"); BLOCK_COMMENT("assert klasses not null");
{ Label L_a, L_b; { Label L_a, L_b;
__ br_notnull(G3_src_klass, false, Assembler::pt, L_b); // it is broken if klass is NULL __ br_notnull_short(G3_src_klass, Assembler::pt, L_b); // it is broken if klass is NULL
__ delayed()->nop();
__ bind(L_a); __ bind(L_a);
__ stop("broken null klass"); __ stop("broken null klass");
__ bind(L_b); __ bind(L_b);
@ -2937,9 +2918,7 @@ class StubGenerator: public StubCodeGenerator {
} }
// if (src->klass() != dst->klass()) return -1; // if (src->klass() != dst->klass()) return -1;
__ cmp(G3_src_klass, G4_dst_klass); __ cmp_and_brx_short(G3_src_klass, G4_dst_klass, Assembler::notEqual, Assembler::pn, L_failed);
__ brx(Assembler::notEqual, false, Assembler::pn, L_failed);
__ delayed()->nop();
// if (!src->is_Array()) return -1; // if (!src->is_Array()) return -1;
__ cmp(G5_lh, Klass::_lh_neutral_value); // < 0 __ cmp(G5_lh, Klass::_lh_neutral_value); // < 0
@ -3007,9 +2986,7 @@ class StubGenerator: public StubCodeGenerator {
__ delayed()->signx(length, count); // length __ delayed()->signx(length, count); // length
#ifdef ASSERT #ifdef ASSERT
{ Label L; { Label L;
__ cmp(G3_elsize, LogBytesPerLong); __ cmp_and_br_short(G3_elsize, LogBytesPerLong, Assembler::equal, Assembler::pt, L);
__ br(Assembler::equal, false, Assembler::pt, L);
__ delayed()->nop();
__ stop("must be long copy, but elsize is wrong"); __ stop("must be long copy, but elsize is wrong");
__ bind(L); __ bind(L);
} }

View File

@ -190,9 +190,7 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
const Register size = G1_scratch; const Register size = G1_scratch;
if (EnableInvokeDynamic) { if (EnableInvokeDynamic) {
__ ldub(Address(Lbcp, 0), G1_scratch); // Load current bytecode. __ ldub(Address(Lbcp, 0), G1_scratch); // Load current bytecode.
__ cmp(G1_scratch, Bytecodes::_invokedynamic); __ cmp_and_br_short(G1_scratch, Bytecodes::_invokedynamic, Assembler::equal, Assembler::pn, L_giant_index);
__ br(Assembler::equal, false, Assembler::pn, L_giant_index);
__ delayed()->nop();
} }
__ get_cache_and_index_at_bcp(cache, G1_scratch, 1); __ get_cache_and_index_at_bcp(cache, G1_scratch, 1);
__ bind(L_got_cache); __ bind(L_got_cache);
@ -207,8 +205,7 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
if (EnableInvokeDynamic) { if (EnableInvokeDynamic) {
__ bind(L_giant_index); __ bind(L_giant_index);
__ get_cache_and_index_at_bcp(cache, G1_scratch, 1, sizeof(u4)); __ get_cache_and_index_at_bcp(cache, G1_scratch, 1, sizeof(u4));
__ ba(false, L_got_cache); __ ba_short(L_got_cache);
__ delayed()->nop();
} }
return entry; return entry;
@ -221,9 +218,7 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, i
{ Label L; { Label L;
Address exception_addr(G2_thread, Thread::pending_exception_offset()); Address exception_addr(G2_thread, Thread::pending_exception_offset());
__ ld_ptr(exception_addr, Gtemp); // Load pending exception. __ ld_ptr(exception_addr, Gtemp); // Load pending exception.
__ tst(Gtemp); __ br_null_short(Gtemp, Assembler::pt, L);
__ brx(Assembler::equal, false, Assembler::pt, L);
__ delayed()->nop();
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception)); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception));
__ should_not_reach_here(); __ should_not_reach_here();
__ bind(L); __ bind(L);
@ -304,8 +299,7 @@ void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile
if (ProfileInterpreter) { if (ProfileInterpreter) {
// If no method data exists, go to profile_continue. // If no method data exists, go to profile_continue.
__ ld_ptr(Lmethod, methodOopDesc::method_data_offset(), G4_scratch); __ ld_ptr(Lmethod, methodOopDesc::method_data_offset(), G4_scratch);
__ br_null(G4_scratch, false, Assembler::pn, no_mdo); __ br_null_short(G4_scratch, Assembler::pn, no_mdo);
__ delayed()->nop();
// Increment counter // Increment counter
Address mdo_invocation_counter(G4_scratch, Address mdo_invocation_counter(G4_scratch,
in_bytes(methodDataOopDesc::invocation_counter_offset()) + in_bytes(methodDataOopDesc::invocation_counter_offset()) +
@ -313,8 +307,7 @@ void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile
__ increment_mask_and_jump(mdo_invocation_counter, increment, mask, __ increment_mask_and_jump(mdo_invocation_counter, increment, mask,
G3_scratch, Lscratch, G3_scratch, Lscratch,
Assembler::zero, overflow); Assembler::zero, overflow);
__ ba(false, done); __ ba_short(done);
__ delayed()->nop();
} }
// Increment counter in methodOop // Increment counter in methodOop
@ -340,9 +333,7 @@ void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile
// Test to see if we should create a method data oop // Test to see if we should create a method data oop
AddressLiteral profile_limit((address)&InvocationCounter::InterpreterProfileLimit); AddressLiteral profile_limit((address)&InvocationCounter::InterpreterProfileLimit);
__ load_contents(profile_limit, G3_scratch); __ load_contents(profile_limit, G3_scratch);
__ cmp(O0, G3_scratch); __ cmp_and_br_short(O0, G3_scratch, Assembler::lessUnsigned, Assembler::pn, *profile_method_continue);
__ br(Assembler::lessUnsigned, false, Assembler::pn, *profile_method_continue);
__ delayed()->nop();
// if no method data exists, go to profile_method // if no method data exists, go to profile_method
__ test_method_data_pointer(*profile_method); __ test_method_data_pointer(*profile_method);
@ -351,7 +342,7 @@ void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile
AddressLiteral invocation_limit((address)&InvocationCounter::InterpreterInvocationLimit); AddressLiteral invocation_limit((address)&InvocationCounter::InterpreterInvocationLimit);
__ load_contents(invocation_limit, G3_scratch); __ load_contents(invocation_limit, G3_scratch);
__ cmp(O0, G3_scratch); __ cmp(O0, G3_scratch);
__ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow); __ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow); // Far distance
__ delayed()->nop(); __ delayed()->nop();
} }
@ -410,19 +401,14 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rframe
assert_different_registers(Rframe_size, Rscratch, Rscratch2); assert_different_registers(Rframe_size, Rscratch, Rscratch2);
__ set( page_size, Rscratch ); __ set(page_size, Rscratch);
__ cmp( Rframe_size, Rscratch ); __ cmp_and_br_short(Rframe_size, Rscratch, Assembler::lessEqual, Assembler::pt, after_frame_check);
__ br( Assembler::lessEqual, false, Assembler::pt, after_frame_check );
__ delayed()->nop();
// get the stack base, and in debug, verify it is non-zero // get the stack base, and in debug, verify it is non-zero
__ ld_ptr( G2_thread, Thread::stack_base_offset(), Rscratch ); __ ld_ptr( G2_thread, Thread::stack_base_offset(), Rscratch );
#ifdef ASSERT #ifdef ASSERT
Label base_not_zero; Label base_not_zero;
__ cmp( Rscratch, G0 ); __ br_notnull_short(Rscratch, Assembler::pn, base_not_zero);
__ brx( Assembler::notEqual, false, Assembler::pn, base_not_zero );
__ delayed()->nop();
__ stop("stack base is zero in generate_stack_overflow_check"); __ stop("stack base is zero in generate_stack_overflow_check");
__ bind(base_not_zero); __ bind(base_not_zero);
#endif #endif
@ -432,9 +418,7 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rframe
__ ld_ptr( G2_thread, Thread::stack_size_offset(), Rscratch2 ); __ ld_ptr( G2_thread, Thread::stack_size_offset(), Rscratch2 );
#ifdef ASSERT #ifdef ASSERT
Label size_not_zero; Label size_not_zero;
__ cmp( Rscratch2, G0 ); __ br_notnull_short(Rscratch2, Assembler::pn, size_not_zero);
__ brx( Assembler::notEqual, false, Assembler::pn, size_not_zero );
__ delayed()->nop();
__ stop("stack size is zero in generate_stack_overflow_check"); __ stop("stack size is zero in generate_stack_overflow_check");
__ bind(size_not_zero); __ bind(size_not_zero);
#endif #endif
@ -450,9 +434,7 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rframe
// the frame is greater than one page in size, so check against // the frame is greater than one page in size, so check against
// the bottom of the stack // the bottom of the stack
__ cmp( SP, Rscratch ); __ cmp_and_brx_short(SP, Rscratch, Assembler::greater, Assembler::pt, after_frame_check);
__ brx( Assembler::greater, false, Assembler::pt, after_frame_check );
__ delayed()->nop();
// Save the return address as the exception pc // Save the return address as the exception pc
__ st_ptr(O7, saved_exception_pc); __ st_ptr(O7, saved_exception_pc);
@ -624,9 +606,7 @@ address InterpreterGenerator::generate_empty_entry(void) {
// If we need a safepoint check, generate full interpreter entry. // If we need a safepoint check, generate full interpreter entry.
AddressLiteral sync_state(SafepointSynchronize::address_of_state()); AddressLiteral sync_state(SafepointSynchronize::address_of_state());
__ set(sync_state, G3_scratch); __ set(sync_state, G3_scratch);
__ cmp(G3_scratch, SafepointSynchronize::_not_synchronized); __ cmp_and_br_short(G3_scratch, SafepointSynchronize::_not_synchronized, Assembler::notEqual, Assembler::pn, slow_path);
__ br(Assembler::notEqual, false, Assembler::pn, slow_path);
__ delayed()->nop();
// Code: _return // Code: _return
__ retl(); __ retl();
@ -664,14 +644,12 @@ address InterpreterGenerator::generate_accessor_entry(void) {
AddressLiteral sync_state(SafepointSynchronize::address_of_state()); AddressLiteral sync_state(SafepointSynchronize::address_of_state());
__ load_contents(sync_state, G3_scratch); __ load_contents(sync_state, G3_scratch);
__ cmp(G3_scratch, SafepointSynchronize::_not_synchronized); __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized);
__ br(Assembler::notEqual, false, Assembler::pn, slow_path); __ cmp_and_br_short(G3_scratch, SafepointSynchronize::_not_synchronized, Assembler::notEqual, Assembler::pn, slow_path);
__ delayed()->nop();
// Check if local 0 != NULL // Check if local 0 != NULL
__ ld_ptr(Gargs, G0, Otos_i ); // get local 0 __ ld_ptr(Gargs, G0, Otos_i ); // get local 0
__ tst(Otos_i); // check if local 0 == NULL and go the slow path // check if local 0 == NULL and go the slow path
__ brx(Assembler::zero, false, Assembler::pn, slow_path); __ br_null_short(Otos_i, Assembler::pn, slow_path);
__ delayed()->nop();
// read first instruction word and extract bytecode @ 1 and index @ 2 // read first instruction word and extract bytecode @ 1 and index @ 2
@ -697,9 +675,7 @@ address InterpreterGenerator::generate_accessor_entry(void) {
__ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::indices_offset(), G1_scratch); __ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::indices_offset(), G1_scratch);
__ srl(G1_scratch, 2*BitsPerByte, G1_scratch); __ srl(G1_scratch, 2*BitsPerByte, G1_scratch);
__ and3(G1_scratch, 0xFF, G1_scratch); __ and3(G1_scratch, 0xFF, G1_scratch);
__ cmp(G1_scratch, Bytecodes::_getfield); __ cmp_and_br_short(G1_scratch, Bytecodes::_getfield, Assembler::notEqual, Assembler::pn, slow_path);
__ br(Assembler::notEqual, false, Assembler::pn, slow_path);
__ delayed()->nop();
// Get the type and return field offset from the constant pool cache // Get the type and return field offset from the constant pool cache
__ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::flags_offset(), G1_scratch); __ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::flags_offset(), G1_scratch);
@ -787,9 +763,8 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
// Check if local 0 != NULL // Check if local 0 != NULL
// If the receiver is null then it is OK to jump to the slow path. // If the receiver is null then it is OK to jump to the slow path.
__ ld_ptr(Gargs, G0, Otos_i ); // get local 0 __ ld_ptr(Gargs, G0, Otos_i ); // get local 0
__ tst(Otos_i); // check if local 0 == NULL and go the slow path // check if local 0 == NULL and go the slow path
__ brx(Assembler::zero, false, Assembler::pn, slow_path); __ cmp_and_brx_short(Otos_i, 0, Assembler::equal, Assembler::pn, slow_path);
__ delayed()->nop();
// Load the value of the referent field. // Load the value of the referent field.
@ -952,9 +927,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
{ Label L; { Label L;
Address signature_handler(Lmethod, methodOopDesc::signature_handler_offset()); Address signature_handler(Lmethod, methodOopDesc::signature_handler_offset());
__ ld_ptr(signature_handler, G3_scratch); __ ld_ptr(signature_handler, G3_scratch);
__ tst(G3_scratch); __ br_notnull_short(G3_scratch, Assembler::pt, L);
__ brx(Assembler::notZero, false, Assembler::pt, L);
__ delayed()->nop();
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), Lmethod); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), Lmethod);
__ ld_ptr(signature_handler, G3_scratch); __ ld_ptr(signature_handler, G3_scratch);
__ bind(L); __ bind(L);
@ -1019,9 +992,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
#ifdef ASSERT #ifdef ASSERT
if (!PrintSignatureHandlers) // do not dirty the output with this if (!PrintSignatureHandlers) // do not dirty the output with this
{ Label L; { Label L;
__ tst(O1); __ br_notnull_short(O1, Assembler::pt, L);
__ brx(Assembler::notZero, false, Assembler::pt, L);
__ delayed()->nop();
__ stop("mirror is missing"); __ stop("mirror is missing");
__ bind(L); __ bind(L);
} }
@ -1038,9 +1009,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
#ifdef ASSERT #ifdef ASSERT
{ Label L; { Label L;
__ tst(O0); __ br_notnull_short(O0, Assembler::pt, L);
__ brx(Assembler::notZero, false, Assembler::pt, L);
__ delayed()->nop();
__ stop("native entry point is missing"); __ stop("native entry point is missing");
__ bind(L); __ bind(L);
} }
@ -1079,9 +1048,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
#ifdef ASSERT #ifdef ASSERT
{ Label L; { Label L;
__ ld(thread_state, G3_scratch); __ ld(thread_state, G3_scratch);
__ cmp(G3_scratch, _thread_in_Java); __ cmp_and_br_short(G3_scratch, _thread_in_Java, Assembler::equal, Assembler::pt, L);
__ br(Assembler::equal, false, Assembler::pt, L);
__ delayed()->nop();
__ stop("Wrong thread state in native stub"); __ stop("Wrong thread state in native stub");
__ bind(L); __ bind(L);
} }
@ -1134,9 +1101,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
Label L; Label L;
__ br(Assembler::notEqual, false, Assembler::pn, L); __ br(Assembler::notEqual, false, Assembler::pn, L);
__ delayed()->ld(G2_thread, JavaThread::suspend_flags_offset(), G3_scratch); __ delayed()->ld(G2_thread, JavaThread::suspend_flags_offset(), G3_scratch);
__ cmp(G3_scratch, 0); __ cmp_and_br_short(G3_scratch, 0, Assembler::equal, Assembler::pt, no_block);
__ br(Assembler::equal, false, Assembler::pt, no_block);
__ delayed()->nop();
__ bind(L); __ bind(L);
// Block. Save any potential method result value before the operation and // Block. Save any potential method result value before the operation and
@ -1185,9 +1150,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
Label no_oop, store_result; Label no_oop, store_result;
__ set((intptr_t)AbstractInterpreter::result_handler(T_OBJECT), G3_scratch); __ set((intptr_t)AbstractInterpreter::result_handler(T_OBJECT), G3_scratch);
__ cmp(G3_scratch, Lscratch); __ cmp_and_brx_short(G3_scratch, Lscratch, Assembler::notEqual, Assembler::pt, no_oop);
__ brx(Assembler::notEqual, false, Assembler::pt, no_oop);
__ delayed()->nop();
__ addcc(G0, O0, O0); __ addcc(G0, O0, O0);
__ brx(Assembler::notZero, true, Assembler::pt, store_result); // if result is not NULL: __ brx(Assembler::notZero, true, Assembler::pt, store_result); // if result is not NULL:
__ delayed()->ld_ptr(O0, 0, O0); // unbox it __ delayed()->ld_ptr(O0, 0, O0); // unbox it
@ -1206,9 +1169,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
{ Label L; { Label L;
Address exception_addr(G2_thread, Thread::pending_exception_offset()); Address exception_addr(G2_thread, Thread::pending_exception_offset());
__ ld_ptr(exception_addr, Gtemp); __ ld_ptr(exception_addr, Gtemp);
__ tst(Gtemp); __ br_null_short(Gtemp, Assembler::pt, L);
__ brx(Assembler::equal, false, Assembler::pt, L);
__ delayed()->nop();
// Note: This could be handled more efficiently since we know that the native // Note: This could be handled more efficiently since we know that the native
// method doesn't have an exception handler. We could directly return // method doesn't have an exception handler. We could directly return
// to the exception handler for the caller. // to the exception handler for the caller.
@ -1245,9 +1206,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
#ifdef ASSERT #ifdef ASSERT
{ {
Label ok; Label ok;
__ cmp(I5_savedSP, FP); __ cmp_and_brx_short(I5_savedSP, FP, Assembler::greaterEqualUnsigned, Assembler::pt, ok);
__ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, ok);
__ delayed()->nop();
__ stop("bad I5_savedSP value"); __ stop("bad I5_savedSP value");
__ should_not_reach_here(); __ should_not_reach_here();
__ bind(ok); __ bind(ok);
@ -1429,8 +1388,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method)); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
__ set_method_data_pointer_for_bcp(); __ set_method_data_pointer_for_bcp();
__ ba(false, profile_method_continue); __ ba_short(profile_method_continue);
__ delayed()->nop();
} }
// handle invocation counter overflow // handle invocation counter overflow
@ -1856,9 +1814,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
// adapter frames in C2. // adapter frames in C2.
Label caller_not_deoptimized; Label caller_not_deoptimized;
__ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), I7); __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), I7);
__ tst(O0); __ br_notnull_short(O0, Assembler::pt, caller_not_deoptimized);
__ brx(Assembler::notEqual, false, Assembler::pt, caller_not_deoptimized);
__ delayed()->nop();
const Register Gtmp1 = G3_scratch; const Register Gtmp1 = G3_scratch;
const Register Gtmp2 = G1_scratch; const Register Gtmp2 = G1_scratch;
@ -1992,10 +1948,10 @@ address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state
void TemplateInterpreterGenerator::set_vtos_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) { void TemplateInterpreterGenerator::set_vtos_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) {
assert(t->is_valid() && t->tos_in() == vtos, "illegal template"); assert(t->is_valid() && t->tos_in() == vtos, "illegal template");
Label L; Label L;
aep = __ pc(); __ push_ptr(); __ ba(false, L); __ delayed()->nop(); aep = __ pc(); __ push_ptr(); __ ba_short(L);
fep = __ pc(); __ push_f(); __ ba(false, L); __ delayed()->nop(); fep = __ pc(); __ push_f(); __ ba_short(L);
dep = __ pc(); __ push_d(); __ ba(false, L); __ delayed()->nop(); dep = __ pc(); __ push_d(); __ ba_short(L);
lep = __ pc(); __ push_l(); __ ba(false, L); __ delayed()->nop(); lep = __ pc(); __ push_l(); __ ba_short(L);
iep = __ pc(); __ push_i(); iep = __ pc(); __ push_i();
bep = cep = sep = iep; // there aren't any bep = cep = sep = iep; // there aren't any
vep = __ pc(); __ bind(L); // fall through vep = __ pc(); __ bind(L); // fall through

View File

@ -149,39 +149,68 @@ Address TemplateTable::at_bcp(int offset) {
} }
void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register Rbyte_code, void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
Register Rscratch, Register temp_reg, bool load_bc_into_bc_reg/*=true*/,
bool load_bc_into_scratch /*=true*/) { int byte_no) {
// With sharing on, may need to test methodOop flag. // With sharing on, may need to test methodOop flag.
if (!RewriteBytecodes) return; if (!RewriteBytecodes) return;
if (load_bc_into_scratch) __ set(bc, Rbyte_code); Label L_patch_done;
Label patch_done;
if (JvmtiExport::can_post_breakpoint()) { switch (bc) {
Label fast_patch; case Bytecodes::_fast_aputfield:
__ ldub(at_bcp(0), Rscratch); case Bytecodes::_fast_bputfield:
__ cmp(Rscratch, Bytecodes::_breakpoint); case Bytecodes::_fast_cputfield:
__ br(Assembler::notEqual, false, Assembler::pt, fast_patch); case Bytecodes::_fast_dputfield:
__ delayed()->nop(); // don't bother to hoist the stb here case Bytecodes::_fast_fputfield:
// perform the quickening, slowly, in the bowels of the breakpoint table case Bytecodes::_fast_iputfield:
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), Lmethod, Lbcp, Rbyte_code); case Bytecodes::_fast_lputfield:
__ ba(false, patch_done); case Bytecodes::_fast_sputfield:
__ delayed()->nop(); {
__ bind(fast_patch); // We skip bytecode quickening for putfield instructions when
// the put_code written to the constant pool cache is zero.
// This is required so that every execution of this instruction
// calls out to InterpreterRuntime::resolve_get_put to do
// additional, required work.
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
assert(load_bc_into_bc_reg, "we use bc_reg as temp");
__ get_cache_and_index_and_bytecode_at_bcp(bc_reg, temp_reg, temp_reg, byte_no, 1);
__ set(bc, bc_reg);
__ cmp_and_br_short(temp_reg, 0, Assembler::equal, Assembler::pn, L_patch_done); // don't patch
}
break;
default:
assert(byte_no == -1, "sanity");
if (load_bc_into_bc_reg) {
__ set(bc, bc_reg);
}
} }
if (JvmtiExport::can_post_breakpoint()) {
Label L_fast_patch;
__ ldub(at_bcp(0), temp_reg);
__ cmp_and_br_short(temp_reg, Bytecodes::_breakpoint, Assembler::notEqual, Assembler::pt, L_fast_patch);
// perform the quickening, slowly, in the bowels of the breakpoint table
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), Lmethod, Lbcp, bc_reg);
__ ba_short(L_patch_done);
__ bind(L_fast_patch);
}
#ifdef ASSERT #ifdef ASSERT
Bytecodes::Code orig_bytecode = Bytecodes::java_code(bc); Bytecodes::Code orig_bytecode = Bytecodes::java_code(bc);
Label okay; Label L_okay;
__ ldub(at_bcp(0), Rscratch); __ ldub(at_bcp(0), temp_reg);
__ cmp(Rscratch, orig_bytecode); __ cmp(temp_reg, orig_bytecode);
__ br(Assembler::equal, false, Assembler::pt, okay); __ br(Assembler::equal, false, Assembler::pt, L_okay);
__ delayed() ->cmp(Rscratch, Rbyte_code); __ delayed()->cmp(temp_reg, bc_reg);
__ br(Assembler::equal, false, Assembler::pt, okay); __ br(Assembler::equal, false, Assembler::pt, L_okay);
__ delayed()->nop(); __ delayed()->nop();
__ stop("Rewriting wrong bytecode location"); __ stop("patching the wrong bytecode");
__ bind(okay); __ bind(L_okay);
#endif #endif
__ stb(Rbyte_code, at_bcp(0));
__ bind(patch_done); // patch bytecode
__ stb(bc_reg, at_bcp(0));
__ bind(L_patch_done);
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
@ -281,17 +310,14 @@ void TemplateTable::ldc(bool wide) {
// get type from tags // get type from tags
__ add(O2, tags_offset, O2); __ add(O2, tags_offset, O2);
__ ldub(O2, O1, O2); __ ldub(O2, O1, O2);
__ cmp(O2, JVM_CONSTANT_UnresolvedString); // unresolved string? If so, must resolve // unresolved string? If so, must resolve
__ brx(Assembler::equal, true, Assembler::pt, call_ldc); __ cmp_and_brx_short(O2, JVM_CONSTANT_UnresolvedString, Assembler::equal, Assembler::pt, call_ldc);
__ delayed()->nop();
__ cmp(O2, JVM_CONSTANT_UnresolvedClass); // unresolved class? If so, must resolve // unresolved class? If so, must resolve
__ brx(Assembler::equal, true, Assembler::pt, call_ldc); __ cmp_and_brx_short(O2, JVM_CONSTANT_UnresolvedClass, Assembler::equal, Assembler::pt, call_ldc);
__ delayed()->nop();
__ cmp(O2, JVM_CONSTANT_UnresolvedClassInError); // unresolved class in error state // unresolved class in error state
__ brx(Assembler::equal, true, Assembler::pn, call_ldc); __ cmp_and_brx_short(O2, JVM_CONSTANT_UnresolvedClassInError, Assembler::equal, Assembler::pn, call_ldc);
__ delayed()->nop();
__ cmp(O2, JVM_CONSTANT_Class); // need to call vm to get java mirror of the class __ cmp(O2, JVM_CONSTANT_Class); // need to call vm to get java mirror of the class
__ brx(Assembler::notEqual, true, Assembler::pt, notClass); __ brx(Assembler::notEqual, true, Assembler::pt, notClass);
@ -301,8 +327,7 @@ void TemplateTable::ldc(bool wide) {
__ set(wide, O1); __ set(wide, O1);
call_VM(Otos_i, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), O1); call_VM(Otos_i, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), O1);
__ push(atos); __ push(atos);
__ ba(false, exit); __ ba_short(exit);
__ delayed()->nop();
__ bind(notClass); __ bind(notClass);
// __ add(O0, base_offset, O0); // __ add(O0, base_offset, O0);
@ -312,8 +337,7 @@ void TemplateTable::ldc(bool wide) {
__ delayed()->cmp(O2, JVM_CONSTANT_String); __ delayed()->cmp(O2, JVM_CONSTANT_String);
__ ld(O0, O1, Otos_i); __ ld(O0, O1, Otos_i);
__ push(itos); __ push(itos);
__ ba(false, exit); __ ba_short(exit);
__ delayed()->nop();
__ bind(notInt); __ bind(notInt);
// __ cmp(O2, JVM_CONSTANT_String); // __ cmp(O2, JVM_CONSTANT_String);
@ -325,8 +349,7 @@ void TemplateTable::ldc(bool wide) {
__ ld_ptr(O0, O1, Otos_i); __ ld_ptr(O0, O1, Otos_i);
__ verify_oop(Otos_i); __ verify_oop(Otos_i);
__ push(atos); __ push(atos);
__ ba(false, exit); __ ba_short(exit);
__ delayed()->nop();
__ bind(notString); __ bind(notString);
// __ ldf(FloatRegisterImpl::S, O0, O1, Ftos_f); // __ ldf(FloatRegisterImpl::S, O0, O1, Ftos_f);
@ -365,9 +388,7 @@ void TemplateTable::fast_aldc(bool wide) {
__ load_klass(Otos_i, Rcon_klass); __ load_klass(Otos_i, Rcon_klass);
AddressLiteral array_klass_addr((address)Universe::systemObjArrayKlassObj_addr()); AddressLiteral array_klass_addr((address)Universe::systemObjArrayKlassObj_addr());
__ load_contents(array_klass_addr, Rarray_klass); __ load_contents(array_klass_addr, Rarray_klass);
__ cmp(Rarray_klass, Rcon_klass); __ cmp_and_brx_short(Rarray_klass, Rcon_klass, Assembler::notEqual, Assembler::pt, L_done);
__ brx(Assembler::notEqual, false, Assembler::pt, L_done);
__ delayed()->nop();
__ ld(Address(Otos_i, arrayOopDesc::length_offset_in_bytes()), Rcon_klass); __ ld(Address(Otos_i, arrayOopDesc::length_offset_in_bytes()), Rcon_klass);
__ tst(Rcon_klass); __ tst(Rcon_klass);
__ brx(Assembler::zero, true, Assembler::pt, L_done); __ brx(Assembler::zero, true, Assembler::pt, L_done);
@ -397,9 +418,7 @@ void TemplateTable::ldc2_w() {
__ sll(O1, LogBytesPerWord, O1); __ sll(O1, LogBytesPerWord, O1);
__ add(O0, O1, G3_scratch); __ add(O0, O1, G3_scratch);
__ cmp(O2, JVM_CONSTANT_Double); __ cmp_and_brx_short(O2, JVM_CONSTANT_Double, Assembler::notEqual, Assembler::pt, Long);
__ brx(Assembler::notEqual, false, Assembler::pt, Long);
__ delayed()->nop();
// A double can be placed at word-aligned locations in the constant pool. // A double can be placed at word-aligned locations in the constant pool.
// Check out Conversions.java for an example. // Check out Conversions.java for an example.
// Also constantPoolOopDesc::header_size() is 20, which makes it very difficult // Also constantPoolOopDesc::header_size() is 20, which makes it very difficult
@ -413,8 +432,7 @@ void TemplateTable::ldc2_w() {
f->successor()); f->successor());
#endif #endif
__ push(dtos); __ push(dtos);
__ ba(false, exit); __ ba_short(exit);
__ delayed()->nop();
__ bind(Long); __ bind(Long);
#ifdef _LP64 #ifdef _LP64
@ -453,9 +471,7 @@ void TemplateTable::iload() {
// last two iloads in a pair. Comparing against fast_iload means that // last two iloads in a pair. Comparing against fast_iload means that
// the next bytecode is neither an iload or a caload, and therefore // the next bytecode is neither an iload or a caload, and therefore
// an iload pair. // an iload pair.
__ cmp(G3_scratch, (int)Bytecodes::_iload); __ cmp_and_br_short(G3_scratch, (int)Bytecodes::_iload, Assembler::equal, Assembler::pn, done);
__ br(Assembler::equal, false, Assembler::pn, done);
__ delayed()->nop();
__ cmp(G3_scratch, (int)Bytecodes::_fast_iload); __ cmp(G3_scratch, (int)Bytecodes::_fast_iload);
__ br(Assembler::equal, false, Assembler::pn, rewrite); __ br(Assembler::equal, false, Assembler::pn, rewrite);
@ -697,9 +713,7 @@ void TemplateTable::aload_0() {
aload(0); aload(0);
// if _getfield then wait with rewrite // if _getfield then wait with rewrite
__ cmp(G3_scratch, (int)Bytecodes::_getfield); __ cmp_and_br_short(G3_scratch, (int)Bytecodes::_getfield, Assembler::equal, Assembler::pn, done);
__ br(Assembler::equal, false, Assembler::pn, done);
__ delayed()->nop();
// if _igetfield then rewrite to _fast_iaccess_0 // if _igetfield then rewrite to _fast_iaccess_0
assert(Bytecodes::java_code(Bytecodes::_fast_iaccess_0) == Bytecodes::_aload_0, "adjust fast bytecode def"); assert(Bytecodes::java_code(Bytecodes::_fast_iaccess_0) == Bytecodes::_aload_0, "adjust fast bytecode def");
@ -867,8 +881,7 @@ void TemplateTable::aastore() {
__ index_check_without_pop(O3, O2, UseCompressedOops ? 2 : LogBytesPerWord, G3_scratch, O1); __ index_check_without_pop(O3, O2, UseCompressedOops ? 2 : LogBytesPerWord, G3_scratch, O1);
// do array store check - check for NULL value first // do array store check - check for NULL value first
__ br_null( Otos_i, false, Assembler::pn, is_null ); __ br_null_short( Otos_i, Assembler::pn, is_null );
__ delayed()->nop();
__ load_klass(O3, O4); // get array klass __ load_klass(O3, O4); // get array klass
__ load_klass(Otos_i, O5); // get value klass __ load_klass(Otos_i, O5); // get value klass
@ -899,7 +912,7 @@ void TemplateTable::aastore() {
__ bind(store_ok); __ bind(store_ok);
do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Otos_i, G3_scratch, _bs->kind(), true); do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Otos_i, G3_scratch, _bs->kind(), true);
__ ba(false,done); __ ba(done);
__ delayed()->inc(Lesp, 3* Interpreter::stackElementSize); // adj sp (pops array, index and value) __ delayed()->inc(Lesp, 3* Interpreter::stackElementSize); // adj sp (pops array, index and value)
__ bind(is_null); __ bind(is_null);
@ -1633,16 +1646,14 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) {
if (ProfileInterpreter) { if (ProfileInterpreter) {
// If no method data exists, go to profile_continue. // If no method data exists, go to profile_continue.
__ ld_ptr(Lmethod, methodOopDesc::method_data_offset(), G4_scratch); __ ld_ptr(Lmethod, methodOopDesc::method_data_offset(), G4_scratch);
__ br_null(G4_scratch, false, Assembler::pn, Lno_mdo); __ br_null_short(G4_scratch, Assembler::pn, Lno_mdo);
__ delayed()->nop();
// Increment backedge counter in the MDO // Increment backedge counter in the MDO
Address mdo_backedge_counter(G4_scratch, in_bytes(methodDataOopDesc::backedge_counter_offset()) + Address mdo_backedge_counter(G4_scratch, in_bytes(methodDataOopDesc::backedge_counter_offset()) +
in_bytes(InvocationCounter::counter_offset())); in_bytes(InvocationCounter::counter_offset()));
__ increment_mask_and_jump(mdo_backedge_counter, increment, mask, G3_scratch, Lscratch, __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, G3_scratch, Lscratch,
Assembler::notZero, &Lforward); Assembler::notZero, &Lforward);
__ ba(false, Loverflow); __ ba_short(Loverflow);
__ delayed()->nop();
} }
// If there's no MDO, increment counter in methodOop // If there's no MDO, increment counter in methodOop
@ -1658,14 +1669,11 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) {
// Was an OSR adapter generated? // Was an OSR adapter generated?
// O0 = osr nmethod // O0 = osr nmethod
__ br_null(O0, false, Assembler::pn, Lforward); __ br_null_short(O0, Assembler::pn, Lforward);
__ delayed()->nop();
// Has the nmethod been invalidated already? // Has the nmethod been invalidated already?
__ ld(O0, nmethod::entry_bci_offset(), O2); __ ld(O0, nmethod::entry_bci_offset(), O2);
__ cmp(O2, InvalidOSREntryBci); __ cmp_and_br_short(O2, InvalidOSREntryBci, Assembler::equal, Assembler::pn, Lforward);
__ br(Assembler::equal, false, Assembler::pn, Lforward);
__ delayed()->nop();
// migrate the interpreter frame off of the stack // migrate the interpreter frame off of the stack
@ -1830,7 +1838,7 @@ void TemplateTable::tableswitch() {
__ profile_switch_case(O2, O3, G3_scratch, G4_scratch); __ profile_switch_case(O2, O3, G3_scratch, G4_scratch);
__ sll(O2, LogBytesPerInt, O2); __ sll(O2, LogBytesPerInt, O2);
__ add(O2, 3 * BytesPerInt, O2); __ add(O2, 3 * BytesPerInt, O2);
__ ba(false, continue_execution); __ ba(continue_execution);
__ delayed()->ld(O1, O2, O2); __ delayed()->ld(O1, O2, O2);
// handle default // handle default
__ bind(default_case); __ bind(default_case);
@ -1858,7 +1866,7 @@ void TemplateTable::fast_linearswitch() {
__ ld(O1, BytesPerInt, O2); __ ld(O1, BytesPerInt, O2);
__ sll(O2, LogBytesPerInt + 1, O2); // in word-pairs __ sll(O2, LogBytesPerInt + 1, O2); // in word-pairs
__ add(O1, 2 * BytesPerInt, O3); // set first pair addr __ add(O1, 2 * BytesPerInt, O3); // set first pair addr
__ ba(false, loop_entry); __ ba(loop_entry);
__ delayed()->add(O3, O2, O2); // counter now points past last pair __ delayed()->add(O3, O2, O2); // counter now points past last pair
// table search // table search
@ -1877,8 +1885,7 @@ void TemplateTable::fast_linearswitch() {
__ ld(O1, 0, O4); // get default offset __ ld(O1, 0, O4); // get default offset
if (ProfileInterpreter) { if (ProfileInterpreter) {
__ profile_switch_default(O3); __ profile_switch_default(O3);
__ ba(false, continue_execution); __ ba_short(continue_execution);
__ delayed()->nop();
} }
// entry found -> get offset // entry found -> get offset
@ -1944,7 +1951,7 @@ void TemplateTable::fast_binaryswitch() {
// and start // and start
Label entry; Label entry;
__ ba(false, entry); __ ba(entry);
__ delayed()->ld( Rarray, -BytesPerInt, Rj); __ delayed()->ld( Rarray, -BytesPerInt, Rj);
// (Rj is already in the native byte-ordering.) // (Rj is already in the native byte-ordering.)
@ -2002,8 +2009,7 @@ void TemplateTable::fast_binaryswitch() {
// (Rj is already in the native byte-ordering.) // (Rj is already in the native byte-ordering.)
if (ProfileInterpreter) { if (ProfileInterpreter) {
__ ba(false, continue_execution); __ ba_short(continue_execution);
__ delayed()->nop();
} }
__ bind(default_case); // fall through (if not profiling) __ bind(default_case); // fall through (if not profiling)
@ -2087,12 +2093,12 @@ void TemplateTable::resolve_cache_and_index(int byte_no,
// Depends on cpCacheOop layout! // Depends on cpCacheOop layout!
Label resolved; Label resolved;
__ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
if (byte_no == f1_oop) { if (byte_no == f1_oop) {
// We are resolved if the f1 field contains a non-null object (CallSite, etc.) // We are resolved if the f1 field contains a non-null object (CallSite, etc.)
// This kind of CP cache entry does not need to match the flags byte, because // This kind of CP cache entry does not need to match the flags byte, because
// there is a 1-1 relation between bytecode type and CP entry type. // there is a 1-1 relation between bytecode type and CP entry type.
assert_different_registers(result, Rcache); assert_different_registers(result, Rcache);
__ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
__ ld_ptr(Rcache, constantPoolCacheOopDesc::base_offset() + __ ld_ptr(Rcache, constantPoolCacheOopDesc::base_offset() +
ConstantPoolCacheEntry::f1_offset(), result); ConstantPoolCacheEntry::f1_offset(), result);
__ tst(result); __ tst(result);
@ -2101,15 +2107,9 @@ void TemplateTable::resolve_cache_and_index(int byte_no,
} else { } else {
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
assert(result == noreg, ""); //else change code for setting result assert(result == noreg, ""); //else change code for setting result
const int shift_count = (1 + byte_no)*BitsPerByte; __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, Lbyte_code, byte_no, 1, index_size);
__ cmp(Lbyte_code, (int) bytecode()); // have we resolved this bytecode?
__ ld_ptr(Rcache, constantPoolCacheOopDesc::base_offset() + __ br(Assembler::equal, false, Assembler::pt, resolved);
ConstantPoolCacheEntry::indices_offset(), Lbyte_code);
__ srl( Lbyte_code, shift_count, Lbyte_code );
__ and3( Lbyte_code, 0xFF, Lbyte_code );
__ cmp( Lbyte_code, (int)bytecode());
__ br( Assembler::equal, false, Assembler::pt, resolved);
__ delayed()->set((int)bytecode(), O1); __ delayed()->set((int)bytecode(), O1);
} }
@ -2216,9 +2216,7 @@ void TemplateTable::jvmti_post_field_access(Register Rcache,
assert_different_registers(Rcache, index, G1_scratch); assert_different_registers(Rcache, index, G1_scratch);
AddressLiteral get_field_access_count_addr(JvmtiExport::get_field_access_count_addr()); AddressLiteral get_field_access_count_addr(JvmtiExport::get_field_access_count_addr());
__ load_contents(get_field_access_count_addr, G1_scratch); __ load_contents(get_field_access_count_addr, G1_scratch);
__ tst(G1_scratch); __ cmp_and_br_short(G1_scratch, 0, Assembler::equal, Assembler::pt, Label1);
__ br(Assembler::zero, false, Assembler::pt, Label1);
__ delayed()->nop();
__ add(Rcache, in_bytes(cp_base_offset), Rcache); __ add(Rcache, in_bytes(cp_base_offset), Rcache);
@ -2298,7 +2296,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
if (!is_static) { if (!is_static) {
patch_bytecode(Bytecodes::_fast_agetfield, G3_scratch, G4_scratch); patch_bytecode(Bytecodes::_fast_agetfield, G3_scratch, G4_scratch);
} }
__ ba(false, checkVolatile); __ ba(checkVolatile);
__ delayed()->tst(Lscratch); __ delayed()->tst(Lscratch);
__ bind(notObj); __ bind(notObj);
@ -2313,7 +2311,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
if (!is_static) { if (!is_static) {
patch_bytecode(Bytecodes::_fast_igetfield, G3_scratch, G4_scratch); patch_bytecode(Bytecodes::_fast_igetfield, G3_scratch, G4_scratch);
} }
__ ba(false, checkVolatile); __ ba(checkVolatile);
__ delayed()->tst(Lscratch); __ delayed()->tst(Lscratch);
__ bind(notInt); __ bind(notInt);
@ -2329,7 +2327,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
if (!is_static) { if (!is_static) {
patch_bytecode(Bytecodes::_fast_lgetfield, G3_scratch, G4_scratch); patch_bytecode(Bytecodes::_fast_lgetfield, G3_scratch, G4_scratch);
} }
__ ba(false, checkVolatile); __ ba(checkVolatile);
__ delayed()->tst(Lscratch); __ delayed()->tst(Lscratch);
__ bind(notLong); __ bind(notLong);
@ -2344,7 +2342,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
if (!is_static) { if (!is_static) {
patch_bytecode(Bytecodes::_fast_bgetfield, G3_scratch, G4_scratch); patch_bytecode(Bytecodes::_fast_bgetfield, G3_scratch, G4_scratch);
} }
__ ba(false, checkVolatile); __ ba(checkVolatile);
__ delayed()->tst(Lscratch); __ delayed()->tst(Lscratch);
__ bind(notByte); __ bind(notByte);
@ -2359,7 +2357,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
if (!is_static) { if (!is_static) {
patch_bytecode(Bytecodes::_fast_cgetfield, G3_scratch, G4_scratch); patch_bytecode(Bytecodes::_fast_cgetfield, G3_scratch, G4_scratch);
} }
__ ba(false, checkVolatile); __ ba(checkVolatile);
__ delayed()->tst(Lscratch); __ delayed()->tst(Lscratch);
__ bind(notChar); __ bind(notChar);
@ -2374,7 +2372,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
if (!is_static) { if (!is_static) {
patch_bytecode(Bytecodes::_fast_sgetfield, G3_scratch, G4_scratch); patch_bytecode(Bytecodes::_fast_sgetfield, G3_scratch, G4_scratch);
} }
__ ba(false, checkVolatile); __ ba(checkVolatile);
__ delayed()->tst(Lscratch); __ delayed()->tst(Lscratch);
__ bind(notShort); __ bind(notShort);
@ -2390,7 +2388,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
if (!is_static) { if (!is_static) {
patch_bytecode(Bytecodes::_fast_fgetfield, G3_scratch, G4_scratch); patch_bytecode(Bytecodes::_fast_fgetfield, G3_scratch, G4_scratch);
} }
__ ba(false, checkVolatile); __ ba(checkVolatile);
__ delayed()->tst(Lscratch); __ delayed()->tst(Lscratch);
__ bind(notFloat); __ bind(notFloat);
@ -2499,9 +2497,7 @@ void TemplateTable::jvmti_post_fast_field_mod() {
Label done; Label done;
AddressLiteral get_field_modification_count_addr(JvmtiExport::get_field_modification_count_addr()); AddressLiteral get_field_modification_count_addr(JvmtiExport::get_field_modification_count_addr());
__ load_contents(get_field_modification_count_addr, G4_scratch); __ load_contents(get_field_modification_count_addr, G4_scratch);
__ tst(G4_scratch); __ cmp_and_br_short(G4_scratch, 0, Assembler::equal, Assembler::pt, done);
__ br(Assembler::zero, false, Assembler::pt, done);
__ delayed()->nop();
__ pop_ptr(G4_scratch); // copy the object pointer from tos __ pop_ptr(G4_scratch); // copy the object pointer from tos
__ verify_oop(G4_scratch); __ verify_oop(G4_scratch);
__ push_ptr(G4_scratch); // put the object pointer back on tos __ push_ptr(G4_scratch); // put the object pointer back on tos
@ -2552,9 +2548,7 @@ void TemplateTable::jvmti_post_field_mod(Register Rcache, Register index, bool i
assert_different_registers(Rcache, index, G1_scratch); assert_different_registers(Rcache, index, G1_scratch);
AddressLiteral get_field_modification_count_addr(JvmtiExport::get_field_modification_count_addr()); AddressLiteral get_field_modification_count_addr(JvmtiExport::get_field_modification_count_addr());
__ load_contents(get_field_modification_count_addr, G1_scratch); __ load_contents(get_field_modification_count_addr, G1_scratch);
__ tst(G1_scratch); __ cmp_and_br_short(G1_scratch, 0, Assembler::zero, Assembler::pt, Label1);
__ br(Assembler::zero, false, Assembler::pt, Label1);
__ delayed()->nop();
// The Rcache and index registers have been already set. // The Rcache and index registers have been already set.
// This allows to eliminate this call but the Rcache and index // This allows to eliminate this call but the Rcache and index
@ -2584,8 +2578,7 @@ void TemplateTable::jvmti_post_field_mod(Register Rcache, Register index, bool i
__ br(Assembler::equal, false, Assembler::pt, two_word); __ br(Assembler::equal, false, Assembler::pt, two_word);
__ delayed()->nop(); __ delayed()->nop();
__ inc(G4_scratch, Interpreter::expr_offset_in_bytes(1)); __ inc(G4_scratch, Interpreter::expr_offset_in_bytes(1));
__ br(Assembler::always, false, Assembler::pt, valsizeknown); __ ba_short(valsizeknown);
__ delayed()->nop();
__ bind(two_word); __ bind(two_word);
__ inc(G4_scratch, Interpreter::expr_offset_in_bytes(2)); __ inc(G4_scratch, Interpreter::expr_offset_in_bytes(2));
@ -2636,9 +2629,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
__ and3(Rflags, Lscratch, Lscratch); __ and3(Rflags, Lscratch, Lscratch);
if (__ membar_has_effect(read_bits)) { if (__ membar_has_effect(read_bits)) {
__ tst(Lscratch); __ cmp_and_br_short(Lscratch, 0, Assembler::equal, Assembler::pt, notVolatile);
__ br(Assembler::zero, false, Assembler::pt, notVolatile);
__ delayed()->nop();
volatile_barrier(read_bits); volatile_barrier(read_bits);
__ bind(notVolatile); __ bind(notVolatile);
} }
@ -2653,150 +2644,162 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
if (is_static) { if (is_static) {
// putstatic with object type most likely, check that first // putstatic with object type most likely, check that first
__ cmp(Rflags, atos ); __ cmp(Rflags, atos);
__ br(Assembler::notEqual, false, Assembler::pt, notObj); __ br(Assembler::notEqual, false, Assembler::pt, notObj);
__ delayed() ->cmp(Rflags, itos ); __ delayed()->cmp(Rflags, itos);
// atos // atos
__ pop_ptr(); {
__ verify_oop(Otos_i); __ pop_ptr();
__ verify_oop(Otos_i);
do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false); do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false);
__ ba(checkVolatile);
__ ba(false, checkVolatile); __ delayed()->tst(Lscratch);
__ delayed()->tst(Lscratch); }
__ bind(notObj); __ bind(notObj);
// cmp(Rflags, itos);
// cmp(Rflags, itos );
__ br(Assembler::notEqual, false, Assembler::pt, notInt); __ br(Assembler::notEqual, false, Assembler::pt, notInt);
__ delayed() ->cmp(Rflags, btos ); __ delayed()->cmp(Rflags, btos);
// itos // itos
__ pop_i(); {
__ st(Otos_i, Rclass, Roffset); __ pop_i();
__ ba(false, checkVolatile); __ st(Otos_i, Rclass, Roffset);
__ delayed()->tst(Lscratch); __ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
__ bind(notInt); __ bind(notInt);
} else { } else {
// putfield with int type most likely, check that first // putfield with int type most likely, check that first
__ cmp(Rflags, itos ); __ cmp(Rflags, itos);
__ br(Assembler::notEqual, false, Assembler::pt, notInt); __ br(Assembler::notEqual, false, Assembler::pt, notInt);
__ delayed() ->cmp(Rflags, atos ); __ delayed()->cmp(Rflags, atos);
// itos // itos
__ pop_i(); {
pop_and_check_object(Rclass); __ pop_i();
__ st(Otos_i, Rclass, Roffset); pop_and_check_object(Rclass);
patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch); __ st(Otos_i, Rclass, Roffset);
__ ba(false, checkVolatile); patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch, true, byte_no);
__ delayed()->tst(Lscratch); __ ba(checkVolatile);
__ delayed()->tst(Lscratch);
}
__ bind(notInt); __ bind(notInt);
// cmp(Rflags, atos ); // cmp(Rflags, atos);
__ br(Assembler::notEqual, false, Assembler::pt, notObj); __ br(Assembler::notEqual, false, Assembler::pt, notObj);
__ delayed() ->cmp(Rflags, btos ); __ delayed()->cmp(Rflags, btos);
// atos // atos
__ pop_ptr(); {
pop_and_check_object(Rclass); __ pop_ptr();
__ verify_oop(Otos_i); pop_and_check_object(Rclass);
__ verify_oop(Otos_i);
do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false); do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false);
patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch, true, byte_no);
patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch); __ ba(checkVolatile);
__ ba(false, checkVolatile); __ delayed()->tst(Lscratch);
__ delayed()->tst(Lscratch); }
__ bind(notObj); __ bind(notObj);
} }
// cmp(Rflags, btos ); // cmp(Rflags, btos);
__ br(Assembler::notEqual, false, Assembler::pt, notByte); __ br(Assembler::notEqual, false, Assembler::pt, notByte);
__ delayed() ->cmp(Rflags, ltos ); __ delayed()->cmp(Rflags, ltos);
// btos // btos
__ pop_i(); {
if (!is_static) pop_and_check_object(Rclass); __ pop_i();
__ stb(Otos_i, Rclass, Roffset); if (!is_static) pop_and_check_object(Rclass);
if (!is_static) { __ stb(Otos_i, Rclass, Roffset);
patch_bytecode(Bytecodes::_fast_bputfield, G3_scratch, G4_scratch); if (!is_static) {
patch_bytecode(Bytecodes::_fast_bputfield, G3_scratch, G4_scratch, true, byte_no);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
} }
__ ba(false, checkVolatile);
__ delayed()->tst(Lscratch);
__ bind(notByte); __ bind(notByte);
// cmp(Rflags, ltos);
// cmp(Rflags, ltos );
__ br(Assembler::notEqual, false, Assembler::pt, notLong); __ br(Assembler::notEqual, false, Assembler::pt, notLong);
__ delayed() ->cmp(Rflags, ctos ); __ delayed()->cmp(Rflags, ctos);
// ltos // ltos
__ pop_l(); {
if (!is_static) pop_and_check_object(Rclass); __ pop_l();
__ st_long(Otos_l, Rclass, Roffset); if (!is_static) pop_and_check_object(Rclass);
if (!is_static) { __ st_long(Otos_l, Rclass, Roffset);
patch_bytecode(Bytecodes::_fast_lputfield, G3_scratch, G4_scratch); if (!is_static) {
patch_bytecode(Bytecodes::_fast_lputfield, G3_scratch, G4_scratch, true, byte_no);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
} }
__ ba(false, checkVolatile);
__ delayed()->tst(Lscratch);
__ bind(notLong); __ bind(notLong);
// cmp(Rflags, ctos);
// cmp(Rflags, ctos );
__ br(Assembler::notEqual, false, Assembler::pt, notChar); __ br(Assembler::notEqual, false, Assembler::pt, notChar);
__ delayed() ->cmp(Rflags, stos ); __ delayed()->cmp(Rflags, stos);
// ctos (char) // ctos (char)
__ pop_i(); {
if (!is_static) pop_and_check_object(Rclass); __ pop_i();
__ sth(Otos_i, Rclass, Roffset); if (!is_static) pop_and_check_object(Rclass);
if (!is_static) { __ sth(Otos_i, Rclass, Roffset);
patch_bytecode(Bytecodes::_fast_cputfield, G3_scratch, G4_scratch); if (!is_static) {
patch_bytecode(Bytecodes::_fast_cputfield, G3_scratch, G4_scratch, true, byte_no);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
} }
__ ba(false, checkVolatile);
__ delayed()->tst(Lscratch);
__ bind(notChar); __ bind(notChar);
// cmp(Rflags, stos ); // cmp(Rflags, stos);
__ br(Assembler::notEqual, false, Assembler::pt, notShort); __ br(Assembler::notEqual, false, Assembler::pt, notShort);
__ delayed() ->cmp(Rflags, ftos ); __ delayed()->cmp(Rflags, ftos);
// stos (char) // stos (short)
__ pop_i(); {
if (!is_static) pop_and_check_object(Rclass); __ pop_i();
__ sth(Otos_i, Rclass, Roffset); if (!is_static) pop_and_check_object(Rclass);
if (!is_static) { __ sth(Otos_i, Rclass, Roffset);
patch_bytecode(Bytecodes::_fast_sputfield, G3_scratch, G4_scratch); if (!is_static) {
patch_bytecode(Bytecodes::_fast_sputfield, G3_scratch, G4_scratch, true, byte_no);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
} }
__ ba(false, checkVolatile);
__ delayed()->tst(Lscratch);
__ bind(notShort); __ bind(notShort);
// cmp(Rflags, ftos ); // cmp(Rflags, ftos);
__ br(Assembler::notZero, false, Assembler::pt, notFloat); __ br(Assembler::notZero, false, Assembler::pt, notFloat);
__ delayed()->nop(); __ delayed()->nop();
// ftos // ftos
__ pop_f(); {
if (!is_static) pop_and_check_object(Rclass); __ pop_f();
__ stf(FloatRegisterImpl::S, Ftos_f, Rclass, Roffset); if (!is_static) pop_and_check_object(Rclass);
if (!is_static) { __ stf(FloatRegisterImpl::S, Ftos_f, Rclass, Roffset);
patch_bytecode(Bytecodes::_fast_fputfield, G3_scratch, G4_scratch); if (!is_static) {
patch_bytecode(Bytecodes::_fast_fputfield, G3_scratch, G4_scratch, true, byte_no);
}
__ ba(checkVolatile);
__ delayed()->tst(Lscratch);
} }
__ ba(false, checkVolatile);
__ delayed()->tst(Lscratch);
__ bind(notFloat); __ bind(notFloat);
// dtos // dtos
__ pop_d(); {
if (!is_static) pop_and_check_object(Rclass); __ pop_d();
__ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset); if (!is_static) pop_and_check_object(Rclass);
if (!is_static) { __ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset);
patch_bytecode(Bytecodes::_fast_dputfield, G3_scratch, G4_scratch); if (!is_static) {
patch_bytecode(Bytecodes::_fast_dputfield, G3_scratch, G4_scratch, true, byte_no);
}
} }
__ bind(checkVolatile); __ bind(checkVolatile);
@ -2833,9 +2836,7 @@ void TemplateTable::fast_storefield(TosState state) {
__ set((1 << ConstantPoolCacheEntry::volatileField), Lscratch); __ set((1 << ConstantPoolCacheEntry::volatileField), Lscratch);
__ and3(Rflags, Lscratch, Lscratch); __ and3(Rflags, Lscratch, Lscratch);
if (__ membar_has_effect(read_bits)) { if (__ membar_has_effect(read_bits)) {
__ tst(Lscratch); __ cmp_and_br_short(Lscratch, 0, Assembler::equal, Assembler::pt, notVolatile);
__ br(Assembler::zero, false, Assembler::pt, notVolatile);
__ delayed()->nop();
volatile_barrier(read_bits); volatile_barrier(read_bits);
__ bind(notVolatile); __ bind(notVolatile);
} }
@ -2864,9 +2865,7 @@ void TemplateTable::fast_storefield(TosState state) {
} }
if (__ membar_has_effect(write_bits)) { if (__ membar_has_effect(write_bits)) {
__ tst(Lscratch); __ cmp_and_br_short(Lscratch, 0, Assembler::equal, Assembler::pt, exit);
__ br(Assembler::zero, false, Assembler::pt, exit);
__ delayed()->nop();
volatile_barrier(Assembler::StoreLoad); volatile_barrier(Assembler::StoreLoad);
__ bind(exit); __ bind(exit);
} }
@ -3226,8 +3225,7 @@ void TemplateTable::invokeinterface(int byte_no) {
// the VM should throw IncompatibleClassChangeError. linkResolver checks // the VM should throw IncompatibleClassChangeError. linkResolver checks
// this too but that's only if the entry isn't already resolved, so we // this too but that's only if the entry isn't already resolved, so we
// need to check again. // need to check again.
__ br_notnull( Rtemp, false, Assembler::pt, ok); __ br_notnull_short( Rtemp, Assembler::pt, ok);
__ delayed()->nop();
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError)); call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError));
__ should_not_reach_here(); __ should_not_reach_here();
__ bind(ok); __ bind(ok);
@ -3251,9 +3249,7 @@ void TemplateTable::invokeinterface(int byte_no) {
// Check for abstract method error. // Check for abstract method error.
{ {
Label ok; Label ok;
__ tst(G5_method); __ br_notnull_short(G5_method, Assembler::pt, ok);
__ brx(Assembler::notZero, false, Assembler::pt, ok);
__ delayed()->nop();
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError)); call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
__ should_not_reach_here(); __ should_not_reach_here();
__ bind(ok); __ bind(ok);
@ -3408,17 +3404,14 @@ void TemplateTable::_new() {
#else #else
__ srl(RfreeValue, LogHeapWordSize, RfreeValue); __ srl(RfreeValue, LogHeapWordSize, RfreeValue);
#endif #endif
__ cmp(RtlabWasteLimitValue, RfreeValue); __ cmp_and_brx_short(RtlabWasteLimitValue, RfreeValue, Assembler::greaterEqualUnsigned, Assembler::pt, slow_case); // tlab waste is small
__ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, slow_case); // tlab waste is small
__ delayed()->nop();
// increment waste limit to prevent getting stuck on this slow path // increment waste limit to prevent getting stuck on this slow path
__ add(RtlabWasteLimitValue, ThreadLocalAllocBuffer::refill_waste_limit_increment(), RtlabWasteLimitValue); __ add(RtlabWasteLimitValue, ThreadLocalAllocBuffer::refill_waste_limit_increment(), RtlabWasteLimitValue);
__ st_ptr(RtlabWasteLimitValue, G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset())); __ st_ptr(RtlabWasteLimitValue, G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset()));
} else { } else {
// No allocation in the shared eden. // No allocation in the shared eden.
__ br(Assembler::always, false, Assembler::pt, slow_case); __ ba_short(slow_case);
__ delayed()->nop();
} }
} }
@ -3440,18 +3433,14 @@ void TemplateTable::_new() {
// RnewTopValue contains the top address after the new object // RnewTopValue contains the top address after the new object
// has been allocated. // has been allocated.
__ cmp(RnewTopValue, RendValue); __ cmp_and_brx_short(RnewTopValue, RendValue, Assembler::greaterUnsigned, Assembler::pn, slow_case);
__ brx(Assembler::greaterUnsigned, false, Assembler::pn, slow_case);
__ delayed()->nop();
__ casx_under_lock(RtopAddr, RoldTopValue, RnewTopValue, __ casx_under_lock(RtopAddr, RoldTopValue, RnewTopValue,
VM_Version::v9_instructions_work() ? NULL : VM_Version::v9_instructions_work() ? NULL :
(address)StubRoutines::Sparc::atomic_memory_operation_lock_addr()); (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
// if someone beat us on the allocation, try again, otherwise continue // if someone beat us on the allocation, try again, otherwise continue
__ cmp(RoldTopValue, RnewTopValue); __ cmp_and_brx_short(RoldTopValue, RnewTopValue, Assembler::notEqual, Assembler::pn, retry);
__ brx(Assembler::notEqual, false, Assembler::pn, retry);
__ delayed()->nop();
// bump total bytes allocated by this thread // bump total bytes allocated by this thread
// RoldTopValue and RtopAddr are dead, so can use G1 and G3 // RoldTopValue and RtopAddr are dead, so can use G1 and G3
@ -3474,8 +3463,7 @@ void TemplateTable::_new() {
__ br(Assembler::notEqual, false, Assembler::pt, loop); __ br(Assembler::notEqual, false, Assembler::pt, loop);
__ delayed()->subcc(Roffset, wordSize, Roffset); __ delayed()->subcc(Roffset, wordSize, Roffset);
} }
__ br(Assembler::always, false, Assembler::pt, initialize_header); __ ba_short(initialize_header);
__ delayed()->nop();
} }
// slow case // slow case
@ -3485,8 +3473,7 @@ void TemplateTable::_new() {
call_VM(Otos_i, CAST_FROM_FN_PTR(address, InterpreterRuntime::_new), O1, O2); call_VM(Otos_i, CAST_FROM_FN_PTR(address, InterpreterRuntime::_new), O1, O2);
__ ba(false, done); __ ba_short(done);
__ delayed()->nop();
// Initialize the header: mark, klass // Initialize the header: mark, klass
__ bind(initialize_header); __ bind(initialize_header);
@ -3550,8 +3537,7 @@ void TemplateTable::checkcast() {
Register RspecifiedKlass = O4; Register RspecifiedKlass = O4;
// Check for casting a NULL // Check for casting a NULL
__ br_null(Otos_i, false, Assembler::pn, is_null); __ br_null_short(Otos_i, Assembler::pn, is_null);
__ delayed()->nop();
// Get value klass in RobjKlass // Get value klass in RobjKlass
__ load_klass(Otos_i, RobjKlass); // get value klass __ load_klass(Otos_i, RobjKlass); // get value klass
@ -3571,8 +3557,7 @@ void TemplateTable::checkcast() {
call_VM(RspecifiedKlass, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) ); call_VM(RspecifiedKlass, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) );
__ pop_ptr(Otos_i, G3_scratch); // restore receiver __ pop_ptr(Otos_i, G3_scratch); // restore receiver
__ br(Assembler::always, false, Assembler::pt, resolved); __ ba_short(resolved);
__ delayed()->nop();
// Extract target class from constant pool // Extract target class from constant pool
__ bind(quicked); __ bind(quicked);
@ -3591,8 +3576,7 @@ void TemplateTable::checkcast() {
__ bind(cast_ok); __ bind(cast_ok);
if (ProfileInterpreter) { if (ProfileInterpreter) {
__ ba(false, done); __ ba_short(done);
__ delayed()->nop();
} }
__ bind(is_null); __ bind(is_null);
__ profile_null_seen(G3_scratch); __ profile_null_seen(G3_scratch);
@ -3608,8 +3592,7 @@ void TemplateTable::instanceof() {
Register RspecifiedKlass = O4; Register RspecifiedKlass = O4;
// Check for casting a NULL // Check for casting a NULL
__ br_null(Otos_i, false, Assembler::pt, is_null); __ br_null_short(Otos_i, Assembler::pt, is_null);
__ delayed()->nop();
// Get value klass in RobjKlass // Get value klass in RobjKlass
__ load_klass(Otos_i, RobjKlass); // get value klass __ load_klass(Otos_i, RobjKlass); // get value klass
@ -3629,9 +3612,7 @@ void TemplateTable::instanceof() {
call_VM(RspecifiedKlass, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) ); call_VM(RspecifiedKlass, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) );
__ pop_ptr(Otos_i, G3_scratch); // restore receiver __ pop_ptr(Otos_i, G3_scratch); // restore receiver
__ br(Assembler::always, false, Assembler::pt, resolved); __ ba_short(resolved);
__ delayed()->nop();
// Extract target class from constant pool // Extract target class from constant pool
__ bind(quicked); __ bind(quicked);
@ -3649,8 +3630,7 @@ void TemplateTable::instanceof() {
__ clr( Otos_i ); __ clr( Otos_i );
if (ProfileInterpreter) { if (ProfileInterpreter) {
__ ba(false, done); __ ba_short(done);
__ delayed()->nop();
} }
__ bind(is_null); __ bind(is_null);
__ profile_null_seen(G3_scratch); __ profile_null_seen(G3_scratch);
@ -3724,7 +3704,7 @@ void TemplateTable::monitorenter() {
{ {
Label entry, loop, exit; Label entry, loop, exit;
__ add( __ top_most_monitor(), O2 ); // last one to check __ add( __ top_most_monitor(), O2 ); // last one to check
__ ba( false, entry ); __ ba( entry );
__ delayed()->mov( Lmonitors, O3 ); // first one to check __ delayed()->mov( Lmonitors, O3 ); // first one to check
@ -3757,8 +3737,7 @@ void TemplateTable::monitorenter() {
{ Label allocated; { Label allocated;
// found free slot? // found free slot?
__ br_notnull(O1, false, Assembler::pn, allocated); __ br_notnull_short(O1, Assembler::pn, allocated);
__ delayed()->nop();
__ add_monitor_to_stack( false, O2, O3 ); __ add_monitor_to_stack( false, O2, O3 );
__ mov(Lmonitors, O1); __ mov(Lmonitors, O1);
@ -3791,7 +3770,7 @@ void TemplateTable::monitorexit() {
{ Label entry, loop, found; { Label entry, loop, found;
__ add( __ top_most_monitor(), O2 ); // last one to check __ add( __ top_most_monitor(), O2 ); // last one to check
__ ba(false, entry ); __ ba(entry);
// use Lscratch to hold monitor elem to check, start with most recent monitor, // use Lscratch to hold monitor elem to check, start with most recent monitor,
// By using a local it survives the call to the C routine. // By using a local it survives the call to the C routine.
__ delayed()->mov( Lmonitors, Lscratch ); __ delayed()->mov( Lmonitors, Lscratch );

View File

@ -44,24 +44,40 @@ void VM_Version::initialize() {
PrefetchScanIntervalInBytes = prefetch_scan_interval_in_bytes(); PrefetchScanIntervalInBytes = prefetch_scan_interval_in_bytes();
PrefetchFieldsAhead = prefetch_fields_ahead(); PrefetchFieldsAhead = prefetch_fields_ahead();
assert(0 <= AllocatePrefetchInstr && AllocatePrefetchInstr <= 1, "invalid value");
if( AllocatePrefetchInstr < 0 ) AllocatePrefetchInstr = 0;
if( AllocatePrefetchInstr > 1 ) AllocatePrefetchInstr = 0;
// Allocation prefetch settings // Allocation prefetch settings
intx cache_line_size = L1_data_cache_line_size(); intx cache_line_size = prefetch_data_size();
if( cache_line_size > AllocatePrefetchStepSize ) if( cache_line_size > AllocatePrefetchStepSize )
AllocatePrefetchStepSize = cache_line_size; AllocatePrefetchStepSize = cache_line_size;
if( FLAG_IS_DEFAULT(AllocatePrefetchLines) )
AllocatePrefetchLines = 3; // Optimistic value assert(AllocatePrefetchLines > 0, "invalid value");
assert( AllocatePrefetchLines > 0, "invalid value"); if( AllocatePrefetchLines < 1 ) // set valid value in product VM
if( AllocatePrefetchLines < 1 ) // set valid value in product VM AllocatePrefetchLines = 3;
AllocatePrefetchLines = 1; // Conservative value assert(AllocateInstancePrefetchLines > 0, "invalid value");
if( AllocateInstancePrefetchLines < 1 ) // set valid value in product VM
AllocateInstancePrefetchLines = 1;
AllocatePrefetchDistance = allocate_prefetch_distance(); AllocatePrefetchDistance = allocate_prefetch_distance();
AllocatePrefetchStyle = allocate_prefetch_style(); AllocatePrefetchStyle = allocate_prefetch_style();
assert(AllocatePrefetchDistance % AllocatePrefetchStepSize == 0, "invalid value"); assert((AllocatePrefetchDistance % AllocatePrefetchStepSize) == 0 &&
(AllocatePrefetchDistance > 0), "invalid value");
if ((AllocatePrefetchDistance % AllocatePrefetchStepSize) != 0 ||
(AllocatePrefetchDistance <= 0)) {
AllocatePrefetchDistance = AllocatePrefetchStepSize;
}
if (AllocatePrefetchStyle == 3 && !has_blk_init()) {
warning("BIS instructions are not available on this CPU");
FLAG_SET_DEFAULT(AllocatePrefetchStyle, 1);
}
UseSSE = 0; // Only on x86 and x64 UseSSE = 0; // Only on x86 and x64
_supports_cx8 = has_v9(); _supports_cx8 = has_v9();
if (is_niagara()) { if (is_niagara()) {
// Indirect branch is the same cost as direct // Indirect branch is the same cost as direct
@ -94,19 +110,42 @@ void VM_Version::initialize() {
FLAG_SET_DEFAULT(InteriorEntryAlignment, 4); FLAG_SET_DEFAULT(InteriorEntryAlignment, 4);
} }
if (is_niagara_plus()) { if (is_niagara_plus()) {
if (has_blk_init() && AllocatePrefetchStyle > 0 && if (has_blk_init() && UseTLAB &&
FLAG_IS_DEFAULT(AllocatePrefetchStyle)) { FLAG_IS_DEFAULT(AllocatePrefetchInstr)) {
// Use BIS instruction for allocation prefetch. // Use BIS instruction for TLAB allocation prefetch.
FLAG_SET_DEFAULT(AllocatePrefetchStyle, 3); FLAG_SET_ERGO(intx, AllocatePrefetchInstr, 1);
if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
FLAG_SET_ERGO(intx, AllocatePrefetchStyle, 3);
}
if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) { if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
// Use smaller prefetch distance on N2 with BIS // Use smaller prefetch distance with BIS
FLAG_SET_DEFAULT(AllocatePrefetchDistance, 64); FLAG_SET_DEFAULT(AllocatePrefetchDistance, 64);
} }
} }
if (is_T4()) {
// Double number of prefetched cache lines on T4
// since L2 cache line size is smaller (32 bytes).
if (FLAG_IS_DEFAULT(AllocatePrefetchLines)) {
FLAG_SET_ERGO(intx, AllocatePrefetchLines, AllocatePrefetchLines*2);
}
if (FLAG_IS_DEFAULT(AllocateInstancePrefetchLines)) {
FLAG_SET_ERGO(intx, AllocateInstancePrefetchLines, AllocateInstancePrefetchLines*2);
}
}
if (AllocatePrefetchStyle != 3 && FLAG_IS_DEFAULT(AllocatePrefetchDistance)) { if (AllocatePrefetchStyle != 3 && FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
// Use different prefetch distance without BIS // Use different prefetch distance without BIS
FLAG_SET_DEFAULT(AllocatePrefetchDistance, 256); FLAG_SET_DEFAULT(AllocatePrefetchDistance, 256);
} }
if (AllocatePrefetchInstr == 1) {
// Need a space at the end of TLAB for BIS since it
// will fault when accessing memory outside of heap.
// +1 for rounding up to next cache line, +1 to be safe
int lines = AllocatePrefetchLines + 2;
int step_size = AllocatePrefetchStepSize;
int distance = AllocatePrefetchDistance;
_reserve_for_allocation_prefetch = (distance + step_size*lines)/(int)HeapWordSize;
}
} }
#endif #endif
} }
@ -116,27 +155,49 @@ void VM_Version::initialize() {
if (FLAG_IS_DEFAULT(UsePopCountInstruction)) { if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
FLAG_SET_DEFAULT(UsePopCountInstruction, true); FLAG_SET_DEFAULT(UsePopCountInstruction, true);
} }
} else if (UsePopCountInstruction) {
warning("POPC instruction is not available on this CPU");
FLAG_SET_DEFAULT(UsePopCountInstruction, false);
}
// T4 and newer Sparc cpus have new compare and branch instruction.
if (has_cbcond()) {
if (FLAG_IS_DEFAULT(UseCBCond)) {
FLAG_SET_DEFAULT(UseCBCond, true);
}
} else if (UseCBCond) {
warning("CBCOND instruction is not available on this CPU");
FLAG_SET_DEFAULT(UseCBCond, false);
} }
#ifdef COMPILER2 #ifdef COMPILER2
// T4 and newer Sparc cpus have fast RDPC.
if (has_fast_rdpc() && FLAG_IS_DEFAULT(UseRDPCForConstantTableBase)) {
// FLAG_SET_DEFAULT(UseRDPCForConstantTableBase, true);
}
// Currently not supported anywhere. // Currently not supported anywhere.
FLAG_SET_DEFAULT(UseFPUForSpilling, false); FLAG_SET_DEFAULT(UseFPUForSpilling, false);
assert((InteriorEntryAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size");
#endif #endif
assert((CodeEntryAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size");
assert((OptoLoopAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size");
char buf[512]; char buf[512];
jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
(has_v8() ? ", has_v8" : ""), (has_v9() ? ", v9" : (has_v8() ? ", v8" : "")),
(has_v9() ? ", has_v9" : ""),
(has_hardware_popc() ? ", popc" : ""), (has_hardware_popc() ? ", popc" : ""),
(has_vis1() ? ", has_vis1" : ""), (has_vis1() ? ", vis1" : ""),
(has_vis2() ? ", has_vis2" : ""), (has_vis2() ? ", vis2" : ""),
(has_vis3() ? ", has_vis3" : ""), (has_vis3() ? ", vis3" : ""),
(has_blk_init() ? ", has_blk_init" : ""), (has_blk_init() ? ", blk_init" : ""),
(is_ultra3() ? ", is_ultra3" : ""), (has_cbcond() ? ", cbcond" : ""),
(is_sun4v() ? ", is_sun4v" : ""), (is_ultra3() ? ", ultra3" : ""),
(is_niagara() ? ", is_niagara" : ""), (is_sun4v() ? ", sun4v" : ""),
(is_niagara_plus() ? ", is_niagara_plus" : ""), (is_niagara_plus() ? ", niagara_plus" : (is_niagara() ? ", niagara" : "")),
(is_sparc64() ? ", is_sparc64" : ""), (is_sparc64() ? ", sparc64" : ""),
(!has_hardware_mul32() ? ", no-mul32" : ""), (!has_hardware_mul32() ? ", no-mul32" : ""),
(!has_hardware_div32() ? ", no-div32" : ""), (!has_hardware_div32() ? ", no-div32" : ""),
(!has_hardware_fsmuld() ? ", no-fsmuld" : "")); (!has_hardware_fsmuld() ? ", no-fsmuld" : ""));
@ -158,14 +219,20 @@ void VM_Version::initialize() {
#ifndef PRODUCT #ifndef PRODUCT
if (PrintMiscellaneous && Verbose) { if (PrintMiscellaneous && Verbose) {
tty->print("Allocation: "); tty->print("Allocation");
if (AllocatePrefetchStyle <= 0) { if (AllocatePrefetchStyle <= 0) {
tty->print_cr("no prefetching"); tty->print_cr(": no prefetching");
} else { } else {
tty->print(" prefetching: ");
if (AllocatePrefetchInstr == 0) {
tty->print("PREFETCH");
} else if (AllocatePrefetchInstr == 1) {
tty->print("BIS");
}
if (AllocatePrefetchLines > 1) { if (AllocatePrefetchLines > 1) {
tty->print_cr("PREFETCH %d, %d lines of size %d bytes", AllocatePrefetchDistance, AllocatePrefetchLines, AllocatePrefetchStepSize); tty->print_cr(" at distance %d, %d lines of %d bytes", AllocatePrefetchDistance, AllocatePrefetchLines, AllocatePrefetchStepSize);
} else { } else {
tty->print_cr("PREFETCH %d, one line", AllocatePrefetchDistance); tty->print_cr(" at distance %d, one line of %d bytes", AllocatePrefetchDistance, AllocatePrefetchStepSize);
} }
} }
if (PrefetchCopyIntervalInBytes > 0) { if (PrefetchCopyIntervalInBytes > 0) {

View File

@ -31,44 +31,46 @@
class VM_Version: public Abstract_VM_Version { class VM_Version: public Abstract_VM_Version {
protected: protected:
enum Feature_Flag { enum Feature_Flag {
v8_instructions = 0, v8_instructions = 0,
hardware_mul32 = 1, hardware_mul32 = 1,
hardware_div32 = 2, hardware_div32 = 2,
hardware_fsmuld = 3, hardware_fsmuld = 3,
hardware_popc = 4, hardware_popc = 4,
v9_instructions = 5, v9_instructions = 5,
vis1_instructions = 6, vis1_instructions = 6,
vis2_instructions = 7, vis2_instructions = 7,
sun4v_instructions = 8, sun4v_instructions = 8,
blk_init_instructions = 9, blk_init_instructions = 9,
fmaf_instructions = 10, fmaf_instructions = 10,
fmau_instructions = 11, fmau_instructions = 11,
vis3_instructions = 12, vis3_instructions = 12,
sparc64_family = 13, sparc64_family = 13,
T_family = 14, T_family = 14,
T1_model = 15 T1_model = 15,
cbcond_instructions = 16
}; };
enum Feature_Flag_Set { enum Feature_Flag_Set {
unknown_m = 0, unknown_m = 0,
all_features_m = -1, all_features_m = -1,
v8_instructions_m = 1 << v8_instructions, v8_instructions_m = 1 << v8_instructions,
hardware_mul32_m = 1 << hardware_mul32, hardware_mul32_m = 1 << hardware_mul32,
hardware_div32_m = 1 << hardware_div32, hardware_div32_m = 1 << hardware_div32,
hardware_fsmuld_m = 1 << hardware_fsmuld, hardware_fsmuld_m = 1 << hardware_fsmuld,
hardware_popc_m = 1 << hardware_popc, hardware_popc_m = 1 << hardware_popc,
v9_instructions_m = 1 << v9_instructions, v9_instructions_m = 1 << v9_instructions,
vis1_instructions_m = 1 << vis1_instructions, vis1_instructions_m = 1 << vis1_instructions,
vis2_instructions_m = 1 << vis2_instructions, vis2_instructions_m = 1 << vis2_instructions,
sun4v_m = 1 << sun4v_instructions, sun4v_m = 1 << sun4v_instructions,
blk_init_instructions_m = 1 << blk_init_instructions, blk_init_instructions_m = 1 << blk_init_instructions,
fmaf_instructions_m = 1 << fmaf_instructions, fmaf_instructions_m = 1 << fmaf_instructions,
fmau_instructions_m = 1 << fmau_instructions, fmau_instructions_m = 1 << fmau_instructions,
vis3_instructions_m = 1 << vis3_instructions, vis3_instructions_m = 1 << vis3_instructions,
sparc64_family_m = 1 << sparc64_family, sparc64_family_m = 1 << sparc64_family,
T_family_m = 1 << T_family, T_family_m = 1 << T_family,
T1_model_m = 1 << T1_model, T1_model_m = 1 << T1_model,
cbcond_instructions_m = 1 << cbcond_instructions,
generic_v8_m = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m, generic_v8_m = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m,
generic_v9_m = generic_v8_m | v9_instructions_m, generic_v9_m = generic_v8_m | v9_instructions_m,
@ -111,25 +113,35 @@ public:
static bool has_vis2() { return (_features & vis2_instructions_m) != 0; } static bool has_vis2() { return (_features & vis2_instructions_m) != 0; }
static bool has_vis3() { return (_features & vis3_instructions_m) != 0; } static bool has_vis3() { return (_features & vis3_instructions_m) != 0; }
static bool has_blk_init() { return (_features & blk_init_instructions_m) != 0; } static bool has_blk_init() { return (_features & blk_init_instructions_m) != 0; }
static bool has_cbcond() { return (_features & cbcond_instructions_m) != 0; }
static bool supports_compare_and_exchange() static bool supports_compare_and_exchange()
{ return has_v9(); } { return has_v9(); }
static bool is_ultra3() { return (_features & ultra3_m) == ultra3_m; }
static bool is_sun4v() { return (_features & sun4v_m) != 0; }
// Returns true if the platform is in the niagara line (T series) // Returns true if the platform is in the niagara line (T series)
// and newer than the niagara1. // and newer than the niagara1.
static bool is_niagara_plus() { return is_T_family(_features) && !is_T1_model(_features); } static bool is_niagara_plus() { return is_T_family(_features) && !is_T1_model(_features); }
static bool is_T4() { return is_T_family(_features) && has_cbcond(); }
// Fujitsu SPARC64 // Fujitsu SPARC64
static bool is_sparc64() { return (_features & sparc64_family_m) != 0; } static bool is_sparc64() { return (_features & sparc64_family_m) != 0; }
static bool is_sun4v() { return (_features & sun4v_m) != 0; }
static bool is_ultra3() { return (_features & ultra3_m) == ultra3_m && !is_sun4v() && !is_sparc64(); }
static bool has_fast_fxtof() { return is_niagara() || is_sparc64() || has_v9() && !is_ultra3(); } static bool has_fast_fxtof() { return is_niagara() || is_sparc64() || has_v9() && !is_ultra3(); }
static bool has_fast_idiv() { return is_niagara_plus() || is_sparc64(); } static bool has_fast_idiv() { return is_niagara_plus() || is_sparc64(); }
// T4 and newer Sparc have fast RDPC instruction.
static bool has_fast_rdpc() { return is_T4(); }
// T4 and newer Sparc have Most-Recently-Used (MRU) BIS.
static bool has_mru_blk_init() { return has_blk_init() && is_T4(); }
static const char* cpu_features() { return _features_str; } static const char* cpu_features() { return _features_str; }
static intx L1_data_cache_line_size() { static intx prefetch_data_size() {
return 64; // default prefetch block size on sparc return is_T4() ? 32 : 64; // default prefetch block size on sparc
} }
// Prefetch // Prefetch

View File

@ -76,9 +76,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
Label L; Label L;
// check offset vs vtable length // check offset vs vtable length
__ ld(G3_scratch, instanceKlass::vtable_length_offset()*wordSize, G5); __ ld(G3_scratch, instanceKlass::vtable_length_offset()*wordSize, G5);
__ cmp(G5, vtable_index*vtableEntry::size()); __ cmp_and_br_short(G5, vtable_index*vtableEntry::size(), Assembler::greaterUnsigned, Assembler::pt, L);
__ br(Assembler::greaterUnsigned, false, Assembler::pt, L);
__ delayed()->nop();
__ set(vtable_index, O2); __ set(vtable_index, O2);
__ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), O0, O2); __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), O0, O2);
__ bind(L); __ bind(L);
@ -95,8 +93,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
#ifndef PRODUCT #ifndef PRODUCT
if (DebugVtables) { if (DebugVtables) {
Label L; Label L;
__ br_notnull(G5_method, false, Assembler::pt, L); __ br_notnull_short(G5_method, Assembler::pt, L);
__ delayed()->nop();
__ stop("Vtable entry is ZERO"); __ stop("Vtable entry is ZERO");
__ bind(L); __ bind(L);
} }
@ -177,8 +174,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
#ifndef PRODUCT #ifndef PRODUCT
if (DebugVtables) { if (DebugVtables) {
Label L01; Label L01;
__ bpr(Assembler::rc_nz, false, Assembler::pt, L5_method, L01); __ br_notnull_short(L5_method, Assembler::pt, L01);
__ delayed()->nop();
__ stop("methodOop is null"); __ stop("methodOop is null");
__ bind(L01); __ bind(L01);
__ verify_oop(L5_method); __ verify_oop(L5_method);

View File

@ -1339,9 +1339,8 @@ void Assembler::incl(Address dst) {
emit_operand(rax, dst); emit_operand(rax, dst);
} }
void Assembler::jcc(Condition cc, Label& L, relocInfo::relocType rtype) { void Assembler::jcc(Condition cc, Label& L, bool maybe_short) {
InstructionMark im(this); InstructionMark im(this);
relocate(rtype);
assert((0 <= cc) && (cc < 16), "illegal cc"); assert((0 <= cc) && (cc < 16), "illegal cc");
if (L.is_bound()) { if (L.is_bound()) {
address dst = target(L); address dst = target(L);
@ -1350,7 +1349,7 @@ void Assembler::jcc(Condition cc, Label& L, relocInfo::relocType rtype) {
const int short_size = 2; const int short_size = 2;
const int long_size = 6; const int long_size = 6;
intptr_t offs = (intptr_t)dst - (intptr_t)_code_pos; intptr_t offs = (intptr_t)dst - (intptr_t)_code_pos;
if (rtype == relocInfo::none && is8bit(offs - short_size)) { if (maybe_short && is8bit(offs - short_size)) {
// 0111 tttn #8-bit disp // 0111 tttn #8-bit disp
emit_byte(0x70 | cc); emit_byte(0x70 | cc);
emit_byte((offs - short_size) & 0xFF); emit_byte((offs - short_size) & 0xFF);
@ -1399,7 +1398,7 @@ void Assembler::jmp(Address adr) {
emit_operand(rsp, adr); emit_operand(rsp, adr);
} }
void Assembler::jmp(Label& L, relocInfo::relocType rtype) { void Assembler::jmp(Label& L, bool maybe_short) {
if (L.is_bound()) { if (L.is_bound()) {
address entry = target(L); address entry = target(L);
assert(entry != NULL, "jmp most probably wrong"); assert(entry != NULL, "jmp most probably wrong");
@ -1407,7 +1406,7 @@ void Assembler::jmp(Label& L, relocInfo::relocType rtype) {
const int short_size = 2; const int short_size = 2;
const int long_size = 5; const int long_size = 5;
intptr_t offs = entry - _code_pos; intptr_t offs = entry - _code_pos;
if (rtype == relocInfo::none && is8bit(offs - short_size)) { if (maybe_short && is8bit(offs - short_size)) {
emit_byte(0xEB); emit_byte(0xEB);
emit_byte((offs - short_size) & 0xFF); emit_byte((offs - short_size) & 0xFF);
} else { } else {
@ -1420,7 +1419,6 @@ void Assembler::jmp(Label& L, relocInfo::relocType rtype) {
// the forward jump will not run beyond 256 bytes, use jmpb to // the forward jump will not run beyond 256 bytes, use jmpb to
// force an 8-bit displacement. // force an 8-bit displacement.
InstructionMark im(this); InstructionMark im(this);
relocate(rtype);
L.add_patch_at(code(), locator()); L.add_patch_at(code(), locator());
emit_byte(0xE9); emit_byte(0xE9);
emit_long(0); emit_long(0);
@ -2309,7 +2307,7 @@ void Assembler::prefetch_prefix(Address src) {
} }
void Assembler::prefetchnta(Address src) { void Assembler::prefetchnta(Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), "must support")); NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
InstructionMark im(this); InstructionMark im(this);
prefetch_prefix(src); prefetch_prefix(src);
emit_byte(0x18); emit_byte(0x18);
@ -2317,7 +2315,7 @@ void Assembler::prefetchnta(Address src) {
} }
void Assembler::prefetchr(Address src) { void Assembler::prefetchr(Address src) {
NOT_LP64(assert(VM_Version::supports_3dnow_prefetch(), "must support")); assert(VM_Version::supports_3dnow_prefetch(), "must support");
InstructionMark im(this); InstructionMark im(this);
prefetch_prefix(src); prefetch_prefix(src);
emit_byte(0x0D); emit_byte(0x0D);
@ -2349,7 +2347,7 @@ void Assembler::prefetcht2(Address src) {
} }
void Assembler::prefetchw(Address src) { void Assembler::prefetchw(Address src) {
NOT_LP64(assert(VM_Version::supports_3dnow_prefetch(), "must support")); assert(VM_Version::supports_3dnow_prefetch(), "must support");
InstructionMark im(this); InstructionMark im(this);
prefetch_prefix(src); prefetch_prefix(src);
emit_byte(0x0D); emit_byte(0x0D);
@ -3674,7 +3672,7 @@ void Assembler::prefix(Address adr, Register reg, bool byteinst) {
} else { } else {
if (adr.index_needs_rex()) { if (adr.index_needs_rex()) {
prefix(REX_X); prefix(REX_X);
} else if (reg->encoding() >= 4 ) { } else if (byteinst && reg->encoding() >= 4 ) {
prefix(REX); prefix(REX);
} }
} }

View File

@ -1065,8 +1065,7 @@ private:
// Note: The same Label can be used for forward and backward branches // Note: The same Label can be used for forward and backward branches
// but it may be bound only once. // but it may be bound only once.
void jcc(Condition cc, Label& L, void jcc(Condition cc, Label& L, bool maybe_short = true);
relocInfo::relocType rtype = relocInfo::none);
// Conditional jump to a 8-bit offset to L. // Conditional jump to a 8-bit offset to L.
// WARNING: be very careful using this for forward jumps. If the label is // WARNING: be very careful using this for forward jumps. If the label is
@ -1077,7 +1076,7 @@ private:
void jmp(Address entry); // pc <- entry void jmp(Address entry); // pc <- entry
// Label operations & relative jumps (PPUM Appendix D) // Label operations & relative jumps (PPUM Appendix D)
void jmp(Label& L, relocInfo::relocType rtype = relocInfo::none); // unconditional jump to L void jmp(Label& L, bool maybe_short = true); // unconditional jump to L
void jmp(Register entry); // pc <- entry void jmp(Register entry); // pc <- entry

View File

@ -233,7 +233,7 @@ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register reg, int bcp_off
void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Register index, void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Register index,
int bcp_offset, size_t index_size) { int bcp_offset, size_t index_size) {
assert(cache != index, "must use different registers"); assert_different_registers(cache, index);
get_cache_index_at_bcp(index, bcp_offset, index_size); get_cache_index_at_bcp(index, bcp_offset, index_size);
movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below");
@ -241,6 +241,20 @@ void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Regis
} }
void InterpreterMacroAssembler::get_cache_and_index_and_bytecode_at_bcp(Register cache,
Register index,
Register bytecode,
int byte_no,
int bcp_offset,
size_t index_size) {
get_cache_and_index_at_bcp(cache, index, bcp_offset, index_size);
movptr(bytecode, Address(cache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset()));
const int shift_count = (1 + byte_no) * BitsPerByte;
shrptr(bytecode, shift_count);
andptr(bytecode, 0xFF);
}
void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, Register tmp, void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, Register tmp,
int bcp_offset, size_t index_size) { int bcp_offset, size_t index_size) {
assert(cache != tmp, "must use different register"); assert(cache != tmp, "must use different register");

View File

@ -83,6 +83,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
} }
void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset); 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, size_t index_size = sizeof(u2)); void get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2)); void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2)); void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2));

View File

@ -233,7 +233,7 @@ void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
Register index, Register index,
int bcp_offset, int bcp_offset,
size_t index_size) { size_t index_size) {
assert(cache != index, "must use different registers"); assert_different_registers(cache, index);
get_cache_index_at_bcp(index, bcp_offset, index_size); get_cache_index_at_bcp(index, bcp_offset, index_size);
movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below"); assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
@ -242,6 +242,22 @@ void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
} }
void InterpreterMacroAssembler::get_cache_and_index_and_bytecode_at_bcp(Register cache,
Register index,
Register bytecode,
int byte_no,
int bcp_offset,
size_t index_size) {
get_cache_and_index_at_bcp(cache, index, bcp_offset, index_size);
// We use a 32-bit load here since the layout of 64-bit words on
// little-endian machines allow us that.
movl(bytecode, Address(cache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset()));
const int shift_count = (1 + byte_no) * BitsPerByte;
shrl(bytecode, shift_count);
andl(bytecode, 0xFF);
}
void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
Register tmp, Register tmp,
int bcp_offset, int bcp_offset,

View File

@ -100,13 +100,11 @@ class InterpreterMacroAssembler: public MacroAssembler {
} }
void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset); void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset);
void get_cache_and_index_at_bcp(Register cache, Register index, void get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset, size_t index_size = sizeof(u2));
int bcp_offset, size_t index_size = sizeof(u2)); void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2)); void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2));
void pop_ptr(Register r = rax); void pop_ptr(Register r = rax);
void pop_i(Register r = rax); void pop_i(Register r = rax);
void pop_l(Register r = rax); void pop_l(Register r = rax);

View File

@ -1192,11 +1192,11 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
const int jobject_oop_offset = 0; const int jobject_oop_offset = 0;
__ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject
__ movptr(rsi, rsp); __ movptr(saved_last_sp, rsp);
__ subptr(rsp, 3 * wordSize); __ subptr(rsp, 3 * wordSize);
__ push(rax_pc); // restore caller PC __ push(rax_pc); // restore caller PC
__ movptr(__ argument_address(constant(2)), rarg0_code); __ movl (__ argument_address(constant(2)), rarg0_code);
__ movptr(__ argument_address(constant(1)), rarg1_actual); __ movptr(__ argument_address(constant(1)), rarg1_actual);
__ movptr(__ argument_address(constant(0)), rarg2_required); __ movptr(__ argument_address(constant(0)), rarg2_required);
jump_from_method_handle(_masm, rbx_method, rax); jump_from_method_handle(_masm, rbx_method, rax);

View File

@ -202,45 +202,74 @@ Address TemplateTable::at_bcp(int offset) {
} }
void TemplateTable::patch_bytecode(Bytecodes::Code bytecode, Register bc, void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
Register scratch, Register temp_reg, bool load_bc_into_bc_reg/*=true*/,
bool load_bc_into_scratch/*=true*/) { int byte_no) {
if (!RewriteBytecodes) return;
Label L_patch_done;
if (!RewriteBytecodes) return; switch (bc) {
// the pair bytecodes have already done the load. case Bytecodes::_fast_aputfield:
if (load_bc_into_scratch) { case Bytecodes::_fast_bputfield:
__ movl(bc, bytecode); case Bytecodes::_fast_cputfield:
case Bytecodes::_fast_dputfield:
case Bytecodes::_fast_fputfield:
case Bytecodes::_fast_iputfield:
case Bytecodes::_fast_lputfield:
case Bytecodes::_fast_sputfield:
{
// We skip bytecode quickening for putfield instructions when
// the put_code written to the constant pool cache is zero.
// This is required so that every execution of this instruction
// calls out to InterpreterRuntime::resolve_get_put to do
// additional, required work.
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
assert(load_bc_into_bc_reg, "we use bc_reg as temp");
__ get_cache_and_index_and_bytecode_at_bcp(bc_reg, temp_reg, temp_reg, byte_no, 1);
__ movl(bc_reg, bc);
__ cmpl(temp_reg, (int) 0);
__ jcc(Assembler::zero, L_patch_done); // don't patch
}
break;
default:
assert(byte_no == -1, "sanity");
// the pair bytecodes have already done the load.
if (load_bc_into_bc_reg) {
__ movl(bc_reg, bc);
}
} }
Label patch_done;
if (JvmtiExport::can_post_breakpoint()) { if (JvmtiExport::can_post_breakpoint()) {
Label fast_patch; Label L_fast_patch;
// if a breakpoint is present we can't rewrite the stream directly // if a breakpoint is present we can't rewrite the stream directly
__ movzbl(scratch, at_bcp(0)); __ movzbl(temp_reg, at_bcp(0));
__ cmpl(scratch, Bytecodes::_breakpoint); __ cmpl(temp_reg, Bytecodes::_breakpoint);
__ jcc(Assembler::notEqual, fast_patch); __ jcc(Assembler::notEqual, L_fast_patch);
__ get_method(scratch); __ get_method(temp_reg);
// Let breakpoint table handling rewrite to quicker bytecode // Let breakpoint table handling rewrite to quicker bytecode
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, rsi, bc); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), temp_reg, rsi, bc_reg);
#ifndef ASSERT #ifndef ASSERT
__ jmpb(patch_done); __ jmpb(L_patch_done);
#else #else
__ jmp(patch_done); __ jmp(L_patch_done);
#endif #endif
__ bind(fast_patch); __ bind(L_fast_patch);
} }
#ifdef ASSERT #ifdef ASSERT
Label okay; Label L_okay;
__ load_unsigned_byte(scratch, at_bcp(0)); __ load_unsigned_byte(temp_reg, at_bcp(0));
__ cmpl(scratch, (int)Bytecodes::java_code(bytecode)); __ cmpl(temp_reg, (int)Bytecodes::java_code(bc));
__ jccb(Assembler::equal, okay); __ jccb(Assembler::equal, L_okay);
__ cmpl(scratch, bc); __ cmpl(temp_reg, bc_reg);
__ jcc(Assembler::equal, okay); __ jcc(Assembler::equal, L_okay);
__ stop("patching the wrong bytecode"); __ stop("patching the wrong bytecode");
__ bind(okay); __ bind(L_okay);
#endif #endif
// patch bytecode // patch bytecode
__ movb(at_bcp(0), bc); __ movb(at_bcp(0), bc_reg);
__ bind(patch_done); __ bind(L_patch_done);
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
@ -2060,24 +2089,20 @@ void TemplateTable::resolve_cache_and_index(int byte_no,
assert_different_registers(result, Rcache, index, temp); assert_different_registers(result, Rcache, index, temp);
Label resolved; Label resolved;
__ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
if (byte_no == f1_oop) { if (byte_no == f1_oop) {
// We are resolved if the f1 field contains a non-null object (CallSite, etc.) // We are resolved if the f1 field contains a non-null object (CallSite, etc.)
// This kind of CP cache entry does not need to match the flags byte, because // This kind of CP cache entry does not need to match the flags byte, because
// there is a 1-1 relation between bytecode type and CP entry type. // there is a 1-1 relation between bytecode type and CP entry type.
assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD) assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD)
__ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
__ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset())); __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()));
__ testptr(result, result); __ testptr(result, result);
__ jcc(Assembler::notEqual, resolved); __ jcc(Assembler::notEqual, resolved);
} else { } else {
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
assert(result == noreg, ""); //else change code for setting result assert(result == noreg, ""); //else change code for setting result
const int shift_count = (1 + byte_no)*BitsPerByte; __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size);
__ movl(temp, Address(Rcache, index, Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); __ cmpl(temp, (int) bytecode()); // have we resolved this bytecode?
__ shrl(temp, shift_count);
// have we resolved this bytecode?
__ andl(temp, 0xFF);
__ cmpl(temp, (int)bytecode());
__ jcc(Assembler::equal, resolved); __ jcc(Assembler::equal, resolved);
} }
@ -2453,138 +2478,153 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
__ shrl(flags, ConstantPoolCacheEntry::tosBits); __ shrl(flags, ConstantPoolCacheEntry::tosBits);
assert(btos == 0, "change code, btos != 0"); assert(btos == 0, "change code, btos != 0");
// btos
__ andl(flags, 0x0f); __ andl(flags, 0x0f);
__ jcc(Assembler::notZero, notByte); __ jcc(Assembler::notZero, notByte);
__ pop(btos); // btos
if (!is_static) pop_and_check_object(obj); {
__ movb(lo, rax ); __ pop(btos);
if (!is_static) { if (!is_static) pop_and_check_object(obj);
patch_bytecode(Bytecodes::_fast_bputfield, rcx, rbx); __ movb(lo, rax);
if (!is_static) {
patch_bytecode(Bytecodes::_fast_bputfield, rcx, rbx, true, byte_no);
}
__ jmp(Done);
} }
__ jmp(Done);
__ bind(notByte); __ bind(notByte);
// itos __ cmpl(flags, itos);
__ cmpl(flags, itos );
__ jcc(Assembler::notEqual, notInt); __ jcc(Assembler::notEqual, notInt);
__ pop(itos); // itos
if (!is_static) pop_and_check_object(obj); {
__ pop(itos);
__ movl(lo, rax ); if (!is_static) pop_and_check_object(obj);
if (!is_static) { __ movl(lo, rax);
patch_bytecode(Bytecodes::_fast_iputfield, rcx, rbx); if (!is_static) {
patch_bytecode(Bytecodes::_fast_iputfield, rcx, rbx, true, byte_no);
}
__ jmp(Done);
} }
__ jmp(Done);
__ bind(notInt); __ bind(notInt);
// atos __ cmpl(flags, atos);
__ cmpl(flags, atos );
__ jcc(Assembler::notEqual, notObj); __ jcc(Assembler::notEqual, notObj);
__ pop(atos); // atos
if (!is_static) pop_and_check_object(obj); {
__ pop(atos);
do_oop_store(_masm, lo, rax, _bs->kind(), false); if (!is_static) pop_and_check_object(obj);
do_oop_store(_masm, lo, rax, _bs->kind(), false);
if (!is_static) { if (!is_static) {
patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx); patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx, true, byte_no);
}
__ jmp(Done);
} }
__ jmp(Done);
__ bind(notObj); __ bind(notObj);
// ctos __ cmpl(flags, ctos);
__ cmpl(flags, ctos );
__ jcc(Assembler::notEqual, notChar); __ jcc(Assembler::notEqual, notChar);
__ pop(ctos); // ctos
if (!is_static) pop_and_check_object(obj); {
__ movw(lo, rax ); __ pop(ctos);
if (!is_static) { if (!is_static) pop_and_check_object(obj);
patch_bytecode(Bytecodes::_fast_cputfield, rcx, rbx); __ movw(lo, rax);
if (!is_static) {
patch_bytecode(Bytecodes::_fast_cputfield, rcx, rbx, true, byte_no);
}
__ jmp(Done);
} }
__ jmp(Done);
__ bind(notChar); __ bind(notChar);
// stos __ cmpl(flags, stos);
__ cmpl(flags, stos );
__ jcc(Assembler::notEqual, notShort); __ jcc(Assembler::notEqual, notShort);
__ pop(stos); // stos
if (!is_static) pop_and_check_object(obj); {
__ movw(lo, rax ); __ pop(stos);
if (!is_static) { if (!is_static) pop_and_check_object(obj);
patch_bytecode(Bytecodes::_fast_sputfield, rcx, rbx); __ movw(lo, rax);
if (!is_static) {
patch_bytecode(Bytecodes::_fast_sputfield, rcx, rbx, true, byte_no);
}
__ jmp(Done);
} }
__ jmp(Done);
__ bind(notShort); __ bind(notShort);
// ltos __ cmpl(flags, ltos);
__ cmpl(flags, ltos );
__ jcc(Assembler::notEqual, notLong); __ jcc(Assembler::notEqual, notLong);
Label notVolatileLong; // ltos
__ testl(rdx, rdx); {
__ jcc(Assembler::zero, notVolatileLong); Label notVolatileLong;
__ testl(rdx, rdx);
__ jcc(Assembler::zero, notVolatileLong);
__ pop(ltos); // overwrites rdx, do this after testing volatile. __ pop(ltos); // overwrites rdx, do this after testing volatile.
if (!is_static) pop_and_check_object(obj); if (!is_static) pop_and_check_object(obj);
// Replace with real volatile test // Replace with real volatile test
__ push(rdx); __ push(rdx);
__ push(rax); // Must update atomically with FIST __ push(rax); // Must update atomically with FIST
__ fild_d(Address(rsp,0)); // So load into FPU register __ fild_d(Address(rsp,0)); // So load into FPU register
__ fistp_d(lo); // and put into memory atomically __ fistp_d(lo); // and put into memory atomically
__ addptr(rsp, 2*wordSize); __ addptr(rsp, 2*wordSize);
// volatile_barrier(); // volatile_barrier();
volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
Assembler::StoreStore)); Assembler::StoreStore));
// Don't rewrite volatile version // Don't rewrite volatile version
__ jmp(notVolatile); __ jmp(notVolatile);
__ bind(notVolatileLong); __ bind(notVolatileLong);
__ pop(ltos); // overwrites rdx __ pop(ltos); // overwrites rdx
if (!is_static) pop_and_check_object(obj); if (!is_static) pop_and_check_object(obj);
NOT_LP64(__ movptr(hi, rdx)); NOT_LP64(__ movptr(hi, rdx));
__ movptr(lo, rax); __ movptr(lo, rax);
if (!is_static) { if (!is_static) {
patch_bytecode(Bytecodes::_fast_lputfield, rcx, rbx); patch_bytecode(Bytecodes::_fast_lputfield, rcx, rbx, true, byte_no);
}
__ jmp(notVolatile);
} }
__ jmp(notVolatile);
__ bind(notLong); __ bind(notLong);
// ftos __ cmpl(flags, ftos);
__ cmpl(flags, ftos );
__ jcc(Assembler::notEqual, notFloat); __ jcc(Assembler::notEqual, notFloat);
__ pop(ftos); // ftos
if (!is_static) pop_and_check_object(obj); {
__ fstp_s(lo); __ pop(ftos);
if (!is_static) { if (!is_static) pop_and_check_object(obj);
patch_bytecode(Bytecodes::_fast_fputfield, rcx, rbx); __ fstp_s(lo);
if (!is_static) {
patch_bytecode(Bytecodes::_fast_fputfield, rcx, rbx, true, byte_no);
}
__ jmp(Done);
} }
__ jmp(Done);
__ bind(notFloat); __ bind(notFloat);
// dtos #ifdef ASSERT
__ cmpl(flags, dtos ); __ cmpl(flags, dtos);
__ jcc(Assembler::notEqual, notDouble); __ jcc(Assembler::notEqual, notDouble);
#endif
__ pop(dtos); // dtos
if (!is_static) pop_and_check_object(obj); {
__ fstp_d(lo); __ pop(dtos);
if (!is_static) { if (!is_static) pop_and_check_object(obj);
patch_bytecode(Bytecodes::_fast_dputfield, rcx, rbx); __ fstp_d(lo);
if (!is_static) {
patch_bytecode(Bytecodes::_fast_dputfield, rcx, rbx, true, byte_no);
}
__ jmp(Done);
} }
__ jmp(Done);
#ifdef ASSERT
__ bind(notDouble); __ bind(notDouble);
__ stop("Bad state"); __ stop("Bad state");
#endif
__ bind(Done); __ bind(Done);

View File

@ -203,46 +203,74 @@ Address TemplateTable::at_bcp(int offset) {
return Address(r13, offset); return Address(r13, offset);
} }
void TemplateTable::patch_bytecode(Bytecodes::Code bytecode, Register bc, void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
Register scratch, Register temp_reg, bool load_bc_into_bc_reg/*=true*/,
bool load_bc_into_scratch/*=true*/) { int byte_no) {
if (!RewriteBytecodes) { if (!RewriteBytecodes) return;
return; Label L_patch_done;
switch (bc) {
case Bytecodes::_fast_aputfield:
case Bytecodes::_fast_bputfield:
case Bytecodes::_fast_cputfield:
case Bytecodes::_fast_dputfield:
case Bytecodes::_fast_fputfield:
case Bytecodes::_fast_iputfield:
case Bytecodes::_fast_lputfield:
case Bytecodes::_fast_sputfield:
{
// We skip bytecode quickening for putfield instructions when
// the put_code written to the constant pool cache is zero.
// This is required so that every execution of this instruction
// calls out to InterpreterRuntime::resolve_get_put to do
// additional, required work.
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
assert(load_bc_into_bc_reg, "we use bc_reg as temp");
__ get_cache_and_index_and_bytecode_at_bcp(temp_reg, bc_reg, temp_reg, byte_no, 1);
__ movl(bc_reg, bc);
__ cmpl(temp_reg, (int) 0);
__ jcc(Assembler::zero, L_patch_done); // don't patch
}
break;
default:
assert(byte_no == -1, "sanity");
// the pair bytecodes have already done the load.
if (load_bc_into_bc_reg) {
__ movl(bc_reg, bc);
}
} }
// the pair bytecodes have already done the load.
if (load_bc_into_scratch) {
__ movl(bc, bytecode);
}
Label patch_done;
if (JvmtiExport::can_post_breakpoint()) { if (JvmtiExport::can_post_breakpoint()) {
Label fast_patch; Label L_fast_patch;
// if a breakpoint is present we can't rewrite the stream directly // if a breakpoint is present we can't rewrite the stream directly
__ movzbl(scratch, at_bcp(0)); __ movzbl(temp_reg, at_bcp(0));
__ cmpl(scratch, Bytecodes::_breakpoint); __ cmpl(temp_reg, Bytecodes::_breakpoint);
__ jcc(Assembler::notEqual, fast_patch); __ jcc(Assembler::notEqual, L_fast_patch);
__ get_method(scratch); __ get_method(temp_reg);
// Let breakpoint table handling rewrite to quicker bytecode // 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), temp_reg, r13, bc_reg);
#ifndef ASSERT #ifndef ASSERT
__ jmpb(patch_done); __ jmpb(L_patch_done);
#else #else
__ jmp(patch_done); __ jmp(L_patch_done);
#endif #endif
__ bind(fast_patch); __ bind(L_fast_patch);
} }
#ifdef ASSERT #ifdef ASSERT
Label okay; Label L_okay;
__ load_unsigned_byte(scratch, at_bcp(0)); __ load_unsigned_byte(temp_reg, at_bcp(0));
__ cmpl(scratch, (int) Bytecodes::java_code(bytecode)); __ cmpl(temp_reg, (int) Bytecodes::java_code(bc));
__ jcc(Assembler::equal, okay); __ jcc(Assembler::equal, L_okay);
__ cmpl(scratch, bc); __ cmpl(temp_reg, bc_reg);
__ jcc(Assembler::equal, okay); __ jcc(Assembler::equal, L_okay);
__ stop("patching the wrong bytecode"); __ stop("patching the wrong bytecode");
__ bind(okay); __ bind(L_okay);
#endif #endif
// patch bytecode // patch bytecode
__ movb(at_bcp(0), bc); __ movb(at_bcp(0), bc_reg);
__ bind(patch_done); __ bind(L_patch_done);
} }
@ -2098,24 +2126,20 @@ void TemplateTable::resolve_cache_and_index(int byte_no,
assert_different_registers(result, Rcache, index, temp); assert_different_registers(result, Rcache, index, temp);
Label resolved; Label resolved;
__ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
if (byte_no == f1_oop) { if (byte_no == f1_oop) {
// We are resolved if the f1 field contains a non-null object (CallSite, etc.) // We are resolved if the f1 field contains a non-null object (CallSite, etc.)
// This kind of CP cache entry does not need to match the flags byte, because // This kind of CP cache entry does not need to match the flags byte, because
// there is a 1-1 relation between bytecode type and CP entry type. // there is a 1-1 relation between bytecode type and CP entry type.
assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD) assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD)
__ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
__ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset())); __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()));
__ testptr(result, result); __ testptr(result, result);
__ jcc(Assembler::notEqual, resolved); __ jcc(Assembler::notEqual, resolved);
} else { } else {
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
assert(result == noreg, ""); //else change code for setting result assert(result == noreg, ""); //else change code for setting result
const int shift_count = (1 + byte_no) * BitsPerByte; __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size);
__ movl(temp, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); __ cmpl(temp, (int) bytecode()); // have we resolved this bytecode?
__ shrl(temp, shift_count);
// have we resolved this bytecode?
__ andl(temp, 0xFF);
__ cmpl(temp, (int) bytecode());
__ jcc(Assembler::equal, resolved); __ jcc(Assembler::equal, resolved);
} }
@ -2507,101 +2531,123 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
assert(btos == 0, "change code, btos != 0"); assert(btos == 0, "change code, btos != 0");
__ andl(flags, 0x0f); __ andl(flags, 0x0f);
__ jcc(Assembler::notZero, notByte); __ jcc(Assembler::notZero, notByte);
// btos // btos
__ pop(btos); {
if (!is_static) pop_and_check_object(obj); __ pop(btos);
__ movb(field, rax); if (!is_static) pop_and_check_object(obj);
if (!is_static) { __ movb(field, rax);
patch_bytecode(Bytecodes::_fast_bputfield, bc, rbx); if (!is_static) {
patch_bytecode(Bytecodes::_fast_bputfield, bc, rbx, true, byte_no);
}
__ jmp(Done);
} }
__ jmp(Done);
__ bind(notByte); __ bind(notByte);
__ cmpl(flags, atos); __ cmpl(flags, atos);
__ jcc(Assembler::notEqual, notObj); __ jcc(Assembler::notEqual, notObj);
// atos // atos
__ pop(atos); {
if (!is_static) pop_and_check_object(obj); __ pop(atos);
if (!is_static) pop_and_check_object(obj);
// Store into the field // Store into the field
do_oop_store(_masm, field, rax, _bs->kind(), false); do_oop_store(_masm, field, rax, _bs->kind(), false);
if (!is_static) {
if (!is_static) { patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx, true, byte_no);
patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx); }
__ jmp(Done);
} }
__ jmp(Done);
__ bind(notObj); __ bind(notObj);
__ cmpl(flags, itos); __ cmpl(flags, itos);
__ jcc(Assembler::notEqual, notInt); __ jcc(Assembler::notEqual, notInt);
// itos // itos
__ pop(itos); {
if (!is_static) pop_and_check_object(obj); __ pop(itos);
__ movl(field, rax); if (!is_static) pop_and_check_object(obj);
if (!is_static) { __ movl(field, rax);
patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx); if (!is_static) {
patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no);
}
__ jmp(Done);
} }
__ jmp(Done);
__ bind(notInt); __ bind(notInt);
__ cmpl(flags, ctos); __ cmpl(flags, ctos);
__ jcc(Assembler::notEqual, notChar); __ jcc(Assembler::notEqual, notChar);
// ctos // ctos
__ pop(ctos); {
if (!is_static) pop_and_check_object(obj); __ pop(ctos);
__ movw(field, rax); if (!is_static) pop_and_check_object(obj);
if (!is_static) { __ movw(field, rax);
patch_bytecode(Bytecodes::_fast_cputfield, bc, rbx); if (!is_static) {
patch_bytecode(Bytecodes::_fast_cputfield, bc, rbx, true, byte_no);
}
__ jmp(Done);
} }
__ jmp(Done);
__ bind(notChar); __ bind(notChar);
__ cmpl(flags, stos); __ cmpl(flags, stos);
__ jcc(Assembler::notEqual, notShort); __ jcc(Assembler::notEqual, notShort);
// stos // stos
__ pop(stos); {
if (!is_static) pop_and_check_object(obj); __ pop(stos);
__ movw(field, rax); if (!is_static) pop_and_check_object(obj);
if (!is_static) { __ movw(field, rax);
patch_bytecode(Bytecodes::_fast_sputfield, bc, rbx); if (!is_static) {
patch_bytecode(Bytecodes::_fast_sputfield, bc, rbx, true, byte_no);
}
__ jmp(Done);
} }
__ jmp(Done);
__ bind(notShort); __ bind(notShort);
__ cmpl(flags, ltos); __ cmpl(flags, ltos);
__ jcc(Assembler::notEqual, notLong); __ jcc(Assembler::notEqual, notLong);
// ltos // ltos
__ pop(ltos); {
if (!is_static) pop_and_check_object(obj); __ pop(ltos);
__ movq(field, rax); if (!is_static) pop_and_check_object(obj);
if (!is_static) { __ movq(field, rax);
patch_bytecode(Bytecodes::_fast_lputfield, bc, rbx); if (!is_static) {
patch_bytecode(Bytecodes::_fast_lputfield, bc, rbx, true, byte_no);
}
__ jmp(Done);
} }
__ jmp(Done);
__ bind(notLong); __ bind(notLong);
__ cmpl(flags, ftos); __ cmpl(flags, ftos);
__ jcc(Assembler::notEqual, notFloat); __ jcc(Assembler::notEqual, notFloat);
// ftos // ftos
__ pop(ftos); {
if (!is_static) pop_and_check_object(obj); __ pop(ftos);
__ movflt(field, xmm0); if (!is_static) pop_and_check_object(obj);
if (!is_static) { __ movflt(field, xmm0);
patch_bytecode(Bytecodes::_fast_fputfield, bc, rbx); if (!is_static) {
patch_bytecode(Bytecodes::_fast_fputfield, bc, rbx, true, byte_no);
}
__ jmp(Done);
} }
__ jmp(Done);
__ bind(notFloat); __ bind(notFloat);
#ifdef ASSERT #ifdef ASSERT
__ cmpl(flags, dtos); __ cmpl(flags, dtos);
__ jcc(Assembler::notEqual, notDouble); __ jcc(Assembler::notEqual, notDouble);
#endif #endif
// dtos // dtos
__ pop(dtos); {
if (!is_static) pop_and_check_object(obj); __ pop(dtos);
__ movdbl(field, xmm0); if (!is_static) pop_and_check_object(obj);
if (!is_static) { __ movdbl(field, xmm0);
patch_bytecode(Bytecodes::_fast_dputfield, bc, rbx); if (!is_static) {
patch_bytecode(Bytecodes::_fast_dputfield, bc, rbx, true, byte_no);
}
} }
#ifdef ASSERT #ifdef ASSERT
@ -2612,12 +2658,12 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
#endif #endif
__ bind(Done); __ bind(Done);
// Check for volatile store // Check for volatile store
__ testl(rdx, rdx); __ testl(rdx, rdx);
__ jcc(Assembler::zero, notVolatile); __ jcc(Assembler::zero, notVolatile);
volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
Assembler::StoreStore)); Assembler::StoreStore));
__ bind(notVolatile); __ bind(notVolatile);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All Rights Reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -557,14 +557,16 @@ void VM_Version::get_processor_features() {
if( !supports_sse() && supports_3dnow_prefetch() ) AllocatePrefetchInstr = 3; if( !supports_sse() && supports_3dnow_prefetch() ) AllocatePrefetchInstr = 3;
// Allocation prefetch settings // Allocation prefetch settings
intx cache_line_size = L1_data_cache_line_size(); intx cache_line_size = prefetch_data_size();
if( cache_line_size > AllocatePrefetchStepSize ) if( cache_line_size > AllocatePrefetchStepSize )
AllocatePrefetchStepSize = cache_line_size; AllocatePrefetchStepSize = cache_line_size;
if( FLAG_IS_DEFAULT(AllocatePrefetchLines) )
AllocatePrefetchLines = 3; // Optimistic value
assert(AllocatePrefetchLines > 0, "invalid value"); assert(AllocatePrefetchLines > 0, "invalid value");
if( AllocatePrefetchLines < 1 ) // set valid value in product VM if( AllocatePrefetchLines < 1 ) // set valid value in product VM
AllocatePrefetchLines = 1; // Conservative value AllocatePrefetchLines = 3;
assert(AllocateInstancePrefetchLines > 0, "invalid value");
if( AllocateInstancePrefetchLines < 1 ) // set valid value in product VM
AllocateInstancePrefetchLines = 1;
AllocatePrefetchDistance = allocate_prefetch_distance(); AllocatePrefetchDistance = allocate_prefetch_distance();
AllocatePrefetchStyle = allocate_prefetch_style(); AllocatePrefetchStyle = allocate_prefetch_style();
@ -601,10 +603,11 @@ void VM_Version::get_processor_features() {
tty->print_cr("Logical CPUs per core: %u", tty->print_cr("Logical CPUs per core: %u",
logical_processors_per_package()); logical_processors_per_package());
tty->print_cr("UseSSE=%d",UseSSE); tty->print_cr("UseSSE=%d",UseSSE);
tty->print("Allocation: "); tty->print("Allocation");
if (AllocatePrefetchStyle <= 0 || UseSSE == 0 && !supports_3dnow_prefetch()) { if (AllocatePrefetchStyle <= 0 || UseSSE == 0 && !supports_3dnow_prefetch()) {
tty->print_cr("no prefetching"); tty->print_cr(": no prefetching");
} else { } else {
tty->print(" prefetching: ");
if (UseSSE == 0 && supports_3dnow_prefetch()) { if (UseSSE == 0 && supports_3dnow_prefetch()) {
tty->print("PREFETCHW"); tty->print("PREFETCHW");
} else if (UseSSE >= 1) { } else if (UseSSE >= 1) {
@ -619,9 +622,9 @@ void VM_Version::get_processor_features() {
} }
} }
if (AllocatePrefetchLines > 1) { if (AllocatePrefetchLines > 1) {
tty->print_cr(" %d, %d lines with step %d bytes", AllocatePrefetchDistance, AllocatePrefetchLines, AllocatePrefetchStepSize); tty->print_cr(" at distance %d, %d lines of %d bytes", AllocatePrefetchDistance, AllocatePrefetchLines, AllocatePrefetchStepSize);
} else { } else {
tty->print_cr(" %d, one line", AllocatePrefetchDistance); tty->print_cr(" at distance %d, one line of %d bytes", AllocatePrefetchDistance, AllocatePrefetchStepSize);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All Rights Reserved. * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -419,7 +419,7 @@ public:
return result; return result;
} }
static intx L1_data_cache_line_size() { static intx prefetch_data_size() {
intx result = 0; intx result = 0;
if (is_intel()) { if (is_intel()) {
result = (_cpuid_info.dcp_cpuid4_ebx.bits.L1_line_size + 1); result = (_cpuid_info.dcp_cpuid4_ebx.bits.L1_line_size + 1);

View File

@ -1369,7 +1369,12 @@ const uint Matcher::vector_ideal_reg(void) {
// //
// NOTE: If the platform does not provide any short branch variants, then // NOTE: If the platform does not provide any short branch variants, then
// this method should return false for offset 0. // this method should return false for offset 0.
bool Matcher::is_short_branch_offset(int rule, int offset) { bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
// The passed offset is relative to address of the branch.
// On 86 a branch displacement is calculated relative to address
// of a next instruction.
offset -= br_size;
// the short version of jmpConUCF2 contains multiple branches, // the short version of jmpConUCF2 contains multiple branches,
// making the reach slightly less // making the reach slightly less
if (rule == jmpConUCF2_rule) if (rule == jmpConUCF2_rule)
@ -1713,18 +1718,6 @@ encode %{
else emit_d32(cbuf,con); else emit_d32(cbuf,con);
%} %}
enc_class Lbl (label labl) %{ // JMP, CALL
Label *l = $labl$$label;
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size()+4)) : 0);
%}
enc_class LblShort (label labl) %{ // JMP, CALL
Label *l = $labl$$label;
int disp = l ? (l->loc_pos() - (cbuf.insts_size()+1)) : 0;
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
emit_d8(cbuf, disp);
%}
enc_class OpcSReg (eRegI dst) %{ // BSWAP enc_class OpcSReg (eRegI dst) %{ // BSWAP
emit_cc(cbuf, $secondary, $dst$$reg ); emit_cc(cbuf, $secondary, $dst$$reg );
%} %}
@ -1747,21 +1740,6 @@ encode %{
emit_rm(cbuf, 0x3, $secondary, $div$$reg ); emit_rm(cbuf, 0x3, $secondary, $div$$reg );
%} %}
enc_class Jcc (cmpOp cop, label labl) %{ // JCC
Label *l = $labl$$label;
$$$emit8$primary;
emit_cc(cbuf, $secondary, $cop$$cmpcode);
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size()+4)) : 0);
%}
enc_class JccShort (cmpOp cop, label labl) %{ // JCC
Label *l = $labl$$label;
emit_cc(cbuf, $primary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.insts_size()+1)) : 0;
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
emit_d8(cbuf, disp);
%}
enc_class enc_cmov(cmpOp cop ) %{ // CMOV enc_class enc_cmov(cmpOp cop ) %{ // CMOV
$$$emit8$primary; $$$emit8$primary;
emit_cc(cbuf, $secondary, $cop$$cmpcode); emit_cc(cbuf, $secondary, $cop$$cmpcode);
@ -4496,7 +4474,6 @@ op_attrib op_cost(0); // Required cost attribute
//----------Instruction Attributes--------------------------------------------- //----------Instruction Attributes---------------------------------------------
ins_attrib ins_cost(100); // Required cost attribute ins_attrib ins_cost(100); // Required cost attribute
ins_attrib ins_size(8); // Required size attribute (in bits) ins_attrib ins_size(8); // Required size attribute (in bits)
ins_attrib ins_pc_relative(0); // Required PC Relative flag
ins_attrib ins_short_branch(0); // Required flag: is this instruction a ins_attrib ins_short_branch(0); // Required flag: is this instruction a
// non-matching short branch variant of some // non-matching short branch variant of some
// long branch? // long branch?
@ -7348,8 +7325,9 @@ instruct prefetchr( memory mem ) %{
ins_cost(100); ins_cost(100);
format %{ "PREFETCHR $mem\t! Prefetch into level 1 cache for read" %} format %{ "PREFETCHR $mem\t! Prefetch into level 1 cache for read" %}
opcode(0x0F, 0x0d); /* Opcode 0F 0d /0 */ ins_encode %{
ins_encode(OpcP, OpcS, RMopc_Mem(0x00,mem)); __ prefetchr($mem$$Address);
%}
ins_pipe(ialu_mem); ins_pipe(ialu_mem);
%} %}
@ -7359,8 +7337,9 @@ instruct prefetchrNTA( memory mem ) %{
ins_cost(100); ins_cost(100);
format %{ "PREFETCHNTA $mem\t! Prefetch into non-temporal cache for read" %} format %{ "PREFETCHNTA $mem\t! Prefetch into non-temporal cache for read" %}
opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */ ins_encode %{
ins_encode(OpcP, OpcS, RMopc_Mem(0x00,mem)); __ prefetchnta($mem$$Address);
%}
ins_pipe(ialu_mem); ins_pipe(ialu_mem);
%} %}
@ -7370,8 +7349,9 @@ instruct prefetchrT0( memory mem ) %{
ins_cost(100); ins_cost(100);
format %{ "PREFETCHT0 $mem\t! Prefetch into L1 and L2 caches for read" %} format %{ "PREFETCHT0 $mem\t! Prefetch into L1 and L2 caches for read" %}
opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */ ins_encode %{
ins_encode(OpcP, OpcS, RMopc_Mem(0x01,mem)); __ prefetcht0($mem$$Address);
%}
ins_pipe(ialu_mem); ins_pipe(ialu_mem);
%} %}
@ -7381,8 +7361,9 @@ instruct prefetchrT2( memory mem ) %{
ins_cost(100); ins_cost(100);
format %{ "PREFETCHT2 $mem\t! Prefetch into L2 cache for read" %} format %{ "PREFETCHT2 $mem\t! Prefetch into L2 cache for read" %}
opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */ ins_encode %{
ins_encode(OpcP, OpcS, RMopc_Mem(0x03,mem)); __ prefetcht2($mem$$Address);
%}
ins_pipe(ialu_mem); ins_pipe(ialu_mem);
%} %}
@ -7397,46 +7378,86 @@ instruct prefetchw0( memory mem ) %{
%} %}
instruct prefetchw( memory mem ) %{ instruct prefetchw( memory mem ) %{
predicate(UseSSE==0 && VM_Version::supports_3dnow_prefetch() || AllocatePrefetchInstr==3); predicate(UseSSE==0 && VM_Version::supports_3dnow_prefetch());
match( PrefetchWrite mem ); match( PrefetchWrite mem );
ins_cost(100); ins_cost(100);
format %{ "PREFETCHW $mem\t! Prefetch into L1 cache and mark modified" %} format %{ "PREFETCHW $mem\t! Prefetch into L1 cache and mark modified" %}
opcode(0x0F, 0x0D); /* Opcode 0F 0D /1 */ ins_encode %{
ins_encode(OpcP, OpcS, RMopc_Mem(0x01,mem)); __ prefetchw($mem$$Address);
%}
ins_pipe(ialu_mem); ins_pipe(ialu_mem);
%} %}
instruct prefetchwNTA( memory mem ) %{ instruct prefetchwNTA( memory mem ) %{
predicate(UseSSE>=1 && AllocatePrefetchInstr==0); predicate(UseSSE>=1);
match(PrefetchWrite mem); match(PrefetchWrite mem);
ins_cost(100); ins_cost(100);
format %{ "PREFETCHNTA $mem\t! Prefetch into non-temporal cache for write" %} format %{ "PREFETCHNTA $mem\t! Prefetch into non-temporal cache for write" %}
opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */ ins_encode %{
ins_encode(OpcP, OpcS, RMopc_Mem(0x00,mem)); __ prefetchnta($mem$$Address);
%}
ins_pipe(ialu_mem); ins_pipe(ialu_mem);
%} %}
instruct prefetchwT0( memory mem ) %{ // Prefetch instructions for allocation.
instruct prefetchAlloc0( memory mem ) %{
predicate(UseSSE==0 && AllocatePrefetchInstr!=3);
match(PrefetchAllocation mem);
ins_cost(0);
size(0);
format %{ "Prefetch allocation (non-SSE is empty encoding)" %}
ins_encode();
ins_pipe(empty);
%}
instruct prefetchAlloc( memory mem ) %{
predicate(AllocatePrefetchInstr==3);
match( PrefetchAllocation mem );
ins_cost(100);
format %{ "PREFETCHW $mem\t! Prefetch allocation into L1 cache and mark modified" %}
ins_encode %{
__ prefetchw($mem$$Address);
%}
ins_pipe(ialu_mem);
%}
instruct prefetchAllocNTA( memory mem ) %{
predicate(UseSSE>=1 && AllocatePrefetchInstr==0);
match(PrefetchAllocation mem);
ins_cost(100);
format %{ "PREFETCHNTA $mem\t! Prefetch allocation into non-temporal cache for write" %}
ins_encode %{
__ prefetchnta($mem$$Address);
%}
ins_pipe(ialu_mem);
%}
instruct prefetchAllocT0( memory mem ) %{
predicate(UseSSE>=1 && AllocatePrefetchInstr==1); predicate(UseSSE>=1 && AllocatePrefetchInstr==1);
match(PrefetchWrite mem); match(PrefetchAllocation mem);
ins_cost(100); ins_cost(100);
format %{ "PREFETCHT0 $mem\t! Prefetch into L1 and L2 caches for write" %} format %{ "PREFETCHT0 $mem\t! Prefetch allocation into L1 and L2 caches for write" %}
opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */ ins_encode %{
ins_encode(OpcP, OpcS, RMopc_Mem(0x01,mem)); __ prefetcht0($mem$$Address);
%}
ins_pipe(ialu_mem); ins_pipe(ialu_mem);
%} %}
instruct prefetchwT2( memory mem ) %{ instruct prefetchAllocT2( memory mem ) %{
predicate(UseSSE>=1 && AllocatePrefetchInstr==2); predicate(UseSSE>=1 && AllocatePrefetchInstr==2);
match(PrefetchWrite mem); match(PrefetchAllocation mem);
ins_cost(100); ins_cost(100);
format %{ "PREFETCHT2 $mem\t! Prefetch into L2 cache for write" %} format %{ "PREFETCHT2 $mem\t! Prefetch allocation into L2 cache for write" %}
opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */ ins_encode %{
ins_encode(OpcP, OpcS, RMopc_Mem(0x03,mem)); __ prefetcht2($mem$$Address);
%}
ins_pipe(ialu_mem); ins_pipe(ialu_mem);
%} %}
@ -7806,8 +7827,7 @@ instruct membar_acquire() %{
%} %}
instruct membar_acquire_lock() %{ instruct membar_acquire_lock() %{
match(MemBarAcquire); match(MemBarAcquireLock);
predicate(Matcher::prior_fast_lock(n));
ins_cost(0); ins_cost(0);
size(0); size(0);
@ -7827,8 +7847,7 @@ instruct membar_release() %{
%} %}
instruct membar_release_lock() %{ instruct membar_release_lock() %{
match(MemBarRelease); match(MemBarReleaseLock);
predicate(Matcher::post_fast_unlock(n));
ins_cost(0); ins_cost(0);
size(0); size(0);
@ -13047,7 +13066,6 @@ instruct jumpXtnd(eRegI switch_val) %{
Address index(noreg, $switch_val$$Register, Address::times_1); Address index(noreg, $switch_val$$Register, Address::times_1);
__ jump(ArrayAddress($constantaddress, index)); __ jump(ArrayAddress($constantaddress, index));
%} %}
ins_pc_relative(1);
ins_pipe(pipe_jmp); ins_pipe(pipe_jmp);
%} %}
@ -13059,10 +13077,11 @@ instruct jmpDir(label labl) %{
ins_cost(300); ins_cost(300);
format %{ "JMP $labl" %} format %{ "JMP $labl" %}
size(5); size(5);
opcode(0xE9); ins_encode %{
ins_encode( OpcP, Lbl( labl ) ); Label* L = $labl$$label;
__ jmp(*L, false); // Always long jump
%}
ins_pipe( pipe_jmp ); ins_pipe( pipe_jmp );
ins_pc_relative(1);
%} %}
// Jump Direct Conditional - Label defines a relative address from Jcc+1 // Jump Direct Conditional - Label defines a relative address from Jcc+1
@ -13073,10 +13092,11 @@ instruct jmpCon(cmpOp cop, eFlagsReg cr, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "J$cop $labl" %} format %{ "J$cop $labl" %}
size(6); size(6);
opcode(0x0F, 0x80); ins_encode %{
ins_encode( Jcc( cop, labl) ); Label* L = $labl$$label;
__ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
%}
ins_pipe( pipe_jcc ); ins_pipe( pipe_jcc );
ins_pc_relative(1);
%} %}
// Jump Direct Conditional - Label defines a relative address from Jcc+1 // Jump Direct Conditional - Label defines a relative address from Jcc+1
@ -13087,10 +13107,11 @@ instruct jmpLoopEnd(cmpOp cop, eFlagsReg cr, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "J$cop $labl\t# Loop end" %} format %{ "J$cop $labl\t# Loop end" %}
size(6); size(6);
opcode(0x0F, 0x80); ins_encode %{
ins_encode( Jcc( cop, labl) ); Label* L = $labl$$label;
__ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
%}
ins_pipe( pipe_jcc ); ins_pipe( pipe_jcc );
ins_pc_relative(1);
%} %}
// Jump Direct Conditional - Label defines a relative address from Jcc+1 // Jump Direct Conditional - Label defines a relative address from Jcc+1
@ -13101,10 +13122,11 @@ instruct jmpLoopEndU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "J$cop,u $labl\t# Loop end" %} format %{ "J$cop,u $labl\t# Loop end" %}
size(6); size(6);
opcode(0x0F, 0x80); ins_encode %{
ins_encode( Jcc( cop, labl) ); Label* L = $labl$$label;
__ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
%}
ins_pipe( pipe_jcc ); ins_pipe( pipe_jcc );
ins_pc_relative(1);
%} %}
instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{ instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
@ -13114,10 +13136,11 @@ instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
ins_cost(200); ins_cost(200);
format %{ "J$cop,u $labl\t# Loop end" %} format %{ "J$cop,u $labl\t# Loop end" %}
size(6); size(6);
opcode(0x0F, 0x80); ins_encode %{
ins_encode( Jcc( cop, labl) ); Label* L = $labl$$label;
__ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
%}
ins_pipe( pipe_jcc ); ins_pipe( pipe_jcc );
ins_pc_relative(1);
%} %}
// Jump Direct Conditional - using unsigned comparison // Jump Direct Conditional - using unsigned comparison
@ -13128,10 +13151,11 @@ instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "J$cop,u $labl" %} format %{ "J$cop,u $labl" %}
size(6); size(6);
opcode(0x0F, 0x80); ins_encode %{
ins_encode(Jcc(cop, labl)); Label* L = $labl$$label;
__ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
%}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
%} %}
instruct jmpConUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{ instruct jmpConUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
@ -13141,10 +13165,11 @@ instruct jmpConUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
ins_cost(200); ins_cost(200);
format %{ "J$cop,u $labl" %} format %{ "J$cop,u $labl" %}
size(6); size(6);
opcode(0x0F, 0x80); ins_encode %{
ins_encode(Jcc(cop, labl)); Label* L = $labl$$label;
__ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
%}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
%} %}
instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{ instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
@ -13162,31 +13187,21 @@ instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
$$emit$$"done:" $$emit$$"done:"
} }
%} %}
size(12);
opcode(0x0F, 0x80);
ins_encode %{ ins_encode %{
Label* l = $labl$$label; Label* l = $labl$$label;
$$$emit8$primary;
emit_cc(cbuf, $secondary, Assembler::parity);
int parity_disp = -1;
bool ok = false;
if ($cop$$cmpcode == Assembler::notEqual) { if ($cop$$cmpcode == Assembler::notEqual) {
// the two jumps 6 bytes apart so the jump distances are too __ jcc(Assembler::parity, *l, false);
parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0; __ jcc(Assembler::notEqual, *l, false);
} else if ($cop$$cmpcode == Assembler::equal) { } else if ($cop$$cmpcode == Assembler::equal) {
parity_disp = 6; Label done;
ok = true; __ jccb(Assembler::parity, done);
__ jcc(Assembler::equal, *l, false);
__ bind(done);
} else { } else {
ShouldNotReachHere(); ShouldNotReachHere();
} }
emit_d32(cbuf, parity_disp);
$$$emit8$primary;
emit_cc(cbuf, $secondary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
emit_d32(cbuf, disp);
%} %}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
%} %}
// ============================================================================ // ============================================================================
@ -13251,10 +13266,11 @@ instruct jmpDir_short(label labl) %{
ins_cost(300); ins_cost(300);
format %{ "JMP,s $labl" %} format %{ "JMP,s $labl" %}
size(2); size(2);
opcode(0xEB); ins_encode %{
ins_encode( OpcP, LblShort( labl ) ); Label* L = $labl$$label;
__ jmpb(*L);
%}
ins_pipe( pipe_jmp ); ins_pipe( pipe_jmp );
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -13266,10 +13282,11 @@ instruct jmpCon_short(cmpOp cop, eFlagsReg cr, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "J$cop,s $labl" %} format %{ "J$cop,s $labl" %}
size(2); size(2);
opcode(0x70); ins_encode %{
ins_encode( JccShort( cop, labl) ); Label* L = $labl$$label;
__ jccb((Assembler::Condition)($cop$$cmpcode), *L);
%}
ins_pipe( pipe_jcc ); ins_pipe( pipe_jcc );
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -13281,10 +13298,11 @@ instruct jmpLoopEnd_short(cmpOp cop, eFlagsReg cr, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "J$cop,s $labl\t# Loop end" %} format %{ "J$cop,s $labl\t# Loop end" %}
size(2); size(2);
opcode(0x70); ins_encode %{
ins_encode( JccShort( cop, labl) ); Label* L = $labl$$label;
__ jccb((Assembler::Condition)($cop$$cmpcode), *L);
%}
ins_pipe( pipe_jcc ); ins_pipe( pipe_jcc );
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -13296,10 +13314,11 @@ instruct jmpLoopEndU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "J$cop,us $labl\t# Loop end" %} format %{ "J$cop,us $labl\t# Loop end" %}
size(2); size(2);
opcode(0x70); ins_encode %{
ins_encode( JccShort( cop, labl) ); Label* L = $labl$$label;
__ jccb((Assembler::Condition)($cop$$cmpcode), *L);
%}
ins_pipe( pipe_jcc ); ins_pipe( pipe_jcc );
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -13310,10 +13329,11 @@ instruct jmpLoopEndUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "J$cop,us $labl\t# Loop end" %} format %{ "J$cop,us $labl\t# Loop end" %}
size(2); size(2);
opcode(0x70); ins_encode %{
ins_encode( JccShort( cop, labl) ); Label* L = $labl$$label;
__ jccb((Assembler::Condition)($cop$$cmpcode), *L);
%}
ins_pipe( pipe_jcc ); ins_pipe( pipe_jcc );
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -13325,10 +13345,11 @@ instruct jmpConU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "J$cop,us $labl" %} format %{ "J$cop,us $labl" %}
size(2); size(2);
opcode(0x70); ins_encode %{
ins_encode( JccShort( cop, labl) ); Label* L = $labl$$label;
__ jccb((Assembler::Condition)($cop$$cmpcode), *L);
%}
ins_pipe( pipe_jcc ); ins_pipe( pipe_jcc );
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -13339,10 +13360,11 @@ instruct jmpConUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "J$cop,us $labl" %} format %{ "J$cop,us $labl" %}
size(2); size(2);
opcode(0x70); ins_encode %{
ins_encode( JccShort( cop, labl) ); Label* L = $labl$$label;
__ jccb((Assembler::Condition)($cop$$cmpcode), *L);
%}
ins_pipe( pipe_jcc ); ins_pipe( pipe_jcc );
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -13362,27 +13384,21 @@ instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
} }
%} %}
size(4); size(4);
opcode(0x70);
ins_encode %{ ins_encode %{
Label* l = $labl$$label; Label* l = $labl$$label;
emit_cc(cbuf, $primary, Assembler::parity);
int parity_disp = -1;
if ($cop$$cmpcode == Assembler::notEqual) { if ($cop$$cmpcode == Assembler::notEqual) {
parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0; __ jccb(Assembler::parity, *l);
__ jccb(Assembler::notEqual, *l);
} else if ($cop$$cmpcode == Assembler::equal) { } else if ($cop$$cmpcode == Assembler::equal) {
parity_disp = 2; Label done;
__ jccb(Assembler::parity, done);
__ jccb(Assembler::equal, *l);
__ bind(done);
} else { } else {
ShouldNotReachHere(); ShouldNotReachHere();
} }
emit_d8(cbuf, parity_disp);
emit_cc(cbuf, $primary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
emit_d8(cbuf, disp);
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
%} %}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -13855,7 +13871,6 @@ instruct CallStaticJavaDirect(method meth) %{
call_epilog, call_epilog,
post_call_FPU ); post_call_FPU );
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
ins_pc_relative(1);
ins_alignment(4); ins_alignment(4);
%} %}
@ -13879,7 +13894,6 @@ instruct CallStaticJavaHandle(method meth, eBPRegP ebp_mh_SP_save) %{
call_epilog, call_epilog,
post_call_FPU ); post_call_FPU );
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
ins_pc_relative(1);
ins_alignment(4); ins_alignment(4);
%} %}
@ -13899,7 +13913,6 @@ instruct CallDynamicJavaDirect(method meth) %{
call_epilog, call_epilog,
post_call_FPU ); post_call_FPU );
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
ins_pc_relative(1);
ins_alignment(4); ins_alignment(4);
%} %}
@ -13917,7 +13930,6 @@ instruct CallRuntimeDirect(method meth) %{
Java_To_Runtime( meth ), Java_To_Runtime( meth ),
post_call_FPU ); post_call_FPU );
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
ins_pc_relative(1);
%} %}
// Call runtime without safepoint // Call runtime without safepoint
@ -13933,7 +13945,6 @@ instruct CallLeafDirect(method meth) %{
Java_To_Runtime( meth ), Java_To_Runtime( meth ),
Verify_FPU_For_Leaf, post_call_FPU ); Verify_FPU_For_Leaf, post_call_FPU );
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
ins_pc_relative(1);
%} %}
instruct CallLeafNoFPDirect(method meth) %{ instruct CallLeafNoFPDirect(method meth) %{
@ -13945,7 +13956,6 @@ instruct CallLeafNoFPDirect(method meth) %{
opcode(0xE8); /* E8 cd */ opcode(0xE8); /* E8 cd */
ins_encode(Java_To_Runtime(meth)); ins_encode(Java_To_Runtime(meth));
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
ins_pc_relative(1);
%} %}
@ -14024,7 +14034,6 @@ instruct cmpFastLock( eFlagsReg cr, eRegP object, eRegP box, eAXRegI tmp, eRegP
format %{ "FASTLOCK $object, $box KILLS $tmp,$scr" %} format %{ "FASTLOCK $object, $box KILLS $tmp,$scr" %}
ins_encode( Fast_Lock(object,box,tmp,scr) ); ins_encode( Fast_Lock(object,box,tmp,scr) );
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
ins_pc_relative(1);
%} %}
instruct cmpFastUnlock( eFlagsReg cr, eRegP object, eAXRegP box, eRegP tmp ) %{ instruct cmpFastUnlock( eFlagsReg cr, eRegP object, eAXRegP box, eRegP tmp ) %{
@ -14034,7 +14043,6 @@ instruct cmpFastUnlock( eFlagsReg cr, eRegP object, eAXRegP box, eRegP tmp ) %{
format %{ "FASTUNLOCK $object, $box, $tmp" %} format %{ "FASTUNLOCK $object, $box, $tmp" %}
ins_encode( Fast_Unlock(object,box,tmp) ); ins_encode( Fast_Unlock(object,box,tmp) );
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
ins_pc_relative(1);
%} %}

View File

@ -1966,7 +1966,12 @@ const uint Matcher::vector_ideal_reg(void) {
// //
// NOTE: If the platform does not provide any short branch variants, then // NOTE: If the platform does not provide any short branch variants, then
// this method should return false for offset 0. // this method should return false for offset 0.
bool Matcher::is_short_branch_offset(int rule, int offset) { bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
// The passed offset is relative to address of the branch.
// On 86 a branch displacement is calculated relative to address
// of a next instruction.
offset -= br_size;
// the short version of jmpConUCF2 contains multiple branches, // the short version of jmpConUCF2 contains multiple branches,
// making the reach slightly less // making the reach slightly less
if (rule == jmpConUCF2_rule) if (rule == jmpConUCF2_rule)
@ -2426,22 +2431,6 @@ encode %{
} }
%} %}
enc_class Lbl(label labl)
%{
// JMP, CALL
Label* l = $labl$$label;
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0);
%}
enc_class LblShort(label labl)
%{
// JMP, CALL
Label* l = $labl$$label;
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
emit_d8(cbuf, disp);
%}
enc_class opc2_reg(rRegI dst) enc_class opc2_reg(rRegI dst)
%{ %{
// BSWAP // BSWAP
@ -2460,25 +2449,6 @@ encode %{
emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7);
%} %}
enc_class Jcc(cmpOp cop, label labl)
%{
// JCC
Label* l = $labl$$label;
$$$emit8$primary;
emit_cc(cbuf, $secondary, $cop$$cmpcode);
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0);
%}
enc_class JccShort (cmpOp cop, label labl)
%{
// JCC
Label *l = $labl$$label;
emit_cc(cbuf, $primary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
emit_d8(cbuf, disp);
%}
enc_class enc_cmov(cmpOp cop) enc_class enc_cmov(cmpOp cop)
%{ %{
// CMOV // CMOV
@ -4013,7 +3983,6 @@ op_attrib op_cost(0); // Required cost attribute
//----------Instruction Attributes--------------------------------------------- //----------Instruction Attributes---------------------------------------------
ins_attrib ins_cost(100); // Required cost attribute ins_attrib ins_cost(100); // Required cost attribute
ins_attrib ins_size(8); // Required size attribute (in bits) ins_attrib ins_size(8); // Required size attribute (in bits)
ins_attrib ins_pc_relative(0); // Required PC Relative flag
ins_attrib ins_short_branch(0); // Required flag: is this instruction ins_attrib ins_short_branch(0); // Required flag: is this instruction
// a non-matching short branch variant // a non-matching short branch variant
// of some long branch? // of some long branch?
@ -6648,8 +6617,9 @@ instruct prefetchr( memory mem ) %{
ins_cost(125); ins_cost(125);
format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %} format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %}
opcode(0x0F, 0x0D); /* Opcode 0F 0D /0 */ ins_encode %{
ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x00, mem)); __ prefetchr($mem$$Address);
%}
ins_pipe(ialu_mem); ins_pipe(ialu_mem);
%} %}
@ -6659,8 +6629,9 @@ instruct prefetchrNTA( memory mem ) %{
ins_cost(125); ins_cost(125);
format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %} format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %}
opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */ ins_encode %{
ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x00, mem)); __ prefetchnta($mem$$Address);
%}
ins_pipe(ialu_mem); ins_pipe(ialu_mem);
%} %}
@ -6670,8 +6641,9 @@ instruct prefetchrT0( memory mem ) %{
ins_cost(125); ins_cost(125);
format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %} format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %}
opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */ ins_encode %{
ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x01, mem)); __ prefetcht0($mem$$Address);
%}
ins_pipe(ialu_mem); ins_pipe(ialu_mem);
%} %}
@ -6681,52 +6653,70 @@ instruct prefetchrT2( memory mem ) %{
ins_cost(125); ins_cost(125);
format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %} format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %}
opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */ ins_encode %{
ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x03, mem)); __ prefetcht2($mem$$Address);
ins_pipe(ialu_mem); %}
%}
instruct prefetchw( memory mem ) %{
predicate(AllocatePrefetchInstr==3);
match(PrefetchWrite mem);
ins_cost(125);
format %{ "PREFETCHW $mem\t# Prefetch into level 1 cache and mark modified" %}
opcode(0x0F, 0x0D); /* Opcode 0F 0D /1 */
ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x01, mem));
ins_pipe(ialu_mem); ins_pipe(ialu_mem);
%} %}
instruct prefetchwNTA( memory mem ) %{ instruct prefetchwNTA( memory mem ) %{
predicate(AllocatePrefetchInstr==0);
match(PrefetchWrite mem); match(PrefetchWrite mem);
ins_cost(125); ins_cost(125);
format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %} format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %}
opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */ ins_encode %{
ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x00, mem)); __ prefetchnta($mem$$Address);
%}
ins_pipe(ialu_mem); ins_pipe(ialu_mem);
%} %}
instruct prefetchwT0( memory mem ) %{ // Prefetch instructions for allocation.
instruct prefetchAlloc( memory mem ) %{
predicate(AllocatePrefetchInstr==3);
match(PrefetchAllocation mem);
ins_cost(125);
format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %}
ins_encode %{
__ prefetchw($mem$$Address);
%}
ins_pipe(ialu_mem);
%}
instruct prefetchAllocNTA( memory mem ) %{
predicate(AllocatePrefetchInstr==0);
match(PrefetchAllocation mem);
ins_cost(125);
format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %}
ins_encode %{
__ prefetchnta($mem$$Address);
%}
ins_pipe(ialu_mem);
%}
instruct prefetchAllocT0( memory mem ) %{
predicate(AllocatePrefetchInstr==1); predicate(AllocatePrefetchInstr==1);
match(PrefetchWrite mem); match(PrefetchAllocation mem);
ins_cost(125); ins_cost(125);
format %{ "PREFETCHT0 $mem\t# Prefetch to level 1 and 2 caches for write" %} format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %}
opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */ ins_encode %{
ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x01, mem)); __ prefetcht0($mem$$Address);
%}
ins_pipe(ialu_mem); ins_pipe(ialu_mem);
%} %}
instruct prefetchwT2( memory mem ) %{ instruct prefetchAllocT2( memory mem ) %{
predicate(AllocatePrefetchInstr==2); predicate(AllocatePrefetchInstr==2);
match(PrefetchWrite mem); match(PrefetchAllocation mem);
ins_cost(125); ins_cost(125);
format %{ "PREFETCHT2 $mem\t# Prefetch to level 2 cache for write" %} format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %}
opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */ ins_encode %{
ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x03, mem)); __ prefetcht2($mem$$Address);
%}
ins_pipe(ialu_mem); ins_pipe(ialu_mem);
%} %}
@ -7376,8 +7366,7 @@ instruct membar_acquire()
instruct membar_acquire_lock() instruct membar_acquire_lock()
%{ %{
match(MemBarAcquire); match(MemBarAcquireLock);
predicate(Matcher::prior_fast_lock(n));
ins_cost(0); ins_cost(0);
size(0); size(0);
@ -7399,8 +7388,7 @@ instruct membar_release()
instruct membar_release_lock() instruct membar_release_lock()
%{ %{
match(MemBarRelease); match(MemBarReleaseLock);
predicate(Matcher::post_fast_unlock(n));
ins_cost(0); ins_cost(0);
size(0); size(0);
@ -7547,7 +7535,6 @@ instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
__ jmp(dispatch); __ jmp(dispatch);
%} %}
ins_pipe(pipe_jmp); ins_pipe(pipe_jmp);
ins_pc_relative(1);
%} %}
instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
@ -7568,7 +7555,6 @@ instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest)
__ jmp(dispatch); __ jmp(dispatch);
%} %}
ins_pipe(pipe_jmp); ins_pipe(pipe_jmp);
ins_pc_relative(1);
%} %}
instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ instruct jumpXtnd(rRegL switch_val, rRegI dest) %{
@ -7589,7 +7575,6 @@ instruct jumpXtnd(rRegL switch_val, rRegI dest) %{
__ jmp(dispatch); __ jmp(dispatch);
%} %}
ins_pipe(pipe_jmp); ins_pipe(pipe_jmp);
ins_pc_relative(1);
%} %}
// Conditional move // Conditional move
@ -12017,10 +12002,11 @@ instruct jmpDir(label labl)
ins_cost(300); ins_cost(300);
format %{ "jmp $labl" %} format %{ "jmp $labl" %}
size(5); size(5);
opcode(0xE9); ins_encode %{
ins_encode(OpcP, Lbl(labl)); Label* L = $labl$$label;
__ jmp(*L, false); // Always long jump
%}
ins_pipe(pipe_jmp); ins_pipe(pipe_jmp);
ins_pc_relative(1);
%} %}
// Jump Direct Conditional - Label defines a relative address from Jcc+1 // Jump Direct Conditional - Label defines a relative address from Jcc+1
@ -12032,10 +12018,11 @@ instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl)
ins_cost(300); ins_cost(300);
format %{ "j$cop $labl" %} format %{ "j$cop $labl" %}
size(6); size(6);
opcode(0x0F, 0x80); ins_encode %{
ins_encode(Jcc(cop, labl)); Label* L = $labl$$label;
__ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
%}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
%} %}
// Jump Direct Conditional - Label defines a relative address from Jcc+1 // Jump Direct Conditional - Label defines a relative address from Jcc+1
@ -12047,10 +12034,11 @@ instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl)
ins_cost(300); ins_cost(300);
format %{ "j$cop $labl\t# loop end" %} format %{ "j$cop $labl\t# loop end" %}
size(6); size(6);
opcode(0x0F, 0x80); ins_encode %{
ins_encode(Jcc(cop, labl)); Label* L = $labl$$label;
__ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
%}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
%} %}
// Jump Direct Conditional - Label defines a relative address from Jcc+1 // Jump Direct Conditional - Label defines a relative address from Jcc+1
@ -12061,10 +12049,11 @@ instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "j$cop,u $labl\t# loop end" %} format %{ "j$cop,u $labl\t# loop end" %}
size(6); size(6);
opcode(0x0F, 0x80); ins_encode %{
ins_encode(Jcc(cop, labl)); Label* L = $labl$$label;
__ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
%}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
%} %}
instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
@ -12074,10 +12063,11 @@ instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
ins_cost(200); ins_cost(200);
format %{ "j$cop,u $labl\t# loop end" %} format %{ "j$cop,u $labl\t# loop end" %}
size(6); size(6);
opcode(0x0F, 0x80); ins_encode %{
ins_encode(Jcc(cop, labl)); Label* L = $labl$$label;
__ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
%}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
%} %}
// Jump Direct Conditional - using unsigned comparison // Jump Direct Conditional - using unsigned comparison
@ -12088,10 +12078,11 @@ instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "j$cop,u $labl" %} format %{ "j$cop,u $labl" %}
size(6); size(6);
opcode(0x0F, 0x80); ins_encode %{
ins_encode(Jcc(cop, labl)); Label* L = $labl$$label;
__ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
%}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
%} %}
instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
@ -12101,10 +12092,11 @@ instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
ins_cost(200); ins_cost(200);
format %{ "j$cop,u $labl" %} format %{ "j$cop,u $labl" %}
size(6); size(6);
opcode(0x0F, 0x80); ins_encode %{
ins_encode(Jcc(cop, labl)); Label* L = $labl$$label;
__ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
%}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
%} %}
instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
@ -12122,29 +12114,21 @@ instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
$$emit$$"done:" $$emit$$"done:"
} }
%} %}
size(12);
opcode(0x0F, 0x80);
ins_encode %{ ins_encode %{
Label* l = $labl$$label; Label* l = $labl$$label;
$$$emit8$primary;
emit_cc(cbuf, $secondary, Assembler::parity);
int parity_disp = -1;
if ($cop$$cmpcode == Assembler::notEqual) { if ($cop$$cmpcode == Assembler::notEqual) {
// the two jumps 6 bytes apart so the jump distances are too __ jcc(Assembler::parity, *l, false);
parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0; __ jcc(Assembler::notEqual, *l, false);
} else if ($cop$$cmpcode == Assembler::equal) { } else if ($cop$$cmpcode == Assembler::equal) {
parity_disp = 6; Label done;
__ jccb(Assembler::parity, done);
__ jcc(Assembler::equal, *l, false);
__ bind(done);
} else { } else {
ShouldNotReachHere(); ShouldNotReachHere();
} }
emit_d32(cbuf, parity_disp);
$$$emit8$primary;
emit_cc(cbuf, $secondary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
emit_d32(cbuf, disp);
%} %}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
%} %}
// ============================================================================ // ============================================================================
@ -12218,10 +12202,11 @@ instruct jmpDir_short(label labl) %{
ins_cost(300); ins_cost(300);
format %{ "jmp,s $labl" %} format %{ "jmp,s $labl" %}
size(2); size(2);
opcode(0xEB); ins_encode %{
ins_encode(OpcP, LblShort(labl)); Label* L = $labl$$label;
__ jmpb(*L);
%}
ins_pipe(pipe_jmp); ins_pipe(pipe_jmp);
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -12233,10 +12218,11 @@ instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "j$cop,s $labl" %} format %{ "j$cop,s $labl" %}
size(2); size(2);
opcode(0x70); ins_encode %{
ins_encode(JccShort(cop, labl)); Label* L = $labl$$label;
__ jccb((Assembler::Condition)($cop$$cmpcode), *L);
%}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -12248,10 +12234,11 @@ instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "j$cop,s $labl\t# loop end" %} format %{ "j$cop,s $labl\t# loop end" %}
size(2); size(2);
opcode(0x70); ins_encode %{
ins_encode(JccShort(cop, labl)); Label* L = $labl$$label;
__ jccb((Assembler::Condition)($cop$$cmpcode), *L);
%}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -12263,10 +12250,11 @@ instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "j$cop,us $labl\t# loop end" %} format %{ "j$cop,us $labl\t# loop end" %}
size(2); size(2);
opcode(0x70); ins_encode %{
ins_encode(JccShort(cop, labl)); Label* L = $labl$$label;
__ jccb((Assembler::Condition)($cop$$cmpcode), *L);
%}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -12277,10 +12265,11 @@ instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "j$cop,us $labl\t# loop end" %} format %{ "j$cop,us $labl\t# loop end" %}
size(2); size(2);
opcode(0x70); ins_encode %{
ins_encode(JccShort(cop, labl)); Label* L = $labl$$label;
__ jccb((Assembler::Condition)($cop$$cmpcode), *L);
%}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -12292,10 +12281,11 @@ instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "j$cop,us $labl" %} format %{ "j$cop,us $labl" %}
size(2); size(2);
opcode(0x70); ins_encode %{
ins_encode(JccShort(cop, labl)); Label* L = $labl$$label;
__ jccb((Assembler::Condition)($cop$$cmpcode), *L);
%}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -12306,10 +12296,11 @@ instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
ins_cost(300); ins_cost(300);
format %{ "j$cop,us $labl" %} format %{ "j$cop,us $labl" %}
size(2); size(2);
opcode(0x70); ins_encode %{
ins_encode(JccShort(cop, labl)); Label* L = $labl$$label;
__ jccb((Assembler::Condition)($cop$$cmpcode), *L);
%}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -12329,27 +12320,21 @@ instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
} }
%} %}
size(4); size(4);
opcode(0x70);
ins_encode %{ ins_encode %{
Label* l = $labl$$label; Label* l = $labl$$label;
emit_cc(cbuf, $primary, Assembler::parity);
int parity_disp = -1;
if ($cop$$cmpcode == Assembler::notEqual) { if ($cop$$cmpcode == Assembler::notEqual) {
parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0; __ jccb(Assembler::parity, *l);
__ jccb(Assembler::notEqual, *l);
} else if ($cop$$cmpcode == Assembler::equal) { } else if ($cop$$cmpcode == Assembler::equal) {
parity_disp = 2; Label done;
__ jccb(Assembler::parity, done);
__ jccb(Assembler::equal, *l);
__ bind(done);
} else { } else {
ShouldNotReachHere(); ShouldNotReachHere();
} }
emit_d8(cbuf, parity_disp);
emit_cc(cbuf, $primary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
emit_d8(cbuf, disp);
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
%} %}
ins_pipe(pipe_jcc); ins_pipe(pipe_jcc);
ins_pc_relative(1);
ins_short_branch(1); ins_short_branch(1);
%} %}
@ -12366,7 +12351,6 @@ instruct cmpFastLock(rFlagsReg cr,
format %{ "fastlock $object,$box,$tmp,$scr" %} format %{ "fastlock $object,$box,$tmp,$scr" %}
ins_encode(Fast_Lock(object, box, tmp, scr)); ins_encode(Fast_Lock(object, box, tmp, scr));
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
ins_pc_relative(1);
%} %}
instruct cmpFastUnlock(rFlagsReg cr, instruct cmpFastUnlock(rFlagsReg cr,
@ -12379,7 +12363,6 @@ instruct cmpFastUnlock(rFlagsReg cr,
format %{ "fastunlock $object, $box, $tmp" %} format %{ "fastunlock $object, $box, $tmp" %}
ins_encode(Fast_Unlock(object, box, tmp)); ins_encode(Fast_Unlock(object, box, tmp));
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
ins_pc_relative(1);
%} %}
@ -12432,7 +12415,6 @@ instruct CallStaticJavaDirect(method meth) %{
opcode(0xE8); /* E8 cd */ opcode(0xE8); /* E8 cd */
ins_encode(Java_Static_Call(meth), call_epilog); ins_encode(Java_Static_Call(meth), call_epilog);
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
ins_pc_relative(1);
ins_alignment(4); ins_alignment(4);
%} %}
@ -12454,7 +12436,6 @@ instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{
restore_SP, restore_SP,
call_epilog); call_epilog);
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
ins_pc_relative(1);
ins_alignment(4); ins_alignment(4);
%} %}
@ -12472,7 +12453,6 @@ instruct CallDynamicJavaDirect(method meth)
opcode(0xE8); /* E8 cd */ opcode(0xE8); /* E8 cd */
ins_encode(Java_Dynamic_Call(meth), call_epilog); ins_encode(Java_Dynamic_Call(meth), call_epilog);
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
ins_pc_relative(1);
ins_alignment(4); ins_alignment(4);
%} %}
@ -12487,7 +12467,6 @@ instruct CallRuntimeDirect(method meth)
opcode(0xE8); /* E8 cd */ opcode(0xE8); /* E8 cd */
ins_encode(Java_To_Runtime(meth)); ins_encode(Java_To_Runtime(meth));
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
ins_pc_relative(1);
%} %}
// Call runtime without safepoint // Call runtime without safepoint
@ -12501,7 +12480,6 @@ instruct CallLeafDirect(method meth)
opcode(0xE8); /* E8 cd */ opcode(0xE8); /* E8 cd */
ins_encode(Java_To_Runtime(meth)); ins_encode(Java_To_Runtime(meth));
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
ins_pc_relative(1);
%} %}
// Call runtime without safepoint // Call runtime without safepoint
@ -12515,7 +12493,6 @@ instruct CallLeafNoFPDirect(method meth)
opcode(0xE8); /* E8 cd */ opcode(0xE8); /* E8 cd */
ins_encode(Java_To_Runtime(meth)); ins_encode(Java_To_Runtime(meth));
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
ins_pc_relative(1);
%} %}
// Return Instruction // Return Instruction

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010 Red Hat, Inc. * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -417,3 +417,11 @@ void ZeroFrame::identify_vp_word(int frame_index,
return; return;
} }
} }
#ifdef ASSERT
void frame::describe_pd(FrameValues& values, int frame_no) {
}
#endif

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
// Adapters
enum /* platform_dependent_constants */ {
adapter_code_size = 0
};
#define TARGET_ARCH_NYI_6939861 1
// ..#ifdef TARGET_ARCH_NYI_6939861
// .. // Here are some backward compatible declarations until the 6939861 ports are updated.
// .. #define _adapter_flyby (_EK_LIMIT + 10)
// .. #define _adapter_ricochet (_EK_LIMIT + 11)
// .. #define _adapter_opt_spread_1 _adapter_opt_spread_1_ref
// .. #define _adapter_opt_spread_more _adapter_opt_spread_ref
// .. enum {
// .. _INSERT_NO_MASK = -1,
// .. _INSERT_REF_MASK = 0,
// .. _INSERT_INT_MASK = 1,
// .. _INSERT_LONG_MASK = 3
// .. };
// .. static void get_ek_bound_mh_info(EntryKind ek, BasicType& arg_type, int& arg_mask, int& arg_slots) {
// .. arg_type = ek_bound_mh_arg_type(ek);
// .. arg_mask = 0;
// .. arg_slots = type2size[arg_type];;
// .. }
// .. static void get_ek_adapter_opt_swap_rot_info(EntryKind ek, int& swap_bytes, int& rotate) {
// .. int swap_slots = ek_adapter_opt_swap_slots(ek);
// .. rotate = ek_adapter_opt_swap_mode(ek);
// .. swap_bytes = swap_slots * Interpreter::stackElementSize;
// .. }
// .. static int get_ek_adapter_opt_spread_info(EntryKind ek) {
// .. return ek_adapter_opt_spread_count(ek);
// .. }
// ..
// .. static void insert_arg_slots(MacroAssembler* _masm,
// .. RegisterOrConstant arg_slots,
// .. int arg_mask,
// .. Register argslot_reg,
// .. Register temp_reg, Register temp2_reg, Register temp3_reg = noreg);
// ..
// .. static void remove_arg_slots(MacroAssembler* _masm,
// .. RegisterOrConstant arg_slots,
// .. Register argslot_reg,
// .. Register temp_reg, Register temp2_reg, Register temp3_reg = noreg);
// ..
// .. static void trace_method_handle(MacroAssembler* _masm, const char* adaptername) PRODUCT_RETURN;
// ..#endif //TARGET_ARCH_NYI_6939861

View File

@ -46,14 +46,6 @@
#include "shark/sharkCompiler.hpp" #include "shark/sharkCompiler.hpp"
#endif #endif
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, int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
VMRegPair *regs, VMRegPair *regs,
@ -114,22 +106,22 @@ static SafepointBlob* generate_empty_safepoint_blob() {
return SafepointBlob::create(&buffer, NULL, 0); return SafepointBlob::create(&buffer, NULL, 0);
} }
void SharedRuntime::generate_stubs() { static DeoptimizationBlob* generate_empty_deopt_blob() {
_wrong_method_blob = CodeBuffer buffer("handler_blob", 0, 0);
generate_empty_runtime_stub("wrong_method_stub"); return DeoptimizationBlob::create(&buffer, NULL, 0, 0, 0, 0);
_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(); void SharedRuntime::generate_deopt_blob() {
_polling_page_return_handler_blob = _deopt_blob = generate_empty_deopt_blob();
generate_empty_safepoint_blob(); }
SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause_return) {
return generate_empty_safepoint_blob();
}
RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const char* name) {
return generate_empty_runtime_stub("resolve_blob");
} }
int SharedRuntime::c_calling_convention(const BasicType *sig_bt, int SharedRuntime::c_calling_convention(const BasicType *sig_bt,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright 2010 Red Hat, Inc. * Copyright 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
@ -69,7 +69,8 @@ void ZeroStack::handle_overflow(TRAPS) {
break; break;
case _thread_in_vm: case _thread_in_vm:
Exceptions::throw_stack_overflow_exception(thread, __FILE__, __LINE__); Exceptions::throw_stack_overflow_exception(thread, __FILE__, __LINE__,
methodHandle());
break; break;
default: default:

View File

@ -125,6 +125,10 @@
# include <inttypes.h> # include <inttypes.h>
# include <sys/ioctl.h> # include <sys/ioctl.h>
#ifdef AMD64
#include <asm/vsyscall.h>
#endif
#define MAX_PATH (2 * K) #define MAX_PATH (2 * K)
// for timer info max values which include all bits // for timer info max values which include all bits
@ -2534,7 +2538,7 @@ void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
} }
void os::free_memory(char *addr, size_t bytes) { void os::free_memory(char *addr, size_t bytes) {
::madvise(addr, bytes, MADV_DONTNEED); commit_memory(addr, bytes, false);
} }
void os::numa_make_global(char *addr, size_t bytes) { void os::numa_make_global(char *addr, size_t bytes) {
@ -2578,6 +2582,22 @@ char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info
return end; return end;
} }
int os::Linux::sched_getcpu_syscall(void) {
unsigned int cpu;
int retval = -1;
#if defined(IA32)
retval = syscall(SYS_getcpu, &cpu, NULL, NULL);
#elif defined(AMD64)
typedef long (*vgetcpu_t)(unsigned int *cpu, unsigned int *node, unsigned long *tcache);
vgetcpu_t vgetcpu = (vgetcpu_t)VSYSCALL_ADDR(__NR_vgetcpu);
retval = vgetcpu(&cpu, NULL, NULL);
#endif
return (retval == -1) ? retval : cpu;
}
// Something to do with the numa-aware allocator needs these symbols // Something to do with the numa-aware allocator needs these symbols
extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { } extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { }
extern "C" JNIEXPORT void numa_error(char *where) { } extern "C" JNIEXPORT void numa_error(char *where) { }
@ -2601,6 +2621,10 @@ bool os::Linux::libnuma_init() {
set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t,
dlsym(RTLD_DEFAULT, "sched_getcpu"))); dlsym(RTLD_DEFAULT, "sched_getcpu")));
// If it's not, try a direct syscall.
if (sched_getcpu() == -1)
set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, (void*)&sched_getcpu_syscall));
if (sched_getcpu() != -1) { // Does it work? if (sched_getcpu() != -1) { // Does it work?
void *handle = dlopen("libnuma.so.1", RTLD_LAZY); void *handle = dlopen("libnuma.so.1", RTLD_LAZY);
if (handle != NULL) { if (handle != NULL) {

View File

@ -263,6 +263,7 @@ private:
static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; } static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; }
static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; } static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; }
static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; } static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; }
static int sched_getcpu_syscall(void);
public: public:
static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; } static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; }
static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) { static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) {

View File

@ -3252,7 +3252,6 @@ bool os::unguard_memory(char* addr, size_t bytes) {
// supported Solaris versions, this combination // supported Solaris versions, this combination
// is equivalent to +UseISM -UseMPSS. // is equivalent to +UseISM -UseMPSS.
typedef int (*getpagesizes_func_type) (size_t[], int);
static size_t _large_page_size = 0; static size_t _large_page_size = 0;
bool os::Solaris::ism_sanity_check(bool warn, size_t * page_size) { bool os::Solaris::ism_sanity_check(bool warn, size_t * page_size) {
@ -3284,23 +3283,29 @@ static void insertion_sort_descending(size_t* array, int len) {
} }
bool os::Solaris::mpss_sanity_check(bool warn, size_t * page_size) { bool os::Solaris::mpss_sanity_check(bool warn, size_t * page_size) {
getpagesizes_func_type getpagesizes_func =
CAST_TO_FN_PTR(getpagesizes_func_type, dlsym(RTLD_DEFAULT, "getpagesizes"));
if (getpagesizes_func == NULL) {
if (warn) {
warning("MPSS is not supported by the operating system.");
}
return false;
}
const unsigned int usable_count = VM_Version::page_size_count(); const unsigned int usable_count = VM_Version::page_size_count();
if (usable_count == 1) { if (usable_count == 1) {
return false; return false;
} }
// Find the right getpagesizes interface. When solaris 11 is the minimum
// build platform, getpagesizes() (without the '2') can be called directly.
typedef int (*gps_t)(size_t[], int);
gps_t gps_func = CAST_TO_FN_PTR(gps_t, dlsym(RTLD_DEFAULT, "getpagesizes2"));
if (gps_func == NULL) {
gps_func = CAST_TO_FN_PTR(gps_t, dlsym(RTLD_DEFAULT, "getpagesizes"));
if (gps_func == NULL) {
if (warn) {
warning("MPSS is not supported by the operating system.");
}
return false;
}
}
// Fill the array of page sizes. // Fill the array of page sizes.
int n = getpagesizes_func(_page_sizes, page_sizes_max); int n = (*gps_func)(_page_sizes, page_sizes_max);
assert(n > 0, "Solaris bug?"); assert(n > 0, "Solaris bug?");
if (n == page_sizes_max) { if (n == page_sizes_max) {
// Add a sentinel value (necessary only if the array was completely filled // Add a sentinel value (necessary only if the array was completely filled
// since it is static (zeroed at initialization)). // since it is static (zeroed at initialization)).
@ -3308,6 +3313,7 @@ bool os::Solaris::mpss_sanity_check(bool warn, size_t * page_size) {
DEBUG_ONLY(warning("increase the size of the os::_page_sizes array.");) DEBUG_ONLY(warning("increase the size of the os::_page_sizes array.");)
} }
assert(_page_sizes[n] == 0, "missing sentinel"); assert(_page_sizes[n] == 0, "missing sentinel");
trace_page_sizes("available page sizes", _page_sizes, n);
if (n == 1) return false; // Only one page size available. if (n == 1) return false; // Only one page size available.
@ -3337,6 +3343,7 @@ bool os::Solaris::mpss_sanity_check(bool warn, size_t * page_size) {
} }
*page_size = _page_sizes[0]; *page_size = _page_sizes[0];
trace_page_sizes("usable page sizes", _page_sizes, end + 1);
return true; return true;
} }

View File

@ -24,6 +24,7 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "prims/jvm.h" #include "prims/jvm.h"
#include "runtime/os.hpp"
#include "utilities/decoder.hpp" #include "utilities/decoder.hpp"
HMODULE Decoder::_dbghelp_handle = NULL; HMODULE Decoder::_dbghelp_handle = NULL;
@ -35,7 +36,7 @@ void Decoder::initialize() {
if (!_initialized) { if (!_initialized) {
_initialized = true; _initialized = true;
HMODULE handle = ::LoadLibrary("dbghelp.dll"); HINSTANCE handle = os::win32::load_Windows_dll("dbghelp.dll", NULL, 0);
if (!handle) { if (!handle) {
_decoder_status = helper_not_found; _decoder_status = helper_not_found;
return; return;

View File

@ -30,10 +30,33 @@
* JNI conversion, which should be sorted out later. * JNI conversion, which should be sorted out later.
*/ */
#include <windows.h> // JDK7 requires VS2010
// #include <windef.h> #if _MSC_VER >= 1600
// #include <winbase.h> // JDK7 minimum platform requirement: Windows XP
#if _WIN32_WINNT < 0x0501
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#endif
#include <windows.h>
#if _MSC_VER <= 1200
// Psapi.h doesn't come with Visual Studio 6; it can be downloaded as Platform
// SDK from Microsoft. Here are the definitions copied from Psapi.h
typedef struct _MODULEINFO {
LPVOID lpBaseOfDll;
DWORD SizeOfImage;
LPVOID EntryPoint;
} MODULEINFO, *LPMODULEINFO;
#else
#include <Psapi.h>
#endif
#include <Tlhelp32.h>
// #include "jni.h" // #include "jni.h"

View File

@ -98,7 +98,6 @@
#include <imagehlp.h> // For os::dll_address_to_function_name #include <imagehlp.h> // For os::dll_address_to_function_name
/* for enumerating dll libraries */ /* for enumerating dll libraries */
#include <tlhelp32.h>
#include <vdmdbg.h> #include <vdmdbg.h>
// for timer info max values which include all bits // for timer info max values which include all bits
@ -241,11 +240,11 @@ void os::init_system_properties_values() {
/* Win32 library search order (See the documentation for LoadLibrary): /* Win32 library search order (See the documentation for LoadLibrary):
* *
* 1. The directory from which application is loaded. * 1. The directory from which application is loaded.
* 2. The current directory * 2. The system wide Java Extensions directory (Java only)
* 3. The system wide Java Extensions directory (Java only) * 3. System directory (GetSystemDirectory)
* 4. System directory (GetSystemDirectory) * 4. Windows directory (GetWindowsDirectory)
* 5. Windows directory (GetWindowsDirectory) * 5. The PATH environment variable
* 6. The PATH environment variable * 6. The current directory
*/ */
char *library_path; char *library_path;
@ -261,8 +260,6 @@ void os::init_system_properties_values() {
*(strrchr(tmp, '\\')) = '\0'; *(strrchr(tmp, '\\')) = '\0';
strcat(library_path, tmp); strcat(library_path, tmp);
strcat(library_path, ";.");
GetWindowsDirectory(tmp, sizeof(tmp)); GetWindowsDirectory(tmp, sizeof(tmp));
strcat(library_path, ";"); strcat(library_path, ";");
strcat(library_path, tmp); strcat(library_path, tmp);
@ -281,6 +278,8 @@ void os::init_system_properties_values() {
strcat(library_path, path_str); strcat(library_path, path_str);
} }
strcat(library_path, ";.");
Arguments::set_library_path(library_path); Arguments::set_library_path(library_path);
FREE_C_HEAP_ARRAY(char, library_path); FREE_C_HEAP_ARRAY(char, library_path);
} }
@ -939,7 +938,7 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
return; return;
} }
dbghelp = LoadLibrary("DBGHELP.DLL"); dbghelp = os::win32::load_Windows_dll("DBGHELP.DLL", NULL, 0);
if (dbghelp == NULL) { if (dbghelp == NULL) {
VMError::report_coredump_status("Failed to load dbghelp.dll", false); VMError::report_coredump_status("Failed to load dbghelp.dll", false);
@ -1204,70 +1203,6 @@ const char* os::get_current_directory(char *buf, int buflen) {
//----------------------------------------------------------- //-----------------------------------------------------------
// Helper functions for fatal error handler // Helper functions for fatal error handler
// The following library functions are resolved dynamically at runtime:
// PSAPI functions, for Windows NT, 2000, XP
// psapi.h doesn't come with Visual Studio 6; it can be downloaded as Platform
// SDK from Microsoft. Here are the definitions copied from psapi.h
typedef struct _MODULEINFO {
LPVOID lpBaseOfDll;
DWORD SizeOfImage;
LPVOID EntryPoint;
} MODULEINFO, *LPMODULEINFO;
static BOOL (WINAPI *_EnumProcessModules) ( HANDLE, HMODULE *, DWORD, LPDWORD );
static DWORD (WINAPI *_GetModuleFileNameEx) ( HANDLE, HMODULE, LPTSTR, DWORD );
static BOOL (WINAPI *_GetModuleInformation)( HANDLE, HMODULE, LPMODULEINFO, DWORD );
// ToolHelp Functions, for Windows 95, 98 and ME
static HANDLE(WINAPI *_CreateToolhelp32Snapshot)(DWORD,DWORD) ;
static BOOL (WINAPI *_Module32First) (HANDLE,LPMODULEENTRY32) ;
static BOOL (WINAPI *_Module32Next) (HANDLE,LPMODULEENTRY32) ;
bool _has_psapi;
bool _psapi_init = false;
bool _has_toolhelp;
static bool _init_psapi() {
HINSTANCE psapi = LoadLibrary( "PSAPI.DLL" ) ;
if( psapi == NULL ) return false ;
_EnumProcessModules = CAST_TO_FN_PTR(
BOOL(WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD),
GetProcAddress(psapi, "EnumProcessModules")) ;
_GetModuleFileNameEx = CAST_TO_FN_PTR(
DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR, DWORD),
GetProcAddress(psapi, "GetModuleFileNameExA"));
_GetModuleInformation = CAST_TO_FN_PTR(
BOOL (WINAPI *)(HANDLE, HMODULE, LPMODULEINFO, DWORD),
GetProcAddress(psapi, "GetModuleInformation"));
_has_psapi = (_EnumProcessModules && _GetModuleFileNameEx && _GetModuleInformation);
_psapi_init = true;
return _has_psapi;
}
static bool _init_toolhelp() {
HINSTANCE kernel32 = LoadLibrary("Kernel32.DLL") ;
if (kernel32 == NULL) return false ;
_CreateToolhelp32Snapshot = CAST_TO_FN_PTR(
HANDLE(WINAPI *)(DWORD,DWORD),
GetProcAddress(kernel32, "CreateToolhelp32Snapshot"));
_Module32First = CAST_TO_FN_PTR(
BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32),
GetProcAddress(kernel32, "Module32First" ));
_Module32Next = CAST_TO_FN_PTR(
BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32),
GetProcAddress(kernel32, "Module32Next" ));
_has_toolhelp = (_CreateToolhelp32Snapshot && _Module32First && _Module32Next);
return _has_toolhelp;
}
#ifdef _WIN64 #ifdef _WIN64
// Helper routine which returns true if address in // Helper routine which returns true if address in
// within the NTDLL address space. // within the NTDLL address space.
@ -1279,7 +1214,7 @@ static bool _addr_in_ntdll( address addr )
hmod = GetModuleHandle("NTDLL.DLL"); hmod = GetModuleHandle("NTDLL.DLL");
if ( hmod == NULL ) return false; if ( hmod == NULL ) return false;
if ( !_GetModuleInformation( GetCurrentProcess(), hmod, if ( !os::PSApiDll::GetModuleInformation( GetCurrentProcess(), hmod,
&minfo, sizeof(MODULEINFO)) ) &minfo, sizeof(MODULEINFO)) )
return false; return false;
@ -1318,14 +1253,16 @@ static int _enumerate_modules_winnt( int pid, EnumModulesCallbackFunc func, void
static char filename[ MAX_PATH ]; static char filename[ MAX_PATH ];
int result = 0; int result = 0;
if (!_has_psapi && (_psapi_init || !_init_psapi())) return 0; if (!os::PSApiDll::PSApiAvailable()) {
return 0;
}
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, pid ) ; FALSE, pid ) ;
if (hProcess == NULL) return 0; if (hProcess == NULL) return 0;
DWORD size_needed; DWORD size_needed;
if (!_EnumProcessModules(hProcess, modules, if (!os::PSApiDll::EnumProcessModules(hProcess, modules,
sizeof(modules), &size_needed)) { sizeof(modules), &size_needed)) {
CloseHandle( hProcess ); CloseHandle( hProcess );
return 0; return 0;
@ -1336,13 +1273,13 @@ static int _enumerate_modules_winnt( int pid, EnumModulesCallbackFunc func, void
for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) { for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) {
// Get Full pathname: // Get Full pathname:
if(!_GetModuleFileNameEx(hProcess, modules[i], if(!os::PSApiDll::GetModuleFileNameEx(hProcess, modules[i],
filename, sizeof(filename))) { filename, sizeof(filename))) {
filename[0] = '\0'; filename[0] = '\0';
} }
MODULEINFO modinfo; MODULEINFO modinfo;
if (!_GetModuleInformation(hProcess, modules[i], if (!os::PSApiDll::GetModuleInformation(hProcess, modules[i],
&modinfo, sizeof(modinfo))) { &modinfo, sizeof(modinfo))) {
modinfo.lpBaseOfDll = NULL; modinfo.lpBaseOfDll = NULL;
modinfo.SizeOfImage = 0; modinfo.SizeOfImage = 0;
@ -1366,17 +1303,19 @@ static int _enumerate_modules_windows( int pid, EnumModulesCallbackFunc func, vo
static MODULEENTRY32 modentry ; static MODULEENTRY32 modentry ;
int result = 0; int result = 0;
if (!_has_toolhelp) return 0; if (!os::Kernel32Dll::HelpToolsAvailable()) {
return 0;
}
// Get a handle to a Toolhelp snapshot of the system // Get a handle to a Toolhelp snapshot of the system
hSnapShot = _CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid ) ; hSnapShot = os::Kernel32Dll::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid ) ;
if( hSnapShot == INVALID_HANDLE_VALUE ) { if( hSnapShot == INVALID_HANDLE_VALUE ) {
return FALSE ; return FALSE ;
} }
// iterate through all modules // iterate through all modules
modentry.dwSize = sizeof(MODULEENTRY32) ; modentry.dwSize = sizeof(MODULEENTRY32) ;
bool not_done = _Module32First( hSnapShot, &modentry ) != 0; bool not_done = os::Kernel32Dll::Module32First( hSnapShot, &modentry ) != 0;
while( not_done ) { while( not_done ) {
// invoke the callback // invoke the callback
@ -1385,7 +1324,7 @@ static int _enumerate_modules_windows( int pid, EnumModulesCallbackFunc func, vo
if (result) break; if (result) break;
modentry.dwSize = sizeof(MODULEENTRY32) ; modentry.dwSize = sizeof(MODULEENTRY32) ;
not_done = _Module32Next( hSnapShot, &modentry ) != 0; not_done = os::Kernel32Dll::Module32Next( hSnapShot, &modentry ) != 0;
} }
CloseHandle(hSnapShot); CloseHandle(hSnapShot);
@ -1631,10 +1570,6 @@ void os::print_dll_info(outputStream *st) {
enumerate_modules(pid, _print_module, (void *)st); enumerate_modules(pid, _print_module, (void *)st);
} }
// function pointer to Windows API "GetNativeSystemInfo".
typedef void (WINAPI *GetNativeSystemInfo_func_type)(LPSYSTEM_INFO);
static GetNativeSystemInfo_func_type _GetNativeSystemInfo;
void os::print_os_info(outputStream* st) { void os::print_os_info(outputStream* st) {
st->print("OS:"); st->print("OS:");
@ -1661,17 +1596,10 @@ void os::print_os_info(outputStream* st) {
// find out whether we are running on 64 bit processor or not. // find out whether we are running on 64 bit processor or not.
SYSTEM_INFO si; SYSTEM_INFO si;
ZeroMemory(&si, sizeof(SYSTEM_INFO)); ZeroMemory(&si, sizeof(SYSTEM_INFO));
// Check to see if _GetNativeSystemInfo has been initialized. if (!os::Kernel32Dll::GetNativeSystemInfoAvailable()){
if (_GetNativeSystemInfo == NULL) {
HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32.dll"));
_GetNativeSystemInfo =
CAST_TO_FN_PTR(GetNativeSystemInfo_func_type,
GetProcAddress(hKernel32,
"GetNativeSystemInfo"));
if (_GetNativeSystemInfo == NULL)
GetSystemInfo(&si); GetSystemInfo(&si);
} else { } else {
_GetNativeSystemInfo(&si); os::Kernel32Dll::GetNativeSystemInfo(&si);
} }
if (os_vers == 5002) { if (os_vers == 5002) {
if (osvi.wProductType == VER_NT_WORKSTATION && if (osvi.wProductType == VER_NT_WORKSTATION &&
@ -2683,47 +2611,14 @@ int os::vm_allocation_granularity() {
#define MEM_LARGE_PAGES 0x20000000 #define MEM_LARGE_PAGES 0x20000000
#endif #endif
// GetLargePageMinimum is only available on Windows 2003. The other functions
// are available on NT but not on Windows 98/Me. We have to resolve them at
// runtime.
typedef SIZE_T (WINAPI *GetLargePageMinimum_func_type) (void);
typedef BOOL (WINAPI *AdjustTokenPrivileges_func_type)
(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
typedef BOOL (WINAPI *OpenProcessToken_func_type) (HANDLE, DWORD, PHANDLE);
typedef BOOL (WINAPI *LookupPrivilegeValue_func_type) (LPCTSTR, LPCTSTR, PLUID);
static GetLargePageMinimum_func_type _GetLargePageMinimum;
static AdjustTokenPrivileges_func_type _AdjustTokenPrivileges;
static OpenProcessToken_func_type _OpenProcessToken;
static LookupPrivilegeValue_func_type _LookupPrivilegeValue;
static HINSTANCE _kernel32;
static HINSTANCE _advapi32;
static HANDLE _hProcess; static HANDLE _hProcess;
static HANDLE _hToken; static HANDLE _hToken;
static size_t _large_page_size = 0; static size_t _large_page_size = 0;
static bool resolve_functions_for_large_page_init() { static bool resolve_functions_for_large_page_init() {
_kernel32 = LoadLibrary("kernel32.dll"); return os::Kernel32Dll::GetLargePageMinimumAvailable() &&
if (_kernel32 == NULL) return false; os::Advapi32Dll::AdvapiAvailable();
_GetLargePageMinimum = CAST_TO_FN_PTR(GetLargePageMinimum_func_type,
GetProcAddress(_kernel32, "GetLargePageMinimum"));
if (_GetLargePageMinimum == NULL) return false;
_advapi32 = LoadLibrary("advapi32.dll");
if (_advapi32 == NULL) return false;
_AdjustTokenPrivileges = CAST_TO_FN_PTR(AdjustTokenPrivileges_func_type,
GetProcAddress(_advapi32, "AdjustTokenPrivileges"));
_OpenProcessToken = CAST_TO_FN_PTR(OpenProcessToken_func_type,
GetProcAddress(_advapi32, "OpenProcessToken"));
_LookupPrivilegeValue = CAST_TO_FN_PTR(LookupPrivilegeValue_func_type,
GetProcAddress(_advapi32, "LookupPrivilegeValueA"));
return _AdjustTokenPrivileges != NULL &&
_OpenProcessToken != NULL &&
_LookupPrivilegeValue != NULL;
} }
static bool request_lock_memory_privilege() { static bool request_lock_memory_privilege() {
@ -2732,8 +2627,8 @@ static bool request_lock_memory_privilege() {
LUID luid; LUID luid;
if (_hProcess != NULL && if (_hProcess != NULL &&
_OpenProcessToken(_hProcess, TOKEN_ADJUST_PRIVILEGES, &_hToken) && os::Advapi32Dll::OpenProcessToken(_hProcess, TOKEN_ADJUST_PRIVILEGES, &_hToken) &&
_LookupPrivilegeValue(NULL, "SeLockMemoryPrivilege", &luid)) { os::Advapi32Dll::LookupPrivilegeValue(NULL, "SeLockMemoryPrivilege", &luid)) {
TOKEN_PRIVILEGES tp; TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1; tp.PrivilegeCount = 1;
@ -2742,7 +2637,7 @@ static bool request_lock_memory_privilege() {
// AdjustTokenPrivileges() may return TRUE even when it couldn't change the // AdjustTokenPrivileges() may return TRUE even when it couldn't change the
// privilege. Check GetLastError() too. See MSDN document. // privilege. Check GetLastError() too. See MSDN document.
if (_AdjustTokenPrivileges(_hToken, false, &tp, sizeof(tp), NULL, NULL) && if (os::Advapi32Dll::AdjustTokenPrivileges(_hToken, false, &tp, sizeof(tp), NULL, NULL) &&
(GetLastError() == ERROR_SUCCESS)) { (GetLastError() == ERROR_SUCCESS)) {
return true; return true;
} }
@ -2752,14 +2647,6 @@ static bool request_lock_memory_privilege() {
} }
static void cleanup_after_large_page_init() { static void cleanup_after_large_page_init() {
_GetLargePageMinimum = NULL;
_AdjustTokenPrivileges = NULL;
_OpenProcessToken = NULL;
_LookupPrivilegeValue = NULL;
if (_kernel32) FreeLibrary(_kernel32);
_kernel32 = NULL;
if (_advapi32) FreeLibrary(_advapi32);
_advapi32 = NULL;
if (_hProcess) CloseHandle(_hProcess); if (_hProcess) CloseHandle(_hProcess);
_hProcess = NULL; _hProcess = NULL;
if (_hToken) CloseHandle(_hToken); if (_hToken) CloseHandle(_hToken);
@ -2777,7 +2664,7 @@ void os::large_page_init() {
# define WARN(msg) if (warn_on_failure) { warning(msg); } # define WARN(msg) if (warn_on_failure) { warning(msg); }
if (resolve_functions_for_large_page_init()) { if (resolve_functions_for_large_page_init()) {
if (request_lock_memory_privilege()) { if (request_lock_memory_privilege()) {
size_t s = _GetLargePageMinimum(); size_t s = os::Kernel32Dll::GetLargePageMinimum();
if (s) { if (s) {
#if defined(IA32) || defined(AMD64) #if defined(IA32) || defined(AMD64)
if (s > 4*M || LargePageSizeInBytes > 4*M) { if (s > 4*M || LargePageSizeInBytes > 4*M) {
@ -3190,18 +3077,10 @@ typedef BOOL (WINAPI * STTSignature)(void) ;
os::YieldResult os::NakedYield() { os::YieldResult os::NakedYield() {
// Use either SwitchToThread() or Sleep(0) // Use either SwitchToThread() or Sleep(0)
// Consider passing back the return value from SwitchToThread(). // Consider passing back the return value from SwitchToThread().
// We use GetProcAddress() as ancient Win9X versions of windows doen't support SwitchToThread. if (os::Kernel32Dll::SwitchToThreadAvailable()) {
// In that case we revert to Sleep(0). return SwitchToThread() ? os::YIELD_SWITCHED : os::YIELD_NONEREADY ;
static volatile STTSignature stt = (STTSignature) 1 ;
if (stt == ((STTSignature) 1)) {
stt = (STTSignature) ::GetProcAddress (LoadLibrary ("Kernel32.dll"), "SwitchToThread") ;
// It's OK if threads race during initialization as the operation above is idempotent.
}
if (stt != NULL) {
return (*stt)() ? os::YIELD_SWITCHED : os::YIELD_NONEREADY ;
} else { } else {
Sleep (0) ; Sleep(0);
} }
return os::YIELD_UNKNOWN ; return os::YIELD_UNKNOWN ;
} }
@ -3425,6 +3304,44 @@ void os::win32::initialize_system_info() {
} }
HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf, int ebuflen) {
char path[MAX_PATH];
DWORD size;
DWORD pathLen = (DWORD)sizeof(path);
HINSTANCE result = NULL;
// only allow library name without path component
assert(strchr(name, '\\') == NULL, "path not allowed");
assert(strchr(name, ':') == NULL, "path not allowed");
if (strchr(name, '\\') != NULL || strchr(name, ':') != NULL) {
jio_snprintf(ebuf, ebuflen,
"Invalid parameter while calling os::win32::load_windows_dll(): cannot take path: %s", name);
return NULL;
}
// search system directory
if ((size = GetSystemDirectory(path, pathLen)) > 0) {
strcat(path, "\\");
strcat(path, name);
if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) {
return result;
}
}
// try Windows directory
if ((size = GetWindowsDirectory(path, pathLen)) > 0) {
strcat(path, "\\");
strcat(path, name);
if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) {
return result;
}
}
jio_snprintf(ebuf, ebuflen,
"os::win32::load_windows_dll() cannot load %s from system directories.", name);
return NULL;
}
void os::win32::setmode_streams() { void os::win32::setmode_streams() {
_setmode(_fileno(stdin), _O_BINARY); _setmode(_fileno(stdin), _O_BINARY);
_setmode(_fileno(stdout), _O_BINARY); _setmode(_fileno(stdout), _O_BINARY);
@ -3658,10 +3575,6 @@ jint os::init_2(void) {
} }
} }
// initialize PSAPI or ToolHelp for fatal error handler
if (win32::is_nt()) _init_psapi();
else _init_toolhelp();
#ifndef _WIN64 #ifndef _WIN64
// Print something if NX is enabled (win32 on AMD64) // Print something if NX is enabled (win32 on AMD64)
NOT_PRODUCT(if (PrintMiscellaneous && Verbose) nx_check_protection()); NOT_PRODUCT(if (PrintMiscellaneous && Verbose) nx_check_protection());
@ -4708,12 +4621,6 @@ static int getLastErrorString(char *buf, size_t len)
// We don't build a headless jre for Windows // We don't build a headless jre for Windows
bool os::is_headless_jre() { return false; } bool os::is_headless_jre() { return false; }
// OS_SocketInterface
// Not used on Windows
// OS_SocketInterface
typedef struct hostent * (PASCAL FAR *ws2_ifn_ptr_t)(...);
ws2_ifn_ptr_t *get_host_by_name_fn = NULL;
typedef CRITICAL_SECTION mutex_t; typedef CRITICAL_SECTION mutex_t;
#define mutexInit(m) InitializeCriticalSection(m) #define mutexInit(m) InitializeCriticalSection(m)
@ -4721,58 +4628,36 @@ typedef CRITICAL_SECTION mutex_t;
#define mutexLock(m) EnterCriticalSection(m) #define mutexLock(m) EnterCriticalSection(m)
#define mutexUnlock(m) LeaveCriticalSection(m) #define mutexUnlock(m) LeaveCriticalSection(m)
static bool sockfnptrs_initialized = FALSE; static bool sock_initialized = FALSE;
static mutex_t sockFnTableMutex; static mutex_t sockFnTableMutex;
/* is Winsock2 loaded? better to be explicit than to rely on sockfnptrs */ static void initSock() {
static bool winsock2Available = FALSE;
static void initSockFnTable() {
int (PASCAL FAR* WSAStartupPtr)(WORD, LPWSADATA);
WSADATA wsadata; WSADATA wsadata;
if (!os::WinSock2Dll::WinSock2Available()) {
jio_fprintf(stderr, "Could not load Winsock 2 (error: %d)\n",
::GetLastError());
return;
}
if (sock_initialized == TRUE) return;
::mutexInit(&sockFnTableMutex); ::mutexInit(&sockFnTableMutex);
::mutexLock(&sockFnTableMutex); ::mutexLock(&sockFnTableMutex);
if (os::WinSock2Dll::WSAStartup(MAKEWORD(1,1), &wsadata) != 0) {
if (sockfnptrs_initialized == FALSE) { jio_fprintf(stderr, "Could not initialize Winsock\n");
HMODULE hWinsock;
/* try to load Winsock2, and if that fails, load Winsock */
hWinsock = ::LoadLibrary("ws2_32.dll");
if (hWinsock == NULL) {
jio_fprintf(stderr, "Could not load Winsock 2 (error: %d)\n",
::GetLastError());
return;
}
/* If we loaded a DLL, then we might as well initialize it. */
WSAStartupPtr = (int (PASCAL FAR *)(WORD, LPWSADATA))
::GetProcAddress(hWinsock, "WSAStartup");
if (WSAStartupPtr(MAKEWORD(1,1), &wsadata) != 0) {
jio_fprintf(stderr, "Could not initialize Winsock\n");
}
get_host_by_name_fn
= (ws2_ifn_ptr_t*) GetProcAddress(hWinsock, "gethostbyname");
} }
sock_initialized = TRUE;
assert(get_host_by_name_fn != NULL,
"gethostbyname function not found");
sockfnptrs_initialized = TRUE;
::mutexUnlock(&sockFnTableMutex); ::mutexUnlock(&sockFnTableMutex);
} }
struct hostent* os::get_host_by_name(char* name) { struct hostent* os::get_host_by_name(char* name) {
if (!sockfnptrs_initialized) { if (!sock_initialized) {
initSockFnTable(); initSock();
} }
if (!os::WinSock2Dll::WinSock2Available()) {
assert(sockfnptrs_initialized == TRUE && get_host_by_name_fn != NULL, return NULL;
"sockfnptrs is not initialized or pointer to gethostbyname function is NULL"); }
return (*get_host_by_name_fn)(name); return (struct hostent*)os::WinSock2Dll::gethostbyname(name);
} }
@ -4869,3 +4754,367 @@ int os::set_sock_opt(int fd, int level, int optname,
ShouldNotReachHere(); ShouldNotReachHere();
return 0; return 0;
} }
// Kernel32 API
typedef SIZE_T (WINAPI* GetLargePageMinimum_Fn)(void);
GetLargePageMinimum_Fn os::Kernel32Dll::_GetLargePageMinimum = NULL;
BOOL os::Kernel32Dll::initialized = FALSE;
SIZE_T os::Kernel32Dll::GetLargePageMinimum() {
assert(initialized && _GetLargePageMinimum != NULL,
"GetLargePageMinimumAvailable() not yet called");
return _GetLargePageMinimum();
}
BOOL os::Kernel32Dll::GetLargePageMinimumAvailable() {
if (!initialized) {
initialize();
}
return _GetLargePageMinimum != NULL;
}
#ifndef JDK6_OR_EARLIER
void os::Kernel32Dll::initialize() {
if (!initialized) {
HMODULE handle = ::GetModuleHandle("Kernel32.dll");
assert(handle != NULL, "Just check");
_GetLargePageMinimum = (GetLargePageMinimum_Fn)::GetProcAddress(handle, "GetLargePageMinimum");
initialized = TRUE;
}
}
// Kernel32 API
inline BOOL os::Kernel32Dll::SwitchToThread() {
return ::SwitchToThread();
}
inline BOOL os::Kernel32Dll::SwitchToThreadAvailable() {
return true;
}
// Help tools
inline BOOL os::Kernel32Dll::HelpToolsAvailable() {
return true;
}
inline HANDLE os::Kernel32Dll::CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessId) {
return ::CreateToolhelp32Snapshot(dwFlags, th32ProcessId);
}
inline BOOL os::Kernel32Dll::Module32First(HANDLE hSnapshot,LPMODULEENTRY32 lpme) {
return ::Module32First(hSnapshot, lpme);
}
inline BOOL os::Kernel32Dll::Module32Next(HANDLE hSnapshot,LPMODULEENTRY32 lpme) {
return ::Module32Next(hSnapshot, lpme);
}
inline BOOL os::Kernel32Dll::GetNativeSystemInfoAvailable() {
return true;
}
inline void os::Kernel32Dll::GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) {
::GetNativeSystemInfo(lpSystemInfo);
}
// PSAPI API
inline BOOL os::PSApiDll::EnumProcessModules(HANDLE hProcess, HMODULE *lpModule, DWORD cb, LPDWORD lpcbNeeded) {
return ::EnumProcessModules(hProcess, lpModule, cb, lpcbNeeded);
}
inline DWORD os::PSApiDll::GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize) {
return ::GetModuleFileNameEx(hProcess, hModule, lpFilename, nSize);
}
inline BOOL os::PSApiDll::GetModuleInformation(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb) {
return ::GetModuleInformation(hProcess, hModule, lpmodinfo, cb);
}
inline BOOL os::PSApiDll::PSApiAvailable() {
return true;
}
// WinSock2 API
inline BOOL os::WinSock2Dll::WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) {
return ::WSAStartup(wVersionRequested, lpWSAData);
}
inline struct hostent* os::WinSock2Dll::gethostbyname(const char *name) {
return ::gethostbyname(name);
}
inline BOOL os::WinSock2Dll::WinSock2Available() {
return true;
}
// Advapi API
inline BOOL os::Advapi32Dll::AdjustTokenPrivileges(HANDLE TokenHandle,
BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength) {
return ::AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges, NewState,
BufferLength, PreviousState, ReturnLength);
}
inline BOOL os::Advapi32Dll::OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess,
PHANDLE TokenHandle) {
return ::OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle);
}
inline BOOL os::Advapi32Dll::LookupPrivilegeValue(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid) {
return ::LookupPrivilegeValue(lpSystemName, lpName, lpLuid);
}
inline BOOL os::Advapi32Dll::AdvapiAvailable() {
return true;
}
#else
// Kernel32 API
typedef BOOL (WINAPI* SwitchToThread_Fn)(void);
typedef HANDLE (WINAPI* CreateToolhelp32Snapshot_Fn)(DWORD,DWORD);
typedef BOOL (WINAPI* Module32First_Fn)(HANDLE,LPMODULEENTRY32);
typedef BOOL (WINAPI* Module32Next_Fn)(HANDLE,LPMODULEENTRY32);
typedef void (WINAPI* GetNativeSystemInfo_Fn)(LPSYSTEM_INFO);
SwitchToThread_Fn os::Kernel32Dll::_SwitchToThread = NULL;
CreateToolhelp32Snapshot_Fn os::Kernel32Dll::_CreateToolhelp32Snapshot = NULL;
Module32First_Fn os::Kernel32Dll::_Module32First = NULL;
Module32Next_Fn os::Kernel32Dll::_Module32Next = NULL;
GetNativeSystemInfo_Fn os::Kernel32Dll::_GetNativeSystemInfo = NULL;
void os::Kernel32Dll::initialize() {
if (!initialized) {
HMODULE handle = ::GetModuleHandle("Kernel32.dll");
assert(handle != NULL, "Just check");
_SwitchToThread = (SwitchToThread_Fn)::GetProcAddress(handle, "SwitchToThread");
_GetLargePageMinimum = (GetLargePageMinimum_Fn)::GetProcAddress(handle, "GetLargePageMinimum");
_CreateToolhelp32Snapshot = (CreateToolhelp32Snapshot_Fn)
::GetProcAddress(handle, "CreateToolhelp32Snapshot");
_Module32First = (Module32First_Fn)::GetProcAddress(handle, "Module32First");
_Module32Next = (Module32Next_Fn)::GetProcAddress(handle, "Module32Next");
_GetNativeSystemInfo = (GetNativeSystemInfo_Fn)::GetProcAddress(handle, "GetNativeSystemInfo");
initialized = TRUE;
}
}
BOOL os::Kernel32Dll::SwitchToThread() {
assert(initialized && _SwitchToThread != NULL,
"SwitchToThreadAvailable() not yet called");
return _SwitchToThread();
}
BOOL os::Kernel32Dll::SwitchToThreadAvailable() {
if (!initialized) {
initialize();
}
return _SwitchToThread != NULL;
}
// Help tools
BOOL os::Kernel32Dll::HelpToolsAvailable() {
if (!initialized) {
initialize();
}
return _CreateToolhelp32Snapshot != NULL &&
_Module32First != NULL &&
_Module32Next != NULL;
}
HANDLE os::Kernel32Dll::CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessId) {
assert(initialized && _CreateToolhelp32Snapshot != NULL,
"HelpToolsAvailable() not yet called");
return _CreateToolhelp32Snapshot(dwFlags, th32ProcessId);
}
BOOL os::Kernel32Dll::Module32First(HANDLE hSnapshot,LPMODULEENTRY32 lpme) {
assert(initialized && _Module32First != NULL,
"HelpToolsAvailable() not yet called");
return _Module32First(hSnapshot, lpme);
}
inline BOOL os::Kernel32Dll::Module32Next(HANDLE hSnapshot,LPMODULEENTRY32 lpme) {
assert(initialized && _Module32Next != NULL,
"HelpToolsAvailable() not yet called");
return _Module32Next(hSnapshot, lpme);
}
BOOL os::Kernel32Dll::GetNativeSystemInfoAvailable() {
if (!initialized) {
initialize();
}
return _GetNativeSystemInfo != NULL;
}
void os::Kernel32Dll::GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) {
assert(initialized && _GetNativeSystemInfo != NULL,
"GetNativeSystemInfoAvailable() not yet called");
_GetNativeSystemInfo(lpSystemInfo);
}
// PSAPI API
typedef BOOL (WINAPI *EnumProcessModules_Fn)(HANDLE, HMODULE *, DWORD, LPDWORD);
typedef BOOL (WINAPI *GetModuleFileNameEx_Fn)(HANDLE, HMODULE, LPTSTR, DWORD);;
typedef BOOL (WINAPI *GetModuleInformation_Fn)(HANDLE, HMODULE, LPMODULEINFO, DWORD);
EnumProcessModules_Fn os::PSApiDll::_EnumProcessModules = NULL;
GetModuleFileNameEx_Fn os::PSApiDll::_GetModuleFileNameEx = NULL;
GetModuleInformation_Fn os::PSApiDll::_GetModuleInformation = NULL;
BOOL os::PSApiDll::initialized = FALSE;
void os::PSApiDll::initialize() {
if (!initialized) {
HMODULE handle = os::win32::load_Windows_dll("PSAPI.DLL", NULL, 0);
if (handle != NULL) {
_EnumProcessModules = (EnumProcessModules_Fn)::GetProcAddress(handle,
"EnumProcessModules");
_GetModuleFileNameEx = (GetModuleFileNameEx_Fn)::GetProcAddress(handle,
"GetModuleFileNameExA");
_GetModuleInformation = (GetModuleInformation_Fn)::GetProcAddress(handle,
"GetModuleInformation");
}
initialized = TRUE;
}
}
BOOL os::PSApiDll::EnumProcessModules(HANDLE hProcess, HMODULE *lpModule, DWORD cb, LPDWORD lpcbNeeded) {
assert(initialized && _EnumProcessModules != NULL,
"PSApiAvailable() not yet called");
return _EnumProcessModules(hProcess, lpModule, cb, lpcbNeeded);
}
DWORD os::PSApiDll::GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize) {
assert(initialized && _GetModuleFileNameEx != NULL,
"PSApiAvailable() not yet called");
return _GetModuleFileNameEx(hProcess, hModule, lpFilename, nSize);
}
BOOL os::PSApiDll::GetModuleInformation(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb) {
assert(initialized && _GetModuleInformation != NULL,
"PSApiAvailable() not yet called");
return _GetModuleInformation(hProcess, hModule, lpmodinfo, cb);
}
BOOL os::PSApiDll::PSApiAvailable() {
if (!initialized) {
initialize();
}
return _EnumProcessModules != NULL &&
_GetModuleFileNameEx != NULL &&
_GetModuleInformation != NULL;
}
// WinSock2 API
typedef int (PASCAL FAR* WSAStartup_Fn)(WORD, LPWSADATA);
typedef struct hostent *(PASCAL FAR *gethostbyname_Fn)(...);
WSAStartup_Fn os::WinSock2Dll::_WSAStartup = NULL;
gethostbyname_Fn os::WinSock2Dll::_gethostbyname = NULL;
BOOL os::WinSock2Dll::initialized = FALSE;
void os::WinSock2Dll::initialize() {
if (!initialized) {
HMODULE handle = os::win32::load_Windows_dll("ws2_32.dll", NULL, 0);
if (handle != NULL) {
_WSAStartup = (WSAStartup_Fn)::GetProcAddress(handle, "WSAStartup");
_gethostbyname = (gethostbyname_Fn)::GetProcAddress(handle, "gethostbyname");
}
initialized = TRUE;
}
}
BOOL os::WinSock2Dll::WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) {
assert(initialized && _WSAStartup != NULL,
"WinSock2Available() not yet called");
return _WSAStartup(wVersionRequested, lpWSAData);
}
struct hostent* os::WinSock2Dll::gethostbyname(const char *name) {
assert(initialized && _gethostbyname != NULL,
"WinSock2Available() not yet called");
return _gethostbyname(name);
}
BOOL os::WinSock2Dll::WinSock2Available() {
if (!initialized) {
initialize();
}
return _WSAStartup != NULL &&
_gethostbyname != NULL;
}
typedef BOOL (WINAPI *AdjustTokenPrivileges_Fn)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
typedef BOOL (WINAPI *OpenProcessToken_Fn)(HANDLE, DWORD, PHANDLE);
typedef BOOL (WINAPI *LookupPrivilegeValue_Fn)(LPCTSTR, LPCTSTR, PLUID);
AdjustTokenPrivileges_Fn os::Advapi32Dll::_AdjustTokenPrivileges = NULL;
OpenProcessToken_Fn os::Advapi32Dll::_OpenProcessToken = NULL;
LookupPrivilegeValue_Fn os::Advapi32Dll::_LookupPrivilegeValue = NULL;
BOOL os::Advapi32Dll::initialized = FALSE;
void os::Advapi32Dll::initialize() {
if (!initialized) {
HMODULE handle = os::win32::load_Windows_dll("advapi32.dll", NULL, 0);
if (handle != NULL) {
_AdjustTokenPrivileges = (AdjustTokenPrivileges_Fn)::GetProcAddress(handle,
"AdjustTokenPrivileges");
_OpenProcessToken = (OpenProcessToken_Fn)::GetProcAddress(handle,
"OpenProcessToken");
_LookupPrivilegeValue = (LookupPrivilegeValue_Fn)::GetProcAddress(handle,
"LookupPrivilegeValueA");
}
initialized = TRUE;
}
}
BOOL os::Advapi32Dll::AdjustTokenPrivileges(HANDLE TokenHandle,
BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength) {
assert(initialized && _AdjustTokenPrivileges != NULL,
"AdvapiAvailable() not yet called");
return _AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges, NewState,
BufferLength, PreviousState, ReturnLength);
}
BOOL os::Advapi32Dll::OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess,
PHANDLE TokenHandle) {
assert(initialized && _OpenProcessToken != NULL,
"AdvapiAvailable() not yet called");
return _OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle);
}
BOOL os::Advapi32Dll::LookupPrivilegeValue(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid) {
assert(initialized && _LookupPrivilegeValue != NULL,
"AdvapiAvailable() not yet called");
return _LookupPrivilegeValue(lpSystemName, lpName, lpLuid);
}
BOOL os::Advapi32Dll::AdvapiAvailable() {
if (!initialized) {
initialize();
}
return _AdjustTokenPrivileges != NULL &&
_OpenProcessToken != NULL &&
_LookupPrivilegeValue != NULL;
}
#endif

View File

@ -24,7 +24,6 @@
#ifndef OS_WINDOWS_VM_OS_WINDOWS_HPP #ifndef OS_WINDOWS_VM_OS_WINDOWS_HPP
#define OS_WINDOWS_VM_OS_WINDOWS_HPP #define OS_WINDOWS_VM_OS_WINDOWS_HPP
// Win32_OS defines the interface to windows operating systems // Win32_OS defines the interface to windows operating systems
class win32 { class win32 {
@ -55,6 +54,9 @@ class win32 {
static julong available_memory(); static julong available_memory();
static julong physical_memory() { return _physical_memory; } static julong physical_memory() { return _physical_memory; }
// load dll from Windows system directory or Windows directory
static HINSTANCE load_Windows_dll(const char* name, char *ebuf, int ebuflen);
public: public:
// Generic interface: // Generic interface:
@ -132,4 +134,100 @@ class PlatformParker : public CHeapObj {
} ; } ;
// JDK7 requires VS2010
#if _MSC_VER < 1600
#define JDK6_OR_EARLIER 1
#endif
class WinSock2Dll: AllStatic {
public:
static BOOL WSAStartup(WORD, LPWSADATA);
static struct hostent* gethostbyname(const char *name);
static BOOL WinSock2Available();
#ifdef JDK6_OR_EARLIER
private:
static int (PASCAL FAR* _WSAStartup)(WORD, LPWSADATA);
static struct hostent *(PASCAL FAR *_gethostbyname)(...);
static BOOL initialized;
static void initialize();
#endif
};
class Kernel32Dll: AllStatic {
public:
static BOOL SwitchToThread();
static SIZE_T GetLargePageMinimum();
static BOOL SwitchToThreadAvailable();
static BOOL GetLargePageMinimumAvailable();
// Help tools
static BOOL HelpToolsAvailable();
static HANDLE CreateToolhelp32Snapshot(DWORD,DWORD);
static BOOL Module32First(HANDLE,LPMODULEENTRY32);
static BOOL Module32Next(HANDLE,LPMODULEENTRY32);
static BOOL GetNativeSystemInfoAvailable();
static void GetNativeSystemInfo(LPSYSTEM_INFO);
private:
// GetLargePageMinimum available on Windows Vista/Windows Server 2003
// and later
static SIZE_T (WINAPI *_GetLargePageMinimum)(void);
static BOOL initialized;
static void initialize();
#ifdef JDK6_OR_EARLIER
private:
static BOOL (WINAPI *_SwitchToThread)(void);
static HANDLE (WINAPI* _CreateToolhelp32Snapshot)(DWORD,DWORD);
static BOOL (WINAPI* _Module32First)(HANDLE,LPMODULEENTRY32);
static BOOL (WINAPI* _Module32Next)(HANDLE,LPMODULEENTRY32);
static void (WINAPI *_GetNativeSystemInfo)(LPSYSTEM_INFO);
#endif
};
class Advapi32Dll: AllStatic {
public:
static BOOL AdjustTokenPrivileges(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
static BOOL OpenProcessToken(HANDLE, DWORD, PHANDLE);
static BOOL LookupPrivilegeValue(LPCTSTR, LPCTSTR, PLUID);
static BOOL AdvapiAvailable();
#ifdef JDK6_OR_EARLIER
private:
static BOOL (WINAPI *_AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
static BOOL (WINAPI *_OpenProcessToken)(HANDLE, DWORD, PHANDLE);
static BOOL (WINAPI *_LookupPrivilegeValue)(LPCTSTR, LPCTSTR, PLUID);
static BOOL initialized;
static void initialize();
#endif
};
class PSApiDll: AllStatic {
public:
static BOOL EnumProcessModules(HANDLE, HMODULE *, DWORD, LPDWORD);
static DWORD GetModuleFileNameEx(HANDLE, HMODULE, LPTSTR, DWORD);
static BOOL GetModuleInformation(HANDLE, HMODULE, LPMODULEINFO, DWORD);
static BOOL PSApiAvailable();
#ifdef JDK6_OR_EARLIER
private:
static BOOL (WINAPI *_EnumProcessModules)(HANDLE, HMODULE *, DWORD, LPDWORD);
static BOOL (WINAPI *_GetModuleFileNameEx)(HANDLE, HMODULE, LPTSTR, DWORD);;
static BOOL (WINAPI *_GetModuleInformation)(HANDLE, HMODULE, LPMODULEINFO, DWORD);
static BOOL initialized;
static void initialize();
#endif
};
#endif // OS_WINDOWS_VM_OS_WINDOWS_HPP #endif // OS_WINDOWS_VM_OS_WINDOWS_HPP

View File

@ -154,7 +154,7 @@ void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
return 5; return MachNode::size(ra_);
} }
%} %}

View File

@ -167,7 +167,8 @@ void MachBreakpointNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
} }
uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const { uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
return 5; // distance could be far and requires load and call through register
return MachNode::size(ra_);
} }
%} %}

View File

@ -1,5 +1,5 @@
!! !!
!! Copyright (c) 2005, 2008 Oracle and/or its affiliates. All rights reserved. !! Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
!! DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. !! DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
!! !!
!! This code is free software; you can redistribute it and/or modify it !! This code is free software; you can redistribute it and/or modify it

View File

@ -114,6 +114,11 @@ int VM_Version::platform_features(int features) {
#endif #endif
if (av & AV_SPARC_VIS3) features |= vis3_instructions_m; if (av & AV_SPARC_VIS3) features |= vis3_instructions_m;
#ifndef AV_SPARC_CBCOND
#define AV_SPARC_CBCOND 0x10000000 /* compare and branch instrs supported */
#endif
if (av & AV_SPARC_CBCOND) features |= cbcond_instructions_m;
} else { } else {
// getisax(2) failed, use the old legacy code. // getisax(2) failed, use the old legacy code.
#ifndef PRODUCT #ifndef PRODUCT

View File

@ -161,7 +161,7 @@ void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
return 5; return MachNode::size(ra_);
} }
%} %}

View File

@ -180,7 +180,8 @@ void MachBreakpointNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const
{ {
return 5; // distance could be far and requires load and call through register
return MachNode::size(ra_);
} }
%} %}

View File

@ -482,7 +482,7 @@ class CompilerInterfaceVC10 extends CompilerInterface {
"/export:JVM_GetThreadStateNames "+ "/export:JVM_GetThreadStateNames "+
"/export:JVM_GetThreadStateValues "+ "/export:JVM_GetThreadStateValues "+
"/export:JVM_InitAgentProperties"); "/export:JVM_InitAgentProperties");
addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib"); addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib;psapi.lib");
addAttr(rv, "OutputFile", outDll); addAttr(rv, "OutputFile", outDll);
addAttr(rv, "SuppressStartupBanner", "true"); addAttr(rv, "SuppressStartupBanner", "true");
addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def"); addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def");

View File

@ -1,4 +1,4 @@
Copyright (c) 2008 Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it This code is free software; you can redistribute it and/or modify it

View File

@ -126,9 +126,6 @@ void ADLParser::parse() {
if (_globalNames[AttributeForm::_ins_cost] == NULL) { if (_globalNames[AttributeForm::_ins_cost] == NULL) {
parse_err(SEMERR, "Did not declare 'ins_cost' attribute"); parse_err(SEMERR, "Did not declare 'ins_cost' attribute");
} }
if (_globalNames[AttributeForm::_ins_pc_relative] == NULL) {
parse_err(SEMERR, "Did not declare 'ins_pc_relative' attribute");
}
if (_globalNames[AttributeForm::_op_cost] == NULL) { if (_globalNames[AttributeForm::_op_cost] == NULL) {
parse_err(SEMERR, "Did not declare 'op_cost' attribute"); parse_err(SEMERR, "Did not declare 'op_cost' attribute");
} }

View File

@ -331,10 +331,18 @@ void ArchDesc::inspectInstructions() {
// Find result type for match // Find result type for match
const char *result = instr->reduce_result(); const char *result = instr->reduce_result();
if ( instr->is_ideal_branch() && instr->label_position() == -1 ||
!instr->is_ideal_branch() && instr->label_position() != -1) {
syntax_err(instr->_linenum, "%s: Only branches to a label are supported\n", rootOp);
}
Attribute *attr = instr->_attribs; Attribute *attr = instr->_attribs;
while (attr != NULL) { while (attr != NULL) {
if (strcmp(attr->_ident,"ins_short_branch") == 0 && if (strcmp(attr->_ident,"ins_short_branch") == 0 &&
attr->int_val(*this) != 0) { attr->int_val(*this) != 0) {
if (!instr->is_ideal_branch() || instr->label_position() == -1) {
syntax_err(instr->_linenum, "%s: Only short branch to a label is supported\n", rootOp);
}
instr->set_short_branch(true); instr->set_short_branch(true);
} else if (strcmp(attr->_ident,"ins_alignment") == 0 && } else if (strcmp(attr->_ident,"ins_alignment") == 0 &&
attr->int_val(*this) != 0) { attr->int_val(*this) != 0) {

View File

@ -291,15 +291,6 @@ int InstructForm::is_tls_instruction() const {
} }
// Return 'true' if this instruction matches an ideal 'Copy*' node
bool InstructForm::is_ideal_unlock() const {
return _matrule ? _matrule->is_ideal_unlock() : false;
}
bool InstructForm::is_ideal_call_leaf() const {
return _matrule ? _matrule->is_ideal_call_leaf() : false;
}
// Return 'true' if this instruction matches an ideal 'If' node // Return 'true' if this instruction matches an ideal 'If' node
bool InstructForm::is_ideal_if() const { bool InstructForm::is_ideal_if() const {
if( _matrule == NULL ) return false; if( _matrule == NULL ) return false;
@ -349,12 +340,11 @@ bool InstructForm::is_ideal_jump() const {
return _matrule->is_ideal_jump(); return _matrule->is_ideal_jump();
} }
// Return 'true' if instruction matches ideal 'If' | 'Goto' | // Return 'true' if instruction matches ideal 'If' | 'Goto' | 'CountedLoopEnd'
// 'CountedLoopEnd' | 'Jump'
bool InstructForm::is_ideal_branch() const { bool InstructForm::is_ideal_branch() const {
if( _matrule == NULL ) return false; if( _matrule == NULL ) return false;
return _matrule->is_ideal_if() || _matrule->is_ideal_goto() || _matrule->is_ideal_jump(); return _matrule->is_ideal_if() || _matrule->is_ideal_goto();
} }
@ -392,7 +382,7 @@ bool InstructForm::is_ideal_nop() const {
bool InstructForm::is_ideal_control() const { bool InstructForm::is_ideal_control() const {
if ( ! _matrule) return false; if ( ! _matrule) return false;
return is_ideal_return() || is_ideal_branch() || is_ideal_halt(); return is_ideal_return() || is_ideal_branch() || _matrule->is_ideal_jump() || is_ideal_halt();
} }
// Return 'true' if this instruction matches an ideal 'Call' node // Return 'true' if this instruction matches an ideal 'Call' node
@ -633,6 +623,8 @@ bool InstructForm::is_wide_memory_kill(FormDict &globals) const {
if( strcmp(_matrule->_opType,"MemBarRelease") == 0 ) return true; if( strcmp(_matrule->_opType,"MemBarRelease") == 0 ) return true;
if( strcmp(_matrule->_opType,"MemBarAcquire") == 0 ) return true; if( strcmp(_matrule->_opType,"MemBarAcquire") == 0 ) return true;
if( strcmp(_matrule->_opType,"MemBarReleaseLock") == 0 ) return true;
if( strcmp(_matrule->_opType,"MemBarAcquireLock") == 0 ) return true;
return false; return false;
} }
@ -1094,6 +1086,9 @@ const char *InstructForm::mach_base_class(FormDict &globals) const {
else if (is_ideal_if()) { else if (is_ideal_if()) {
return "MachIfNode"; return "MachIfNode";
} }
else if (is_ideal_goto()) {
return "MachGotoNode";
}
else if (is_ideal_fastlock()) { else if (is_ideal_fastlock()) {
return "MachFastLockNode"; return "MachFastLockNode";
} }
@ -1185,6 +1180,34 @@ bool InstructForm::check_branch_variant(ArchDesc &AD, InstructForm *short_branch
strcmp(reduce_result(), short_branch->reduce_result()) == 0 && strcmp(reduce_result(), short_branch->reduce_result()) == 0 &&
_matrule->equivalent(AD.globalNames(), short_branch->_matrule)) { _matrule->equivalent(AD.globalNames(), short_branch->_matrule)) {
// The instructions are equivalent. // The instructions are equivalent.
// Now verify that both instructions have the same parameters and
// the same effects. Both branch forms should have the same inputs
// and resulting projections to correctly replace a long branch node
// with corresponding short branch node during code generation.
bool different = false;
if (short_branch->_components.count() != _components.count()) {
different = true;
} else if (_components.count() > 0) {
short_branch->_components.reset();
_components.reset();
Component *comp;
while ((comp = _components.iter()) != NULL) {
Component *short_comp = short_branch->_components.iter();
if (short_comp == NULL ||
short_comp->_type != comp->_type ||
short_comp->_usedef != comp->_usedef) {
different = true;
break;
}
}
if (short_branch->_components.iter() != NULL)
different = true;
}
if (different) {
globalAD->syntax_err(short_branch->_linenum, "Instruction %s and its short form %s have different parameters\n", _ident, short_branch->_ident);
}
if (AD._short_branch_debug) { if (AD._short_branch_debug) {
fprintf(stderr, "Instruction %s has short form %s\n", _ident, short_branch->_ident); fprintf(stderr, "Instruction %s has short form %s\n", _ident, short_branch->_ident);
} }
@ -2706,7 +2729,6 @@ void ConstructRule::output(FILE *fp) {
int AttributeForm::_insId = 0; // start counter at 0 int AttributeForm::_insId = 0; // start counter at 0
int AttributeForm::_opId = 0; // start counter at 0 int AttributeForm::_opId = 0; // start counter at 0
const char* AttributeForm::_ins_cost = "ins_cost"; // required name const char* AttributeForm::_ins_cost = "ins_cost"; // required name
const char* AttributeForm::_ins_pc_relative = "ins_pc_relative";
const char* AttributeForm::_op_cost = "op_cost"; // required name const char* AttributeForm::_op_cost = "op_cost"; // required name
AttributeForm::AttributeForm(char *attr, int type, char *attrdef) AttributeForm::AttributeForm(char *attr, int type, char *attrdef)
@ -3368,7 +3390,9 @@ int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
"ClearArray" "ClearArray"
}; };
int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*); int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);
if( strcmp(_opType,"PrefetchRead")==0 || strcmp(_opType,"PrefetchWrite")==0 ) if( strcmp(_opType,"PrefetchRead")==0 ||
strcmp(_opType,"PrefetchWrite")==0 ||
strcmp(_opType,"PrefetchAllocation")==0 )
return 1; return 1;
if( _lChild ) { if( _lChild ) {
const char *opType = _lChild->_opType; const char *opType = _lChild->_opType;
@ -3623,7 +3647,27 @@ bool MatchNode::equivalent(FormDict &globals, MatchNode *mNode2) {
assert( mNode2->_opType, "Must have _opType"); assert( mNode2->_opType, "Must have _opType");
const Form *form = globals[_opType]; const Form *form = globals[_opType];
const Form *form2 = globals[mNode2->_opType]; const Form *form2 = globals[mNode2->_opType];
return (form == form2); if( form != form2 ) {
return false;
}
// Check that their children also match
if (_lChild ) {
if( !_lChild->equivalent(globals, mNode2->_lChild) )
return false;
} else if (mNode2->_lChild) {
return false; // I have NULL left child, mNode2 has non-NULL left child.
}
if (_rChild ) {
if( !_rChild->equivalent(globals, mNode2->_rChild) )
return false;
} else if (mNode2->_rChild) {
return false; // I have NULL right child, mNode2 has non-NULL right child.
}
// We've made it through the gauntlet.
return true;
} }
//-------------------------- has_commutative_op ------------------------------- //-------------------------- has_commutative_op -------------------------------
@ -3909,19 +3953,6 @@ int MatchRule::is_expensive() const {
return 0; return 0;
} }
bool MatchRule::is_ideal_unlock() const {
if( !_opType ) return false;
return !strcmp(_opType,"Unlock") || !strcmp(_opType,"FastUnlock");
}
bool MatchRule::is_ideal_call_leaf() const {
if( !_opType ) return false;
return !strcmp(_opType,"CallLeaf") ||
!strcmp(_opType,"CallLeafNoFP");
}
bool MatchRule::is_ideal_if() const { bool MatchRule::is_ideal_if() const {
if( !_opType ) return false; if( !_opType ) return false;
return return
@ -3941,6 +3972,8 @@ bool MatchRule::is_ideal_membar() const {
return return
!strcmp(_opType,"MemBarAcquire" ) || !strcmp(_opType,"MemBarAcquire" ) ||
!strcmp(_opType,"MemBarRelease" ) || !strcmp(_opType,"MemBarRelease" ) ||
!strcmp(_opType,"MemBarAcquireLock") ||
!strcmp(_opType,"MemBarReleaseLock") ||
!strcmp(_opType,"MemBarVolatile" ) || !strcmp(_opType,"MemBarVolatile" ) ||
!strcmp(_opType,"MemBarCPUOrder" ) ; !strcmp(_opType,"MemBarCPUOrder" ) ;
} }

View File

@ -145,8 +145,6 @@ public:
virtual int is_empty_encoding() const; // _size=0 and/or _insencode empty virtual int is_empty_encoding() const; // _size=0 and/or _insencode empty
virtual int is_tls_instruction() const; // tlsLoadP rule or ideal ThreadLocal virtual int is_tls_instruction() const; // tlsLoadP rule or ideal ThreadLocal
virtual int is_ideal_copy() const; // node matches ideal 'Copy*' virtual int is_ideal_copy() const; // node matches ideal 'Copy*'
virtual bool is_ideal_unlock() const; // node matches ideal 'Unlock'
virtual bool is_ideal_call_leaf() const; // node matches ideal 'CallLeaf'
virtual bool is_ideal_if() const; // node matches ideal 'If' virtual bool is_ideal_if() const; // node matches ideal 'If'
virtual bool is_ideal_fastlock() const; // node matches 'FastLock' virtual bool is_ideal_fastlock() const; // node matches 'FastLock'
virtual bool is_ideal_membar() const; // node matches ideal 'MemBarXXX' virtual bool is_ideal_membar() const; // node matches ideal 'MemBarXXX'
@ -857,7 +855,6 @@ public:
int type() { return id;} // return this object's "id" int type() { return id;} // return this object's "id"
static const char* _ins_cost; // "ins_cost" static const char* _ins_cost; // "ins_cost"
static const char* _ins_pc_relative; // "ins_pc_relative"
static const char* _op_cost; // "op_cost" static const char* _op_cost; // "op_cost"
void dump(); // Debug printer void dump(); // Debug printer
@ -1002,8 +999,6 @@ public:
bool is_chain_rule(FormDict &globals) const; bool is_chain_rule(FormDict &globals) const;
int is_ideal_copy() const; int is_ideal_copy() const;
int is_expensive() const; // node matches ideal 'CosD' int is_expensive() const; // node matches ideal 'CosD'
bool is_ideal_unlock() const;
bool is_ideal_call_leaf() const;
bool is_ideal_if() const; // node matches ideal 'If' bool is_ideal_if() const; // node matches ideal 'If'
bool is_ideal_fastlock() const; // node matches ideal 'FastLock' bool is_ideal_fastlock() const; // node matches ideal 'FastLock'
bool is_ideal_jump() const; // node matches ideal 'Jump' bool is_ideal_jump() const; // node matches ideal 'Jump'

View File

@ -3088,12 +3088,19 @@ void ArchDesc::defineClasses(FILE *fp) {
int label_position = instr->label_position(); int label_position = instr->label_position();
if( label_position != -1 ) { if( label_position != -1 ) {
// Set the label // Set the label
fprintf(fp,"void %sNode::label_set( Label& label, uint block_num ) {\n", instr->_ident); fprintf(fp,"void %sNode::label_set( Label* label, uint block_num ) {\n", instr->_ident);
fprintf(fp," labelOper* oper = (labelOper*)(opnd_array(%d));\n", fprintf(fp," labelOper* oper = (labelOper*)(opnd_array(%d));\n",
label_position ); label_position );
fprintf(fp," oper->_label = &label;\n"); fprintf(fp," oper->_label = label;\n");
fprintf(fp," oper->_block_num = block_num;\n"); fprintf(fp," oper->_block_num = block_num;\n");
fprintf(fp,"}\n"); fprintf(fp,"}\n");
// Save the label
fprintf(fp,"void %sNode::save_label( Label** label, uint* block_num ) {\n", instr->_ident);
fprintf(fp," labelOper* oper = (labelOper*)(opnd_array(%d));\n",
label_position );
fprintf(fp," *label = oper->_label;\n");
fprintf(fp," *block_num = oper->_block_num;\n");
fprintf(fp,"}\n");
} }
} }

View File

@ -1519,8 +1519,9 @@ void ArchDesc::declareClasses(FILE *fp) {
// Declare Node::methods that set operand Label's contents // Declare Node::methods that set operand Label's contents
int label_position = instr->label_position(); int label_position = instr->label_position();
if( label_position != -1 ) { if( label_position != -1 ) {
// Set the label, stored in labelOper::_branch_label // Set/Save the label, stored in labelOper::_branch_label
fprintf(fp," virtual void label_set( Label& label, uint block_num );\n"); fprintf(fp," virtual void label_set( Label* label, uint block_num );\n");
fprintf(fp," virtual void save_label( Label** label, uint* block_num );\n");
} }
// If this instruction contains a methodOper // If this instruction contains a methodOper
@ -1536,16 +1537,16 @@ void ArchDesc::declareClasses(FILE *fp) {
// Each instruction attribute results in a virtual call of same name. // Each instruction attribute results in a virtual call of same name.
// The ins_cost is not handled here. // The ins_cost is not handled here.
Attribute *attr = instr->_attribs; Attribute *attr = instr->_attribs;
bool is_pc_relative = false; bool avoid_back_to_back = false;
while (attr != NULL) { while (attr != NULL) {
if (strcmp(attr->_ident,"ins_cost") && if (strcmp(attr->_ident,"ins_cost") &&
strcmp(attr->_ident,"ins_pc_relative")) { strcmp(attr->_ident,"ins_short_branch")) {
fprintf(fp," int %s() const { return %s; }\n", fprintf(fp," int %s() const { return %s; }\n",
attr->_ident, attr->_val); attr->_ident, attr->_val);
} }
// Check value for ins_pc_relative, and if it is true (1), set the flag // Check value for ins_avoid_back_to_back, and if it is true (1), set the flag
if (!strcmp(attr->_ident,"ins_pc_relative") && attr->int_val(*this) != 0) if (!strcmp(attr->_ident,"ins_avoid_back_to_back") && attr->int_val(*this) != 0)
is_pc_relative = true; avoid_back_to_back = true;
attr = (Attribute *)attr->_next; attr = (Attribute *)attr->_next;
} }
@ -1657,20 +1658,10 @@ void ArchDesc::declareClasses(FILE *fp) {
fprintf(fp," _num_opnds = %d; _opnds = _opnd_array; ", instr->num_opnds()); fprintf(fp," _num_opnds = %d; _opnds = _opnd_array; ", instr->num_opnds());
bool node_flags_set = false; bool node_flags_set = false;
// flag: if this instruction matches an ideal 'Goto' node
if ( instr->is_ideal_goto() ) {
fprintf(fp,"init_flags(Flag_is_Goto");
node_flags_set = true;
}
// flag: if this instruction matches an ideal 'Copy*' node // flag: if this instruction matches an ideal 'Copy*' node
if ( instr->is_ideal_copy() != 0 ) { if ( instr->is_ideal_copy() != 0 ) {
if ( node_flags_set ) { fprintf(fp,"init_flags(Flag_is_Copy");
fprintf(fp," | Flag_is_Copy"); node_flags_set = true;
} else {
fprintf(fp,"init_flags(Flag_is_Copy");
node_flags_set = true;
}
} }
// Is an instruction is a constant? If so, get its type // Is an instruction is a constant? If so, get its type
@ -1688,16 +1679,6 @@ void ArchDesc::declareClasses(FILE *fp) {
} }
} }
// flag: if instruction matches 'If' | 'Goto' | 'CountedLoopEnd | 'Jump'
if ( instr->is_ideal_branch() ) {
if ( node_flags_set ) {
fprintf(fp," | Flag_is_Branch");
} else {
fprintf(fp,"init_flags(Flag_is_Branch");
node_flags_set = true;
}
}
// flag: if this instruction is cisc alternate // flag: if this instruction is cisc alternate
if ( can_cisc_spill() && instr->is_cisc_alternate() ) { if ( can_cisc_spill() && instr->is_cisc_alternate() ) {
if ( node_flags_set ) { if ( node_flags_set ) {
@ -1708,16 +1689,6 @@ void ArchDesc::declareClasses(FILE *fp) {
} }
} }
// flag: if this instruction is pc relative
if ( is_pc_relative ) {
if ( node_flags_set ) {
fprintf(fp," | Flag_is_pc_relative");
} else {
fprintf(fp,"init_flags(Flag_is_pc_relative");
node_flags_set = true;
}
}
// flag: if this instruction has short branch form // flag: if this instruction has short branch form
if ( instr->has_short_branch_form() ) { if ( instr->has_short_branch_form() ) {
if ( node_flags_set ) { if ( node_flags_set ) {
@ -1728,6 +1699,16 @@ void ArchDesc::declareClasses(FILE *fp) {
} }
} }
// flag: if this instruction should not be generated back to back.
if ( avoid_back_to_back ) {
if ( node_flags_set ) {
fprintf(fp," | Flag_avoid_back_to_back");
} else {
fprintf(fp,"init_flags(Flag_avoid_back_to_back");
node_flags_set = true;
}
}
// Check if machine instructions that USE memory, but do not DEF memory, // Check if machine instructions that USE memory, but do not DEF memory,
// depend upon a node that defines memory in machine-independent graph. // depend upon a node that defines memory in machine-independent graph.
if ( instr->needs_anti_dependence_check(_globalNames) ) { if ( instr->needs_anti_dependence_check(_globalNames) ) {
@ -1743,10 +1724,6 @@ void ArchDesc::declareClasses(FILE *fp) {
fprintf(fp,"); "); fprintf(fp,"); ");
} }
if (instr->is_ideal_unlock() || instr->is_ideal_call_leaf()) {
fprintf(fp,"clear_flag(Flag_is_safepoint_node); ");
}
fprintf(fp,"}\n"); fprintf(fp,"}\n");
// size_of, used by base class's clone to obtain the correct size. // size_of, used by base class's clone to obtain the correct size.

View File

@ -3033,6 +3033,9 @@ bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known) {
if (callee->should_exclude()) { if (callee->should_exclude()) {
// callee is excluded // callee is excluded
INLINE_BAILOUT("excluded by CompilerOracle") INLINE_BAILOUT("excluded by CompilerOracle")
} else if (callee->should_not_inline()) {
// callee is excluded
INLINE_BAILOUT("disallowed by CompilerOracle")
} else if (!callee->can_be_compiled()) { } else if (!callee->can_be_compiled()) {
// callee is not compilable (prob. has breakpoints) // callee is not compilable (prob. has breakpoints)
INLINE_BAILOUT("not compilable") INLINE_BAILOUT("not compilable")
@ -3410,24 +3413,6 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) {
// Proper inlining of methods with jsrs requires a little more work. // Proper inlining of methods with jsrs requires a little more work.
if (callee->has_jsrs() ) INLINE_BAILOUT("jsrs not handled properly by inliner yet"); if (callee->has_jsrs() ) INLINE_BAILOUT("jsrs not handled properly by inliner yet");
// now perform tests that are based on flag settings
if (inline_level() > MaxInlineLevel ) INLINE_BAILOUT("too-deep inlining");
if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("too-deep recursive inlining");
if (callee->code_size() > max_inline_size() ) INLINE_BAILOUT("callee is too large");
// don't inline throwable methods unless the inlining tree is rooted in a throwable class
if (callee->name() == ciSymbol::object_initializer_name() &&
callee->holder()->is_subclass_of(ciEnv::current()->Throwable_klass())) {
// Throwable constructor call
IRScope* top = scope();
while (top->caller() != NULL) {
top = top->caller();
}
if (!top->method()->holder()->is_subclass_of(ciEnv::current()->Throwable_klass())) {
INLINE_BAILOUT("don't inline Throwable constructors");
}
}
// When SSE2 is used on intel, then no special handling is needed // When SSE2 is used on intel, then no special handling is needed
// for strictfp because the enum-constant is fixed at compile time, // for strictfp because the enum-constant is fixed at compile time,
// the check for UseSSE2 is needed here // the check for UseSSE2 is needed here
@ -3435,13 +3420,36 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) {
INLINE_BAILOUT("caller and callee have different strict fp requirements"); INLINE_BAILOUT("caller and callee have different strict fp requirements");
} }
if (compilation()->env()->num_inlined_bytecodes() > DesiredMethodLimit) {
INLINE_BAILOUT("total inlining greater than DesiredMethodLimit");
}
if (is_profiling() && !callee->ensure_method_data()) { if (is_profiling() && !callee->ensure_method_data()) {
INLINE_BAILOUT("mdo allocation failed"); INLINE_BAILOUT("mdo allocation failed");
} }
// now perform tests that are based on flag settings
if (callee->should_inline()) {
// ignore heuristic controls on inlining
} else {
if (inline_level() > MaxInlineLevel ) INLINE_BAILOUT("too-deep inlining");
if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("too-deep recursive inlining");
if (callee->code_size() > max_inline_size() ) INLINE_BAILOUT("callee is too large");
// don't inline throwable methods unless the inlining tree is rooted in a throwable class
if (callee->name() == ciSymbol::object_initializer_name() &&
callee->holder()->is_subclass_of(ciEnv::current()->Throwable_klass())) {
// Throwable constructor call
IRScope* top = scope();
while (top->caller() != NULL) {
top = top->caller();
}
if (!top->method()->holder()->is_subclass_of(ciEnv::current()->Throwable_klass())) {
INLINE_BAILOUT("don't inline Throwable constructors");
}
}
if (compilation()->env()->num_inlined_bytecodes() > DesiredMethodLimit) {
INLINE_BAILOUT("total inlining greater than DesiredMethodLimit");
}
}
#ifndef PRODUCT #ifndef PRODUCT
// printing // printing
if (PrintInlining) { if (PrintInlining) {

View File

@ -28,6 +28,16 @@
// ciCallSite // ciCallSite
bool ciCallSite::is_constant_call_site() {
return klass()->is_subclass_of(CURRENT_ENV->ConstantCallSite_klass());
}
bool ciCallSite::is_mutable_call_site() {
return klass()->is_subclass_of(CURRENT_ENV->MutableCallSite_klass());
}
bool ciCallSite::is_volatile_call_site() {
return klass()->is_subclass_of(CURRENT_ENV->VolatileCallSite_klass());
}
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciCallSite::get_target // ciCallSite::get_target
// //

View File

@ -37,6 +37,10 @@ public:
// What kind of ciObject is this? // What kind of ciObject is this?
bool is_call_site() const { return true; } bool is_call_site() const { return true; }
bool is_constant_call_site();
bool is_mutable_call_site();
bool is_volatile_call_site();
// Return the target MethodHandle of this CallSite. // Return the target MethodHandle of this CallSite.
ciMethodHandle* get_target() const; ciMethodHandle* get_target() const;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -178,6 +178,8 @@ public:
bool is_volatile () { return flags().is_volatile(); } bool is_volatile () { return flags().is_volatile(); }
bool is_transient () { return flags().is_transient(); } bool is_transient () { return flags().is_transient(); }
bool is_call_site_target() { return ((holder() == CURRENT_ENV->CallSite_klass()) && (name() == ciSymbol::target_name())); }
// Debugging output // Debugging output
void print(); void print();
void print_name_on(outputStream* st); void print_name_on(outputStream* st);

View File

@ -1350,13 +1350,13 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
_codecache_sweep_counter = 0; _codecache_sweep_counter = 0;
} }
// Force compilation // Force compilation
CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_initial_compile, CompileBroker::compile_method(m, InvocationEntryBci, CompilationPolicy::policy()->initial_compile_level(),
methodHandle(), 0, "CTW", THREAD); methodHandle(), 0, "CTW", THREAD);
if (HAS_PENDING_EXCEPTION) { if (HAS_PENDING_EXCEPTION) {
clear_pending_exception_if_not_oom(CHECK); clear_pending_exception_if_not_oom(CHECK);
tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_counter, m->name()->as_C_string()); tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_counter, m->name()->as_C_string());
} }
if (TieredCompilation) { if (TieredCompilation && TieredStopAtLevel >= CompLevel_full_optimization) {
// Clobber the first compile and force second tier compilation // Clobber the first compile and force second tier compilation
nmethod* nm = m->code(); nmethod* nm = m->code();
if (nm != NULL) { if (nm != NULL) {

View File

@ -1019,6 +1019,16 @@ void java_lang_ThreadGroup::compute_offsets() {
compute_offset(_ngroups_offset, k, vmSymbols::ngroups_name(), vmSymbols::int_signature()); compute_offset(_ngroups_offset, k, vmSymbols::ngroups_name(), vmSymbols::int_signature());
} }
oop java_lang_Throwable::unassigned_stacktrace() {
instanceKlass* ik = instanceKlass::cast(SystemDictionary::Throwable_klass());
address addr = ik->static_field_addr(static_unassigned_stacktrace_offset);
if (UseCompressedOops) {
return oopDesc::load_decode_heap_oop((narrowOop *)addr);
} else {
return oopDesc::load_decode_heap_oop((oop*)addr);
}
}
oop java_lang_Throwable::backtrace(oop throwable) { oop java_lang_Throwable::backtrace(oop throwable) {
return throwable->obj_field_acquire(backtrace_offset); return throwable->obj_field_acquire(backtrace_offset);
} }
@ -1044,9 +1054,13 @@ void java_lang_Throwable::set_message(oop throwable, oop value) {
} }
void java_lang_Throwable::set_stacktrace(oop throwable, oop st_element_array) {
throwable->obj_field_put(stackTrace_offset, st_element_array);
}
void java_lang_Throwable::clear_stacktrace(oop throwable) { void java_lang_Throwable::clear_stacktrace(oop throwable) {
assert(JDK_Version::is_gte_jdk14x_version(), "should only be called in >= 1.4"); assert(JDK_Version::is_gte_jdk14x_version(), "should only be called in >= 1.4");
throwable->obj_field_put(stackTrace_offset, NULL); set_stacktrace(throwable, NULL);
} }
@ -1340,6 +1354,7 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle met
if (JDK_Version::is_gte_jdk14x_version()) { if (JDK_Version::is_gte_jdk14x_version()) {
// New since 1.4, clear lazily constructed Java level stacktrace if // New since 1.4, clear lazily constructed Java level stacktrace if
// refilling occurs // refilling occurs
// This is unnecessary in 1.7+ but harmless
clear_stacktrace(throwable()); clear_stacktrace(throwable());
} }
@ -1541,6 +1556,15 @@ void java_lang_Throwable::fill_in_stack_trace_of_preallocated_backtrace(Handle t
// Bail-out for deep stacks // Bail-out for deep stacks
if (chunk_count >= max_chunks) break; if (chunk_count >= max_chunks) break;
} }
// For Java 7+ we support the Throwable immutability protocol defined for Java 7. This support
// was missing in 7u0 so in 7u0 there is a workaround in the Throwable class. That workaround
// can be removed in a JDK using this JVM version
if (JDK_Version::is_gte_jdk17x_version()) {
java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace());
assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized");
}
} }
@ -2770,6 +2794,7 @@ int java_lang_Throwable::backtrace_offset;
int java_lang_Throwable::detailMessage_offset; int java_lang_Throwable::detailMessage_offset;
int java_lang_Throwable::cause_offset; int java_lang_Throwable::cause_offset;
int java_lang_Throwable::stackTrace_offset; int java_lang_Throwable::stackTrace_offset;
int java_lang_Throwable::static_unassigned_stacktrace_offset;
int java_lang_reflect_AccessibleObject::override_offset; int java_lang_reflect_AccessibleObject::override_offset;
int java_lang_reflect_Method::clazz_offset; int java_lang_reflect_Method::clazz_offset;
int java_lang_reflect_Method::name_offset; int java_lang_reflect_Method::name_offset;
@ -2947,6 +2972,7 @@ void JavaClasses::compute_hard_coded_offsets() {
java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header; java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header;
java_lang_Throwable::cause_offset = java_lang_Throwable::hc_cause_offset * x + header; java_lang_Throwable::cause_offset = java_lang_Throwable::hc_cause_offset * x + header;
java_lang_Throwable::stackTrace_offset = java_lang_Throwable::hc_stackTrace_offset * x + header; java_lang_Throwable::stackTrace_offset = java_lang_Throwable::hc_stackTrace_offset * x + header;
java_lang_Throwable::static_unassigned_stacktrace_offset = java_lang_Throwable::hc_static_unassigned_stacktrace_offset * x;
// java_lang_boxing_object // java_lang_boxing_object
java_lang_boxing_object::value_offset = java_lang_boxing_object::hc_value_offset + header; java_lang_boxing_object::value_offset = java_lang_boxing_object::hc_value_offset + header;

View File

@ -393,6 +393,9 @@ class java_lang_Throwable: AllStatic {
hc_cause_offset = 2, // New since 1.4 hc_cause_offset = 2, // New since 1.4
hc_stackTrace_offset = 3 // New since 1.4 hc_stackTrace_offset = 3 // New since 1.4
}; };
enum {
hc_static_unassigned_stacktrace_offset = 0 // New since 1.7
};
// Trace constants // Trace constants
enum { enum {
trace_methods_offset = 0, trace_methods_offset = 0,
@ -406,6 +409,7 @@ class java_lang_Throwable: AllStatic {
static int detailMessage_offset; static int detailMessage_offset;
static int cause_offset; static int cause_offset;
static int stackTrace_offset; static int stackTrace_offset;
static int static_unassigned_stacktrace_offset;
// Printing // Printing
static char* print_stack_element_to_buffer(methodOop method, int bci); static char* print_stack_element_to_buffer(methodOop method, int bci);
@ -414,6 +418,9 @@ class java_lang_Throwable: AllStatic {
static void clear_stacktrace(oop throwable); static void clear_stacktrace(oop throwable);
// No stack trace available // No stack trace available
static const char* no_stack_trace_message(); static const char* no_stack_trace_message();
// Stacktrace (post JDK 1.7.0 to allow immutability protocol to be followed)
static void set_stacktrace(oop throwable, oop st_element_array);
static oop unassigned_stacktrace();
public: public:
// Backtrace // Backtrace
@ -438,7 +445,6 @@ class java_lang_Throwable: AllStatic {
static void allocate_backtrace(Handle throwable, TRAPS); static void allocate_backtrace(Handle throwable, TRAPS);
// Fill in current stack trace for throwable with preallocated backtrace (no GC) // Fill in current stack trace for throwable with preallocated backtrace (no GC)
static void fill_in_stack_trace_of_preallocated_backtrace(Handle throwable); static void fill_in_stack_trace_of_preallocated_backtrace(Handle throwable);
// Fill in current stack trace, can cause GC // Fill in current stack trace, can cause GC
static void fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS); static void fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS);
static void fill_in_stack_trace(Handle throwable, methodHandle method = methodHandle()); static void fill_in_stack_trace(Handle throwable, methodHandle method = methodHandle());

View File

@ -1978,7 +1978,7 @@ void SystemDictionary::initialize_preloaded_classes(TRAPS) {
// JSR 292 classes // JSR 292 classes
WKID jsr292_group_start = WK_KLASS_ENUM_NAME(MethodHandle_klass); WKID jsr292_group_start = WK_KLASS_ENUM_NAME(MethodHandle_klass);
WKID jsr292_group_end = WK_KLASS_ENUM_NAME(CallSite_klass); WKID jsr292_group_end = WK_KLASS_ENUM_NAME(VolatileCallSite_klass);
initialize_wk_klasses_until(jsr292_group_start, scan, CHECK); initialize_wk_klasses_until(jsr292_group_start, scan, CHECK);
if (EnableInvokeDynamic) { if (EnableInvokeDynamic) {
initialize_wk_klasses_through(jsr292_group_end, scan, CHECK); initialize_wk_klasses_through(jsr292_group_end, scan, CHECK);

Some files were not shown because too many files have changed in this diff Show More