src/share/vm/opto/library_call.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/opto/library_call.cpp Wed Oct 29 11:45:35 2014
--- new/src/share/vm/opto/library_call.cpp Wed Oct 29 11:45:35 2014
*** 266,275 ****
--- 266,276 ----
bool inline_unsafe_ordered_store(BasicType type);
bool inline_unsafe_fence(vmIntrinsics::ID id);
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);
Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
*** 867,876 ****
--- 868,879 ----
case vmIntrinsics::_getCallerClass: return inline_native_Reflection_getCallerClass();
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());
case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
*** 3544,3553 ****
--- 3547,3651 ----
C->set_has_split_ifs(true); // Has chance for split-if optimization
set_result(region, phi);
return true;
}
+ //-------------------------inline_Class_cast-------------------
+ bool LibraryCallKit::inline_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; // dead path (mirror->is_top()).
+ }
+ if (obj == NULL || obj->is_top()) {
+ return false; // dead path
+ }
+ const TypeOopPtr* tp = _gvn.type(obj)->isa_oopptr();
+
+ // First, see if Class.cast() can be folded statically.
+ // java_mirror_type() returns non-null for compile-time Class constants.
+ ciType* tm = mirror_con->java_mirror_type();
+ if (tm != NULL && tm->is_klass() &&
+ tp != NULL && tp->klass() != NULL && tp->klass()->is_loaded()) {
+ int static_res = C->static_subtype_check(tm->as_klass(), tp->klass());
+ if (static_res == Compile::SSC_always_true) {
+ // isInstance() is true - fold the code.
+ set_result(obj);
+ return true;
+ } else if (static_res == Compile::SSC_always_false) {
+ // Don't use intrinsic, have to throw ClassCastException.
+ return false;
+ }
+ }
+ // Generate dynamic checks.
+ // Class.cast() is java implementation of _checkcast bytecode.
+ // Do checkcast (Parse::do_checkcast()) optimizations here.
+
+ // Throw uncommon trap if the value we are casting
+ // _from_ is not loaded, and value is not null.
+ // If the value _is_ NULL, then the checkcast does nothing.
+ if (tp != NULL && tp->klass() != NULL && !tp->klass()->is_loaded()) {
+ if (C->log() != NULL) {
+ // %%% Cannot happen?
+ C->log()->elem("assert_null reason='class_cast' superklass='%d' klass='%d'",
+ C->log()->identify(tm), C->log()->identify(tp->klass()));
+ }
+ // When null_assert is hit this method will be deoptimized and
+ // klass will be loaded by Interpreter.
+ obj = null_assert(obj);
+ if (stopped()) {
+ return true;
+ }
+ assert(_gvn.type(obj)->higher_equal(TypePtr::NULL_PTR), "what's left behind is null" );
+ set_result(obj);
+ return true;
+ }
+
+ // Bailout intrinsic and do normal inlining if exception path is frequent.
+ if (too_many_traps(Deoptimization::Reason_intrinsic)) {
+ return false;
+ }
+
+ mirror = null_check(mirror);
+ // If mirror is dead, only null-path is taken.
+ if (stopped()) {
+ return true;
+ }
+
+ // Not-subtype or the mirror's klass ptr is NULL (in case it is a primitive).
+ enum { _bad_type_path = 1, _prim_path = 2, PATH_LIMIT };
+ RegionNode* region = new RegionNode(PATH_LIMIT);
+ record_for_igvn(region);
+
+ // Now load the mirror's klass metaobject, and null-check it.
+ // If kls is null, we have a primitive mirror and
+ // nothing is an instance of a primitive type.
+ Node* kls = load_klass_from_mirror(mirror, false, region, _prim_path);
+
+ Node* res = top();
+ if (!stopped()) {
+ Node* bad_type_ctrl = top();
+ // Do checkcast optimizations.
+ res = gen_checkcast(obj, kls, &bad_type_ctrl);
+ region->init_req(_bad_type_path, bad_type_ctrl);
+ }
+ if (region->in(_prim_path) != top() ||
+ region->in(_bad_type_path) != top()) {
+ // Let Interpreter throw ClassCastException.
+ PreserveJVMState pjvms(this);
+ set_control(_gvn.transform(region));
+ uncommon_trap(Deoptimization::Reason_intrinsic,
+ Deoptimization::Action_maybe_recompile);
+ }
+ if (!stopped()) {
+ set_result(res);
+ }
+ return true;
+ }
+
+
//--------------------------inline_native_subtype_check------------------------
// This intrinsic takes the JNI calls out of the heart of
// UnsafeFieldAccessorImpl.set, which improves Field.set, readObject, etc.
bool LibraryCallKit::inline_native_subtype_check() {
// Pull both arguments off the stack.
src/share/vm/opto/library_call.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File