--- old/src/share/vm/opto/parse2.cpp 2013-10-17 18:54:53.292930046 +0200 +++ new/src/share/vm/opto/parse2.cpp 2013-10-17 18:54:53.058550438 +0200 @@ -2239,6 +2239,31 @@ a = pop(); b = pop(); c = _gvn.transform( new (C) CmpPNode(b, a) ); + // 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; + if (c->in(1)->Opcode() == Op_DecodeNKlass) { + load_klass = c->in(1)->in(1); + } else { + load_klass = c->in(1); + } + if (load_klass->in(2)->is_AddP()) { + Node* obj = load_klass->in(2)->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); + // now redo the CmpP which should always fail or succeed and + // be optimized out + c = _gvn.transform( new (C) CmpPNode(b, a) ); + } + } + } do_if(btest, c); break;