303 |
304 |
304 bool inline_profileBoolean(); |
305 bool inline_profileBoolean(); |
305 bool inline_isCompileConstant(); |
306 bool inline_isCompileConstant(); |
306 }; |
307 }; |
307 |
308 |
308 |
|
309 //---------------------------make_vm_intrinsic---------------------------- |
309 //---------------------------make_vm_intrinsic---------------------------- |
310 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { |
310 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { |
311 vmIntrinsics::ID id = m->intrinsic_id(); |
311 vmIntrinsics::ID id = m->intrinsic_id(); |
312 assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); |
312 assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); |
313 |
313 |
314 ccstr disable_intr = NULL; |
314 if (!m->is_loaded()) { |
315 |
315 // Do not attempt to inline unloaded methods. |
316 if ((DisableIntrinsic[0] != '\0' |
|
317 && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) || |
|
318 (method_has_option_value("DisableIntrinsic", disable_intr) |
|
319 && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) { |
|
320 // disabled by a user request on the command line: |
|
321 // example: -XX:DisableIntrinsic=_hashCode,_getClass |
|
322 return NULL; |
316 return NULL; |
323 } |
317 } |
324 |
318 |
325 if (!m->is_loaded()) { |
319 C2Compiler* compiler = (C2Compiler*)CompileBroker::compiler(CompLevel_full_optimization); |
326 // do not attempt to inline unloaded methods |
320 bool is_available = false; |
327 return NULL; |
321 |
328 } |
322 { |
329 |
323 // For calling is_intrinsic_supported and is_intrinsic_disabled_by_flag |
330 // Only a few intrinsics implement a virtual dispatch. |
324 // the compiler must transition to '_thread_in_vm' state because both |
331 // They are expensive calls which are also frequently overridden. |
325 // methods access VM-internal data. |
332 if (is_virtual) { |
326 VM_ENTRY_MARK; |
333 switch (id) { |
327 methodHandle mh(THREAD, m->get_Method()); |
334 case vmIntrinsics::_hashCode: |
328 methodHandle ct(THREAD, method()->get_Method()); |
335 case vmIntrinsics::_clone: |
329 is_available = compiler->is_intrinsic_supported(mh, is_virtual) && |
336 // OK, Object.hashCode and Object.clone intrinsics come in both flavors |
330 !compiler->is_intrinsic_disabled_by_flag(mh, ct); |
337 break; |
331 } |
338 default: |
332 |
339 return NULL; |
333 if (is_available) { |
340 } |
|
341 } |
|
342 |
|
343 // -XX:-InlineNatives disables nearly all intrinsics: |
|
344 if (!InlineNatives) { |
|
345 switch (id) { |
|
346 case vmIntrinsics::_indexOf: |
|
347 case vmIntrinsics::_compareTo: |
|
348 case vmIntrinsics::_equals: |
|
349 case vmIntrinsics::_equalsC: |
|
350 case vmIntrinsics::_getAndAddInt: |
|
351 case vmIntrinsics::_getAndAddLong: |
|
352 case vmIntrinsics::_getAndSetInt: |
|
353 case vmIntrinsics::_getAndSetLong: |
|
354 case vmIntrinsics::_getAndSetObject: |
|
355 case vmIntrinsics::_loadFence: |
|
356 case vmIntrinsics::_storeFence: |
|
357 case vmIntrinsics::_fullFence: |
|
358 break; // InlineNatives does not control String.compareTo |
|
359 case vmIntrinsics::_Reference_get: |
|
360 break; // InlineNatives does not control Reference.get |
|
361 default: |
|
362 return NULL; |
|
363 } |
|
364 } |
|
365 |
|
366 int predicates = 0; |
|
367 bool does_virtual_dispatch = false; |
|
368 |
|
369 switch (id) { |
|
370 case vmIntrinsics::_compareTo: |
|
371 if (!SpecialStringCompareTo) return NULL; |
|
372 if (!Matcher::match_rule_supported(Op_StrComp)) return NULL; |
|
373 break; |
|
374 case vmIntrinsics::_indexOf: |
|
375 if (!SpecialStringIndexOf) return NULL; |
|
376 break; |
|
377 case vmIntrinsics::_equals: |
|
378 if (!SpecialStringEquals) return NULL; |
|
379 if (!Matcher::match_rule_supported(Op_StrEquals)) return NULL; |
|
380 break; |
|
381 case vmIntrinsics::_equalsC: |
|
382 if (!SpecialArraysEquals) return NULL; |
|
383 if (!Matcher::match_rule_supported(Op_AryEq)) return NULL; |
|
384 break; |
|
385 case vmIntrinsics::_arraycopy: |
|
386 if (!InlineArrayCopy) return NULL; |
|
387 break; |
|
388 case vmIntrinsics::_copyMemory: |
|
389 if (StubRoutines::unsafe_arraycopy() == NULL) return NULL; |
|
390 if (!InlineArrayCopy) return NULL; |
|
391 break; |
|
392 case vmIntrinsics::_hashCode: |
|
393 if (!InlineObjectHash) return NULL; |
|
394 does_virtual_dispatch = true; |
|
395 break; |
|
396 case vmIntrinsics::_clone: |
|
397 does_virtual_dispatch = true; |
|
398 case vmIntrinsics::_copyOf: |
|
399 case vmIntrinsics::_copyOfRange: |
|
400 if (!InlineObjectCopy) return NULL; |
|
401 // These also use the arraycopy intrinsic mechanism: |
|
402 if (!InlineArrayCopy) return NULL; |
|
403 break; |
|
404 case vmIntrinsics::_encodeISOArray: |
|
405 if (!SpecialEncodeISOArray) return NULL; |
|
406 if (!Matcher::match_rule_supported(Op_EncodeISOArray)) return NULL; |
|
407 break; |
|
408 case vmIntrinsics::_checkIndex: |
|
409 // We do not intrinsify this. The optimizer does fine with it. |
|
410 return NULL; |
|
411 |
|
412 case vmIntrinsics::_getCallerClass: |
|
413 if (!InlineReflectionGetCallerClass) return NULL; |
|
414 if (SystemDictionary::reflect_CallerSensitive_klass() == NULL) return NULL; |
|
415 break; |
|
416 |
|
417 case vmIntrinsics::_bitCount_i: |
|
418 if (!Matcher::match_rule_supported(Op_PopCountI)) return NULL; |
|
419 break; |
|
420 |
|
421 case vmIntrinsics::_bitCount_l: |
|
422 if (!Matcher::match_rule_supported(Op_PopCountL)) return NULL; |
|
423 break; |
|
424 |
|
425 case vmIntrinsics::_numberOfLeadingZeros_i: |
|
426 if (!Matcher::match_rule_supported(Op_CountLeadingZerosI)) return NULL; |
|
427 break; |
|
428 |
|
429 case vmIntrinsics::_numberOfLeadingZeros_l: |
|
430 if (!Matcher::match_rule_supported(Op_CountLeadingZerosL)) return NULL; |
|
431 break; |
|
432 |
|
433 case vmIntrinsics::_numberOfTrailingZeros_i: |
|
434 if (!Matcher::match_rule_supported(Op_CountTrailingZerosI)) return NULL; |
|
435 break; |
|
436 |
|
437 case vmIntrinsics::_numberOfTrailingZeros_l: |
|
438 if (!Matcher::match_rule_supported(Op_CountTrailingZerosL)) return NULL; |
|
439 break; |
|
440 |
|
441 case vmIntrinsics::_reverseBytes_c: |
|
442 if (!Matcher::match_rule_supported(Op_ReverseBytesUS)) return NULL; |
|
443 break; |
|
444 case vmIntrinsics::_reverseBytes_s: |
|
445 if (!Matcher::match_rule_supported(Op_ReverseBytesS)) return NULL; |
|
446 break; |
|
447 case vmIntrinsics::_reverseBytes_i: |
|
448 if (!Matcher::match_rule_supported(Op_ReverseBytesI)) return NULL; |
|
449 break; |
|
450 case vmIntrinsics::_reverseBytes_l: |
|
451 if (!Matcher::match_rule_supported(Op_ReverseBytesL)) return NULL; |
|
452 break; |
|
453 |
|
454 case vmIntrinsics::_Reference_get: |
|
455 // Use the intrinsic version of Reference.get() so that the value in |
|
456 // the referent field can be registered by the G1 pre-barrier code. |
|
457 // Also add memory barrier to prevent commoning reads from this field |
|
458 // across safepoint since GC can change it value. |
|
459 break; |
|
460 |
|
461 case vmIntrinsics::_compareAndSwapObject: |
|
462 #ifdef _LP64 |
|
463 if (!UseCompressedOops && !Matcher::match_rule_supported(Op_CompareAndSwapP)) return NULL; |
|
464 #endif |
|
465 break; |
|
466 |
|
467 case vmIntrinsics::_compareAndSwapLong: |
|
468 if (!Matcher::match_rule_supported(Op_CompareAndSwapL)) return NULL; |
|
469 break; |
|
470 |
|
471 case vmIntrinsics::_getAndAddInt: |
|
472 if (!Matcher::match_rule_supported(Op_GetAndAddI)) return NULL; |
|
473 break; |
|
474 |
|
475 case vmIntrinsics::_getAndAddLong: |
|
476 if (!Matcher::match_rule_supported(Op_GetAndAddL)) return NULL; |
|
477 break; |
|
478 |
|
479 case vmIntrinsics::_getAndSetInt: |
|
480 if (!Matcher::match_rule_supported(Op_GetAndSetI)) return NULL; |
|
481 break; |
|
482 |
|
483 case vmIntrinsics::_getAndSetLong: |
|
484 if (!Matcher::match_rule_supported(Op_GetAndSetL)) return NULL; |
|
485 break; |
|
486 |
|
487 case vmIntrinsics::_getAndSetObject: |
|
488 #ifdef _LP64 |
|
489 if (!UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetP)) return NULL; |
|
490 if (UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetN)) return NULL; |
|
491 break; |
|
492 #else |
|
493 if (!Matcher::match_rule_supported(Op_GetAndSetP)) return NULL; |
|
494 break; |
|
495 #endif |
|
496 |
|
497 case vmIntrinsics::_aescrypt_encryptBlock: |
|
498 case vmIntrinsics::_aescrypt_decryptBlock: |
|
499 if (!UseAESIntrinsics) return NULL; |
|
500 break; |
|
501 |
|
502 case vmIntrinsics::_multiplyToLen: |
|
503 if (!UseMultiplyToLenIntrinsic) return NULL; |
|
504 break; |
|
505 |
|
506 case vmIntrinsics::_squareToLen: |
|
507 if (!UseSquareToLenIntrinsic) return NULL; |
|
508 break; |
|
509 |
|
510 case vmIntrinsics::_mulAdd: |
|
511 if (!UseMulAddIntrinsic) return NULL; |
|
512 break; |
|
513 |
|
514 case vmIntrinsics::_montgomeryMultiply: |
|
515 if (!UseMontgomeryMultiplyIntrinsic) return NULL; |
|
516 break; |
|
517 case vmIntrinsics::_montgomerySquare: |
|
518 if (!UseMontgomerySquareIntrinsic) return NULL; |
|
519 break; |
|
520 |
|
521 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt: |
|
522 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: |
|
523 if (!UseAESIntrinsics) return NULL; |
|
524 // these two require the predicated logic |
|
525 predicates = 1; |
|
526 break; |
|
527 |
|
528 case vmIntrinsics::_sha_implCompress: |
|
529 if (!UseSHA1Intrinsics) return NULL; |
|
530 break; |
|
531 |
|
532 case vmIntrinsics::_sha2_implCompress: |
|
533 if (!UseSHA256Intrinsics) return NULL; |
|
534 break; |
|
535 |
|
536 case vmIntrinsics::_sha5_implCompress: |
|
537 if (!UseSHA512Intrinsics) return NULL; |
|
538 break; |
|
539 |
|
540 case vmIntrinsics::_digestBase_implCompressMB: |
|
541 if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) return NULL; |
|
542 predicates = 3; |
|
543 break; |
|
544 |
|
545 case vmIntrinsics::_ghash_processBlocks: |
|
546 if (!UseGHASHIntrinsics) return NULL; |
|
547 break; |
|
548 |
|
549 case vmIntrinsics::_updateCRC32: |
|
550 case vmIntrinsics::_updateBytesCRC32: |
|
551 case vmIntrinsics::_updateByteBufferCRC32: |
|
552 if (!UseCRC32Intrinsics) return NULL; |
|
553 break; |
|
554 |
|
555 case vmIntrinsics::_updateBytesCRC32C: |
|
556 case vmIntrinsics::_updateDirectByteBufferCRC32C: |
|
557 if (!UseCRC32CIntrinsics) return NULL; |
|
558 break; |
|
559 |
|
560 case vmIntrinsics::_incrementExactI: |
|
561 case vmIntrinsics::_addExactI: |
|
562 if (!Matcher::match_rule_supported(Op_OverflowAddI) || !UseMathExactIntrinsics) return NULL; |
|
563 break; |
|
564 case vmIntrinsics::_incrementExactL: |
|
565 case vmIntrinsics::_addExactL: |
|
566 if (!Matcher::match_rule_supported(Op_OverflowAddL) || !UseMathExactIntrinsics) return NULL; |
|
567 break; |
|
568 case vmIntrinsics::_decrementExactI: |
|
569 case vmIntrinsics::_subtractExactI: |
|
570 if (!Matcher::match_rule_supported(Op_OverflowSubI) || !UseMathExactIntrinsics) return NULL; |
|
571 break; |
|
572 case vmIntrinsics::_decrementExactL: |
|
573 case vmIntrinsics::_subtractExactL: |
|
574 if (!Matcher::match_rule_supported(Op_OverflowSubL) || !UseMathExactIntrinsics) return NULL; |
|
575 break; |
|
576 case vmIntrinsics::_negateExactI: |
|
577 if (!Matcher::match_rule_supported(Op_OverflowSubI) || !UseMathExactIntrinsics) return NULL; |
|
578 break; |
|
579 case vmIntrinsics::_negateExactL: |
|
580 if (!Matcher::match_rule_supported(Op_OverflowSubL) || !UseMathExactIntrinsics) return NULL; |
|
581 break; |
|
582 case vmIntrinsics::_multiplyExactI: |
|
583 if (!Matcher::match_rule_supported(Op_OverflowMulI) || !UseMathExactIntrinsics) return NULL; |
|
584 break; |
|
585 case vmIntrinsics::_multiplyExactL: |
|
586 if (!Matcher::match_rule_supported(Op_OverflowMulL) || !UseMathExactIntrinsics) return NULL; |
|
587 break; |
|
588 |
|
589 case vmIntrinsics::_getShortUnaligned: |
|
590 case vmIntrinsics::_getCharUnaligned: |
|
591 case vmIntrinsics::_getIntUnaligned: |
|
592 case vmIntrinsics::_getLongUnaligned: |
|
593 case vmIntrinsics::_putShortUnaligned: |
|
594 case vmIntrinsics::_putCharUnaligned: |
|
595 case vmIntrinsics::_putIntUnaligned: |
|
596 case vmIntrinsics::_putLongUnaligned: |
|
597 if (!UseUnalignedAccesses) return NULL; |
|
598 break; |
|
599 |
|
600 default: |
|
601 assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility"); |
334 assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility"); |
602 assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?"); |
335 assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?"); |
603 break; |
336 return new LibraryIntrinsic(m, is_virtual, |
604 } |
337 vmIntrinsics::predicates_needed(id), |
605 |
338 vmIntrinsics::does_virtual_dispatch(id), |
606 // -XX:-InlineClassNatives disables natives from the Class class. |
339 (vmIntrinsics::ID) id); |
607 // The flag applies to all reflective calls, notably Array.newArray |
340 } else { |
608 // (visible to Java programmers as Array.newInstance). |
341 return NULL; |
609 if (m->holder()->name() == ciSymbol::java_lang_Class() || |
342 } |
610 m->holder()->name() == ciSymbol::java_lang_reflect_Array()) { |
|
611 if (!InlineClassNatives) return NULL; |
|
612 } |
|
613 |
|
614 // -XX:-InlineThreadNatives disables natives from the Thread class. |
|
615 if (m->holder()->name() == ciSymbol::java_lang_Thread()) { |
|
616 if (!InlineThreadNatives) return NULL; |
|
617 } |
|
618 |
|
619 // -XX:-InlineMathNatives disables natives from the Math,Float and Double classes. |
|
620 if (m->holder()->name() == ciSymbol::java_lang_Math() || |
|
621 m->holder()->name() == ciSymbol::java_lang_Float() || |
|
622 m->holder()->name() == ciSymbol::java_lang_Double()) { |
|
623 if (!InlineMathNatives) return NULL; |
|
624 } |
|
625 |
|
626 // -XX:-InlineUnsafeOps disables natives from the Unsafe class. |
|
627 if (m->holder()->name() == ciSymbol::sun_misc_Unsafe()) { |
|
628 if (!InlineUnsafeOps) return NULL; |
|
629 } |
|
630 |
|
631 return new LibraryIntrinsic(m, is_virtual, predicates, does_virtual_dispatch, (vmIntrinsics::ID) id); |
|
632 } |
343 } |
633 |
344 |
634 //----------------------register_library_intrinsics----------------------- |
345 //----------------------register_library_intrinsics----------------------- |
635 // Initialize this file's data structures, for each Compile instance. |
346 // Initialize this file's data structures, for each Compile instance. |
636 void Compile::register_library_intrinsics() { |
347 void Compile::register_library_intrinsics() { |
810 case vmIntrinsics::_getChar: return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, !is_volatile); |
521 case vmIntrinsics::_getChar: return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, !is_volatile); |
811 case vmIntrinsics::_getInt: return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, !is_volatile); |
522 case vmIntrinsics::_getInt: return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, !is_volatile); |
812 case vmIntrinsics::_getLong: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, !is_volatile); |
523 case vmIntrinsics::_getLong: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, !is_volatile); |
813 case vmIntrinsics::_getFloat: return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, !is_volatile); |
524 case vmIntrinsics::_getFloat: return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, !is_volatile); |
814 case vmIntrinsics::_getDouble: return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, !is_volatile); |
525 case vmIntrinsics::_getDouble: return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, !is_volatile); |
815 |
|
816 case vmIntrinsics::_putObject: return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, !is_volatile); |
526 case vmIntrinsics::_putObject: return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, !is_volatile); |
817 case vmIntrinsics::_putBoolean: return inline_unsafe_access(!is_native_ptr, is_store, T_BOOLEAN, !is_volatile); |
527 case vmIntrinsics::_putBoolean: return inline_unsafe_access(!is_native_ptr, is_store, T_BOOLEAN, !is_volatile); |
818 case vmIntrinsics::_putByte: return inline_unsafe_access(!is_native_ptr, is_store, T_BYTE, !is_volatile); |
528 case vmIntrinsics::_putByte: return inline_unsafe_access(!is_native_ptr, is_store, T_BYTE, !is_volatile); |
819 case vmIntrinsics::_putShort: return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, !is_volatile); |
529 case vmIntrinsics::_putShort: return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, !is_volatile); |
820 case vmIntrinsics::_putChar: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, !is_volatile); |
530 case vmIntrinsics::_putChar: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, !is_volatile); |