comparison src/share/vm/opto/escape.cpp @ 1815:5867d89c129b

6982537: Crash in Node*step_through_mergemem Reviewed-by: kvn
author never
date Wed, 22 Sep 2010 13:01:12 -0700
parents 60a14ad85270
children e4fcbeb5a698
comparison
equal deleted inserted replaced
1814:fd5d4527cdf5 1815:5867d89c129b
704 704
705 705
706 // 706 //
707 // The next methods are derived from methods in MemNode. 707 // The next methods are derived from methods in MemNode.
708 // 708 //
709 static Node *step_through_mergemem(MergeMemNode *mmem, int alias_idx, const TypeOopPtr *tinst) { 709 static Node *step_through_mergemem(MergeMemNode *mmem, int alias_idx, const TypeOopPtr *toop) {
710 Node *mem = mmem; 710 Node *mem = mmem;
711 // TypeInstPtr::NOTNULL+any is an OOP with unknown offset - generally 711 // TypeOopPtr::NOTNULL+any is an OOP with unknown offset - generally
712 // means an array I have not precisely typed yet. Do not do any 712 // means an array I have not precisely typed yet. Do not do any
713 // alias stuff with it any time soon. 713 // alias stuff with it any time soon.
714 if( tinst->base() != Type::AnyPtr && 714 if( toop->base() != Type::AnyPtr &&
715 !(tinst->klass()->is_java_lang_Object() && 715 !(toop->klass() != NULL &&
716 tinst->offset() == Type::OffsetBot) ) { 716 toop->klass()->is_java_lang_Object() &&
717 toop->offset() == Type::OffsetBot) ) {
717 mem = mmem->memory_at(alias_idx); 718 mem = mmem->memory_at(alias_idx);
718 // Update input if it is progress over what we have now 719 // Update input if it is progress over what we have now
719 } 720 }
720 return mem; 721 return mem;
721 } 722 }
801 // 802 //
802 Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArray<PhiNode *> &orig_phis, PhaseGVN *phase) { 803 Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArray<PhiNode *> &orig_phis, PhaseGVN *phase) {
803 if (orig_mem == NULL) 804 if (orig_mem == NULL)
804 return orig_mem; 805 return orig_mem;
805 Compile* C = phase->C; 806 Compile* C = phase->C;
806 const TypeOopPtr *tinst = C->get_adr_type(alias_idx)->isa_oopptr(); 807 const TypeOopPtr *toop = C->get_adr_type(alias_idx)->isa_oopptr();
807 bool is_instance = (tinst != NULL) && tinst->is_known_instance(); 808 bool is_instance = (toop != NULL) && toop->is_known_instance();
808 Node *start_mem = C->start()->proj_out(TypeFunc::Memory); 809 Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
809 Node *prev = NULL; 810 Node *prev = NULL;
810 Node *result = orig_mem; 811 Node *result = orig_mem;
811 while (prev != result) { 812 while (prev != result) {
812 prev = result; 813 prev = result;
825 if (!is_instance) 826 if (!is_instance)
826 continue; // don't search further for non-instance types 827 continue; // don't search further for non-instance types
827 // skip over a call which does not affect this memory slice 828 // skip over a call which does not affect this memory slice
828 if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) { 829 if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) {
829 Node *proj_in = result->in(0); 830 Node *proj_in = result->in(0);
830 if (proj_in->is_Allocate() && proj_in->_idx == (uint)tinst->instance_id()) { 831 if (proj_in->is_Allocate() && proj_in->_idx == (uint)toop->instance_id()) {
831 break; // hit one of our sentinels 832 break; // hit one of our sentinels
832 } else if (proj_in->is_Call()) { 833 } else if (proj_in->is_Call()) {
833 CallNode *call = proj_in->as_Call(); 834 CallNode *call = proj_in->as_Call();
834 if (!call->may_modify(tinst, phase)) { 835 if (!call->may_modify(toop, phase)) {
835 result = call->in(TypeFunc::Memory); 836 result = call->in(TypeFunc::Memory);
836 } 837 }
837 } else if (proj_in->is_Initialize()) { 838 } else if (proj_in->is_Initialize()) {
838 AllocateNode* alloc = proj_in->as_Initialize()->allocation(); 839 AllocateNode* alloc = proj_in->as_Initialize()->allocation();
839 // Stop if this is the initialization for the object instance which 840 // Stop if this is the initialization for the object instance which
840 // which contains this memory slice, otherwise skip over it. 841 // which contains this memory slice, otherwise skip over it.
841 if (alloc == NULL || alloc->_idx != (uint)tinst->instance_id()) { 842 if (alloc == NULL || alloc->_idx != (uint)toop->instance_id()) {
842 result = proj_in->in(TypeFunc::Memory); 843 result = proj_in->in(TypeFunc::Memory);
843 } 844 }
844 } else if (proj_in->is_MemBar()) { 845 } else if (proj_in->is_MemBar()) {
845 result = proj_in->in(TypeFunc::Memory); 846 result = proj_in->in(TypeFunc::Memory);
846 } 847 }
847 } else if (result->is_MergeMem()) { 848 } else if (result->is_MergeMem()) {
848 MergeMemNode *mmem = result->as_MergeMem(); 849 MergeMemNode *mmem = result->as_MergeMem();
849 result = step_through_mergemem(mmem, alias_idx, tinst); 850 result = step_through_mergemem(mmem, alias_idx, toop);
850 if (result == mmem->base_memory()) { 851 if (result == mmem->base_memory()) {
851 // Didn't find instance memory, search through general slice recursively. 852 // Didn't find instance memory, search through general slice recursively.
852 result = mmem->memory_at(C->get_general_index(alias_idx)); 853 result = mmem->memory_at(C->get_general_index(alias_idx));
853 result = find_inst_mem(result, alias_idx, orig_phis, phase); 854 result = find_inst_mem(result, alias_idx, orig_phis, phase);
854 if (C->failing()) { 855 if (C->failing()) {
864 result = un; 865 result = un;
865 } else { 866 } else {
866 break; 867 break;
867 } 868 }
868 } else if (result->is_ClearArray()) { 869 } else if (result->is_ClearArray()) {
869 if (!ClearArrayNode::step_through(&result, (uint)tinst->instance_id(), phase)) { 870 if (!ClearArrayNode::step_through(&result, (uint)toop->instance_id(), phase)) {
870 // Can not bypass initialization of the instance 871 // Can not bypass initialization of the instance
871 // we are looking for. 872 // we are looking for.
872 break; 873 break;
873 } 874 }
874 // Otherwise skip it (the call updated 'result' value). 875 // Otherwise skip it (the call updated 'result' value).