Mercurial > hg > truffle
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). |