src/share/vm/opto/library_call.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/opto/library_call.cpp Tue Jul 21 17:08:32 2015
--- new/src/share/vm/opto/library_call.cpp Tue Jul 21 17:08:32 2015
*** 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 ****
--- 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");
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
+ // 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:
+ C2Compiler* compiler = (C2Compiler*)CompileBroker::compiler(CompLevel_full_optimization);
+ bool is_available = !vmIntrinsics::is_disabled_by_flags(m->intrinsic_id());
! if (!is_available) {
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;
}
+ {
+ // 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);
}
! 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:
! if (is_available) {
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,
+ vmIntrinsics::predicates_needed(id),
+ vmIntrinsics::does_virtual_dispatch(id),
+ (vmIntrinsics::ID) id);
+ } else {
+ 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() {
*** 802,812 ****
--- 517,526 ----
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);
src/share/vm/opto/library_call.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File