提交 8d5b1740 编写于 作者: J jcoomes

Merge

因为 它太大了无法显示 source diff 。你可以改为 查看blob
......@@ -26,6 +26,7 @@ package sun.jvm.hotspot.interpreter;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.utilities.*;
import sun.jvm.hotspot.runtime.VM;
public class Bytecode {
Method method;
......@@ -45,6 +46,23 @@ public class Bytecode {
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) {
return method.getBytecodeIntArg(bci + offset);
}
......
......@@ -28,29 +28,25 @@ import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.utilities.*;
public class BytecodeLoadConstant extends BytecodeWithCPIndex {
public class BytecodeLoadConstant extends Bytecode {
BytecodeLoadConstant(Method method, int bci) {
super(method, bci);
}
public boolean hasCacheIndex() {
// 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 i = javaCode() == Bytecodes._ldc ?
(int) (0xFF & javaByteAt(1))
: (int) (0xFFFF & javaShortAt(1));
if (hasCacheIndex()) {
return (0xFFFF & VM.getVM().getBytes().swapShort((short) i));
} else {
return i;
}
int rawIndex() {
if (javaCode() == Bytecodes._ldc)
return getIndexU1();
else
return getIndexU2(code(), false);
}
public int poolIndex() {
int i = index();
int i = rawIndex();
if (hasCacheIndex()) {
ConstantPoolCache cpCache = method().getConstants().getCache();
return cpCache.getEntryAt(i).getConstantPoolIndex();
......@@ -61,12 +57,18 @@ public class BytecodeLoadConstant extends BytecodeWithCPIndex {
public int cacheIndex() {
if (hasCacheIndex()) {
return index();
return rawIndex();
} else {
return -1; // no cache index
}
}
public BasicType resultType() {
int index = poolIndex();
ConstantTag tag = method().getConstants().getTagAt(index);
return tag.basicType();
}
private Oop getCachedConstant() {
int i = cacheIndex();
if (i >= 0) {
......@@ -88,7 +90,7 @@ public class BytecodeLoadConstant extends BytecodeWithCPIndex {
jcode == Bytecodes._ldc2_w;
if (! codeOk) return false;
ConstantTag ctag = method().getConstants().getTagAt(index());
ConstantTag ctag = method().getConstants().getTagAt(rawIndex());
if (jcode == Bytecodes._ldc2_w) {
// has to be double or long
return (ctag.isDouble() || ctag.isLong()) ? true: false;
......@@ -107,7 +109,7 @@ public class BytecodeLoadConstant extends BytecodeWithCPIndex {
return false;
}
ConstantTag ctag = method().getConstants().getTagAt(index());
ConstantTag ctag = method().getConstants().getTagAt(poolIndex());
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
// decide based on the oop type.
ConstantPool cpool = method().getConstants();
int cpIndex = index();
int cpIndex = poolIndex();
ConstantPool.CPSlot oop = cpool.getSlotAt(cpIndex);
if (oop.isOop()) {
return (Klass) oop.getOop();
......
/*
* 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.
*
* 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())
? (_method.getBytecodeShortArg(bci() + 2) & 0xFFFF)
: (_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)
public int codeAt(int bci) {
......
......@@ -38,7 +38,6 @@ public abstract class BytecodeWideable extends Bytecode {
// the local variable index
public int getLocalVarIndex() {
return (isWide()) ? (int) (0xFFFF & javaShortAt(1))
: (int) (0xFF & javaByteAt(1));
return (isWide()) ? getIndexU2(code(), true) : getIndexU1();
}
}
......@@ -35,7 +35,7 @@ public abstract class BytecodeWithCPIndex extends 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() {
throw new IllegalArgumentException("must be invokedynamic");
......
......@@ -276,6 +276,34 @@ public class Bytecodes {
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) {
int code = codeAt(method, bci);
switch (code) {
......@@ -337,18 +365,20 @@ public class Bytecodes {
// static Code non_breakpoint_code_at(address bcp, methodOop method = null);
// Bytecode attributes
public static boolean isDefined (int code) { return 0 <= code && code < number_of_codes && _format[code] != null; }
public static boolean wideIsDefined(int code) { return isDefined(code) && _wide_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) && flags(code, true) != 0; }
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 wideFormat (int code) { wideCheck(code); return _wide_format [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 lengthFor (int code) { check(code); return _length [code]; }
public static boolean canTrap (int code) { check(code); return _can_trap [code]; }
public static int lengthFor (int code) { check(code); return _lengths [code] & 0xF; }
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 boolean canRewrite (int code) { check(code); return _can_rewrite [code]; }
public static int wideLengthFor(int code) { wideCheck(code); return wideFormat(code).length(); }
public static boolean canRewrite (int code) { check(code); return has_all_flags(code, _bc_can_rewrite, false); }
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 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; }
......@@ -362,6 +392,92 @@ public class Bytecodes {
public static boolean isZeroConst (int code) { return (code == _aconst_null || code == _iconst_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
//
......@@ -371,10 +487,9 @@ public class Bytecodes {
private static String[] _wide_format;
private static int[] _result_type;
private static byte[] _depth;
private static byte[] _length;
private static boolean[] _can_trap;
private static byte[] _lengths;
private static int[] _java_code;
private static boolean[] _can_rewrite;
private static char[] _flags;
static {
_name = new String [number_of_codes];
......@@ -382,10 +497,9 @@ public class Bytecodes {
_wide_format = new String [number_of_codes];
_result_type = new int [number_of_codes]; // See BasicType.java
_depth = new byte [number_of_codes];
_length = new byte [number_of_codes];
_can_trap = new boolean[number_of_codes];
_lengths = new byte [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
// future
......@@ -712,18 +826,19 @@ public class Bytecodes {
if (Assert.ASSERTS_ENABLED) {
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;
_format [code] = format;
_wide_format [code] = wide_format;
_result_type [code] = result_type;
_depth [code] = (byte) depth;
_can_trap [code] = can_trap;
_length [code] = (byte) (format != null ? format.length() : 0);
_lengths [code] = (byte)((wlen << 4) | (len & 0xF));
_java_code [code] = java_code;
if (java_code != code) {
_can_rewrite[java_code] = true;
} else {
_can_rewrite[java_code] = false;
}
_format [code] = format;
_wide_format [code] = wide_format;
int bc_flags = 0;
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);
}
}
......@@ -164,6 +164,18 @@ public class ConstMethod extends Oop {
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
bytecode stream */
public int getBytecodeIntArg(int bci) {
......@@ -175,6 +187,21 @@ public class ConstMethod extends Oop {
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() {
byte[] bc = new byte[ (int) getCodeSize() ];
for( int i=0; i < bc.length; i++ )
......
......@@ -212,13 +212,60 @@ public class ConstantPool extends Oop implements ClassConstants {
}
public Symbol getNameRefAt(int which) {
int nameIndex = getNameAndTypeAt(getNameAndTypeRefIndexAt(which))[0];
return getSymbolAt(nameIndex);
return implGetNameRefAt(which, false);
}
private Symbol implGetNameRefAt(int which, boolean uncached) {
int signatureIndex = getNameRefIndexAt(implNameAndTypeRefIndexAt(which, uncached));
return getSymbolAt(signatureIndex);
}
public Symbol getSignatureRefAt(int which) {
int sigIndex = getNameAndTypeAt(getNameAndTypeRefIndexAt(which))[1];
return getSymbolAt(sigIndex);
return implGetSignatureRefAt(which, false);
}
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.
......@@ -253,15 +300,7 @@ public class ConstantPool extends Oop implements ClassConstants {
}
public int getNameAndTypeRefIndexAt(int index) {
int refIndex = getFieldOrMethodAt(index);
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;
return implNameAndTypeRefIndexAt(index, false);
}
/** Lookup for entries consisting of (name_index, signature_index) */
......
/*
* 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.
*
* 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) {
if (Assert.ASSERTS_ENABLED) {
Assert.that(0 <= i && i < getLength(), "index out of bounds");
}
if (i < 0 || i >= getLength()) throw new IndexOutOfBoundsException(i + " " + getLength());
return new ConstantPoolCacheEntry(this, i);
}
......@@ -84,21 +82,27 @@ public class ConstantPoolCache extends Oop {
// secondary entries hold invokedynamic call site bindings
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) {
Assert.that(e.isSecondaryEntry(), "must be a secondary entry");
Assert.that(e.isSecondaryEntry(), "must be a secondary entry:" + rawIndex);
}
return e;
}
public ConstantPoolCacheEntry getMainEntryAt(int i) {
int primaryIndex = i;
if (isSecondaryIndex(i)) {
// 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) {
Assert.that(!e.isSecondaryEntry(), "must not be a secondary entry");
Assert.that(!e.isSecondaryEntry(), "must not be a secondary entry:" + primaryIndex);
}
return e;
}
......
......@@ -569,10 +569,10 @@ public class GenerateOopMap {
case Bytecodes._invokedynamic:
// FIXME: print signature of referenced method (need more
// accessors in ConstantPool and ConstantPoolCache)
int idx = currentBC.getIndexBig();
int idx = currentBC.hasIndexU4() ? currentBC.getIndexU4() : currentBC.getIndexU2();
tty.print(" idx " + idx);
/*
int idx = currentBC.getIndexBig();
int idx = currentBC.getIndexU2();
ConstantPool cp = method().getConstants();
int nameAndTypeIdx = cp.name_and_type_ref_index_at(idx);
int signatureIdx = cp.signature_ref_index_at(nameAndTypeIdx);
......@@ -609,10 +609,10 @@ public class GenerateOopMap {
case Bytecodes._invokedynamic:
// FIXME: print signature of referenced method (need more
// accessors in ConstantPool and ConstantPoolCache)
int idx = currentBC.getIndexBig();
int idx = currentBC.hasIndexU4() ? currentBC.getIndexU4() : currentBC.getIndexU2();
tty.print(" idx " + idx);
/*
int idx = currentBC.getIndexBig();
int idx = currentBC.getIndexU2();
constantPoolOop cp = method().constants();
int nameAndTypeIdx = cp.name_and_type_ref_index_at(idx);
int signatureIdx = cp.signature_ref_index_at(nameAndTypeIdx);
......@@ -1118,7 +1118,8 @@ public class GenerateOopMap {
current instruction, starting in the current state. */
void interp1 (BytecodeStream itr) {
if (DEBUG) {
System.err.println(" - bci " + itr.bci());
System.err.println(" - bci " + itr.bci() + " " + itr.code());
printCurrentState(System.err, itr, false);
}
// if (TraceNewOopMapGeneration) {
......@@ -1179,8 +1180,8 @@ public class GenerateOopMap {
case Bytecodes._ldc2_w: ppush(vvCTS); break;
case Bytecodes._ldc: doLdc(itr.getIndex(), itr.bci()); break;
case Bytecodes._ldc_w: doLdc(itr.getIndexBig(), itr.bci());break;
case Bytecodes._ldc: doLdc(itr.bci()); break;
case Bytecodes._ldc_w: doLdc(itr.bci()); break;
case Bytecodes._iload:
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_w: doJsr(itr.dest_w()); break;
case Bytecodes._getstatic: doField(true, true,
itr.getIndexBig(),
itr.bci()); break;
case Bytecodes._putstatic: doField(false, true, itr.getIndexBig(), 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._getstatic: doField(true, true, itr.getIndexU2Cpcache(), itr.bci()); break;
case Bytecodes._putstatic: doField(false, true, itr.getIndexU2Cpcache(), itr.bci()); break;
case Bytecodes._getfield: doField(true, false, itr.getIndexU2Cpcache(), itr.bci()); break;
case Bytecodes._putfield: doField(false, false, itr.getIndexU2Cpcache(), itr.bci()); break;
case Bytecodes._invokevirtual:
case Bytecodes._invokespecial: doMethod(false, false, itr.getIndexBig(), itr.bci()); break;
case Bytecodes._invokestatic: doMethod(true, false, itr.getIndexBig(), itr.bci()); break;
case Bytecodes._invokedynamic: doMethod(false, true, itr.getIndexBig(), itr.bci()); break;
case Bytecodes._invokeinterface: doMethod(false, true, itr.getIndexBig(), itr.bci()); break;
case Bytecodes._invokespecial: doMethod(false, false, itr.getIndexU2Cpcache(), itr.bci()); break;
case Bytecodes._invokestatic: doMethod(true, false, itr.getIndexU2Cpcache(), itr.bci()); break;
case Bytecodes._invokedynamic: doMethod(true, false, itr.getIndexU4(), itr.bci()); break;
case Bytecodes._invokeinterface: doMethod(false, true, itr.getIndexU2Cpcache(), itr.bci()); break;
case Bytecodes._newarray:
case Bytecodes._anewarray: ppNewRef(vCTS, itr.bci()); 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();
ConstantTag tag = cp.getTagAt(idx);
CellTypeState cts = (tag.isString() || tag.isUnresolvedString() ||
tag.isKlass() || tag.isUnresolvedKlass())
? CellTypeState.makeLineRef(bci)
: valCTS;
BasicType bt = ldc.resultType();
CellTypeState cts = (bt == BasicType.T_OBJECT) ? CellTypeState.makeLineRef(bci) : valCTS;
ppush1(cts);
}
......@@ -1729,15 +1726,7 @@ public class GenerateOopMap {
void doMethod (boolean is_static, boolean is_interface, int idx, int bci) {
// Dig up signature for field in constant pool
ConstantPool cp = _method.getConstants();
int nameAndTypeIdx = cp.getTagAt(idx).isNameAndType() ? idx : cp.getNameAndTypeRefIndexAt(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);
}
Symbol signature = cp.getSignatureRefAt(idx);
// Parse method signature
CellTypeStateList out = new CellTypeStateList(4);
......
......@@ -180,12 +180,24 @@ public class Method extends Oop {
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
bytecode stream */
public int getBytecodeIntArg(int 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() {
return getConstMethod().getByteCode();
}
......
......@@ -53,6 +53,9 @@ public class TypeArray extends Array {
public boolean isTypeArray() { return true; }
public byte getByteAt(long index) {
if (index < 0 || index >= getLength()) {
throw new ArrayIndexOutOfBoundsException(index + " " + getLength());
}
long offset = baseOffsetInBytes(BasicType.T_BYTE) + index * getHeap().getByteSize();
return getHandle().getJByteAt(offset);
}
......
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -24,31 +24,33 @@
package sun.jvm.hotspot.utilities;
import sun.jvm.hotspot.runtime.BasicType;
public class ConstantTag {
// These replicated from the VM to save space
private static int JVM_CONSTANT_Utf8 = 1;
private static int JVM_CONSTANT_Unicode = 2; // unused
private static int JVM_CONSTANT_Integer = 3;
private static int JVM_CONSTANT_Float = 4;
private static int JVM_CONSTANT_Long = 5;
private static int JVM_CONSTANT_Double = 6;
private static int JVM_CONSTANT_Class = 7;
private static int JVM_CONSTANT_String = 8;
private static int JVM_CONSTANT_Fieldref = 9;
private static int JVM_CONSTANT_Methodref = 10;
private static int JVM_CONSTANT_InterfaceMethodref = 11;
private static int JVM_CONSTANT_NameAndType = 12;
private static int JVM_CONSTANT_MethodHandle = 15; // JSR 292
private static int JVM_CONSTANT_MethodType = 16; // JSR 292
// static int JVM_CONSTANT_(unused) = 17; // JSR 292 early drafts only
private static int JVM_CONSTANT_InvokeDynamic = 18; // JSR 292
private static int JVM_CONSTANT_Invalid = 0; // For bad value initialization
private static 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 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 int JVM_CONSTANT_UnresolvedClassInError = 104; // Resolution failed
private static int JVM_CONSTANT_Object = 105; // Required for BoundMethodHandle arguments.
private static final int JVM_CONSTANT_Utf8 = 1;
private static final int JVM_CONSTANT_Unicode = 2; // unused
private static final int JVM_CONSTANT_Integer = 3;
private static final int JVM_CONSTANT_Float = 4;
private static final int JVM_CONSTANT_Long = 5;
private static final int JVM_CONSTANT_Double = 6;
private static final int JVM_CONSTANT_Class = 7;
private static final int JVM_CONSTANT_String = 8;
private static final int JVM_CONSTANT_Fieldref = 9;
private static final int JVM_CONSTANT_Methodref = 10;
private static final int JVM_CONSTANT_InterfaceMethodref = 11;
private static final int JVM_CONSTANT_NameAndType = 12;
private static final int JVM_CONSTANT_MethodHandle = 15; // JSR 292
private static final int JVM_CONSTANT_MethodType = 16; // JSR 292
// static final int JVM_CONSTANT_(unused) = 17; // JSR 292 early drafts only
private static final int JVM_CONSTANT_InvokeDynamic = 18; // JSR 292
private static final int JVM_CONSTANT_Invalid = 0; // For bad value initialization
private static final int JVM_CONSTANT_UnresolvedClass = 100; // Temporary tag until actual use
private static final int JVM_CONSTANT_ClassIndex = 101; // Temporary tag while constructing constant pool
private static final int JVM_CONSTANT_UnresolvedString = 102; // Temporary tag until actual use
private static final int JVM_CONSTANT_StringIndex = 103; // Temporary tag while constructing constant pool
private static final int JVM_CONSTANT_UnresolvedClassInError = 104; // Resolution failed
private static final int JVM_CONSTANT_Object = 105; // Required for BoundMethodHandle arguments.
// JVM_CONSTANT_MethodHandle subtypes //FIXME: connect these to data structure
private static int JVM_REF_getField = 1;
......@@ -99,4 +101,31 @@ public class ConstantTag {
public boolean isKlassReference() { return isKlassIndex() || isUnresolvedKlass(); }
public boolean isFieldOrMethod() { return isField() || isMethod() || isInterfaceMethod(); }
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);
}
}
}
......@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2011
HS_MAJOR_VER=22
HS_MINOR_VER=0
HS_BUILD_NUMBER=01
HS_BUILD_NUMBER=03
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
......
......@@ -34,13 +34,13 @@ else
endif
jprt_build_productEmb:
$(MAKE) JAVASE_EMBEDDED=true jprt_build_product
$(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_product
jprt_build_debugEmb:
$(MAKE) JAVASE_EMBEDDED=true jprt_build_debug
$(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_debug
jprt_build_fastdebugEmb:
$(MAKE) JAVASE_EMBEDDED=true jprt_build_fastdebug
$(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_fastdebug
jprt_build_productOpen:
$(MAKE) OPENJDK=true jprt_build_product
......
......@@ -230,7 +230,7 @@ checks: check_os_version check_j2se_version
# Solaris 2.5.1, 2.6).
# 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)
EMPTY_IF_NOT_SUPPORTED = $(filter $(SUPPORTED_OS_VERSION),$(OS_VERSION))
......
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.
This code is free software; you can redistribute it and/or modify it
......
......@@ -124,6 +124,7 @@ EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
# client and server subdirectories have symbolic links to ../libjsig.so
EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so
EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
ifndef BUILD_CLIENT_ONLY
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
......@@ -132,7 +133,6 @@ endif
ifneq ($(ZERO_BUILD), true)
ifeq ($(ARCH_DATA_MODEL), 32)
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so
endif
......
......@@ -70,6 +70,8 @@ EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so
EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
ifneq ($(BUILD_CLIENT_ONLY),true)
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
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
endif
ifeq ($(ARCH_DATA_MODEL), 32)
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.so
......
......@@ -72,9 +72,9 @@ $(shell uname -r -v \
-e '/^[0-4]\. /b' \
-e '/^5\.[0-9] /b' \
-e '/^5\.10 /b' \
-e '/ snv_[0-9][0-9]$/b' \
-e '/ snv_[01][0-4][0-9]$/b' \
-e '/ snv_15[0-8]$/b' \
-e '/ snv_[0-9][0-9]$$/b' \
-e '/ snv_[01][0-4][0-9]$$/b' \
-e '/ snv_15[0-8]$$/b' \
-e 's/.*/-DSOLARIS_11_B159_OR_LATER/' \
-e 'p' \
)
......
......@@ -81,7 +81,6 @@ CPP=ARCH_ERROR
!endif
CPP_FLAGS=$(CPP_FLAGS) /D "WIN32" /D "_WINDOWS"
# Must specify this for sharedRuntimeTrig.cpp
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 \
/opt:ICF,8 /map /debug
!if $(MSC_VER) >= 1600
LINK_FLAGS= $(LINK_FLAGS) psapi.lib
!endif
# Resource compiler settings
RC=rc.exe
RC_FLAGS=/D "HS_VER=$(HS_VER)" \
......
......@@ -171,19 +171,20 @@ ifeq ($(BUILD_WIN_SA), 1)
endif
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)/jvm.dll
EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.pdb
EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.map
EXPORT_LIST += $(EXPORT_LIB_DIR)/jvm.lib
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)/jvm.dll
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.pdb
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.map
# kernel vm
EXPORT_KERNEL_DIR = $(EXPORT_JRE_BIN_DIR)/kernel
EXPORT_LIST += $(EXPORT_KERNEL_DIR)/Xusage.txt
EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.dll
EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.pdb
......
......@@ -66,7 +66,7 @@ $(GENERATED)\sa-jdi.jar: $(AGENT_FILES1:/=\) $(AGENT_FILES2:/=\)
$(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 -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_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal
$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext
......
#
# 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.
#
# This code is free software; you can redistribute it and/or modify it
......
......@@ -761,7 +761,7 @@ class Assembler : public AbstractAssembler {
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 {
// for FBfcc & FBPfcc instruction
......@@ -866,9 +866,18 @@ class Assembler : public AbstractAssembler {
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).
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
static bool is_in_wdisp30_range(address a, address b) {
......@@ -877,7 +886,11 @@ class Assembler : public AbstractAssembler {
enum ASIs { // page 72, v9
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
};
......@@ -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 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 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;
}
// 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
......@@ -1138,7 +1185,26 @@ class Assembler : public AbstractAssembler {
#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:
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
Assembler* delayed() {
#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, 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
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, address d, relocInfo::relocType rt = relocInfo::none);
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
......@@ -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, Label& L );
public:
// pp 144
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( Label& L, relocInfo::relocType rt = relocInfo::runtime_call_type );
public:
// pp 150
// 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, Label& L );
// compares register with zero and branches (V9 and V8 instructions)
void br_zero( Condition c, bool a, Predict p, Register s1, Label& L);
// compares register with zero (32 bit) and branches (V9 and V8 instructions)
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.
// 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 );
......@@ -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, 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, 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, Label& L );
// unconditional short branch
inline void ba( bool a, Label& L );
// unconditional branch
inline void ba( Label& L );
// Branch that tests fp condition codes
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 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); }
// klass oop manipulations if compressed
......@@ -2469,8 +2559,7 @@ public:
Label* L_success,
Label* L_failure,
Label* L_slow_path,
RegisterOrConstant super_check_offset = RegisterOrConstant(-1),
Register instanceof_hack = noreg);
RegisterOrConstant super_check_offset = RegisterOrConstant(-1));
// 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.
......
......@@ -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, 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::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::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::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::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::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::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::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::jmpl( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); }
inline void Assembler::jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { emit_data( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); has_delay_slot(); }
inline void Assembler::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 ) { 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) {
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::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, 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, 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) { 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); }
......@@ -557,8 +561,8 @@ inline void MacroAssembler::brx( Condition c, bool a, Predict p, Label& L ) {
brx(c, a, p, target(L));
}
inline void MacroAssembler::ba( bool a, Label& L ) {
br(always, a, pt, L);
inline void MacroAssembler::ba( Label& L ) {
br(always, false, pt, L);
}
// Warning: V9 only functions
......
......@@ -303,9 +303,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) {
assert(_oop_index >= 0, "must have oop index");
__ load_heap_oop(_obj, java_lang_Class::klass_offset_in_bytes(), G3);
__ ld_ptr(G3, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc), G3);
__ cmp(G2_thread, G3);
__ br(Assembler::notEqual, false, Assembler::pn, call_patch);
__ delayed()->nop();
__ cmp_and_brx_short(G2_thread, G3, Assembler::notEqual, Assembler::pn, call_patch);
// load_klass patches may execute the patched code before it's
// copied back into place so we need to jump back into the main
......
......@@ -217,9 +217,7 @@ void LIR_Assembler::osr_entry() {
{
Label L;
__ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7);
__ cmp(G0, O7);
__ br(Assembler::notEqual, false, Assembler::pt, L);
__ delayed()->nop();
__ cmp_and_br_short(O7, G0, Assembler::notEqual, Assembler::pt, L);
__ stop("locked object is NULL");
__ bind(L);
}
......@@ -2096,10 +2094,10 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
__ xor3(O0, -1, tmp);
__ sub(length, tmp, length);
__ 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);
} else {
__ br_zero(Assembler::less, false, Assembler::pn, O0, *stub->entry());
__ cmp_zero_and_br(Assembler::less, O0, *stub->entry());
__ delayed()->nop();
}
__ bind(*stub->continuation());
......@@ -2123,22 +2121,19 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
if (flags & LIR_OpArrayCopy::src_pos_positive_check) {
// test src_pos register
__ tst(src_pos);
__ br(Assembler::less, false, Assembler::pn, *stub->entry());
__ cmp_zero_and_br(Assembler::less, src_pos, *stub->entry());
__ delayed()->nop();
}
if (flags & LIR_OpArrayCopy::dst_pos_positive_check) {
// test dst_pos register
__ tst(dst_pos);
__ br(Assembler::less, false, Assembler::pn, *stub->entry());
__ cmp_zero_and_br(Assembler::less, dst_pos, *stub->entry());
__ delayed()->nop();
}
if (flags & LIR_OpArrayCopy::length_positive_check) {
// make sure length isn't negative
__ tst(length);
__ br(Assembler::less, false, Assembler::pn, *stub->entry());
__ cmp_zero_and_br(Assembler::less, length, *stub->entry());
__ delayed()->nop();
}
......@@ -2261,8 +2256,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
#ifndef PRODUCT
if (PrintC1Statistics) {
Label failed;
__ br_notnull(O0, false, Assembler::pn, failed);
__ delayed()->nop();
__ br_notnull_short(O0, Assembler::pn, failed);
__ inc_counter((address)&Runtime1::_arraycopy_checkcast_cnt, G1, G3);
__ bind(failed);
}
......@@ -2314,9 +2308,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
__ br(Assembler::notEqual, false, Assembler::pn, halt);
// load the raw value of the src klass.
__ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2);
__ cmp(tmp, tmp2);
__ br(Assembler::equal, false, Assembler::pn, known_ok);
__ delayed()->nop();
__ cmp_and_br_short(tmp, tmp2, Assembler::equal, Assembler::pn, known_ok);
} else {
__ cmp(tmp, tmp2);
__ br(Assembler::equal, false, Assembler::pn, known_ok);
......@@ -2330,9 +2322,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
__ cmp(tmp, tmp2);
__ brx(Assembler::notEqual, false, Assembler::pn, halt);
__ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2);
__ cmp(tmp, tmp2);
__ brx(Assembler::equal, false, Assembler::pn, known_ok);
__ delayed()->nop();
__ cmp_and_brx_short(tmp, tmp2, Assembler::equal, Assembler::pn, known_ok);
} else {
__ cmp(tmp, tmp2);
__ 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);
__ ld_ptr(receiver_addr, tmp1);
__ verify_oop(tmp1);
__ cmp(recv, tmp1);
__ brx(Assembler::notEqual, false, Assembler::pt, next_test);
__ delayed()->nop();
__ cmp_and_brx_short(recv, tmp1, Assembler::notEqual, Assembler::pt, next_test);
Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) -
mdo_offset_bias);
__ ld_ptr(data_addr, tmp1);
__ add(tmp1, DataLayout::counter_increment, tmp1);
__ st_ptr(tmp1, data_addr);
__ ba(false, *update_done);
__ ba(*update_done);
__ delayed()->nop();
__ 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)) -
mdo_offset_bias);
__ ld_ptr(recv_addr, tmp1);
__ br_notnull(tmp1, false, Assembler::pt, next_test);
__ delayed()->nop();
__ br_notnull_short(tmp1, Assembler::pt, next_test);
__ st_ptr(recv, recv_addr);
__ set(DataLayout::counter_increment, tmp1);
__ st_ptr(tmp1, mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) -
mdo_offset_bias);
__ ba(false, *update_done);
__ ba(*update_done);
__ delayed()->nop();
__ 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);
Label not_null;
__ br_notnull(obj, false, Assembler::pn, not_null);
__ delayed()->nop();
__ br_notnull_short(obj, Assembler::pn, not_null);
Register mdo = k_RInfo;
Register data_val = Rtmp1;
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);
__ or3(data_val, BitData::null_seen_byte_constant(), data_val);
__ stb(data_val, flags_addr);
__ ba(false, *obj_is_null);
__ ba(*obj_is_null);
__ delayed()->nop();
__ bind(not_null);
} else {
......@@ -2682,7 +2668,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
__ load_klass(obj, recv);
type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success);
// Jump over the failure case
__ ba(false, *success);
__ ba(*success);
__ delayed()->nop();
// Cast failure case
__ 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);
__ sub(tmp1, DataLayout::counter_increment, tmp1);
__ st_ptr(tmp1, data_addr);
__ ba(false, *failure);
__ ba(*failure);
__ delayed()->nop();
}
__ ba(false, *success);
__ ba(*success);
__ delayed()->nop();
}
......@@ -2728,8 +2714,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
if (op->should_profile()) {
Label not_null;
__ br_notnull(value, false, Assembler::pn, not_null);
__ delayed()->nop();
__ br_notnull_short(value, Assembler::pn, not_null);
Register mdo = k_RInfo;
Register data_val = Rtmp1;
jobject2reg(md->constant_encoding(), mdo);
......@@ -2741,12 +2726,10 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
__ ldub(flags_addr, data_val);
__ or3(data_val, BitData::null_seen_byte_constant(), data_val);
__ stb(data_val, flags_addr);
__ ba(false, done);
__ delayed()->nop();
__ ba_short(done);
__ bind(not_null);
} else {
__ br_null(value, false, Assembler::pn, done);
__ delayed()->nop();
__ br_null_short(value, Assembler::pn, done);
}
add_debug_info_for_null_check_here(op->info_for_exception());
__ load_klass(array, k_RInfo);
......@@ -2777,8 +2760,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
}
__ load_klass(value, recv);
type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done);
__ ba(false, done);
__ delayed()->nop();
__ ba_short(done);
// Cast failure case
__ bind(profile_cast_failure);
jobject2reg(md->constant_encoding(), mdo);
......@@ -2790,7 +2772,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
__ ld_ptr(data_addr, tmp1);
__ sub(tmp1, DataLayout::counter_increment, tmp1);
__ st_ptr(tmp1, data_addr);
__ ba(false, *stub->entry());
__ ba(*stub->entry());
__ delayed()->nop();
}
__ bind(done);
......@@ -2808,8 +2790,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
emit_typecheck_helper(op, &success, &failure, &failure);
__ bind(failure);
__ set(0, dst);
__ ba(false, done);
__ delayed()->nop();
__ ba_short(done);
__ bind(success);
__ set(1, dst);
__ bind(done);
......
......@@ -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
verify_oop(receiver);
load_klass(receiver, temp_reg);
cmp(temp_reg, iCache);
brx(Assembler::equal, true, Assembler::pt, L);
delayed()->nop();
cmp_and_brx_short(temp_reg, iCache, Assembler::equal, Assembler::pt, L);
AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub());
jump_to(ic_miss, temp_reg);
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
ld_ptr(Rbox, BasicLock::displaced_header_offset_in_bytes(), Rmark);
br_null(Rmark, false, Assembler::pt, done);
delayed()->nop();
br_null_short(Rmark, Assembler::pt, done);
if (!UseBiasedLocking) {
// load object
ld_ptr(Rbox, BasicObjectLock::obj_offset_in_bytes(), Roop);
......@@ -231,7 +228,7 @@ void C1_MacroAssembler::allocate_object(
if (!is_simm13(obj_size * wordSize)) {
// would need to use extra register to load
// object size => go the slow case for now
br(Assembler::always, false, Assembler::pt, slow_case);
ba(slow_case);
delayed()->nop();
return;
}
......@@ -257,12 +254,10 @@ void C1_MacroAssembler::initialize_object(
Label ok;
ld(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), t1);
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 {
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");
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) {
Label not_null;
br_notnull(r, false, Assembler::pt, not_null);
delayed()->nop();
br_notnull_short(r, Assembler::pt, not_null);
stop("non-null oop required");
bind(not_null);
if (!VerifyOops) return;
......
......@@ -71,8 +71,7 @@ int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address e
{ Label L;
Address exception_addr(G2_thread, Thread::pending_exception_offset());
ld_ptr(exception_addr, Gtemp);
br_null(Gtemp, false, pt, L);
delayed()->nop();
br_null_short(Gtemp, pt, L);
Address vm_result_addr(G2_thread, JavaThread::vm_result_offset());
st_ptr(G0, vm_result_addr);
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");
Label no_deopt;
__ tst(O0);
__ brx(Assembler::equal, false, Assembler::pt, no_deopt);
__ delayed()->nop();
__ br_null_short(O0, Assembler::pt, no_deopt);
// 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
......@@ -402,18 +399,15 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
if (id == fast_new_instance_init_check_id) {
// make sure the klass is initialized
__ ld(G5_klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_t1);
__ cmp(G3_t1, instanceKlass::fully_initialized);
__ br(Assembler::notEqual, false, Assembler::pn, slow_path);
__ delayed()->nop();
__ cmp_and_br_short(G3_t1, instanceKlass::fully_initialized, Assembler::notEqual, Assembler::pn, slow_path);
}
#ifdef ASSERT
// assert object can be fast path allocated
{
Label ok, not_ok;
__ 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)
__ br(Assembler::lessEqual, false, Assembler::pn, not_ok);
__ delayed()->nop();
// make sure it's an instance (LH > 0)
__ cmp_and_br_short(G1_obj_size, 0, Assembler::lessEqual, Assembler::pn, not_ok);
__ btst(Klass::_lh_instance_slow_path_bit, G1_obj_size);
__ br(Assembler::zero, false, Assembler::pn, ok);
__ delayed()->nop();
......@@ -501,9 +495,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
int tag = ((id == new_type_array_id)
? Klass::_lh_array_tag_type_value
: Klass::_lh_array_tag_obj_value);
__ cmp(G3_t1, tag);
__ brx(Assembler::equal, false, Assembler::pt, ok);
__ delayed()->nop();
__ cmp_and_brx_short(G3_t1, tag, Assembler::equal, Assembler::pt, ok);
__ stop("assert(is an array klass)");
__ should_not_reach_here();
__ 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
__ set(C1_MacroAssembler::max_array_allocation_length, G3_t1);
__ cmp(G4_length, G3_t1);
__ br(Assembler::greaterUnsigned, false, Assembler::pn, slow_path);
__ delayed()->nop();
__ cmp_and_br_short(G4_length, G3_t1, Assembler::greaterUnsigned, Assembler::pn, slow_path);
// if we got here then the TLAB allocation failed, so try
// refilling the TLAB or allocating directly from eden.
......
......@@ -544,7 +544,7 @@ address InterpreterGenerator::generate_accessor_entry(void) {
// Generate regular method entry
__ bind(slow_path);
__ ba(false, fast_accessor_slow_entry_path);
__ ba(fast_accessor_slow_entry_path);
__ delayed()->nop();
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()));
__ ld_ptr(exception_addr, G3_scratch);
__ br_notnull(G3_scratch, false, Assembler::pn, pending_exception_present);
__ delayed()->nop();
__ br_notnull_short(G3_scratch, Assembler::pn, pending_exception_present);
__ ld_ptr(Address(G5_method, 0, in_bytes(methodOopDesc::signature_handler_offset())), G3_scratch);
__ bind(L);
}
......@@ -1292,7 +1291,7 @@ void CppInterpreterGenerator::generate_deopt_handling() {
deopt_frame_manager_return_atos = __ pc();
// 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
......@@ -1300,14 +1299,14 @@ void CppInterpreterGenerator::generate_deopt_handling() {
deopt_frame_manager_return_btos = __ pc();
// 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
// deopt needs to jump to here to enter the interpreter (return a result)
deopt_frame_manager_return_itos = __ pc();
// 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
// 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);
#endif /* !_LP64 && COMPILER2 */
// 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
// deopt needs to jump to here to enter the interpreter (return a result)
deopt_frame_manager_return_ftos = __ pc();
// 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
// deopt needs to jump to here to enter the interpreter (return a result)
deopt_frame_manager_return_dtos = __ pc();
// 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
// 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
__ sub(L1_scratch, entry_size, L1_scratch);
__ st_ptr(L1_scratch, STATE(_stack));
__ ba(false, entry);
__ ba(entry);
__ delayed()->add(L1_scratch, wordSize, L1_scratch); // first real entry (undo prepush)
// 2. move expression stack
......@@ -1651,7 +1650,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
__ set((int)BytecodeInterpreter::got_monitors, L1_scratch);
VALIDATE_STATE(G3_scratch, 5);
__ ba(false, call_interpreter);
__ ba(call_interpreter);
__ delayed()->st(L1_scratch, STATE(_msg));
// 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
__ ba(false, call_interpreter);
__ ba(call_interpreter);
__ 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
__ set((int)BytecodeInterpreter::deopt_resume, L1_scratch);
__ ba(false, call_interpreter);
__ ba(call_interpreter);
__ delayed()->st(L1_scratch, STATE(_msg));
// 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)
__ ba(false, resume_interpreter);
__ ba(resume_interpreter);
__ delayed()->mov(L1_scratch, O1);
// 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(_stack_base), O1); // empty java expression stack
__ ba(false, resume_interpreter);
__ ba(resume_interpreter);
__ delayed()->sub(O1, wordSize, O1); // account for prepush
// 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);
__ st(L1_scratch, STATE(_msg));
__ ba(false, call_interpreter_2);
__ ba(call_interpreter_2);
__ delayed()->st_ptr(O1, STATE(_stack));
......@@ -1867,8 +1866,8 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
__ cmp(Gtmp1, O7); // returning to interpreter?
__ brx(Assembler::equal, true, Assembler::pt, re_dispatch); // yep
__ delayed()->nop();
__ ba(false, re_dispatch);
__ delayed()->mov(G0, prevState); // initial entry
__ ba(re_dispatch);
__ 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);
__ delayed()->nop();
__ ld_ptr(STATE(_locals), O1); // get result of popping callee's args
__ ba(false, unwind_recursive_activation);
__ ld_ptr(STATE(_locals), O1); // get result of popping callee's args
__ ba(unwind_recursive_activation);
__ delayed()->nop();
interpreter_frame_manager = entry_point;
......
......@@ -236,17 +236,13 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register scratch_reg)
Label L;
Register thr_state = G3_scratch;
ld_ptr(G2_thread, JavaThread::jvmti_thread_state_offset(), thr_state);
tst(thr_state);
br(zero, false, pt, L); // if (thread->jvmti_thread_state() == NULL) exit;
delayed()->nop();
br_null_short(thr_state, pt, L); // if (thread->jvmti_thread_state() == NULL) exit;
// 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
// is called *during* earlyret handling - we don't want to reenter.
ld(thr_state, JvmtiThreadState::earlyret_state_offset(), G4_scratch);
cmp(G4_scratch, JvmtiThreadState::earlyret_pending);
br(Assembler::notEqual, false, pt, L);
delayed()->nop();
cmp_and_br_short(G4_scratch, JvmtiThreadState::earlyret_pending, Assembler::notEqual, pt, L);
// Call Interpreter::remove_activation_early_entry() to get the address of the
// same-named entrypoint in the generated interpreter code
......@@ -566,9 +562,7 @@ void InterpreterMacroAssembler::verify_sp(Register Rsp, Register Rtemp) {
#ifdef _LP64
sub(Rtemp, STACK_BIAS, Rtemp); // Bias Rtemp before cmp to FP
#endif
cmp(Rtemp, FP);
brx(Assembler::greaterUnsigned, false, Assembler::pn, Bad);
delayed()->nop();
cmp_and_brx_short(Rtemp, FP, Assembler::greaterUnsigned, Assembler::pn, Bad);
// Saved SP must not be ridiculously below current SP.
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
add(Rtemp, STACK_BIAS, Rtemp); // Unbias Rtemp before cmp to Rsp
#endif
cmp(Rsp, Rtemp);
brx(Assembler::lessUnsigned, false, Assembler::pn, Bad);
delayed()->nop();
cmp_and_brx_short(Rsp, Rtemp, Assembler::lessUnsigned, Assembler::pn, Bad);
br(Assembler::always, false, Assembler::pn, OK);
delayed()->nop();
ba_short(OK);
bind(Bad);
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());
ld(interp_only, scratch);
tst(scratch);
br(Assembler::notZero, true, Assembler::pn, skip_compiled_code);
cmp_zero_and_br(Assembler::notZero, scratch, skip_compiled_code, true, Assembler::pn);
delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), target);
bind(skip_compiled_code);
}
......@@ -641,8 +631,7 @@ void InterpreterMacroAssembler::call_from_interpreter(Register target, Register
#ifdef ASSERT
{
Label ok;
br_notnull(target, false, Assembler::pt, ok);
delayed()->nop();
br_notnull_short(target, Assembler::pt, ok);
stop("null entry point");
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,
int bcp_offset, size_t index_size) {
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
// is set.
tstbool(G1_scratch);
br(Assembler::notZero, false, pn, no_unlock);
cmp_zero_and_br(Assembler::notZero, G1_scratch, no_unlock);
delayed()->nop();
// 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 );
ld_ptr(O1, BasicObjectLock::obj_offset_in_bytes(), G3_scratch);
br_notnull(G3_scratch, false, pt, unlock);
delayed()->nop();
br_notnull_short(G3_scratch, pt, unlock);
if (throw_monitor_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) {
MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::new_illegal_monitor_state_exception));
}
ba(false, unlocked);
delayed()->nop();
ba_short(unlocked);
}
bind(unlock);
......@@ -1037,15 +1037,13 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
add(top_most_monitor(), Rmptr, delta);
{ Label L;
// ensure that Rmptr starts out above (or at) Rlimit
cmp(Rmptr, Rlimit);
brx(Assembler::greaterEqualUnsigned, false, pn, L);
delayed()->nop();
cmp_and_brx_short(Rmptr, Rlimit, Assembler::greaterEqualUnsigned, pn, L);
stop("monitor stack has negative size");
bind(L);
}
#endif
bind(restart);
ba(false, entry);
ba(entry);
delayed()->
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) {
MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::new_illegal_monitor_state_exception));
}
ba(false, restart);
delayed()->nop();
ba_short(restart);
}
bind(loop);
......@@ -1073,9 +1070,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
#ifdef ASSERT
{ Label L;
// ensure that Rmptr has not somehow stepped below Rlimit
cmp(Rmptr, Rlimit);
brx(Assembler::greaterEqualUnsigned, false, pn, L);
delayed()->nop();
cmp_and_brx_short(Rmptr, Rlimit, Assembler::greaterEqualUnsigned, pn, L);
stop("ran off the end of the monitor stack");
bind(L);
}
......@@ -1196,9 +1191,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg, Register Object)
(address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
// if the compare and exchange succeeded we are done (we saw an unlocked object)
cmp(mark_reg, temp_reg);
brx(Assembler::equal, true, Assembler::pt, done);
delayed()->nop();
cmp_and_brx_short(mark_reg, temp_reg, Assembler::equal, Assembler::pt, done);
// 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) {
assert(ProfileInterpreter, "must be profiling interpreter");
#ifdef _LP64
bpr(Assembler::rc_z, false, Assembler::pn, ImethodDataPtr, zero_continue);
#else
tst(ImethodDataPtr);
br(Assembler::zero, false, Assembler::pn, zero_continue);
#endif
delayed()->nop();
br_null_short(ImethodDataPtr, Assembler::pn, zero_continue);
}
void InterpreterMacroAssembler::verify_method_data_pointer() {
......@@ -1376,31 +1363,18 @@ void InterpreterMacroAssembler::test_invocation_counter_for_mdp(Register invocat
Label done;
// if no method data exists, and the counter is high enough, make one
#ifdef _LP64
bpr(Assembler::rc_nz, false, Assembler::pn, ImethodDataPtr, done);
#else
tst(ImethodDataPtr);
br(Assembler::notZero, false, Assembler::pn, done);
#endif
br_notnull_short(ImethodDataPtr, Assembler::pn, done);
// Test to see if we should create a method data oop
AddressLiteral profile_limit((address) &InvocationCounter::InterpreterProfileLimit);
#ifdef _LP64
delayed()->nop();
sethi(profile_limit, Rtmp);
#else
delayed()->sethi(profile_limit, Rtmp);
#endif
ld(Rtmp, profile_limit.low10(), Rtmp);
cmp(invocation_count, Rtmp);
br(Assembler::lessUnsigned, false, Assembler::pn, profile_continue);
delayed()->nop();
cmp_and_br_short(invocation_count, Rtmp, Assembler::lessUnsigned, Assembler::pn, profile_continue);
// Build it now.
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
set_method_data_pointer_for_bcp();
ba(false, profile_continue);
delayed()->nop();
ba_short(profile_continue);
bind(done);
}
......@@ -1632,13 +1606,10 @@ void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
Label skip_receiver_profile;
if (receiver_can_be_null) {
Label not_null;
tst(receiver);
brx(Assembler::notZero, false, Assembler::pt, not_null);
delayed()->nop();
br_notnull_short(receiver, Assembler::pt, not_null);
// We are making a call. Increment the count for null receiver.
increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
ba(false, skip_receiver_profile);
delayed()->nop();
ba_short(skip_receiver_profile);
bind(not_null);
}
......@@ -1682,8 +1653,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
// The receiver is receiver[n]. Increment count[n].
int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row));
increment_mdp_data_at(count_offset, scratch);
ba(false, done);
delayed()->nop();
ba_short(done);
bind(next_test);
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.
// Increment total counter to indicate polymorphic case.
increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
ba(false, done);
delayed()->nop();
ba_short(done);
bind(found_null);
} else {
brx(Assembler::notZero, false, Assembler::pt, done);
......@@ -1729,8 +1698,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
mov(DataLayout::counter_increment, scratch);
set_mdp_data_at(count_offset, scratch);
if (start_row > 0) {
ba(false, done);
delayed()->nop();
ba_short(done);
}
}
......@@ -1772,8 +1740,7 @@ void InterpreterMacroAssembler::profile_ret(TosState state,
// 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);
ba(false, profile_continue);
delayed()->nop();
ba_short(profile_continue);
bind(next_test);
}
......@@ -1922,8 +1889,8 @@ void InterpreterMacroAssembler::add_monitor_to_stack( bool stack_is_empty,
// untested("monitor stack expansion");
compute_stack_base(Rtemp);
ba( false, start_copying );
delayed()->cmp( Rtemp, Rlimit); // done? duplicated below
ba(start_copying);
delayed()->cmp(Rtemp, Rlimit); // done? duplicated below
// note: must copy from low memory upwards
// On entry to loop,
......@@ -2010,9 +1977,7 @@ void InterpreterMacroAssembler::check_for_regarea_stomp(Register Rindex, int off
// untested("reg area corruption");
add(Rindex, offset, Rscratch);
add(Rlimit, 64 + STACK_BIAS, Rscratch1);
cmp(Rscratch, Rscratch1);
brx(Assembler::greaterEqualUnsigned, false, pn, L);
delayed()->nop();
cmp_and_brx_short(Rscratch, Rscratch1, Assembler::greaterEqualUnsigned, pn, L);
stop("regsave area is being clobbered");
bind(L);
}
......@@ -2174,9 +2139,7 @@ void InterpreterMacroAssembler::test_backedge_count_for_osr( Register backedge_c
AddressLiteral limit(&InvocationCounter::InterpreterBackwardBranchLimit);
load_contents(limit, Rtmp);
cmp(backedge_count, Rtmp);
br(Assembler::lessUnsigned, false, Assembler::pt, did_not_overflow);
delayed()->nop();
cmp_and_br_short(backedge_count, Rtmp, Assembler::lessUnsigned, Assembler::pt, did_not_overflow);
// When ProfileInterpreter is on, the backedge_count comes from the
// 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?
// O0 = osr nmethod
tst(O0);
brx(Assembler::zero, false, Assembler::pn, overflow_with_error);
delayed()->nop();
br_null_short(O0, Assembler::pn, overflow_with_error);
// Has the nmethod been invalidated already?
ld(O0, nmethod::entry_bci_offset(), O2);
cmp(O2, InvalidOSREntryBci);
br(Assembler::equal, false, Assembler::pn, overflow_with_error);
delayed()->nop();
cmp_and_br_short(O2, InvalidOSREntryBci, Assembler::equal, Assembler::pn, overflow_with_error);
// 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);
const int log2_bytecode_size_limit = 16;
srl(Rtmp, log2_bytecode_size_limit, Rtmp);
br_notnull( Rtmp, false, pt, test );
delayed()->nop();
br_notnull_short( Rtmp, pt, test );
// %%% should use call_VM_leaf here?
save_frame_and_mov(0, Lmethod, O0, reg, O1);
......@@ -2320,9 +2278,7 @@ void InterpreterMacroAssembler::notify_method_entry() {
Register temp_reg = O5;
const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
ld(interp_only, temp_reg);
tst(temp_reg);
br(zero, false, pt, L);
delayed()->nop();
cmp_and_br_short(temp_reg, 0, equal, pt, L);
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_entry));
bind(L);
}
......@@ -2372,9 +2328,7 @@ void InterpreterMacroAssembler::notify_method_exit(bool is_native_method,
Register temp_reg = O5;
const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
ld(interp_only, temp_reg);
tst(temp_reg);
br(zero, false, pt, L);
delayed()->nop();
cmp_and_br_short(temp_reg, 0, equal, pt, L);
// Note: frame::interpreter_frame_result has a dependency on how the
// method result is saved across the call to post_method_exit. For
......
......@@ -189,6 +189,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
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_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_index_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
......
......@@ -191,22 +191,19 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() {
// 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.
// If is_register is false, then we are done the first six integer args.
__ tst(G4_scratch);
__ brx(Assembler::zero, false, Assembler::pt, done);
__ delayed()->nop();
__ br_null_short(G4_scratch, Assembler::pt, done);
}
__ ba(false, NextArg);
__ ba(NextArg);
__ delayed()->srl( G4_scratch, 2, G4_scratch );
__ bind(LoadFloatArg);
__ ldf( FloatRegisterImpl::S, a, ldarg.as_float_register(), 4);
__ ba(false, NextArg);
__ ba(NextArg);
__ delayed()->srl( G4_scratch, 2, G4_scratch );
__ bind(LoadDoubleArg);
__ ldf( FloatRegisterImpl::D, a, ldarg.as_double_register() );
__ ba(false, NextArg);
__ ba(NextArg);
__ delayed()->srl( G4_scratch, 2, G4_scratch );
__ 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);
// returns verified_entry_point or NULL
// we ignore it in any case
__ ba(false, Lcontinue);
__ delayed()->nop();
__ ba_short(Lcontinue);
}
......
......@@ -287,9 +287,7 @@ void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
BLOCK_COMMENT("verify_clean {");
// Magic numbers must check out:
__ set((int32_t) MAGIC_NUMBER_1, O7_temp);
__ cmp(O7_temp, L0_magic_number_1);
__ br(Assembler::equal, false, Assembler::pt, L_ok_1);
__ delayed()->nop();
__ cmp_and_br_short(O7_temp, L0_magic_number_1, Assembler::equal, Assembler::pt, L_ok_1);
__ stop("damaged ricochet frame: MAGIC_NUMBER_1 not found");
__ BIND(L_ok_1);
......@@ -301,9 +299,7 @@ void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
#else
Register FP_temp = FP;
#endif
__ cmp(L4_saved_args_base, FP_temp);
__ br(Assembler::greaterEqualUnsigned, false, Assembler::pt, L_ok_2);
__ delayed()->nop();
__ cmp_and_brx_short(L4_saved_args_base, FP_temp, Assembler::greaterEqualUnsigned, Assembler::pt, L_ok_2);
__ stop("damaged ricochet frame: L4 < FP");
__ BIND(L_ok_2);
......@@ -316,15 +312,11 @@ void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
__ BIND(L_ok_3);
extract_conversion_dest_type(_masm, L5_conversion, O7_temp);
__ cmp(O7_temp, T_VOID);
__ br(Assembler::equal, false, Assembler::pt, L_ok_4);
__ delayed()->nop();
__ cmp_and_br_short(O7_temp, T_VOID, Assembler::equal, Assembler::pt, L_ok_4);
extract_conversion_vminfo(_masm, L5_conversion, O5_temp);
__ ld_ptr(L4_saved_args_base, __ argument_offset(O5_temp, O5_temp), O7_temp);
assert(__ is_simm13(RETURN_VALUE_PLACEHOLDER), "must be simm13");
__ cmp(O7_temp, (int32_t) RETURN_VALUE_PLACEHOLDER);
__ brx(Assembler::equal, false, Assembler::pt, L_ok_4);
__ delayed()->nop();
__ cmp_and_brx_short(O7_temp, (int32_t) RETURN_VALUE_PLACEHOLDER, Assembler::equal, Assembler::pt, L_ok_4);
__ stop("damaged ricochet frame: RETURN_VALUE_PLACEHOLDER not found");
__ BIND(L_ok_4);
BLOCK_COMMENT("} verify_clean");
......@@ -363,9 +355,7 @@ void MethodHandles::load_stack_move(MacroAssembler* _masm,
if (VerifyMethodHandles) {
Label L_ok, L_bad;
int32_t stack_move_limit = 0x0800; // extra-large
__ cmp(stack_move_reg, stack_move_limit);
__ br(Assembler::greaterEqual, false, Assembler::pn, L_bad);
__ delayed()->nop();
__ cmp_and_br_short(stack_move_reg, stack_move_limit, Assembler::greaterEqual, Assembler::pn, L_bad);
__ cmp(stack_move_reg, -stack_move_limit);
__ br(Assembler::greater, false, Assembler::pt, L_ok);
__ delayed()->nop();
......@@ -401,13 +391,9 @@ void MethodHandles::verify_argslot(MacroAssembler* _masm, Register argslot_reg,
// Verify that argslot lies within (Gargs, FP].
Label L_ok, L_bad;
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
__ cmp(argslot_reg, temp_reg);
__ brx(Assembler::greaterUnsigned, false, Assembler::pn, L_bad);
__ delayed()->nop();
__ cmp(Gargs, argslot_reg);
__ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ cmp_and_brx_short(argslot_reg, temp_reg, Assembler::lessEqualUnsigned, Assembler::pt, L_ok);
__ BIND(L_bad);
__ stop(error_message);
__ 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(FP, STACK_BIAS, temp2_reg); // STACK_BIAS is zero on !_LP64
__ cmp(temp_reg, temp2_reg);
__ brx(Assembler::greaterUnsigned, false, Assembler::pn, L_bad);
__ delayed()->nop();
__ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::greaterUnsigned, Assembler::pn, L_bad);
// Gargs points to the first word so adjust by BytesPerWord
__ add(arg_slot_base_reg, BytesPerWord, temp_reg);
__ cmp(Gargs, temp_reg);
__ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ cmp_and_brx_short(Gargs, temp_reg, Assembler::lessEqualUnsigned, Assembler::pt, L_ok);
__ BIND(L_bad);
__ stop(error_message);
__ BIND(L_ok);
......@@ -502,21 +484,16 @@ void MethodHandles::verify_klass(MacroAssembler* _masm,
Label L_ok, L_bad;
BLOCK_COMMENT("verify_klass {");
__ verify_oop(obj_reg);
__ br_null(obj_reg, false, Assembler::pn, L_bad);
__ delayed()->nop();
__ br_null_short(obj_reg, Assembler::pn, L_bad);
__ load_klass(obj_reg, temp_reg);
__ set(ExternalAddress(klass_addr), temp2_reg);
__ ld_ptr(Address(temp2_reg, 0), temp2_reg);
__ cmp(temp_reg, temp2_reg);
__ brx(Assembler::equal, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::equal, Assembler::pt, L_ok);
intptr_t super_check_offset = klass->super_check_offset();
__ ld_ptr(Address(temp_reg, super_check_offset), temp_reg);
__ set(ExternalAddress(klass_addr), temp2_reg);
__ ld_ptr(Address(temp2_reg, 0), temp2_reg);
__ cmp(temp_reg, temp2_reg);
__ brx(Assembler::equal, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::equal, Assembler::pt, L_ok);
__ BIND(L_bad);
__ stop(error_message);
__ BIND(L_ok);
......@@ -671,9 +648,7 @@ static RegisterOrConstant adjust_SP_and_Gargs_down_by_slots(MacroAssembler* _mas
#ifdef ASSERT
{
Label L_ok;
__ cmp(arg_slots.as_register(), 0);
__ br(Assembler::greaterEqual, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ cmp_and_br_short(arg_slots.as_register(), 0, Assembler::greaterEqual, Assembler::pt, L_ok);
__ stop("negative arg_slots");
__ bind(L_ok);
}
......@@ -748,9 +723,7 @@ void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
__ ld_ptr( Address(temp_reg, 0 ), temp2_reg);
__ st_ptr(temp2_reg, Address(temp_reg, offset) );
__ add(temp_reg, wordSize, temp_reg);
__ cmp(temp_reg, argslot_reg);
__ brx(Assembler::lessUnsigned, false, Assembler::pt, loop);
__ delayed()->nop(); // FILLME
__ cmp_and_brx_short(temp_reg, argslot_reg, Assembler::lessUnsigned, Assembler::pt, loop);
}
// 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);
__ st_ptr(temp2_reg, Address(temp_reg, offset) );
__ sub(temp_reg, wordSize, temp_reg);
__ cmp(temp_reg, Gargs);
__ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, L_loop);
__ delayed()->nop(); // FILLME
__ cmp_and_brx_short(temp_reg, Gargs, Assembler::greaterEqualUnsigned, Assembler::pt, L_loop);
}
// And adjust the argslot address to point at the deletion point.
......@@ -848,8 +819,7 @@ void MethodHandles::push_arg_slots(MacroAssembler* _masm,
__ delayed()->nop();
__ ld_ptr( Address(argslot_reg, 0), temp_reg);
__ st_ptr(temp_reg, Address(Gargs, 0));
__ ba(false, L_break);
__ delayed()->nop(); // FILLME
__ ba_short(L_break);
__ BIND(L_plural);
// Loop for 2 or more:
......@@ -863,9 +833,7 @@ void MethodHandles::push_arg_slots(MacroAssembler* _masm,
__ sub(Gargs, wordSize, Gargs );
__ ld_ptr( Address(top_reg, 0), temp2_reg);
__ st_ptr(temp2_reg, Address(Gargs, 0));
__ cmp(top_reg, argslot_reg);
__ brx(Assembler::greaterUnsigned, false, Assembler::pt, L_loop);
__ delayed()->nop(); // FILLME
__ cmp_and_brx_short(top_reg, argslot_reg, Assembler::greaterUnsigned, Assembler::pt, L_loop);
__ BIND(L_break);
}
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);
__ delayed()->nop();
}
__ cmp(bottom_reg, top_reg);
__ brx(Assembler::lessUnsigned, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ cmp_and_brx_short(bottom_reg, top_reg, Assembler::lessUnsigned, Assembler::pt, L_ok);
__ BIND(L_bad);
__ stop("valid bounds (copy up)");
__ BIND(L_ok);
}
#endif
__ cmp(bottom_reg, top_reg);
__ brx(Assembler::greaterEqualUnsigned, false, Assembler::pn, L_break);
__ delayed()->nop();
__ cmp_and_brx_short(bottom_reg, top_reg, Assembler::greaterEqualUnsigned, Assembler::pn, L_break);
// work top down to bottom, copying contiguous data upwards
// In pseudo-code:
// 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);
__ ld_ptr( Address(top_reg, 0 ), temp2_reg);
__ st_ptr(temp2_reg, Address(top_reg, offset) );
__ cmp(top_reg, bottom_reg);
__ brx(Assembler::greaterUnsigned, false, Assembler::pt, L_loop);
__ delayed()->nop(); // FILLME
__ cmp_and_brx_short(top_reg, bottom_reg, Assembler::greaterUnsigned, Assembler::pt, L_loop);
assert(Interpreter::stackElementSize == wordSize, "else change loop");
__ BIND(L_break);
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);
__ delayed()->nop();
}
__ cmp(bottom_reg, top_reg);
__ brx(Assembler::lessUnsigned, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ cmp_and_brx_short(bottom_reg, top_reg, Assembler::lessUnsigned, Assembler::pt, L_ok);
__ BIND(L_bad);
__ stop("valid bounds (copy down)");
__ BIND(L_ok);
}
#endif
__ cmp(bottom_reg, top_reg);
__ brx(Assembler::greaterEqualUnsigned, false, Assembler::pn, L_break);
__ delayed()->nop();
__ cmp_and_brx_short(bottom_reg, top_reg, Assembler::greaterEqualUnsigned, Assembler::pn, L_break);
// work bottom up to top, copying contiguous data downwards
// In pseudo-code:
// 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);
__ st_ptr(temp2_reg, Address(bottom_reg, offset) );
__ add(bottom_reg, wordSize, bottom_reg);
__ cmp(bottom_reg, top_reg);
__ brx(Assembler::lessUnsigned, false, Assembler::pt, L_loop);
__ delayed()->nop(); // FILLME
__ cmp_and_brx_short(bottom_reg, top_reg, Assembler::lessUnsigned, Assembler::pt, L_loop);
assert(Interpreter::stackElementSize == wordSize, "else change loop");
__ BIND(L_break);
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);
__ 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(O2_required, __ argument_address(constant(0), noreg, 0));
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;
__ ld_ptr(vmarg, O2_scratch);
__ tst(O2_scratch);
__ brx(Assembler::zero, false, Assembler::pn, L_done); // No cast if null.
__ delayed()->nop();
__ br_null_short(O2_scratch, Assembler::pn, L_done); // No cast if null.
__ load_klass(O2_scratch, O2_scratch);
// 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
__ sra(O1_scratch, G5_vminfo, O1_scratch);
__ ba(false, done);
__ delayed()->nop();
__ ba_short(done);
__ bind(zero_extend);
// 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 {");
__ load_method_handle_vmslots(O3_scratch, G3_method_handle, O2_scratch);
Label L_count_ok;
__ cmp(O3_scratch, collect_count_constant);
__ br(Assembler::equal, false, Assembler::pt, L_count_ok);
__ delayed()->nop();
__ cmp_and_br_short(O3_scratch, collect_count_constant, Assembler::equal, Assembler::pt, L_count_ok);
__ stop("bad vminfo in AMH.conv");
__ BIND(L_count_ok);
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 {");
extract_conversion_vminfo(_masm, RicochetFrame::L5_conversion, O3_scratch);
Label L_vminfo_ok;
__ cmp(O3_scratch, dest_slot_constant);
__ br(Assembler::equal, false, Assembler::pt, L_vminfo_ok);
__ delayed()->nop();
__ cmp_and_br_short(O3_scratch, dest_slot_constant, Assembler::equal, Assembler::pt, L_vminfo_ok);
__ stop("bad vminfo in AMH.conv");
__ BIND(L_vminfo_ok);
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.
Label L_done;
if (keep3_count.is_register()) {
__ tst(keep3_count.as_register());
__ br(Assembler::zero, false, Assembler::pn, L_done);
__ delayed()->nop();
__ cmp_and_br_short(keep3_count.as_register(), 0, Assembler::equal, Assembler::pn, L_done);
}
if (close_count.is_register()) {
__ cmp(close_count.as_register(), open_count);
__ br(Assembler::equal, false, Assembler::pn, L_done);
__ delayed()->nop();
__ cmp_and_br_short(close_count.as_register(), open_count, Assembler::equal, Assembler::pn, L_done);
}
if (move_keep3 && fix_arg_base) {
......@@ -1999,8 +1944,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
}
if (emit_guard) {
__ ba(false, L_done); // assumes emit_move_up is true also
__ delayed()->nop();
__ ba_short(L_done); // assumes emit_move_up is true also
__ BIND(L_move_up);
}
......@@ -2133,8 +2077,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
#ifdef ASSERT
{ Label L_ok;
__ br_notnull(O7_temp, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ br_notnull_short(O7_temp, Assembler::pt, L_ok);
__ stop("bad method handle return");
__ BIND(L_ok);
}
......@@ -2192,11 +2135,10 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
Label L_skip;
if (length_constant < 0) {
load_conversion_vminfo(_masm, G3_amh_conversion, O3_scratch);
__ br_zero(Assembler::notZero, false, Assembler::pn, O3_scratch, L_skip);
__ delayed()->nop();
__ cmp_zero_and_br(Assembler::notZero, O3_scratch, L_skip);
__ delayed()->nop(); // to avoid back-to-back cbcond instructions
}
__ br_null(O1_array, false, Assembler::pn, L_array_is_empty);
__ delayed()->nop();
__ br_null_short(O1_array, Assembler::pn, L_array_is_empty);
__ BIND(L_skip);
}
__ 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;
__ check_klass_subtype(O2_array_klass, O3_klass, O4_scratch, G5_scratch, L_ok_array_klass);
// If we get here, the type check failed!
__ ba(false, L_bad_array_klass);
__ delayed()->nop();
__ ba_short(L_bad_array_klass);
__ BIND(L_ok_array_klass);
// Check length.
......@@ -2247,8 +2188,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
__ BIND(L_array_is_empty);
remove_arg_slots(_masm, -stack_move_unit() * array_slots,
O0_argslot, O1_scratch, O2_scratch, O3_scratch);
__ ba(false, L_args_done); // no spreading to do
__ delayed()->nop();
__ ba_short(L_args_done); // no spreading to do
__ BIND(L_insert_arg_space);
// come here in the usual case, stack_move < 0 (2 or more spread arguments)
// 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),
O2_scratch); // must be an even register for !_LP64 long moves (uses O2/O3)
__ add(O1_source, type2aelembytes(elem_type), O1_source);
__ cmp(O4_fill_ptr, O0_argslot);
__ brx(Assembler::greaterUnsigned, false, Assembler::pt, L_loop);
__ delayed()->nop(); // FILLME
__ cmp_and_brx_short(O4_fill_ptr, O0_argslot, Assembler::greaterUnsigned, Assembler::pt, L_loop);
} else if (length_constant == 0) {
// nothing to copy
} else {
......
......@@ -600,7 +600,7 @@ class AdapterGenerator {
void AdapterGenerator::patch_callers_callsite() {
Label L;
__ 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.
__ 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
......@@ -1127,8 +1127,7 @@ void AdapterGenerator::gen_i2c_adapter(
Label loop;
__ bind(loop);
__ sub(L0, 1, L0);
__ br_null(L0, false, Assembler::pt, loop);
__ delayed()->nop();
__ br_null_short(L0, Assembler::pt, loop);
__ restore();
}
......@@ -1202,7 +1201,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
// the call site corrected.
__ ld_ptr(G5_method, in_bytes(methodOopDesc::code_offset()), G3_scratch);
__ 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);
__ jump_to(ic_miss, G3_scratch);
__ delayed()->nop();
......@@ -1779,9 +1778,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub());
__ verify_oop(O0);
__ load_klass(O0, temp_reg);
__ cmp(temp_reg, G5_inline_cache_reg);
__ brx(Assembler::equal, true, Assembler::pt, L);
__ delayed()->nop();
__ cmp_and_brx_short(temp_reg, G5_inline_cache_reg, Assembler::equal, Assembler::pt, L);
__ jump_to(ic_miss, temp_reg);
__ delayed()->nop();
......@@ -2182,8 +2179,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
#ifdef ASSERT
{ Label L;
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O0);
__ br_null(O0, false, Assembler::pt, L);
__ delayed()->nop();
__ br_null_short(O0, Assembler::pt, L);
__ stop("no pending exception allowed on exit from IR::monitorenter");
__ bind(L);
}
......@@ -2298,9 +2294,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
Address suspend_state(G2_thread, JavaThread::suspend_flags_offset());
__ br(Assembler::notEqual, false, Assembler::pn, L);
__ delayed()->ld(suspend_state, G3_scratch);
__ cmp(G3_scratch, 0);
__ br(Assembler::equal, false, Assembler::pt, no_block);
__ delayed()->nop();
__ cmp_and_br_short(G3_scratch, 0, Assembler::equal, Assembler::pt, no_block);
__ bind(L);
// 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;
__ ld(G2_thread, JavaThread::stack_guard_state_offset(), G3_scratch);
__ cmp(G3_scratch, JavaThread::stack_guard_yellow_disabled);
__ br(Assembler::notEqual, false, Assembler::pt, no_reguard);
__ delayed()->nop();
__ cmp_and_br_short(G3_scratch, JavaThread::stack_guard_yellow_disabled, Assembler::notEqual, Assembler::pt, no_reguard);
save_native_result(masm, ret_type, stack_slots);
__ call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages));
......@@ -2382,8 +2374,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
#ifdef ASSERT
{ Label L;
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O0);
__ br_null(O0, false, Assembler::pt, L);
__ delayed()->nop();
__ br_null_short(O0, Assembler::pt, L);
__ stop("no pending exception allowed on exit from IR::monitorexit");
__ bind(L);
}
......@@ -2639,9 +2630,7 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub());
__ verify_oop(O0);
__ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), temp_reg);
__ cmp(temp_reg, G5_inline_cache_reg);
__ brx(Assembler::equal, true, Assembler::pt, L);
__ delayed()->nop();
__ cmp_and_brx_short(temp_reg, G5_inline_cache_reg, Assembler::equal, Assembler::pt, L);
__ jump_to(ic_miss, temp_reg);
__ delayed()->nop();
......@@ -3143,8 +3132,7 @@ static void make_new_frames(MacroAssembler* masm, bool deopt) {
gen_new_frame(masm, deopt); // allocate an interpreter frame
__ tst(O4array_size);
__ br(Assembler::notZero, false, Assembler::pn, loop);
__ cmp_zero_and_br(Assembler::notZero, O4array_size, loop);
__ delayed()->add(O3array, wordSize, O3array);
__ 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
map = RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
__ ba(false, cont);
__ ba(cont);
__ delayed()->mov(Deoptimization::Unpack_deopt, L0deopt_mode);
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
Label has_exception;
__ ld_ptr(G2_thread, JavaThread::exception_oop_offset(), Oexception);
__ br_notnull(Oexception, false, Assembler::pt, has_exception);
__ delayed()-> nop();
__ br_notnull_short(Oexception, Assembler::pt, has_exception);
__ stop("no exception in thread");
__ bind(has_exception);
......@@ -3265,14 +3252,13 @@ void SharedRuntime::generate_deopt_blob() {
Label no_pending_exception;
Address exception_addr(G2_thread, Thread::pending_exception_offset());
__ ld_ptr(exception_addr, Oexception);
__ br_null(Oexception, false, Assembler::pt, no_pending_exception);
__ delayed()->nop();
__ br_null_short(Oexception, Assembler::pt, no_pending_exception);
__ stop("must not have pending exception here");
__ bind(no_pending_exception);
}
#endif
__ ba(false, cont);
__ ba(cont);
__ delayed()->mov(Deoptimization::Unpack_exception, L0deopt_mode);;
//
......@@ -3313,9 +3299,7 @@ void SharedRuntime::generate_deopt_blob() {
RegisterSaver::restore_result_registers(masm);
Label noException;
__ cmp(G4deopt_mode, Deoptimization::Unpack_exception); // Was exception pending?
__ br(Assembler::notEqual, false, Assembler::pt, noException);
__ delayed()->nop();
__ cmp_and_br_short(G4deopt_mode, Deoptimization::Unpack_exception, Assembler::notEqual, Assembler::pt, noException);
// Move the pending exception from exception_oop to Oexception so
// 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
// I0/I1 if the return value is long.
Label not_long;
__ cmp(O0,T_LONG);
__ br(Assembler::notEqual, false, Assembler::pt, not_long);
__ delayed()->nop();
__ cmp_and_br_short(O0,T_LONG, Assembler::notEqual, Assembler::pt, not_long);
__ ldd(saved_Greturn1_addr,I0);
__ bind(not_long);
#endif
......@@ -3534,9 +3516,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause
Label pending;
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O1);
__ tst(O1);
__ brx(Assembler::notEqual, true, Assembler::pn, pending);
__ delayed()->nop();
__ br_notnull_short(O1, Assembler::pn, pending);
RegisterSaver::restore_live_registers(masm);
......@@ -3623,9 +3603,7 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const cha
Label pending;
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O1);
__ tst(O1);
__ brx(Assembler::notEqual, true, Assembler::pn, pending);
__ delayed()->nop();
__ br_notnull_short(O1, Assembler::pn, pending);
// get the returned methodOop
......
此差异已折叠。
......@@ -31,44 +31,46 @@
class VM_Version: public Abstract_VM_Version {
protected:
enum Feature_Flag {
v8_instructions = 0,
hardware_mul32 = 1,
hardware_div32 = 2,
hardware_fsmuld = 3,
hardware_popc = 4,
v9_instructions = 5,
vis1_instructions = 6,
vis2_instructions = 7,
sun4v_instructions = 8,
v8_instructions = 0,
hardware_mul32 = 1,
hardware_div32 = 2,
hardware_fsmuld = 3,
hardware_popc = 4,
v9_instructions = 5,
vis1_instructions = 6,
vis2_instructions = 7,
sun4v_instructions = 8,
blk_init_instructions = 9,
fmaf_instructions = 10,
fmau_instructions = 11,
vis3_instructions = 12,
sparc64_family = 13,
T_family = 14,
T1_model = 15
fmaf_instructions = 10,
fmau_instructions = 11,
vis3_instructions = 12,
sparc64_family = 13,
T_family = 14,
T1_model = 15,
cbcond_instructions = 16
};
enum Feature_Flag_Set {
unknown_m = 0,
all_features_m = -1,
v8_instructions_m = 1 << v8_instructions,
hardware_mul32_m = 1 << hardware_mul32,
hardware_div32_m = 1 << hardware_div32,
hardware_fsmuld_m = 1 << hardware_fsmuld,
hardware_popc_m = 1 << hardware_popc,
v9_instructions_m = 1 << v9_instructions,
vis1_instructions_m = 1 << vis1_instructions,
vis2_instructions_m = 1 << vis2_instructions,
sun4v_m = 1 << sun4v_instructions,
v8_instructions_m = 1 << v8_instructions,
hardware_mul32_m = 1 << hardware_mul32,
hardware_div32_m = 1 << hardware_div32,
hardware_fsmuld_m = 1 << hardware_fsmuld,
hardware_popc_m = 1 << hardware_popc,
v9_instructions_m = 1 << v9_instructions,
vis1_instructions_m = 1 << vis1_instructions,
vis2_instructions_m = 1 << vis2_instructions,
sun4v_m = 1 << sun4v_instructions,
blk_init_instructions_m = 1 << blk_init_instructions,
fmaf_instructions_m = 1 << fmaf_instructions,
fmau_instructions_m = 1 << fmau_instructions,
vis3_instructions_m = 1 << vis3_instructions,
sparc64_family_m = 1 << sparc64_family,
T_family_m = 1 << T_family,
T1_model_m = 1 << T1_model,
fmaf_instructions_m = 1 << fmaf_instructions,
fmau_instructions_m = 1 << fmau_instructions,
vis3_instructions_m = 1 << vis3_instructions,
sparc64_family_m = 1 << sparc64_family,
T_family_m = 1 << T_family,
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_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_vis3() { return (_features & vis3_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()
{ 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)
// and newer than the niagara1.
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
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_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 intx L1_data_cache_line_size() {
return 64; // default prefetch block size on sparc
static intx prefetch_data_size() {
return is_T4() ? 32 : 64; // default prefetch block size on sparc
}
// Prefetch
......
......@@ -83,6 +83,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
}
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_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_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2));
......
此差异已折叠。
此差异已折叠。
......@@ -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_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 int sched_getcpu_syscall(void);
public:
static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; }
static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) {
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册