29 #include "compiler/compileLog.hpp"
30 #include "oops/objArrayKlass.hpp"
31 #include "opto/addnode.hpp"
32 #include "opto/callGenerator.hpp"
33 #include "opto/cfgnode.hpp"
34 #include "opto/idealKit.hpp"
35 #include "opto/mulnode.hpp"
36 #include "opto/parse.hpp"
37 #include "opto/runtime.hpp"
38 #include "opto/subnode.hpp"
39 #include "prims/nativeLookup.hpp"
40 #include "runtime/sharedRuntime.hpp"
41 #include "trace/traceMacros.hpp"
42
43 class LibraryIntrinsic : public InlineCallGenerator {
44 // Extend the set of intrinsics known to the runtime:
45 public:
46 private:
47 bool _is_virtual;
48 bool _is_predicted;
49 vmIntrinsics::ID _intrinsic_id;
50
51 public:
52 LibraryIntrinsic(ciMethod* m, bool is_virtual, bool is_predicted, vmIntrinsics::ID id)
53 : InlineCallGenerator(m),
54 _is_virtual(is_virtual),
55 _is_predicted(is_predicted),
56 _intrinsic_id(id)
57 {
58 }
59 virtual bool is_intrinsic() const { return true; }
60 virtual bool is_virtual() const { return _is_virtual; }
61 virtual bool is_predicted() const { return _is_predicted; }
62 virtual JVMState* generate(JVMState* jvms);
63 virtual Node* generate_predicate(JVMState* jvms);
64 vmIntrinsics::ID intrinsic_id() const { return _intrinsic_id; }
65 };
66
67
68 // Local helper class for LibraryIntrinsic:
69 class LibraryCallKit : public GraphKit {
70 private:
71 LibraryIntrinsic* _intrinsic; // the library intrinsic being called
72 Node* _result; // the result node, if any
73 int _reexecute_sp; // the stack pointer when bytecode needs to be reexecuted
74
75 const TypeOopPtr* sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr = false);
76
77 public:
78 LibraryCallKit(JVMState* jvms, LibraryIntrinsic* intrinsic)
79 : GraphKit(jvms),
80 _intrinsic(intrinsic),
81 _result(NULL)
335 case vmIntrinsics::_compareTo:
336 case vmIntrinsics::_equals:
337 case vmIntrinsics::_equalsC:
338 case vmIntrinsics::_getAndAddInt:
339 case vmIntrinsics::_getAndAddLong:
340 case vmIntrinsics::_getAndSetInt:
341 case vmIntrinsics::_getAndSetLong:
342 case vmIntrinsics::_getAndSetObject:
343 case vmIntrinsics::_loadFence:
344 case vmIntrinsics::_storeFence:
345 case vmIntrinsics::_fullFence:
346 break; // InlineNatives does not control String.compareTo
347 case vmIntrinsics::_Reference_get:
348 break; // InlineNatives does not control Reference.get
349 default:
350 return NULL;
351 }
352 }
353
354 bool is_predicted = false;
355
356 switch (id) {
357 case vmIntrinsics::_compareTo:
358 if (!SpecialStringCompareTo) return NULL;
359 if (!Matcher::match_rule_supported(Op_StrComp)) return NULL;
360 break;
361 case vmIntrinsics::_indexOf:
362 if (!SpecialStringIndexOf) return NULL;
363 break;
364 case vmIntrinsics::_equals:
365 if (!SpecialStringEquals) return NULL;
366 if (!Matcher::match_rule_supported(Op_StrEquals)) return NULL;
367 break;
368 case vmIntrinsics::_equalsC:
369 if (!SpecialArraysEquals) return NULL;
370 if (!Matcher::match_rule_supported(Op_AryEq)) return NULL;
371 break;
372 case vmIntrinsics::_arraycopy:
373 if (!InlineArrayCopy) return NULL;
374 break;
375 case vmIntrinsics::_copyMemory:
376 if (StubRoutines::unsafe_arraycopy() == NULL) return NULL;
377 if (!InlineArrayCopy) return NULL;
378 break;
379 case vmIntrinsics::_hashCode:
380 if (!InlineObjectHash) return NULL;
381 break;
382 case vmIntrinsics::_clone:
383 case vmIntrinsics::_copyOf:
384 case vmIntrinsics::_copyOfRange:
385 if (!InlineObjectCopy) return NULL;
386 // These also use the arraycopy intrinsic mechanism:
387 if (!InlineArrayCopy) return NULL;
388 break;
389 case vmIntrinsics::_encodeISOArray:
390 if (!SpecialEncodeISOArray) return NULL;
391 if (!Matcher::match_rule_supported(Op_EncodeISOArray)) return NULL;
392 break;
393 case vmIntrinsics::_checkIndex:
394 // We do not intrinsify this. The optimizer does fine with it.
395 return NULL;
396
397 case vmIntrinsics::_getCallerClass:
398 if (!UseNewReflection) return NULL;
399 if (!InlineReflectionGetCallerClass) return NULL;
400 if (SystemDictionary::reflect_CallerSensitive_klass() == NULL) return NULL;
512 if (!InlineClassNatives) return NULL;
513 }
514
515 // -XX:-InlineThreadNatives disables natives from the Thread class.
516 if (m->holder()->name() == ciSymbol::java_lang_Thread()) {
517 if (!InlineThreadNatives) return NULL;
518 }
519
520 // -XX:-InlineMathNatives disables natives from the Math,Float and Double classes.
521 if (m->holder()->name() == ciSymbol::java_lang_Math() ||
522 m->holder()->name() == ciSymbol::java_lang_Float() ||
523 m->holder()->name() == ciSymbol::java_lang_Double()) {
524 if (!InlineMathNatives) return NULL;
525 }
526
527 // -XX:-InlineUnsafeOps disables natives from the Unsafe class.
528 if (m->holder()->name() == ciSymbol::sun_misc_Unsafe()) {
529 if (!InlineUnsafeOps) return NULL;
530 }
531
532 return new LibraryIntrinsic(m, is_virtual, is_predicted, (vmIntrinsics::ID) id);
533 }
534
535 //----------------------register_library_intrinsics-----------------------
536 // Initialize this file's data structures, for each Compile instance.
537 void Compile::register_library_intrinsics() {
538 // Nothing to do here.
539 }
540
541 JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
542 LibraryCallKit kit(jvms, this);
543 Compile* C = kit.C;
544 int nodes = C->unique();
545 #ifndef PRODUCT
546 if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) {
547 char buf[1000];
548 const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf));
549 tty->print_cr("Intrinsic %s", str);
550 }
551 #endif
552 ciMethod* callee = kit.callee();
|
29 #include "compiler/compileLog.hpp"
30 #include "oops/objArrayKlass.hpp"
31 #include "opto/addnode.hpp"
32 #include "opto/callGenerator.hpp"
33 #include "opto/cfgnode.hpp"
34 #include "opto/idealKit.hpp"
35 #include "opto/mulnode.hpp"
36 #include "opto/parse.hpp"
37 #include "opto/runtime.hpp"
38 #include "opto/subnode.hpp"
39 #include "prims/nativeLookup.hpp"
40 #include "runtime/sharedRuntime.hpp"
41 #include "trace/traceMacros.hpp"
42
43 class LibraryIntrinsic : public InlineCallGenerator {
44 // Extend the set of intrinsics known to the runtime:
45 public:
46 private:
47 bool _is_virtual;
48 bool _is_predicted;
49 bool _is_low_priority;
50 vmIntrinsics::ID _intrinsic_id;
51
52 public:
53 LibraryIntrinsic(ciMethod* m, bool is_virtual, bool is_predicted, bool is_low_priority, vmIntrinsics::ID id)
54 : InlineCallGenerator(m),
55 _is_virtual(is_virtual),
56 _is_predicted(is_predicted),
57 _is_low_priority(is_low_priority),
58 _intrinsic_id(id)
59 {
60 }
61 virtual bool is_intrinsic() const { return true; }
62 virtual bool is_virtual() const { return _is_virtual; }
63 virtual bool is_predicted() const { return _is_predicted; }
64 virtual bool is_low_priority() const { return _is_low_priority; }
65 virtual JVMState* generate(JVMState* jvms);
66 virtual Node* generate_predicate(JVMState* jvms);
67 vmIntrinsics::ID intrinsic_id() const { return _intrinsic_id; }
68 };
69
70
71 // Local helper class for LibraryIntrinsic:
72 class LibraryCallKit : public GraphKit {
73 private:
74 LibraryIntrinsic* _intrinsic; // the library intrinsic being called
75 Node* _result; // the result node, if any
76 int _reexecute_sp; // the stack pointer when bytecode needs to be reexecuted
77
78 const TypeOopPtr* sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr = false);
79
80 public:
81 LibraryCallKit(JVMState* jvms, LibraryIntrinsic* intrinsic)
82 : GraphKit(jvms),
83 _intrinsic(intrinsic),
84 _result(NULL)
338 case vmIntrinsics::_compareTo:
339 case vmIntrinsics::_equals:
340 case vmIntrinsics::_equalsC:
341 case vmIntrinsics::_getAndAddInt:
342 case vmIntrinsics::_getAndAddLong:
343 case vmIntrinsics::_getAndSetInt:
344 case vmIntrinsics::_getAndSetLong:
345 case vmIntrinsics::_getAndSetObject:
346 case vmIntrinsics::_loadFence:
347 case vmIntrinsics::_storeFence:
348 case vmIntrinsics::_fullFence:
349 break; // InlineNatives does not control String.compareTo
350 case vmIntrinsics::_Reference_get:
351 break; // InlineNatives does not control Reference.get
352 default:
353 return NULL;
354 }
355 }
356
357 bool is_predicted = false;
358 bool is_low_priority = false;
359
360 switch (id) {
361 case vmIntrinsics::_compareTo:
362 if (!SpecialStringCompareTo) return NULL;
363 if (!Matcher::match_rule_supported(Op_StrComp)) return NULL;
364 break;
365 case vmIntrinsics::_indexOf:
366 if (!SpecialStringIndexOf) return NULL;
367 break;
368 case vmIntrinsics::_equals:
369 if (!SpecialStringEquals) return NULL;
370 if (!Matcher::match_rule_supported(Op_StrEquals)) return NULL;
371 break;
372 case vmIntrinsics::_equalsC:
373 if (!SpecialArraysEquals) return NULL;
374 if (!Matcher::match_rule_supported(Op_AryEq)) return NULL;
375 break;
376 case vmIntrinsics::_arraycopy:
377 if (!InlineArrayCopy) return NULL;
378 break;
379 case vmIntrinsics::_copyMemory:
380 if (StubRoutines::unsafe_arraycopy() == NULL) return NULL;
381 if (!InlineArrayCopy) return NULL;
382 break;
383 case vmIntrinsics::_hashCode:
384 if (!InlineObjectHash) return NULL;
385 is_low_priority = true;
386 break;
387 case vmIntrinsics::_clone:
388 case vmIntrinsics::_copyOf:
389 case vmIntrinsics::_copyOfRange:
390 if (!InlineObjectCopy) return NULL;
391 // These also use the arraycopy intrinsic mechanism:
392 if (!InlineArrayCopy) return NULL;
393 break;
394 case vmIntrinsics::_encodeISOArray:
395 if (!SpecialEncodeISOArray) return NULL;
396 if (!Matcher::match_rule_supported(Op_EncodeISOArray)) return NULL;
397 break;
398 case vmIntrinsics::_checkIndex:
399 // We do not intrinsify this. The optimizer does fine with it.
400 return NULL;
401
402 case vmIntrinsics::_getCallerClass:
403 if (!UseNewReflection) return NULL;
404 if (!InlineReflectionGetCallerClass) return NULL;
405 if (SystemDictionary::reflect_CallerSensitive_klass() == NULL) return NULL;
517 if (!InlineClassNatives) return NULL;
518 }
519
520 // -XX:-InlineThreadNatives disables natives from the Thread class.
521 if (m->holder()->name() == ciSymbol::java_lang_Thread()) {
522 if (!InlineThreadNatives) return NULL;
523 }
524
525 // -XX:-InlineMathNatives disables natives from the Math,Float and Double classes.
526 if (m->holder()->name() == ciSymbol::java_lang_Math() ||
527 m->holder()->name() == ciSymbol::java_lang_Float() ||
528 m->holder()->name() == ciSymbol::java_lang_Double()) {
529 if (!InlineMathNatives) return NULL;
530 }
531
532 // -XX:-InlineUnsafeOps disables natives from the Unsafe class.
533 if (m->holder()->name() == ciSymbol::sun_misc_Unsafe()) {
534 if (!InlineUnsafeOps) return NULL;
535 }
536
537 return new LibraryIntrinsic(m, is_virtual, is_predicted, is_low_priority, (vmIntrinsics::ID) id);
538 }
539
540 //----------------------register_library_intrinsics-----------------------
541 // Initialize this file's data structures, for each Compile instance.
542 void Compile::register_library_intrinsics() {
543 // Nothing to do here.
544 }
545
546 JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
547 LibraryCallKit kit(jvms, this);
548 Compile* C = kit.C;
549 int nodes = C->unique();
550 #ifndef PRODUCT
551 if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) {
552 char buf[1000];
553 const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf));
554 tty->print_cr("Intrinsic %s", str);
555 }
556 #endif
557 ciMethod* callee = kit.callee();
|