--- old/src/share/vm/opto/c2compiler.cpp 2015-07-31 11:54:46.937274483 +0200 +++ new/src/share/vm/opto/c2compiler.cpp 2015-07-31 11:54:46.753274491 +0200 @@ -157,14 +157,6 @@ Compile::print_timers(); } -bool C2Compiler::is_intrinsic_available(methodHandle method, methodHandle compilation_context) { - // Assume a non-virtual dispatch. A virtual dispatch is - // possible for only a limited set of available intrinsics whereas - // a non-virtual dispatch is possible for all available intrinsics. - return is_intrinsic_supported(method, false) && - !is_intrinsic_disabled_by_flag(method, compilation_context); -} - bool C2Compiler::is_intrinsic_supported(methodHandle method, bool is_virtual) { vmIntrinsics::ID id = method->intrinsic_id(); assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); @@ -436,78 +428,6 @@ return true; } -bool C2Compiler::is_intrinsic_disabled_by_flag(methodHandle method, methodHandle compilation_context) { - vmIntrinsics::ID id = method->intrinsic_id(); - assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); - - if (vmIntrinsics::is_disabled_by_flags(method->intrinsic_id())) { - return true; - } - - // Check if the intrinsic corresponding to 'method' has been disabled on - // the command line by using the DisableIntrinsic flag (either globally - // or on a per-method level, see src/share/vm/compiler/abstractCompiler.hpp - // for details). - // Usually, the compilation context is the caller of the method 'method'. - // The only case when for a non-recursive method 'method' the compilation context - // is not the caller of the 'method' (but it is the method itself) is - // java.lang.ref.Referene::get. - // For java.lang.ref.Reference::get, the intrinsic version is used - // instead of the C2-compiled version so that the value in the referent - // field can be registered by the G1 pre-barrier code. The intrinsified - // version of Reference::get also adds a memory barrier to prevent - // commoning reads from the referent field across safepoint since GC - // can change the referent field's value. See Compile::Compile() - // in src/share/vm/opto/compile.cpp for more details. - ccstr disable_intr = NULL; - if ((DisableIntrinsic[0] != '\0' && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) || - (!compilation_context.is_null() && - CompilerOracle::has_option_value(compilation_context, "DisableIntrinsic", disable_intr) && - strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL) - ) { - return true; - } - - // -XX:-InlineNatives disables nearly all intrinsics except the ones listed in - // the following switch statement. - 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: - case vmIntrinsics::_Reference_get: - break; - default: - return true; - } - } - - if (!InlineUnsafeOps) { - switch (id) { - case vmIntrinsics::_loadFence: - case vmIntrinsics::_storeFence: - case vmIntrinsics::_fullFence: - case vmIntrinsics::_compareAndSwapObject: - case vmIntrinsics::_compareAndSwapLong: - case vmIntrinsics::_compareAndSwapInt: - return true; - default: - return false; - } - } - - return false; -} - int C2Compiler::initial_code_buffer_size() { assert(SegmentedCodeCache, "Should be only used with a segmented code cache"); return Compile::MAX_inst_size + Compile::MAX_locs_size + initial_const_capacity; --- old/src/share/vm/opto/c2_globals.hpp 2015-07-31 11:54:47.017274480 +0200 +++ new/src/share/vm/opto/c2_globals.hpp 2015-07-31 11:54:46.777274490 +0200 @@ -623,9 +623,6 @@ diagnostic(bool, PrintIntrinsics, false, \ "prints attempted and successful inlining of intrinsics") \ \ - diagnostic(ccstrlist, DisableIntrinsic, "", \ - "do not expand intrinsics whose (internal) names appear here") \ - \ develop(bool, StressReflectiveCode, false, \ "Use inexact types at allocations, etc., to test reflection") \ \ --- old/src/share/vm/c1/c1_Compiler.hpp 2015-07-31 11:54:47.025274479 +0200 +++ new/src/share/vm/c1/c1_Compiler.hpp 2015-07-31 11:54:46.781274490 +0200 @@ -55,18 +55,9 @@ // Print compilation timers and statistics virtual void print_timers(); - // Check the availability of an intrinsic for 'method' given a compilation context. - // The compilation context is needed to support per-method usage of the - // DisableIntrinsic flag. However, as C1 ignores the DisableIntrinsic flag, it - // ignores the compilation context. - virtual bool is_intrinsic_available(methodHandle method, methodHandle compilation_context); - // Check if the C1 compiler supports an intrinsic for 'method'. virtual bool is_intrinsic_supported(methodHandle method); - // Processing of command-line flags specific to the C1 compiler. - virtual bool is_intrinsic_disabled_by_flag(methodHandle method); - // Size of the code buffer static int code_buffer_size(); }; --- old/src/share/vm/runtime/globals.hpp 2015-07-31 11:54:47.033274479 +0200 +++ new/src/share/vm/runtime/globals.hpp 2015-07-31 11:54:46.761274491 +0200 @@ -855,6 +855,9 @@ product(bool, UseCRC32CIntrinsics, false, \ "use intrinsics for java.util.zip.CRC32C") \ \ + diagnostic(ccstrlist, DisableIntrinsic, "", \ + "do not expand intrinsics whose (internal) names appear here") \ + \ develop(bool, TraceCallFixup, false, \ "Trace all call fixups") \ \ --- old/src/share/vm/compiler/abstractCompiler.hpp 2015-07-31 11:54:47.077274477 +0200 +++ new/src/share/vm/compiler/abstractCompiler.hpp 2015-07-31 11:54:46.773274491 +0200 @@ -75,8 +75,8 @@ // // The second parameter, 'compilation_context', is needed to implement functionality // related to the DisableIntrinsic command-line flag. The DisableIntrinsic flag can - // be used to prohibit the C2 compiler (but not the C1 compiler) to use an intrinsic. - // There are three ways to disable an intrinsic using the DisableIntrinsic flag: + // be used to prohibit the compilers to use an intrinsic. There are three ways to + // disable an intrinsic using the DisableIntrinsic flag: // // (1) -XX:DisableIntrinsic=_hashCode,_getClass // Disables intrinsification of _hashCode and _getClass globally @@ -96,7 +96,8 @@ // compilation context is aClass::aMethod and java.lang.ref.Reference::get, // respectively. virtual bool is_intrinsic_available(methodHandle method, methodHandle compilation_context) { - return false; + return is_intrinsic_supported(method) && + !vmIntrinsics::is_disabled_by_flags(method, compilation_context); } // Determines if an intrinsic is supported by the compiler, that is, @@ -111,13 +112,6 @@ return false; } - // Implements compiler-specific processing of command-line flags. - // Processing of command-line flags common to all compilers is implemented - // in vmIntrinsicss::is_disabled_by_flag. - virtual bool is_intrinsic_disabled_by_flag(methodHandle method) { - return false; - } - // Compiler type queries. bool is_c1() { return _type == c1; } bool is_c2() { return _type == c2; } --- old/src/share/vm/c1/c1_GraphBuilder.cpp 2015-07-31 11:54:47.045274478 +0200 +++ new/src/share/vm/c1/c1_GraphBuilder.cpp 2015-07-31 11:54:46.773274491 +0200 @@ -3491,8 +3491,16 @@ bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) { // For calling is_intrinsic_available we need to transition to // the '_thread_in_vm' state because is_intrinsic_available() - // does not accesses critical VM-internal data. - if (!_compilation->compiler()->is_intrinsic_available(callee->get_Method(), NULL)) { + // accesses critical VM-internal data. + bool is_available = false; + { + VM_ENTRY_MARK; + methodHandle mh(THREAD, callee->get_Method()); + methodHandle ct(THREAD, method()->get_Method()); + is_available = _compilation->compiler()->is_intrinsic_available(mh, ct); + } + + if (!is_available) { if (!InlineNatives) { // Return false and also set message that the inlining of // intrinsics has been disabled in general. --- old/src/share/vm/opto/c2compiler.hpp 2015-07-31 11:54:47.109274476 +0200 +++ new/src/share/vm/opto/c2compiler.hpp 2015-07-31 11:54:46.793274490 +0200 @@ -51,11 +51,11 @@ // Print compilation timers and statistics void print_timers(); - // Check the availability of an intrinsic for 'method' given a compilation context. - virtual bool is_intrinsic_available(methodHandle method, methodHandle compilation_context); - // Return true if the intrinsification of a method supported by the compiler - // assuming a non-virtual dispatch. Return false otherwise. + // assuming a non-virtual dispatch. (A virtual dispatch is + // possible for only a limited set of available intrinsics whereas + // a non-virtual dispatch is possible for all available intrinsics.) + // Return false otherwise. virtual bool is_intrinsic_supported(methodHandle method) { return is_intrinsic_supported(method, false); } @@ -64,13 +64,6 @@ // the dispatch mode specified by the 'is_virtual' parameter. virtual bool is_intrinsic_supported(methodHandle method, bool is_virtual); - // Processing of command-line flags specific to the C2 compiler. - virtual bool is_intrinsic_disabled_by_flag(methodHandle method) { - return is_intrinsic_disabled_by_flag(method, NULL); - } - - virtual bool is_intrinsic_disabled_by_flag(methodHandle method, methodHandle compilation_context); - // Initial size of the code buffer (may be increased at runtime) static int initial_code_buffer_size(); }; --- old/src/share/vm/classfile/vmSymbols.hpp 2015-07-31 11:54:47.105274476 +0200 +++ new/src/share/vm/classfile/vmSymbols.hpp 2015-07-31 11:54:46.789274490 +0200 @@ -1384,10 +1384,9 @@ // 'method' requires predicated logic. static int predicates_needed(vmIntrinsics::ID id); - // Returns true if an intrinsic is disabled by command-line flags and - // false otherwise. Implements functionality common to the C1 - // and the C2 compiler. - static bool is_disabled_by_flags(vmIntrinsics::ID id); + // Returns true if a compiler intrinsic is disabled by command-line flags + // and false otherwise. + static bool is_disabled_by_flags(methodHandle method, methodHandle compilation_context); }; #endif // SHARE_VM_CLASSFILE_VMSYMBOLS_HPP --- old/src/share/vm/opto/library_call.cpp 2015-07-31 11:54:47.069274477 +0200 +++ new/src/share/vm/opto/library_call.cpp 2015-07-31 11:54:46.789274490 +0200 @@ -327,7 +327,7 @@ methodHandle mh(THREAD, m->get_Method()); methodHandle ct(THREAD, method()->get_Method()); is_available = compiler->is_intrinsic_supported(mh, is_virtual) && - !compiler->is_intrinsic_disabled_by_flag(mh, ct); + !vmIntrinsics::is_disabled_by_flags(mh, ct); } if (is_available) { --- old/src/share/vm/classfile/vmSymbols.cpp 2015-07-31 11:54:47.129274475 +0200 +++ new/src/share/vm/classfile/vmSymbols.cpp 2015-07-31 11:54:46.845274487 +0200 @@ -417,8 +417,59 @@ } } -bool vmIntrinsics::is_disabled_by_flags(vmIntrinsics::ID id) { +bool vmIntrinsics::is_disabled_by_flags(methodHandle method, methodHandle compilation_context) { + vmIntrinsics::ID id = method->intrinsic_id(); assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); + + // Check if the intrinsic corresponding to 'method' has been disabled on + // the command line by using the DisableIntrinsic flag (either globally + // or on a per-method level, see src/share/vm/compiler/abstractCompiler.hpp + // for details). + // Usually, the compilation context is the caller of the method 'method'. + // The only case when for a non-recursive method 'method' the compilation context + // is not the caller of the 'method' (but it is the method itself) is + // java.lang.ref.Referene::get. + // For java.lang.ref.Reference::get, the intrinsic version is used + // instead of the compiled version so that the value in the referent + // field can be registered by the G1 pre-barrier code. The intrinsified + // version of Reference::get also adds a memory barrier to prevent + // commoning reads from the referent field across safepoint since GC + // can change the referent field's value. See Compile::Compile() + // in src/share/vm/opto/compile.cpp or + // GraphBuilder::GraphBuilder() in src/share/vm/c1/c1_GraphBuilder.cpp + // for more details. + ccstr disable_intr = NULL; + if ((DisableIntrinsic[0] != '\0' && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) || + (!compilation_context.is_null() && + CompilerOracle::has_option_value(compilation_context, "DisableIntrinsic", disable_intr) && + strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL) + ) { + return true; + } + + // -XX:-InlineNatives disables nearly all intrinsics except the ones listed in + // the following switch statement. + 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: + case vmIntrinsics::_Reference_get: + break; + default: + return true; + } + } + switch (id) { case vmIntrinsics::_isInstance: case vmIntrinsics::_isAssignableFrom: @@ -430,6 +481,7 @@ case vmIntrinsics::_Class_cast: case vmIntrinsics::_getLength: case vmIntrinsics::_newArray: + case vmIntrinsics::_getClass: if (!InlineClassNatives) return true; break; case vmIntrinsics::_currentThread: @@ -522,6 +574,12 @@ case vmIntrinsics::_getAndSetInt: case vmIntrinsics::_getAndSetLong: case vmIntrinsics::_getAndSetObject: + case vmIntrinsics::_loadFence: + case vmIntrinsics::_storeFence: + case vmIntrinsics::_fullFence: + case vmIntrinsics::_compareAndSwapObject: + case vmIntrinsics::_compareAndSwapLong: + case vmIntrinsics::_compareAndSwapInt: if (!InlineUnsafeOps) return true; break; case vmIntrinsics::_getShortUnaligned: @@ -584,8 +642,8 @@ if (!InlineObjectCopy || !InlineArrayCopy) return true; break; case vmIntrinsics::_compareTo: - if (!SpecialStringCompareTo) return true; - break; + if (!SpecialStringCompareTo) return true; + break; case vmIntrinsics::_indexOf: if (!SpecialStringIndexOf) return true; break; @@ -602,8 +660,8 @@ if (!InlineReflectionGetCallerClass) return true; break; case vmIntrinsics::_multiplyToLen: - if (!UseMultiplyToLenIntrinsic) return true; - break; + if (!UseMultiplyToLenIntrinsic) return true; + break; case vmIntrinsics::_squareToLen: if (!UseSquareToLenIntrinsic) return true; break; --- old/src/share/vm/c1/c1_Compiler.cpp 2015-07-31 11:54:47.141274474 +0200 +++ new/src/share/vm/c1/c1_Compiler.cpp 2015-07-31 11:54:46.905274485 +0200 @@ -239,25 +239,6 @@ return true; } -bool Compiler::is_intrinsic_disabled_by_flag(methodHandle method) { - vmIntrinsics::ID id = method->intrinsic_id(); - assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); - - if (vmIntrinsics::is_disabled_by_flags(id)) { - return true; - } - - if (!InlineNatives && id != vmIntrinsics::_Reference_get) { - return true; - } - - if (!InlineClassNatives && id == vmIntrinsics::_getClass) { - return true; - } - - return false; -} - void Compiler::compile_method(ciEnv* env, ciMethod* method, int entry_bci) { BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob(); assert(buffer_blob != NULL, "Must exist"); @@ -275,7 +256,3 @@ void Compiler::print_timers() { Compilation::print_timers(); } - -bool Compiler::is_intrinsic_available(methodHandle method, methodHandle compilation_context) { - return is_intrinsic_supported(method) && !is_intrinsic_disabled_by_flag(method); -}