diff -r feba5d4126b8 -r 82c7497fbad4 hotspot/src/share/vm/opto/parse2.cpp --- 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;