24
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.hpp"
27 #include "classfile/systemDictionary.hpp"
28 #include "classfile/vmSymbols.hpp"
29 #include "compiler/compileBroker.hpp"
30 #include "compiler/compileLog.hpp"
31 #include "oops/objArrayKlass.hpp"
32 #include "opto/addnode.hpp"
33 #include "opto/callGenerator.hpp"
34 #include "opto/castnode.hpp"
35 #include "opto/cfgnode.hpp"
36 #include "opto/convertnode.hpp"
37 #include "opto/countbitsnode.hpp"
38 #include "opto/intrinsicnode.hpp"
39 #include "opto/idealKit.hpp"
40 #include "opto/mathexactnode.hpp"
41 #include "opto/movenode.hpp"
42 #include "opto/mulnode.hpp"
43 #include "opto/narrowptrnode.hpp"
44 #include "opto/parse.hpp"
45 #include "opto/runtime.hpp"
46 #include "opto/subnode.hpp"
47 #include "prims/nativeLookup.hpp"
48 #include "runtime/sharedRuntime.hpp"
49 #include "trace/traceMacros.hpp"
50
51 class LibraryIntrinsic : public InlineCallGenerator {
52 // Extend the set of intrinsics known to the runtime:
53 public:
54 private:
55 bool _is_virtual;
56 bool _does_virtual_dispatch;
57 int8_t _predicates_count; // Intrinsic is predicated by several conditions
58 int8_t _last_predicate; // Last generated predicate
59 vmIntrinsics::ID _intrinsic_id;
60
61 public:
62 LibraryIntrinsic(ciMethod* m, bool is_virtual, int predicates_count, bool does_virtual_dispatch, vmIntrinsics::ID id)
63 : InlineCallGenerator(m),
270 bool inline_reference_get();
271 bool inline_Class_cast();
272 bool inline_aescrypt_Block(vmIntrinsics::ID id);
273 bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
274 Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
275 Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
276 Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
277 bool inline_sha_implCompress(vmIntrinsics::ID id);
278 bool inline_digestBase_implCompressMB(int predicate);
279 bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA,
280 bool long_state, address stubAddr, const char *stubName,
281 Node* src_start, Node* ofs, Node* limit);
282 Node* get_state_from_sha_object(Node *sha_object);
283 Node* get_state_from_sha5_object(Node *sha_object);
284 Node* inline_digestBase_implCompressMB_predicate(int predicate);
285 bool inline_encodeISOArray();
286 bool inline_updateCRC32();
287 bool inline_updateBytesCRC32();
288 bool inline_updateByteBufferCRC32();
289 bool inline_multiplyToLen();
290 };
291
292
293 //---------------------------make_vm_intrinsic----------------------------
294 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
295 vmIntrinsics::ID id = m->intrinsic_id();
296 assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
297
298 ccstr disable_intr = NULL;
299
300 if ((DisableIntrinsic[0] != '\0'
301 && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) ||
302 (method_has_option_value("DisableIntrinsic", disable_intr)
303 && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) {
304 // disabled by a user request on the command line:
305 // example: -XX:DisableIntrinsic=_hashCode,_getClass
306 return NULL;
307 }
308
309 if (!m->is_loaded()) {
883 case vmIntrinsics::_sha2_implCompress:
884 case vmIntrinsics::_sha5_implCompress:
885 return inline_sha_implCompress(intrinsic_id());
886
887 case vmIntrinsics::_digestBase_implCompressMB:
888 return inline_digestBase_implCompressMB(predicate);
889
890 case vmIntrinsics::_multiplyToLen:
891 return inline_multiplyToLen();
892
893 case vmIntrinsics::_encodeISOArray:
894 return inline_encodeISOArray();
895
896 case vmIntrinsics::_updateCRC32:
897 return inline_updateCRC32();
898 case vmIntrinsics::_updateBytesCRC32:
899 return inline_updateBytesCRC32();
900 case vmIntrinsics::_updateByteBufferCRC32:
901 return inline_updateByteBufferCRC32();
902
903 default:
904 // If you get here, it may be that someone has added a new intrinsic
905 // to the list in vmSymbols.hpp without implementing it here.
906 #ifndef PRODUCT
907 if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) {
908 tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)",
909 vmIntrinsics::name_at(intrinsic_id()), intrinsic_id());
910 }
911 #endif
912 return false;
913 }
914 }
915
916 Node* LibraryCallKit::try_to_predicate(int predicate) {
917 if (!jvms()->has_method()) {
918 // Root JVMState has a null method.
919 assert(map()->memory()->Opcode() == Op_Parm, "");
920 // Insert the memory aliasing node
921 set_all_memory(reset_memory());
922 }
5856
5857 ciKlass* klass_SHA = NULL;
5858 if (klass_SHA_name != NULL) {
5859 klass_SHA = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_SHA_name));
5860 }
5861 if ((klass_SHA == NULL) || !klass_SHA->is_loaded()) {
5862 // if none of SHA/SHA2/SHA5 is loaded, we never take the intrinsic fast path
5863 Node* ctrl = control();
5864 set_control(top()); // no intrinsic path
5865 return ctrl;
5866 }
5867 ciInstanceKlass* instklass_SHA = klass_SHA->as_instance_klass();
5868
5869 Node* instofSHA = gen_instanceof(digestBaseObj, makecon(TypeKlassPtr::make(instklass_SHA)));
5870 Node* cmp_instof = _gvn.transform(new CmpINode(instofSHA, intcon(1)));
5871 Node* bool_instof = _gvn.transform(new BoolNode(cmp_instof, BoolTest::ne));
5872 Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN);
5873
5874 return instof_false; // even if it is NULL
5875 }
|
24
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.hpp"
27 #include "classfile/systemDictionary.hpp"
28 #include "classfile/vmSymbols.hpp"
29 #include "compiler/compileBroker.hpp"
30 #include "compiler/compileLog.hpp"
31 #include "oops/objArrayKlass.hpp"
32 #include "opto/addnode.hpp"
33 #include "opto/callGenerator.hpp"
34 #include "opto/castnode.hpp"
35 #include "opto/cfgnode.hpp"
36 #include "opto/convertnode.hpp"
37 #include "opto/countbitsnode.hpp"
38 #include "opto/intrinsicnode.hpp"
39 #include "opto/idealKit.hpp"
40 #include "opto/mathexactnode.hpp"
41 #include "opto/movenode.hpp"
42 #include "opto/mulnode.hpp"
43 #include "opto/narrowptrnode.hpp"
44 #include "opto/opaquenode.hpp"
45 #include "opto/parse.hpp"
46 #include "opto/runtime.hpp"
47 #include "opto/subnode.hpp"
48 #include "prims/nativeLookup.hpp"
49 #include "runtime/sharedRuntime.hpp"
50 #include "trace/traceMacros.hpp"
51
52 class LibraryIntrinsic : public InlineCallGenerator {
53 // Extend the set of intrinsics known to the runtime:
54 public:
55 private:
56 bool _is_virtual;
57 bool _does_virtual_dispatch;
58 int8_t _predicates_count; // Intrinsic is predicated by several conditions
59 int8_t _last_predicate; // Last generated predicate
60 vmIntrinsics::ID _intrinsic_id;
61
62 public:
63 LibraryIntrinsic(ciMethod* m, bool is_virtual, int predicates_count, bool does_virtual_dispatch, vmIntrinsics::ID id)
64 : InlineCallGenerator(m),
271 bool inline_reference_get();
272 bool inline_Class_cast();
273 bool inline_aescrypt_Block(vmIntrinsics::ID id);
274 bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
275 Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
276 Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
277 Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
278 bool inline_sha_implCompress(vmIntrinsics::ID id);
279 bool inline_digestBase_implCompressMB(int predicate);
280 bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA,
281 bool long_state, address stubAddr, const char *stubName,
282 Node* src_start, Node* ofs, Node* limit);
283 Node* get_state_from_sha_object(Node *sha_object);
284 Node* get_state_from_sha5_object(Node *sha_object);
285 Node* inline_digestBase_implCompressMB_predicate(int predicate);
286 bool inline_encodeISOArray();
287 bool inline_updateCRC32();
288 bool inline_updateBytesCRC32();
289 bool inline_updateByteBufferCRC32();
290 bool inline_multiplyToLen();
291
292 bool inline_profileBoolean();
293 };
294
295
296 //---------------------------make_vm_intrinsic----------------------------
297 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
298 vmIntrinsics::ID id = m->intrinsic_id();
299 assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
300
301 ccstr disable_intr = NULL;
302
303 if ((DisableIntrinsic[0] != '\0'
304 && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) ||
305 (method_has_option_value("DisableIntrinsic", disable_intr)
306 && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) {
307 // disabled by a user request on the command line:
308 // example: -XX:DisableIntrinsic=_hashCode,_getClass
309 return NULL;
310 }
311
312 if (!m->is_loaded()) {
886 case vmIntrinsics::_sha2_implCompress:
887 case vmIntrinsics::_sha5_implCompress:
888 return inline_sha_implCompress(intrinsic_id());
889
890 case vmIntrinsics::_digestBase_implCompressMB:
891 return inline_digestBase_implCompressMB(predicate);
892
893 case vmIntrinsics::_multiplyToLen:
894 return inline_multiplyToLen();
895
896 case vmIntrinsics::_encodeISOArray:
897 return inline_encodeISOArray();
898
899 case vmIntrinsics::_updateCRC32:
900 return inline_updateCRC32();
901 case vmIntrinsics::_updateBytesCRC32:
902 return inline_updateBytesCRC32();
903 case vmIntrinsics::_updateByteBufferCRC32:
904 return inline_updateByteBufferCRC32();
905
906 case vmIntrinsics::_profileBoolean:
907 return inline_profileBoolean();
908
909 default:
910 // If you get here, it may be that someone has added a new intrinsic
911 // to the list in vmSymbols.hpp without implementing it here.
912 #ifndef PRODUCT
913 if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) {
914 tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)",
915 vmIntrinsics::name_at(intrinsic_id()), intrinsic_id());
916 }
917 #endif
918 return false;
919 }
920 }
921
922 Node* LibraryCallKit::try_to_predicate(int predicate) {
923 if (!jvms()->has_method()) {
924 // Root JVMState has a null method.
925 assert(map()->memory()->Opcode() == Op_Parm, "");
926 // Insert the memory aliasing node
927 set_all_memory(reset_memory());
928 }
5862
5863 ciKlass* klass_SHA = NULL;
5864 if (klass_SHA_name != NULL) {
5865 klass_SHA = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_SHA_name));
5866 }
5867 if ((klass_SHA == NULL) || !klass_SHA->is_loaded()) {
5868 // if none of SHA/SHA2/SHA5 is loaded, we never take the intrinsic fast path
5869 Node* ctrl = control();
5870 set_control(top()); // no intrinsic path
5871 return ctrl;
5872 }
5873 ciInstanceKlass* instklass_SHA = klass_SHA->as_instance_klass();
5874
5875 Node* instofSHA = gen_instanceof(digestBaseObj, makecon(TypeKlassPtr::make(instklass_SHA)));
5876 Node* cmp_instof = _gvn.transform(new CmpINode(instofSHA, intcon(1)));
5877 Node* bool_instof = _gvn.transform(new BoolNode(cmp_instof, BoolTest::ne));
5878 Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN);
5879
5880 return instof_false; // even if it is NULL
5881 }
5882
5883 bool LibraryCallKit::inline_profileBoolean() {
5884 Node* counts = argument(1);
5885 const TypeAryPtr* ary = NULL;
5886 ciArray* aobj = NULL;
5887 if (counts->is_Con()
5888 && (ary = counts->bottom_type()->isa_aryptr()) != NULL
5889 && (aobj = ary->const_oop()->as_array()) != NULL
5890 && (aobj->length() == 2)) {
5891 // Profile is int[2] where [0] and [1] correspond to false and true value occurrences respectively.
5892 jint false_cnt = aobj->element_value(0).as_int();
5893 jint true_cnt = aobj->element_value(1).as_int();
5894
5895 method()->set_injected_profile(true);
5896
5897 if (C->log() != NULL) {
5898 C->log()->elem("observe source='profileBoolean' false='%d' true='%d'",
5899 false_cnt, true_cnt);
5900 }
5901
5902 if (false_cnt + true_cnt == 0) {
5903 // According to profile, never executed.
5904 uncommon_trap_exact(Deoptimization::Reason_intrinsic,
5905 Deoptimization::Action_reinterpret);
5906 return true;
5907 }
5908 // Stop profiling.
5909 // MethodHandleImpl::profileBoolean() has profiling logic in it's bytecode.
5910 // By replacing method's body with profile data (represented as ProfileBooleanNode
5911 // on IR level) we effectively disable profiling.
5912 // It enables full speed execution once optimized code is generated.
5913 Node* profile = _gvn.transform(new ProfileBooleanNode(argument(0), false_cnt, true_cnt));
5914 C->record_for_igvn(profile);
5915 set_result(profile);
5916 return true;
5917 } else {
5918 // Continue profiling.
5919 // Profile data isn't available at the moment. So, execute method's bytecode version.
5920 // Usually, when GWT LambdaForms are profiled it means that a stand-alone nmethod
5921 // is compiled and counters aren't available since corresponding MethodHandle
5922 // isn't a compile-time constant.
5923 return false;
5924 }
5925 }
|