comparison src/share/vm/c1/c1_GraphBuilder.cpp @ 4870:2f5980b127e3

7132180: JSR 292: C1 JVM crash with ClassValue/MethodHandle Reviewed-by: never
author twisti
date Tue, 31 Jan 2012 09:53:46 -0800
parents 973293defacd
children f067b4e0e04b
comparison
equal deleted inserted replaced
4869:5ed8f599a788 4870:2f5980b127e3
1 /* 1 /*
2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
3681 3681
3682 if (phi != NULL && phi->operand_count() == 2) { 3682 if (phi != NULL && phi->operand_count() == 2) {
3683 // Get the two MethodHandle inputs from the Phi. 3683 // Get the two MethodHandle inputs from the Phi.
3684 Value op1 = phi->operand_at(0); 3684 Value op1 = phi->operand_at(0);
3685 Value op2 = phi->operand_at(1); 3685 Value op2 = phi->operand_at(1);
3686 ciMethodHandle* mh1 = op1->type()->as_ObjectType()->constant_value()->as_method_handle(); 3686 ObjectType* op1type = op1->type()->as_ObjectType();
3687 ciMethodHandle* mh2 = op2->type()->as_ObjectType()->constant_value()->as_method_handle(); 3687 ObjectType* op2type = op2->type()->as_ObjectType();
3688 3688
3689 // Set the callee to have access to the class and signature in 3689 if (op1type->is_constant() && op2type->is_constant()) {
3690 // the MethodHandleCompiler. 3690 ciMethodHandle* mh1 = op1type->constant_value()->as_method_handle();
3691 mh1->set_callee(callee); 3691 ciMethodHandle* mh2 = op2type->constant_value()->as_method_handle();
3692 mh1->set_caller(method()); 3692
3693 mh2->set_callee(callee); 3693 // Set the callee to have access to the class and signature in
3694 mh2->set_caller(method()); 3694 // the MethodHandleCompiler.
3695 3695 mh1->set_callee(callee);
3696 // Get adapters for the MethodHandles. 3696 mh1->set_caller(method());
3697 ciMethod* mh1_adapter = mh1->get_method_handle_adapter(); 3697 mh2->set_callee(callee);
3698 ciMethod* mh2_adapter = mh2->get_method_handle_adapter(); 3698 mh2->set_caller(method());
3699 3699
3700 if (mh1_adapter != NULL && mh2_adapter != NULL) { 3700 // Get adapters for the MethodHandles.
3701 set_inline_cleanup_info(); 3701 ciMethod* mh1_adapter = mh1->get_method_handle_adapter();
3702 3702 ciMethod* mh2_adapter = mh2->get_method_handle_adapter();
3703 // Build the If guard 3703
3704 BlockBegin* one = new BlockBegin(next_bci()); 3704 if (mh1_adapter != NULL && mh2_adapter != NULL) {
3705 BlockBegin* two = new BlockBegin(next_bci()); 3705 set_inline_cleanup_info();
3706 BlockBegin* end = new BlockBegin(next_bci()); 3706
3707 Instruction* iff = append(new If(phi, If::eql, false, op1, one, two, NULL, false)); 3707 // Build the If guard
3708 block()->set_end(iff->as_BlockEnd()); 3708 BlockBegin* one = new BlockBegin(next_bci());
3709 3709 BlockBegin* two = new BlockBegin(next_bci());
3710 // Connect up the states 3710 BlockBegin* end = new BlockBegin(next_bci());
3711 one->merge(block()->end()->state()); 3711 Instruction* iff = append(new If(phi, If::eql, false, op1, one, two, NULL, false));
3712 two->merge(block()->end()->state()); 3712 block()->set_end(iff->as_BlockEnd());
3713 3713
3714 // Save the state for the second inlinee 3714 // Connect up the states
3715 ValueStack* state_before = copy_state_before(); 3715 one->merge(block()->end()->state());
3716 3716 two->merge(block()->end()->state());
3717 // Parse first adapter 3717
3718 _last = _block = one; 3718 // Save the state for the second inlinee
3719 if (!try_inline_full(mh1_adapter, /*holder_known=*/ true, end)) { 3719 ValueStack* state_before = copy_state_before();
3720 restore_inline_cleanup_info(); 3720
3721 block()->clear_end(); // remove appended iff 3721 // Parse first adapter
3722 return false; 3722 _last = _block = one;
3723 if (!try_inline_full(mh1_adapter, /*holder_known=*/ true, end)) {
3724 restore_inline_cleanup_info();
3725 block()->clear_end(); // remove appended iff
3726 return false;
3727 }
3728
3729 // Parse second adapter
3730 _last = _block = two;
3731 _state = state_before;
3732 if (!try_inline_full(mh2_adapter, /*holder_known=*/ true, end)) {
3733 restore_inline_cleanup_info();
3734 block()->clear_end(); // remove appended iff
3735 return false;
3736 }
3737
3738 connect_to_end(end);
3739 return true;
3723 } 3740 }
3724
3725 // Parse second adapter
3726 _last = _block = two;
3727 _state = state_before;
3728 if (!try_inline_full(mh2_adapter, /*holder_known=*/ true, end)) {
3729 restore_inline_cleanup_info();
3730 block()->clear_end(); // remove appended iff
3731 return false;
3732 }
3733
3734 connect_to_end(end);
3735 return true;
3736 } 3741 }
3737 } 3742 }
3738 } 3743 }
3739 return false; 3744 return false;
3740 } 3745 }