Mercurial > hg > truffle
comparison src/share/vm/opto/callnode.cpp @ 65:99269dbf4ba8
6674588: (Escape Analysis) Improve Escape Analysis code
Summary: Current EA code has several problems which have to be fixed.
Reviewed-by: jrose, sgoldman
author | kvn |
---|---|
date | Fri, 14 Mar 2008 15:26:33 -0700 |
parents | eac007780a58 |
children | 6dbf1a175d6b |
comparison
equal
deleted
inserted
replaced
64:b8f5ba577b02 | 65:99269dbf4ba8 |
---|---|
622 // Do we Match on this edge index or not? Match no edges | 622 // Do we Match on this edge index or not? Match no edges |
623 uint CallNode::match_edge(uint idx) const { | 623 uint CallNode::match_edge(uint idx) const { |
624 return 0; | 624 return 0; |
625 } | 625 } |
626 | 626 |
627 // | |
628 // Determine whether the call could modify a memory value of the | |
629 // specified address type | |
630 // | |
631 bool CallNode::may_modify(const TypePtr *addr_t, PhaseTransform *phase) { | |
632 const TypeOopPtr *adrInst_t = addr_t->isa_oopptr(); | |
633 | |
634 // if not an InstPtr or not an instance type, assume the worst | |
635 if (adrInst_t == NULL || !adrInst_t->is_instance_field()) { | |
636 return true; | |
637 } | |
638 Compile *C = phase->C; | |
639 int offset = adrInst_t->offset(); | |
640 assert(offset >= 0, "should be valid offset"); | |
641 assert(addr_t->isa_instptr() || addr_t->isa_aryptr(), "only instances or arrays are expected"); | |
642 | |
643 int base_idx = C->get_alias_index(adrInst_t); | |
644 ciMethod * meth = is_CallStaticJava() ? as_CallStaticJava()->method() : NULL; | |
645 BCEscapeAnalyzer *bcea = (meth != NULL) ? meth->get_bcea() : NULL; | |
646 | |
647 const TypeTuple * d = tf()->domain(); | |
648 for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { | |
649 const Type* t = d->field_at(i); | |
650 Node *arg = in(i); | |
651 const Type *at = phase->type(arg); | |
652 if (at == TypePtr::NULL_PTR || at == Type::TOP) | |
653 continue; // null can't affect anything | |
654 | |
655 const TypeOopPtr *at_ptr = at->isa_oopptr(); | |
656 if (!arg->is_top() && (t->isa_oopptr() != NULL || | |
657 t->isa_ptr() && at_ptr != NULL)) { | |
658 assert(at_ptr != NULL, "expecting an OopPtr"); | |
659 // If we have found an argument matching adr_base_t, check if the field | |
660 // at the specified offset is modified. Since we don't know the size, | |
661 // assume 8. | |
662 int at_idx = C->get_alias_index(at_ptr->add_offset(offset)->isa_oopptr()); | |
663 if (base_idx == at_idx && | |
664 (bcea == NULL || | |
665 bcea->is_arg_modified(i - TypeFunc::Parms, offset, 8))) { | |
666 return true; | |
667 } | |
668 } | |
669 } | |
670 return false; | |
671 } | |
672 | |
673 // Does this call have a direct reference to n other than debug information? | |
674 bool CallNode::has_non_debug_use(Node *n) { | |
675 const TypeTuple * d = tf()->domain(); | |
676 for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { | |
677 Node *arg = in(i); | |
678 if (arg == n) { | |
679 return true; | |
680 } | |
681 } | |
682 return false; | |
683 } | |
684 | |
685 // Returns the unique CheckCastPP of a call | |
686 // or 'this' if there are several CheckCastPP | |
687 // or returns NULL if there is no one. | |
688 Node *CallNode::result_cast() { | |
689 Node *cast = NULL; | |
690 | |
691 Node *p = proj_out(TypeFunc::Parms); | |
692 if (p == NULL) | |
693 return NULL; | |
694 | |
695 for (DUIterator_Fast imax, i = p->fast_outs(imax); i < imax; i++) { | |
696 Node *use = p->fast_out(i); | |
697 if (use->is_CheckCastPP()) { | |
698 if (cast != NULL) { | |
699 return this; // more than 1 CheckCastPP | |
700 } | |
701 cast = use; | |
702 } | |
703 } | |
704 return cast; | |
705 } | |
706 | |
707 | |
627 //============================================================================= | 708 //============================================================================= |
628 uint CallJavaNode::size_of() const { return sizeof(*this); } | 709 uint CallJavaNode::size_of() const { return sizeof(*this); } |
629 uint CallJavaNode::cmp( const Node &n ) const { | 710 uint CallJavaNode::cmp( const Node &n ) const { |
630 CallJavaNode &call = (CallJavaNode&)n; | 711 CallJavaNode &call = (CallJavaNode&)n; |
631 return CallNode::cmp(call) && _method == call._method; | 712 return CallNode::cmp(call) && _method == call._method; |