1.1 --- a/src/share/vm/opto/escape.cpp Tue Jan 22 11:31:25 2013 -0800 1.2 +++ b/src/share/vm/opto/escape.cpp Tue Jan 22 15:34:16 2013 -0800 1.3 @@ -523,7 +523,8 @@ 1.4 case Op_AryEq: 1.5 case Op_StrComp: 1.6 case Op_StrEquals: 1.7 - case Op_StrIndexOf: { 1.8 + case Op_StrIndexOf: 1.9 + case Op_EncodeISOArray: { 1.10 add_local_var(n, PointsToNode::ArgEscape); 1.11 delayed_worklist->push(n); // Process it later. 1.12 break; 1.13 @@ -701,7 +702,8 @@ 1.14 case Op_AryEq: 1.15 case Op_StrComp: 1.16 case Op_StrEquals: 1.17 - case Op_StrIndexOf: { 1.18 + case Op_StrIndexOf: 1.19 + case Op_EncodeISOArray: { 1.20 // char[] arrays passed to string intrinsic do not escape but 1.21 // they are not scalar replaceable. Adjust escape state for them. 1.22 // Start from in(2) edge since in(1) is memory edge. 1.23 @@ -2581,15 +2583,22 @@ 1.24 } 1.25 // Otherwise skip it (the call updated 'result' value). 1.26 } else if (result->Opcode() == Op_SCMemProj) { 1.27 - assert(result->in(0)->is_LoadStore(), "sanity"); 1.28 - const Type *at = igvn->type(result->in(0)->in(MemNode::Address)); 1.29 + Node* mem = result->in(0); 1.30 + Node* adr = NULL; 1.31 + if (mem->is_LoadStore()) { 1.32 + adr = mem->in(MemNode::Address); 1.33 + } else { 1.34 + assert(mem->Opcode() == Op_EncodeISOArray, "sanity"); 1.35 + adr = mem->in(3); // Memory edge corresponds to destination array 1.36 + } 1.37 + const Type *at = igvn->type(adr); 1.38 if (at != Type::TOP) { 1.39 assert (at->isa_ptr() != NULL, "pointer type required."); 1.40 int idx = C->get_alias_index(at->is_ptr()); 1.41 assert(idx != alias_idx, "Object is not scalar replaceable if a LoadStore node access its field"); 1.42 break; 1.43 } 1.44 - result = result->in(0)->in(MemNode::Memory); 1.45 + result = mem->in(MemNode::Memory); 1.46 } 1.47 } 1.48 if (result->is_Phi()) { 1.49 @@ -2927,6 +2936,11 @@ 1.50 if (m->is_MergeMem()) { 1.51 assert(_mergemem_worklist.contains(m->as_MergeMem()), "EA: missing MergeMem node in the worklist"); 1.52 } 1.53 + } else if (use->Opcode() == Op_EncodeISOArray) { 1.54 + if (use->in(MemNode::Memory) == n || use->in(3) == n) { 1.55 + // EncodeISOArray overwrites destination array 1.56 + memnode_worklist.append_if_missing(use); 1.57 + } 1.58 } else { 1.59 uint op = use->Opcode(); 1.60 if (!(op == Op_CmpP || op == Op_Conv2B || 1.61 @@ -2962,6 +2976,16 @@ 1.62 n = n->as_MemBar()->proj_out(TypeFunc::Memory); 1.63 if (n == NULL) 1.64 continue; 1.65 + } else if (n->Opcode() == Op_EncodeISOArray) { 1.66 + // get the memory projection 1.67 + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { 1.68 + Node *use = n->fast_out(i); 1.69 + if (use->Opcode() == Op_SCMemProj) { 1.70 + n = use; 1.71 + break; 1.72 + } 1.73 + } 1.74 + assert(n->Opcode() == Op_SCMemProj, "memory projection required"); 1.75 } else { 1.76 assert(n->is_Mem(), "memory node required."); 1.77 Node *addr = n->in(MemNode::Address); 1.78 @@ -2999,7 +3023,7 @@ 1.79 Node *use = n->fast_out(i); 1.80 if (use->is_Phi() || use->is_ClearArray()) { 1.81 memnode_worklist.append_if_missing(use); 1.82 - } else if(use->is_Mem() && use->in(MemNode::Memory) == n) { 1.83 + } else if (use->is_Mem() && use->in(MemNode::Memory) == n) { 1.84 if (use->Opcode() == Op_StoreCM) // Ignore cardmark stores 1.85 continue; 1.86 memnode_worklist.append_if_missing(use); 1.87 @@ -3010,6 +3034,11 @@ 1.88 assert(use->in(MemNode::Memory) != n, "EA: missing memory path"); 1.89 } else if (use->is_MergeMem()) { 1.90 assert(_mergemem_worklist.contains(use->as_MergeMem()), "EA: missing MergeMem node in the worklist"); 1.91 + } else if (use->Opcode() == Op_EncodeISOArray) { 1.92 + if (use->in(MemNode::Memory) == n || use->in(3) == n) { 1.93 + // EncodeISOArray overwrites destination array 1.94 + memnode_worklist.append_if_missing(use); 1.95 + } 1.96 } else { 1.97 uint op = use->Opcode(); 1.98 if (!(op == Op_StoreCM ||