src/share/vm/opto/library_call.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
8130832-review Cdiff src/share/vm/opto/library_call.cpp
src/share/vm/opto/library_call.cpp
Print this page
*** 29,38 ****
--- 29,39 ----
#include "compiler/compileBroker.hpp"
#include "compiler/compileLog.hpp"
#include "oops/objArrayKlass.hpp"
#include "opto/addnode.hpp"
#include "opto/arraycopynode.hpp"
+ #include "opto/c2compiler.hpp"
#include "opto/callGenerator.hpp"
#include "opto/castnode.hpp"
#include "opto/cfgnode.hpp"
#include "opto/convertnode.hpp"
#include "opto/countbitsnode.hpp"
*** 302,635 ****
bool inline_profileBoolean();
bool inline_isCompileConstant();
};
-
//---------------------------make_vm_intrinsic----------------------------
CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
vmIntrinsics::ID id = m->intrinsic_id();
assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
- ccstr disable_intr = NULL;
-
- if ((DisableIntrinsic[0] != '\0'
- && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) ||
- (method_has_option_value("DisableIntrinsic", disable_intr)
- && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) {
- // disabled by a user request on the command line:
- // example: -XX:DisableIntrinsic=_hashCode,_getClass
- return NULL;
- }
-
if (!m->is_loaded()) {
! // do not attempt to inline unloaded methods
return NULL;
}
! // Only a few intrinsics implement a virtual dispatch.
! // They are expensive calls which are also frequently overridden.
! if (is_virtual) {
! switch (id) {
! case vmIntrinsics::_hashCode:
! case vmIntrinsics::_clone:
! // OK, Object.hashCode and Object.clone intrinsics come in both flavors
! break;
! default:
return NULL;
}
- }
! // -XX:-InlineNatives disables nearly all intrinsics:
! if (!InlineNatives) {
! switch (id) {
! case vmIntrinsics::_indexOf:
! case vmIntrinsics::_compareTo:
! case vmIntrinsics::_equals:
! case vmIntrinsics::_equalsC:
! case vmIntrinsics::_getAndAddInt:
! case vmIntrinsics::_getAndAddLong:
! case vmIntrinsics::_getAndSetInt:
! case vmIntrinsics::_getAndSetLong:
! case vmIntrinsics::_getAndSetObject:
! case vmIntrinsics::_loadFence:
! case vmIntrinsics::_storeFence:
! case vmIntrinsics::_fullFence:
! break; // InlineNatives does not control String.compareTo
! case vmIntrinsics::_Reference_get:
! break; // InlineNatives does not control Reference.get
! default:
! return NULL;
! }
}
! int predicates = 0;
! bool does_virtual_dispatch = false;
!
! switch (id) {
! case vmIntrinsics::_compareTo:
! if (!SpecialStringCompareTo) return NULL;
! if (!Matcher::match_rule_supported(Op_StrComp)) return NULL;
! break;
! case vmIntrinsics::_indexOf:
! if (!SpecialStringIndexOf) return NULL;
! break;
! case vmIntrinsics::_equals:
! if (!SpecialStringEquals) return NULL;
! if (!Matcher::match_rule_supported(Op_StrEquals)) return NULL;
! break;
! case vmIntrinsics::_equalsC:
! if (!SpecialArraysEquals) return NULL;
! if (!Matcher::match_rule_supported(Op_AryEq)) return NULL;
! break;
! case vmIntrinsics::_arraycopy:
! if (!InlineArrayCopy) return NULL;
! break;
! case vmIntrinsics::_copyMemory:
! if (StubRoutines::unsafe_arraycopy() == NULL) return NULL;
! if (!InlineArrayCopy) return NULL;
! break;
! case vmIntrinsics::_hashCode:
! if (!InlineObjectHash) return NULL;
! does_virtual_dispatch = true;
! break;
! case vmIntrinsics::_clone:
! does_virtual_dispatch = true;
! case vmIntrinsics::_copyOf:
! case vmIntrinsics::_copyOfRange:
! if (!InlineObjectCopy) return NULL;
! // These also use the arraycopy intrinsic mechanism:
! if (!InlineArrayCopy) return NULL;
! break;
! case vmIntrinsics::_encodeISOArray:
! if (!SpecialEncodeISOArray) return NULL;
! if (!Matcher::match_rule_supported(Op_EncodeISOArray)) return NULL;
! break;
! case vmIntrinsics::_checkIndex:
! // We do not intrinsify this. The optimizer does fine with it.
! return NULL;
!
! case vmIntrinsics::_getCallerClass:
! if (!InlineReflectionGetCallerClass) return NULL;
! if (SystemDictionary::reflect_CallerSensitive_klass() == NULL) return NULL;
! break;
!
! case vmIntrinsics::_bitCount_i:
! if (!Matcher::match_rule_supported(Op_PopCountI)) return NULL;
! break;
!
! case vmIntrinsics::_bitCount_l:
! if (!Matcher::match_rule_supported(Op_PopCountL)) return NULL;
! break;
!
! case vmIntrinsics::_numberOfLeadingZeros_i:
! if (!Matcher::match_rule_supported(Op_CountLeadingZerosI)) return NULL;
! break;
!
! case vmIntrinsics::_numberOfLeadingZeros_l:
! if (!Matcher::match_rule_supported(Op_CountLeadingZerosL)) return NULL;
! break;
!
! case vmIntrinsics::_numberOfTrailingZeros_i:
! if (!Matcher::match_rule_supported(Op_CountTrailingZerosI)) return NULL;
! break;
!
! case vmIntrinsics::_numberOfTrailingZeros_l:
! if (!Matcher::match_rule_supported(Op_CountTrailingZerosL)) return NULL;
! break;
!
! case vmIntrinsics::_reverseBytes_c:
! if (!Matcher::match_rule_supported(Op_ReverseBytesUS)) return NULL;
! break;
! case vmIntrinsics::_reverseBytes_s:
! if (!Matcher::match_rule_supported(Op_ReverseBytesS)) return NULL;
! break;
! case vmIntrinsics::_reverseBytes_i:
! if (!Matcher::match_rule_supported(Op_ReverseBytesI)) return NULL;
! break;
! case vmIntrinsics::_reverseBytes_l:
! if (!Matcher::match_rule_supported(Op_ReverseBytesL)) return NULL;
! break;
!
! case vmIntrinsics::_Reference_get:
! // Use the intrinsic version of Reference.get() so that the value in
! // the referent field can be registered by the G1 pre-barrier code.
! // Also add memory barrier to prevent commoning reads from this field
! // across safepoint since GC can change it value.
! break;
!
! case vmIntrinsics::_compareAndSwapObject:
! #ifdef _LP64
! if (!UseCompressedOops && !Matcher::match_rule_supported(Op_CompareAndSwapP)) return NULL;
! #endif
! break;
!
! case vmIntrinsics::_compareAndSwapLong:
! if (!Matcher::match_rule_supported(Op_CompareAndSwapL)) return NULL;
! break;
!
! case vmIntrinsics::_getAndAddInt:
! if (!Matcher::match_rule_supported(Op_GetAndAddI)) return NULL;
! break;
!
! case vmIntrinsics::_getAndAddLong:
! if (!Matcher::match_rule_supported(Op_GetAndAddL)) return NULL;
! break;
!
! case vmIntrinsics::_getAndSetInt:
! if (!Matcher::match_rule_supported(Op_GetAndSetI)) return NULL;
! break;
!
! case vmIntrinsics::_getAndSetLong:
! if (!Matcher::match_rule_supported(Op_GetAndSetL)) return NULL;
! break;
!
! case vmIntrinsics::_getAndSetObject:
! #ifdef _LP64
! if (!UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetP)) return NULL;
! if (UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetN)) return NULL;
! break;
! #else
! if (!Matcher::match_rule_supported(Op_GetAndSetP)) return NULL;
! break;
! #endif
!
! case vmIntrinsics::_aescrypt_encryptBlock:
! case vmIntrinsics::_aescrypt_decryptBlock:
! if (!UseAESIntrinsics) return NULL;
! break;
!
! case vmIntrinsics::_multiplyToLen:
! if (!UseMultiplyToLenIntrinsic) return NULL;
! break;
!
! case vmIntrinsics::_squareToLen:
! if (!UseSquareToLenIntrinsic) return NULL;
! break;
!
! case vmIntrinsics::_mulAdd:
! if (!UseMulAddIntrinsic) return NULL;
! break;
!
! case vmIntrinsics::_montgomeryMultiply:
! if (!UseMontgomeryMultiplyIntrinsic) return NULL;
! break;
! case vmIntrinsics::_montgomerySquare:
! if (!UseMontgomerySquareIntrinsic) return NULL;
! break;
!
! case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
! case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
! if (!UseAESIntrinsics) return NULL;
! // these two require the predicated logic
! predicates = 1;
! break;
!
! case vmIntrinsics::_sha_implCompress:
! if (!UseSHA1Intrinsics) return NULL;
! break;
!
! case vmIntrinsics::_sha2_implCompress:
! if (!UseSHA256Intrinsics) return NULL;
! break;
!
! case vmIntrinsics::_sha5_implCompress:
! if (!UseSHA512Intrinsics) return NULL;
! break;
!
! case vmIntrinsics::_digestBase_implCompressMB:
! if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) return NULL;
! predicates = 3;
! break;
!
! case vmIntrinsics::_ghash_processBlocks:
! if (!UseGHASHIntrinsics) return NULL;
! break;
!
! case vmIntrinsics::_updateCRC32:
! case vmIntrinsics::_updateBytesCRC32:
! case vmIntrinsics::_updateByteBufferCRC32:
! if (!UseCRC32Intrinsics) return NULL;
! break;
!
! case vmIntrinsics::_updateBytesCRC32C:
! case vmIntrinsics::_updateDirectByteBufferCRC32C:
! if (!UseCRC32CIntrinsics) return NULL;
! break;
!
! case vmIntrinsics::_incrementExactI:
! case vmIntrinsics::_addExactI:
! if (!Matcher::match_rule_supported(Op_OverflowAddI) || !UseMathExactIntrinsics) return NULL;
! break;
! case vmIntrinsics::_incrementExactL:
! case vmIntrinsics::_addExactL:
! if (!Matcher::match_rule_supported(Op_OverflowAddL) || !UseMathExactIntrinsics) return NULL;
! break;
! case vmIntrinsics::_decrementExactI:
! case vmIntrinsics::_subtractExactI:
! if (!Matcher::match_rule_supported(Op_OverflowSubI) || !UseMathExactIntrinsics) return NULL;
! break;
! case vmIntrinsics::_decrementExactL:
! case vmIntrinsics::_subtractExactL:
! if (!Matcher::match_rule_supported(Op_OverflowSubL) || !UseMathExactIntrinsics) return NULL;
! break;
! case vmIntrinsics::_negateExactI:
! if (!Matcher::match_rule_supported(Op_OverflowSubI) || !UseMathExactIntrinsics) return NULL;
! break;
! case vmIntrinsics::_negateExactL:
! if (!Matcher::match_rule_supported(Op_OverflowSubL) || !UseMathExactIntrinsics) return NULL;
! break;
! case vmIntrinsics::_multiplyExactI:
! if (!Matcher::match_rule_supported(Op_OverflowMulI) || !UseMathExactIntrinsics) return NULL;
! break;
! case vmIntrinsics::_multiplyExactL:
! if (!Matcher::match_rule_supported(Op_OverflowMulL) || !UseMathExactIntrinsics) return NULL;
! break;
!
! case vmIntrinsics::_getShortUnaligned:
! case vmIntrinsics::_getCharUnaligned:
! case vmIntrinsics::_getIntUnaligned:
! case vmIntrinsics::_getLongUnaligned:
! case vmIntrinsics::_putShortUnaligned:
! case vmIntrinsics::_putCharUnaligned:
! case vmIntrinsics::_putIntUnaligned:
! case vmIntrinsics::_putLongUnaligned:
! if (!UseUnalignedAccesses) return NULL;
! break;
!
! default:
assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility");
assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?");
! break;
! }
!
! // -XX:-InlineClassNatives disables natives from the Class class.
! // The flag applies to all reflective calls, notably Array.newArray
! // (visible to Java programmers as Array.newInstance).
! if (m->holder()->name() == ciSymbol::java_lang_Class() ||
! m->holder()->name() == ciSymbol::java_lang_reflect_Array()) {
! if (!InlineClassNatives) return NULL;
! }
!
! // -XX:-InlineThreadNatives disables natives from the Thread class.
! if (m->holder()->name() == ciSymbol::java_lang_Thread()) {
! if (!InlineThreadNatives) return NULL;
! }
!
! // -XX:-InlineMathNatives disables natives from the Math,Float and Double classes.
! if (m->holder()->name() == ciSymbol::java_lang_Math() ||
! m->holder()->name() == ciSymbol::java_lang_Float() ||
! m->holder()->name() == ciSymbol::java_lang_Double()) {
! if (!InlineMathNatives) return NULL;
! }
!
! // -XX:-InlineUnsafeOps disables natives from the Unsafe class.
! if (m->holder()->name() == ciSymbol::sun_misc_Unsafe()) {
! if (!InlineUnsafeOps) return NULL;
}
-
- return new LibraryIntrinsic(m, is_virtual, predicates, does_virtual_dispatch, (vmIntrinsics::ID) id);
}
//----------------------register_library_intrinsics-----------------------
// Initialize this file's data structures, for each Compile instance.
void Compile::register_library_intrinsics() {
--- 303,350 ----
bool inline_profileBoolean();
bool inline_isCompileConstant();
};
//---------------------------make_vm_intrinsic----------------------------
CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
vmIntrinsics::ID id = m->intrinsic_id();
assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
if (!m->is_loaded()) {
! // Do not attempt to inline unloaded methods.
return NULL;
}
! C2Compiler* compiler = (C2Compiler*)CompileBroker::compiler(CompLevel_full_optimization);
! bool is_available = !vmIntrinsics::is_disabled_by_flags(m->intrinsic_id());
! if (!is_available) {
return NULL;
}
! {
! // For calling is_intrinsic_supported and is_intrinsic_disabled_by_flag
! // we need to transition to the '_thread_in_vm' state because both
! // methods access VM-internal data.
! VM_ENTRY_MARK;
! methodHandle mh(THREAD, m->get_Method());
! methodHandle ct(THREAD, method()->get_Method());
! is_available = is_available &&
! compiler->is_intrinsic_supported(mh, is_virtual) &&
! !compiler->is_intrinsic_disabled_by_flag(mh, ct);
}
! if (is_available) {
assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility");
assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?");
! return new LibraryIntrinsic(m, is_virtual,
! vmIntrinsics::predicates_needed(id),
! vmIntrinsics::does_virtual_dispatch(id),
! (vmIntrinsics::ID) id);
! } else {
! return NULL;
}
}
//----------------------register_library_intrinsics-----------------------
// Initialize this file's data structures, for each Compile instance.
void Compile::register_library_intrinsics() {
*** 802,812 ****
case vmIntrinsics::_getChar: return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, !is_volatile);
case vmIntrinsics::_getInt: return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, !is_volatile);
case vmIntrinsics::_getLong: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, !is_volatile);
case vmIntrinsics::_getFloat: return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, !is_volatile);
case vmIntrinsics::_getDouble: return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, !is_volatile);
-
case vmIntrinsics::_putObject: return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, !is_volatile);
case vmIntrinsics::_putBoolean: return inline_unsafe_access(!is_native_ptr, is_store, T_BOOLEAN, !is_volatile);
case vmIntrinsics::_putByte: return inline_unsafe_access(!is_native_ptr, is_store, T_BYTE, !is_volatile);
case vmIntrinsics::_putShort: return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, !is_volatile);
case vmIntrinsics::_putChar: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, !is_volatile);
--- 517,526 ----
src/share/vm/opto/library_call.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File