comparison src/share/vm/opto/memnode.cpp @ 1100:f96a1a986f7b

6895383: JCK test throws NPE for method compiled with Escape Analysis Summary: Add missing checks for MemBar nodes in EA. Reviewed-by: never
author kvn
date Wed, 09 Dec 2009 16:40:45 -0800
parents 7c57aead6d3e
children c18cbe5936b8
comparison
equal deleted inserted replaced
1099:c5d3d979ae27 1100:f96a1a986f7b
121 } else if (proj_in->is_MemBar()) { 121 } else if (proj_in->is_MemBar()) {
122 result = proj_in->in(TypeFunc::Memory); 122 result = proj_in->in(TypeFunc::Memory);
123 } else { 123 } else {
124 assert(false, "unexpected projection"); 124 assert(false, "unexpected projection");
125 } 125 }
126 } else if (result->is_ClearArray()) {
127 if (!ClearArrayNode::step_through(&result, instance_id, phase)) {
128 // Can not bypass initialization of the instance
129 // we are looking for.
130 break;
131 }
132 // Otherwise skip it (the call updated 'result' value).
126 } else if (result->is_MergeMem()) { 133 } else if (result->is_MergeMem()) {
127 result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty); 134 result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty);
128 } 135 }
129 } 136 }
130 return result; 137 return result;
535 continue; // (a) advance through independent call memory 542 continue; // (a) advance through independent call memory
536 } 543 }
537 } else if (mem->is_Proj() && mem->in(0)->is_MemBar()) { 544 } else if (mem->is_Proj() && mem->in(0)->is_MemBar()) {
538 mem = mem->in(0)->in(TypeFunc::Memory); 545 mem = mem->in(0)->in(TypeFunc::Memory);
539 continue; // (a) advance through independent MemBar memory 546 continue; // (a) advance through independent MemBar memory
547 } else if (mem->is_ClearArray()) {
548 if (ClearArrayNode::step_through(&mem, (uint)addr_t->instance_id(), phase)) {
549 // (the call updated 'mem' value)
550 continue; // (a) advance through independent allocation memory
551 } else {
552 // Can not bypass initialization of the instance
553 // we are looking for.
554 return mem;
555 }
540 } else if (mem->is_MergeMem()) { 556 } else if (mem->is_MergeMem()) {
541 int alias_idx = phase->C->get_alias_index(adr_type()); 557 int alias_idx = phase->C->get_alias_index(adr_type());
542 mem = mem->as_MergeMem()->memory_at(alias_idx); 558 mem = mem->as_MergeMem()->memory_at(alias_idx);
543 continue; // (a) advance through independent MergeMem memory 559 continue; // (a) advance through independent MergeMem memory
544 } 560 }
2452 mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero); 2468 mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero);
2453 } 2469 }
2454 return mem; 2470 return mem;
2455 } 2471 }
2456 2472
2473 //----------------------------step_through----------------------------------
2474 // Return allocation input memory edge if it is different instance
2475 // or itself if it is the one we are looking for.
2476 bool ClearArrayNode::step_through(Node** np, uint instance_id, PhaseTransform* phase) {
2477 Node* n = *np;
2478 assert(n->is_ClearArray(), "sanity");
2479 intptr_t offset;
2480 AllocateNode* alloc = AllocateNode::Ideal_allocation(n->in(3), phase, offset);
2481 // This method is called only before Allocate nodes are expanded during
2482 // macro nodes expansion. Before that ClearArray nodes are only generated
2483 // in LibraryCallKit::generate_arraycopy() which follows allocations.
2484 assert(alloc != NULL, "should have allocation");
2485 if (alloc->_idx == instance_id) {
2486 // Can not bypass initialization of the instance we are looking for.
2487 return false;
2488 }
2489 // Otherwise skip it.
2490 InitializeNode* init = alloc->initialization();
2491 if (init != NULL)
2492 *np = init->in(TypeFunc::Memory);
2493 else
2494 *np = alloc->in(TypeFunc::Memory);
2495 return true;
2496 }
2497
2457 //----------------------------clear_memory------------------------------------- 2498 //----------------------------clear_memory-------------------------------------
2458 // Generate code to initialize object storage to zero. 2499 // Generate code to initialize object storage to zero.
2459 Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest, 2500 Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest,
2460 intptr_t start_offset, 2501 intptr_t start_offset,
2461 Node* end_offset, 2502 Node* end_offset,
2625 2666
2626 //------------------------------Ideal------------------------------------------ 2667 //------------------------------Ideal------------------------------------------
2627 // Return a node which is more "ideal" than the current node. Strip out 2668 // Return a node which is more "ideal" than the current node. Strip out
2628 // control copies 2669 // control copies
2629 Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) { 2670 Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) {
2630 return remove_dead_region(phase, can_reshape) ? this : NULL; 2671 if (remove_dead_region(phase, can_reshape)) return this;
2672
2673 // Eliminate volatile MemBars for scalar replaced objects.
2674 if (can_reshape && req() == (Precedent+1) &&
2675 (Opcode() == Op_MemBarAcquire || Opcode() == Op_MemBarVolatile)) {
2676 // Volatile field loads and stores.
2677 Node* my_mem = in(MemBarNode::Precedent);
2678 if (my_mem != NULL && my_mem->is_Mem()) {
2679 const TypeOopPtr* t_oop = my_mem->in(MemNode::Address)->bottom_type()->isa_oopptr();
2680 // Check for scalar replaced object reference.
2681 if( t_oop != NULL && t_oop->is_known_instance_field() &&
2682 t_oop->offset() != Type::OffsetBot &&
2683 t_oop->offset() != Type::OffsetTop) {
2684 // Replace MemBar projections by its inputs.
2685 PhaseIterGVN* igvn = phase->is_IterGVN();
2686 igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory));
2687 igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control));
2688 // Must return either the original node (now dead) or a new node
2689 // (Do not return a top here, since that would break the uniqueness of top.)
2690 return new (phase->C, 1) ConINode(TypeInt::ZERO);
2691 }
2692 }
2693 }
2694 return NULL;
2631 } 2695 }
2632 2696
2633 //------------------------------Value------------------------------------------ 2697 //------------------------------Value------------------------------------------
2634 const Type *MemBarNode::Value( PhaseTransform *phase ) const { 2698 const Type *MemBarNode::Value( PhaseTransform *phase ) const {
2635 if( !in(0) ) return Type::TOP; 2699 if( !in(0) ) return Type::TOP;