comparison src/share/vm/opto/escape.cpp @ 293:c3e045194476

6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type") Summary: fixed few addP node type and narrow oop type problems. Reviewed-by: rasbold, never
author kvn
date Fri, 01 Aug 2008 10:06:45 -0700
parents b0fe4deeb9fb
children af945ba2e739
comparison
equal deleted inserted replaced
257:40b69ca33f4b 293:c3e045194476
490 490
491 // 491 //
492 // Adjust the type and inputs of an AddP which computes the 492 // Adjust the type and inputs of an AddP which computes the
493 // address of a field of an instance 493 // address of a field of an instance
494 // 494 //
495 void ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) { 495 bool ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) {
496 const TypeOopPtr *base_t = igvn->type(base)->isa_oopptr(); 496 const TypeOopPtr *base_t = igvn->type(base)->isa_oopptr();
497 assert(base_t != NULL && base_t->is_known_instance(), "expecting instance oopptr"); 497 assert(base_t != NULL && base_t->is_known_instance(), "expecting instance oopptr");
498 const TypeOopPtr *t = igvn->type(addp)->isa_oopptr(); 498 const TypeOopPtr *t = igvn->type(addp)->isa_oopptr();
499 if (t == NULL) { 499 if (t == NULL) {
500 // We are computing a raw address for a store captured by an Initialize 500 // We are computing a raw address for a store captured by an Initialize
501 // compute an appropriate address type. 501 // compute an appropriate address type (cases #3 and #5).
502 assert(igvn->type(addp) == TypeRawPtr::NOTNULL, "must be raw pointer"); 502 assert(igvn->type(addp) == TypeRawPtr::NOTNULL, "must be raw pointer");
503 assert(addp->in(AddPNode::Address)->is_Proj(), "base of raw address must be result projection from allocation"); 503 assert(addp->in(AddPNode::Address)->is_Proj(), "base of raw address must be result projection from allocation");
504 int offs = (int)igvn->find_intptr_t_con(addp->in(AddPNode::Offset), Type::OffsetBot); 504 int offs = (int)igvn->find_intptr_t_con(addp->in(AddPNode::Offset), Type::OffsetBot);
505 assert(offs != Type::OffsetBot, "offset must be a constant"); 505 assert(offs != Type::OffsetBot, "offset must be a constant");
506 t = base_t->add_offset(offs)->is_oopptr(); 506 t = base_t->add_offset(offs)->is_oopptr();
507 } 507 }
508 int inst_id = base_t->instance_id(); 508 int inst_id = base_t->instance_id();
509 assert(!t->is_known_instance() || t->instance_id() == inst_id, 509 assert(!t->is_known_instance() || t->instance_id() == inst_id,
510 "old type must be non-instance or match new type"); 510 "old type must be non-instance or match new type");
511
512 // The type 't' could be subclass of 'base_t'.
513 // As result t->offset() could be large then base_t's size and it will
514 // cause the failure in add_offset() with narrow oops since TypeOopPtr()
515 // constructor verifies correctness of the offset.
516 //
517 // It could happend on subclass's branch (from the type profiling
518 // inlining) which was not eliminated during parsing since the exactness
519 // of the allocation type was not propagated to the subclass type check.
520 //
521 // Do nothing for such AddP node and don't process its users since
522 // this code branch will go away.
523 //
524 if (!t->is_known_instance() &&
525 !t->klass()->equals(base_t->klass()) &&
526 t->klass()->is_subtype_of(base_t->klass())) {
527 return false; // bail out
528 }
529
511 const TypeOopPtr *tinst = base_t->add_offset(t->offset())->is_oopptr(); 530 const TypeOopPtr *tinst = base_t->add_offset(t->offset())->is_oopptr();
512 // Do NOT remove the next call: ensure an new alias index is allocated 531 // Do NOT remove the next call: ensure an new alias index is allocated
513 // for the instance type 532 // for the instance type
514 int alias_idx = _compile->get_alias_index(tinst); 533 int alias_idx = _compile->get_alias_index(tinst);
515 igvn->set_type(addp, tinst); 534 igvn->set_type(addp, tinst);
540 igvn->hash_insert(addp); 559 igvn->hash_insert(addp);
541 } 560 }
542 } 561 }
543 // Put on IGVN worklist since at least addp's type was changed above. 562 // Put on IGVN worklist since at least addp's type was changed above.
544 record_for_optimizer(addp); 563 record_for_optimizer(addp);
564 return true;
545 } 565 }
546 566
547 // 567 //
548 // Create a new version of orig_phi if necessary. Returns either the newly 568 // Create a new version of orig_phi if necessary. Returns either the newly
549 // created phi or an existing phi. Sets create_new to indicate wheter a new 569 // created phi or an existing phi. Sets create_new to indicate wheter a new
967 assert(ptset.Size() == 1, "AddP address is unique"); 987 assert(ptset.Size() == 1, "AddP address is unique");
968 uint elem = ptset.getelem(); // Allocation node's index 988 uint elem = ptset.getelem(); // Allocation node's index
969 if (elem == _phantom_object) 989 if (elem == _phantom_object)
970 continue; // Assume the value was set outside this method. 990 continue; // Assume the value was set outside this method.
971 Node *base = get_map(elem); // CheckCastPP node 991 Node *base = get_map(elem); // CheckCastPP node
972 split_AddP(n, base, igvn); 992 if (!split_AddP(n, base, igvn)) continue; // wrong type
973 tinst = igvn->type(base)->isa_oopptr(); 993 tinst = igvn->type(base)->isa_oopptr();
974 } else if (n->is_Phi() || 994 } else if (n->is_Phi() ||
975 n->is_CheckCastPP() || 995 n->is_CheckCastPP() ||
976 n->is_EncodeP() || 996 n->is_EncodeP() ||
977 n->is_DecodeN() || 997 n->is_DecodeN() ||
1010 igvn->hash_delete(tn); 1030 igvn->hash_delete(tn);
1011 igvn->set_type(tn, tn_type); 1031 igvn->set_type(tn, tn_type);
1012 tn->set_type(tn_type); 1032 tn->set_type(tn_type);
1013 igvn->hash_insert(tn); 1033 igvn->hash_insert(tn);
1014 record_for_optimizer(n); 1034 record_for_optimizer(n);
1035 } else {
1036 continue; // wrong type
1015 } 1037 }
1016 } 1038 }
1017 } else { 1039 } else {
1018 continue; 1040 continue;
1019 } 1041 }