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;