Mercurial > hg > truffle
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 } |