--- old/src/share/vm/opto/library_call.cpp 2014-10-21 16:47:08.000000000 -0700 +++ new/src/share/vm/opto/library_call.cpp 2014-10-21 16:47:08.000000000 -0700 @@ -268,6 +268,7 @@ bool inline_fp_conversions(vmIntrinsics::ID id); bool inline_number_methods(vmIntrinsics::ID id); bool inline_reference_get(); + bool inline_Class_cast(); bool inline_aescrypt_Block(vmIntrinsics::ID id); bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id); Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting); @@ -869,6 +870,8 @@ case vmIntrinsics::_Reference_get: return inline_reference_get(); + case vmIntrinsics::_class_cast: return inline_Class_cast(); + case vmIntrinsics::_aescrypt_encryptBlock: case vmIntrinsics::_aescrypt_decryptBlock: return inline_aescrypt_Block(intrinsic_id()); @@ -3546,6 +3549,49 @@ return true; } +//-------------------------inline_Class_cast------------------- +bool LibraryCallKit::inline_Class_cast() { + // See if we can statically collapse isInstance() check in Class.cast(); + Node* mirror = argument(0); // Class + Node* obj = argument(1); + + const TypeInstPtr* mirror_con = _gvn.type(mirror)->isa_instptr(); + if (mirror_con == NULL) { + return false; // cannot happen? + } + const TypeOopPtr* obj_type = _gvn.type(obj)->isa_oopptr(); + if (obj_type == NULL) { + return false; // skip NULL_PTR and TOP + } + + assert(mirror_con->klass()->as_instance_klass() == C->env()->Class_klass(), "sanity"); + // We are loading a special hidden field from a Class mirror object, + // the field which points to the VM's Klass metaobject. + + // java_mirror_type returns non-null for compile-time Class constants. + ciType* t = mirror_con->java_mirror_type(); + if (t == NULL || !t->is_klass()) { + return false; // non-constant or primitive Class + } + // constant oop => constant klass + const TypeKlassPtr* superklass = TypeKlassPtr::make(t->as_klass()); + + if (superklass->singleton()) { + ciKlass* superk = superklass->klass(); + ciKlass* subk = obj_type->klass(); + if (subk != NULL && subk->is_loaded()) { + int static_res = C->static_subtype_check(superk, subk); + if (static_res == Compile::SSC_always_true) { + // isInstance() is true + set_result(obj); + return true; + } + } + } + + return false; +} + //--------------------------inline_native_subtype_check------------------------ // This intrinsic takes the JNI calls out of the heart of // UnsafeFieldAccessorImpl.set, which improves Field.set, readObject, etc.