Tue, 31 Jan 2012 09:53:46 -0800
7132180: JSR 292: C1 JVM crash with ClassValue/MethodHandle
Reviewed-by: never
src/share/vm/c1/c1_GraphBuilder.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp Tue Jan 31 07:18:03 2012 -0800 1.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Tue Jan 31 09:53:46 2012 -0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -3683,56 +3683,61 @@ 1.11 // Get the two MethodHandle inputs from the Phi. 1.12 Value op1 = phi->operand_at(0); 1.13 Value op2 = phi->operand_at(1); 1.14 - ciMethodHandle* mh1 = op1->type()->as_ObjectType()->constant_value()->as_method_handle(); 1.15 - ciMethodHandle* mh2 = op2->type()->as_ObjectType()->constant_value()->as_method_handle(); 1.16 - 1.17 - // Set the callee to have access to the class and signature in 1.18 - // the MethodHandleCompiler. 1.19 - mh1->set_callee(callee); 1.20 - mh1->set_caller(method()); 1.21 - mh2->set_callee(callee); 1.22 - mh2->set_caller(method()); 1.23 - 1.24 - // Get adapters for the MethodHandles. 1.25 - ciMethod* mh1_adapter = mh1->get_method_handle_adapter(); 1.26 - ciMethod* mh2_adapter = mh2->get_method_handle_adapter(); 1.27 - 1.28 - if (mh1_adapter != NULL && mh2_adapter != NULL) { 1.29 - set_inline_cleanup_info(); 1.30 - 1.31 - // Build the If guard 1.32 - BlockBegin* one = new BlockBegin(next_bci()); 1.33 - BlockBegin* two = new BlockBegin(next_bci()); 1.34 - BlockBegin* end = new BlockBegin(next_bci()); 1.35 - Instruction* iff = append(new If(phi, If::eql, false, op1, one, two, NULL, false)); 1.36 - block()->set_end(iff->as_BlockEnd()); 1.37 - 1.38 - // Connect up the states 1.39 - one->merge(block()->end()->state()); 1.40 - two->merge(block()->end()->state()); 1.41 - 1.42 - // Save the state for the second inlinee 1.43 - ValueStack* state_before = copy_state_before(); 1.44 - 1.45 - // Parse first adapter 1.46 - _last = _block = one; 1.47 - if (!try_inline_full(mh1_adapter, /*holder_known=*/ true, end)) { 1.48 - restore_inline_cleanup_info(); 1.49 - block()->clear_end(); // remove appended iff 1.50 - return false; 1.51 + ObjectType* op1type = op1->type()->as_ObjectType(); 1.52 + ObjectType* op2type = op2->type()->as_ObjectType(); 1.53 + 1.54 + if (op1type->is_constant() && op2type->is_constant()) { 1.55 + ciMethodHandle* mh1 = op1type->constant_value()->as_method_handle(); 1.56 + ciMethodHandle* mh2 = op2type->constant_value()->as_method_handle(); 1.57 + 1.58 + // Set the callee to have access to the class and signature in 1.59 + // the MethodHandleCompiler. 1.60 + mh1->set_callee(callee); 1.61 + mh1->set_caller(method()); 1.62 + mh2->set_callee(callee); 1.63 + mh2->set_caller(method()); 1.64 + 1.65 + // Get adapters for the MethodHandles. 1.66 + ciMethod* mh1_adapter = mh1->get_method_handle_adapter(); 1.67 + ciMethod* mh2_adapter = mh2->get_method_handle_adapter(); 1.68 + 1.69 + if (mh1_adapter != NULL && mh2_adapter != NULL) { 1.70 + set_inline_cleanup_info(); 1.71 + 1.72 + // Build the If guard 1.73 + BlockBegin* one = new BlockBegin(next_bci()); 1.74 + BlockBegin* two = new BlockBegin(next_bci()); 1.75 + BlockBegin* end = new BlockBegin(next_bci()); 1.76 + Instruction* iff = append(new If(phi, If::eql, false, op1, one, two, NULL, false)); 1.77 + block()->set_end(iff->as_BlockEnd()); 1.78 + 1.79 + // Connect up the states 1.80 + one->merge(block()->end()->state()); 1.81 + two->merge(block()->end()->state()); 1.82 + 1.83 + // Save the state for the second inlinee 1.84 + ValueStack* state_before = copy_state_before(); 1.85 + 1.86 + // Parse first adapter 1.87 + _last = _block = one; 1.88 + if (!try_inline_full(mh1_adapter, /*holder_known=*/ true, end)) { 1.89 + restore_inline_cleanup_info(); 1.90 + block()->clear_end(); // remove appended iff 1.91 + return false; 1.92 + } 1.93 + 1.94 + // Parse second adapter 1.95 + _last = _block = two; 1.96 + _state = state_before; 1.97 + if (!try_inline_full(mh2_adapter, /*holder_known=*/ true, end)) { 1.98 + restore_inline_cleanup_info(); 1.99 + block()->clear_end(); // remove appended iff 1.100 + return false; 1.101 + } 1.102 + 1.103 + connect_to_end(end); 1.104 + return true; 1.105 } 1.106 - 1.107 - // Parse second adapter 1.108 - _last = _block = two; 1.109 - _state = state_before; 1.110 - if (!try_inline_full(mh2_adapter, /*holder_known=*/ true, end)) { 1.111 - restore_inline_cleanup_info(); 1.112 - block()->clear_end(); // remove appended iff 1.113 - return false; 1.114 - } 1.115 - 1.116 - connect_to_end(end); 1.117 - return true; 1.118 } 1.119 } 1.120 }