3618 // Use the intrinsic version of Reference.get() so that the value in 3619 // the referent field can be registered by the G1 pre-barrier code. 3620 // Also to prevent commoning reads from this field across safepoint 3621 // since GC can change its value. 3622 preserves_state = true; 3623 break; 3624 3625 case vmIntrinsics::_updateCRC32: 3626 case vmIntrinsics::_updateBytesCRC32: 3627 case vmIntrinsics::_updateByteBufferCRC32: 3628 if (!UseCRC32Intrinsics) return false; 3629 cantrap = false; 3630 preserves_state = true; 3631 break; 3632 3633 case vmIntrinsics::_loadFence : 3634 case vmIntrinsics::_storeFence: 3635 case vmIntrinsics::_fullFence : 3636 break; 3637 3638 default : return false; // do not inline 3639 } 3640 // create intrinsic node 3641 const bool has_receiver = !callee->is_static(); 3642 ValueType* result_type = as_ValueType(callee->return_type()); 3643 ValueStack* state_before = copy_state_for_exception(); 3644 3645 Values* args = state()->pop_arguments(callee->arg_size()); 3646 3647 if (is_profiling()) { 3648 // Don't profile in the special case where the root method 3649 // is the intrinsic 3650 if (callee != method()) { 3651 // Note that we'd collect profile data in this method if we wanted it. 3652 compilation()->set_would_profile(true); 3653 if (profile_calls()) { 3654 Value recv = NULL; 3655 if (has_receiver) { 3656 recv = args->at(0); 3657 null_check(recv); 4428 if (success && CIPrintMethodCodes) { 4429 callee->print_codes(); 4430 } 4431 } 4432 4433 bool GraphBuilder::append_unsafe_get_and_set_obj(ciMethod* callee, bool is_add) { 4434 if (InlineUnsafeOps) { 4435 Values* args = state()->pop_arguments(callee->arg_size()); 4436 BasicType t = callee->return_type()->basic_type(); 4437 null_check(args->at(0)); 4438 Instruction* offset = args->at(2); 4439 #ifndef _LP64 4440 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT))); 4441 #endif 4442 Instruction* op = append(new UnsafeGetAndSetObject(t, args->at(1), offset, args->at(3), is_add)); 4443 compilation()->set_has_unsafe_access(true); 4444 kill_all(); 4445 push(op->type(), op); 4446 } 4447 return InlineUnsafeOps; 4448 } 4449 4450 #ifndef PRODUCT 4451 void GraphBuilder::print_stats() { 4452 vmap()->print(); 4453 } 4454 #endif // PRODUCT 4455 4456 void GraphBuilder::profile_call(ciMethod* callee, Value recv, ciKlass* known_holder, Values* obj_args, bool inlined) { 4457 // A default method's holder is an interface 4458 if (known_holder != NULL && known_holder->is_interface()) { 4459 assert(known_holder->is_instance_klass() && ((ciInstanceKlass*)known_holder)->has_default_methods(), "should be default method"); 4460 known_holder = NULL; 4461 } 4462 append(new ProfileCall(method(), bci(), callee, recv, known_holder, obj_args, inlined)); 4463 } 4464 4465 void GraphBuilder::profile_return_type(Value ret, ciMethod* callee, ciMethod* m, int invoke_bci) { 4466 assert((m == NULL) == (invoke_bci < 0), "invalid method and invalid bci together"); 4467 if (m == NULL) { | 3618 // Use the intrinsic version of Reference.get() so that the value in 3619 // the referent field can be registered by the G1 pre-barrier code. 3620 // Also to prevent commoning reads from this field across safepoint 3621 // since GC can change its value. 3622 preserves_state = true; 3623 break; 3624 3625 case vmIntrinsics::_updateCRC32: 3626 case vmIntrinsics::_updateBytesCRC32: 3627 case vmIntrinsics::_updateByteBufferCRC32: 3628 if (!UseCRC32Intrinsics) return false; 3629 cantrap = false; 3630 preserves_state = true; 3631 break; 3632 3633 case vmIntrinsics::_loadFence : 3634 case vmIntrinsics::_storeFence: 3635 case vmIntrinsics::_fullFence : 3636 break; 3637 3638 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt: 3639 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: 3640 if (VM_Version::supports_crypto_acceleration_client()) { 3641 return (append_crypto_cbc_aes(callee)); 3642 } 3643 return false; 3644 3645 default : return false; // do not inline 3646 } 3647 // create intrinsic node 3648 const bool has_receiver = !callee->is_static(); 3649 ValueType* result_type = as_ValueType(callee->return_type()); 3650 ValueStack* state_before = copy_state_for_exception(); 3651 3652 Values* args = state()->pop_arguments(callee->arg_size()); 3653 3654 if (is_profiling()) { 3655 // Don't profile in the special case where the root method 3656 // is the intrinsic 3657 if (callee != method()) { 3658 // Note that we'd collect profile data in this method if we wanted it. 3659 compilation()->set_would_profile(true); 3660 if (profile_calls()) { 3661 Value recv = NULL; 3662 if (has_receiver) { 3663 recv = args->at(0); 3664 null_check(recv); 4435 if (success && CIPrintMethodCodes) { 4436 callee->print_codes(); 4437 } 4438 } 4439 4440 bool GraphBuilder::append_unsafe_get_and_set_obj(ciMethod* callee, bool is_add) { 4441 if (InlineUnsafeOps) { 4442 Values* args = state()->pop_arguments(callee->arg_size()); 4443 BasicType t = callee->return_type()->basic_type(); 4444 null_check(args->at(0)); 4445 Instruction* offset = args->at(2); 4446 #ifndef _LP64 4447 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT))); 4448 #endif 4449 Instruction* op = append(new UnsafeGetAndSetObject(t, args->at(1), offset, args->at(3), is_add)); 4450 compilation()->set_has_unsafe_access(true); 4451 kill_all(); 4452 push(op->type(), op); 4453 } 4454 return InlineUnsafeOps; 4455 } 4456 4457 bool GraphBuilder::append_crypto_cbc_aes(ciMethod* callee) { 4458 4459 if (!UseAESIntrinsics) return false; 4460 4461 ciInstanceKlass* inst = callee->holder()->as_instance_klass(); 4462 ciField* cipher = inst->get_field_by_name(ciSymbol::make("embeddedCipher"), ciSymbol::make("Lcom/sun/crypto/provider/SymmetricCipher;"), false); 4463 if (cipher == NULL) return false; 4464 4465 ciKlass* klass_AESCrypt = inst->find_klass(ciSymbol::make("com/sun/crypto/provider/AESCrypt")); 4466 4467 // if AESCrypt is not even loaded, we never take the intrinsic fast path 4468 if (klass_AESCrypt == NULL || !klass_AESCrypt->is_loaded()) return false; 4469 4470 ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass(); 4471 4472 Value recv = state()->stack_at(0); 4473 Value cipher_inst = append(new LoadField(recv, cipher->offset(), cipher, false, copy_state_for_exception(), false /*needs_patching*/)); 4474 4475 // generate InstanceOf check for further evaluation in LIRAssember 4476 Value insof = append_split(new InstanceOf(instklass_AESCrypt, cipher_inst, copy_state_exhandling())); 4477 4478 Values* args = state()->pop_arguments(callee->arg_size()); 4479 4480 args->push(insof); 4481 4482 // create intrinsic node 4483 ValueType* result_type = as_ValueType(callee->return_type()); 4484 ValueStack* state_before = copy_state_for_exception(); 4485 4486 Intrinsic* result = new Intrinsic(result_type, callee->intrinsic_id(), args, true /*has_receiver*/, state_before, 4487 true /*preserves_state*/, false /*cantrap*/); 4488 // append instruction & push result 4489 Value value = append_split(result); 4490 push(result_type, value); 4491 4492 return true; 4493 } 4494 4495 #ifndef PRODUCT 4496 void GraphBuilder::print_stats() { 4497 vmap()->print(); 4498 } 4499 #endif // PRODUCT 4500 4501 void GraphBuilder::profile_call(ciMethod* callee, Value recv, ciKlass* known_holder, Values* obj_args, bool inlined) { 4502 // A default method's holder is an interface 4503 if (known_holder != NULL && known_holder->is_interface()) { 4504 assert(known_holder->is_instance_klass() && ((ciInstanceKlass*)known_holder)->has_default_methods(), "should be default method"); 4505 known_holder = NULL; 4506 } 4507 append(new ProfileCall(method(), bci(), callee, recv, known_holder, obj_args, inlined)); 4508 } 4509 4510 void GraphBuilder::profile_return_type(Value ret, ciMethod* callee, ciMethod* m, int invoke_bci) { 4511 assert((m == NULL) == (invoke_bci < 0), "invalid method and invalid bci together"); 4512 if (m == NULL) { |