--- a/hotspot/src/share/vm/opto/parse2.cpp Wed Oct 16 10:52:41 2013 +0200
+++ b/hotspot/src/share/vm/opto/parse2.cpp Tue Nov 05 17:38:04 2013 -0800
@@ -268,7 +268,7 @@
return adjoinRange(value, value, dest, table_index);
}
- void print(ciEnv* env) {
+ void print() {
if (is_singleton())
tty->print(" {%d}=>%d", lo(), dest());
else if (lo() == min_jint)
@@ -471,8 +471,8 @@
// These are the switch destinations hanging off the jumpnode
int i = 0;
for (SwitchRange* r = lo; r <= hi; r++) {
- for (int j = r->lo(); j <= r->hi(); j++, i++) {
- Node* input = _gvn.transform(new (C) JumpProjNode(jtn, i, r->dest(), j - lowval));
+ for (int64 j = r->lo(); j <= r->hi(); j++, i++) {
+ Node* input = _gvn.transform(new (C) JumpProjNode(jtn, i, r->dest(), (int)(j - lowval)));
{
PreserveJVMState pjvms(this);
set_control(input);
@@ -632,7 +632,7 @@
}
tty->print(" ");
for( r = lo; r <= hi; r++ ) {
- r->print(env());
+ r->print();
}
tty->print_cr("");
}
@@ -1366,6 +1366,56 @@
}
}
+/**
+ * Use speculative type to optimize CmpP node: if comparison is
+ * against the low level class, cast the object to the speculative
+ * type if any. CmpP should then go away.
+ *
+ * @param c expected CmpP node
+ * @return result of CmpP on object casted to speculative type
+ *
+ */
+Node* Parse::optimize_cmp_with_klass(Node* c) {
+ // If this is transformed by the _gvn to a comparison with the low
+ // level klass then we may be able to use speculation
+ if (c->Opcode() == Op_CmpP &&
+ (c->in(1)->Opcode() == Op_LoadKlass || c->in(1)->Opcode() == Op_DecodeNKlass) &&
+ c->in(2)->is_Con()) {
+ Node* load_klass = NULL;
+ Node* decode = NULL;
+ if (c->in(1)->Opcode() == Op_DecodeNKlass) {
+ decode = c->in(1);
+ load_klass = c->in(1)->in(1);
+ } else {
+ load_klass = c->in(1);
+ }
+ if (load_klass->in(2)->is_AddP()) {
+ Node* addp = load_klass->in(2);
+ Node* obj = addp->in(AddPNode::Address);
+ const TypeOopPtr* obj_type = _gvn.type(obj)->is_oopptr();
+ if (obj_type->speculative_type() != NULL) {
+ ciKlass* k = obj_type->speculative_type();
+ inc_sp(2);
+ obj = maybe_cast_profiled_obj(obj, k);
+ dec_sp(2);
+ // Make the CmpP use the casted obj
+ addp = basic_plus_adr(obj, addp->in(AddPNode::Offset));
+ load_klass = load_klass->clone();
+ load_klass->set_req(2, addp);
+ load_klass = _gvn.transform(load_klass);
+ if (decode != NULL) {
+ decode = decode->clone();
+ decode->set_req(1, load_klass);
+ load_klass = _gvn.transform(decode);
+ }
+ c = c->clone();
+ c->set_req(1, load_klass);
+ c = _gvn.transform(c);
+ }
+ }
+ }
+ return c;
+}
//------------------------------do_one_bytecode--------------------------------
// Parse this bytecode, and alter the Parsers JVM->Node mapping
@@ -2239,6 +2289,7 @@
a = pop();
b = pop();
c = _gvn.transform( new (C) CmpPNode(b, a) );
+ c = optimize_cmp_with_klass(c);
do_if(btest, c);
break;