< prev index next >
src/share/vm/opto/escape.cpp
Print this page
@@ -558,13 +558,17 @@
#endif
}
break;
}
case Op_AryEq:
+ case Op_HasNegatives:
case Op_StrComp:
case Op_StrEquals:
case Op_StrIndexOf:
+ case Op_StrIndexOfChar:
+ case Op_StrInflatedCopy:
+ case Op_StrCompressedCopy:
case Op_EncodeISOArray: {
add_local_var(n, PointsToNode::ArgEscape);
delayed_worklist->push(n); // Process it later.
break;
}
@@ -741,15 +745,19 @@
break;
}
ELSE_FAIL("Op_StoreP");
}
case Op_AryEq:
+ case Op_HasNegatives:
case Op_StrComp:
case Op_StrEquals:
case Op_StrIndexOf:
+ case Op_StrIndexOfChar:
+ case Op_StrInflatedCopy:
+ case Op_StrCompressedCopy:
case Op_EncodeISOArray: {
- // char[] arrays passed to string intrinsic do not escape but
+ // char[]/byte[] arrays passed to string intrinsic do not escape but
// they are not scalar replaceable. Adjust escape state for them.
// Start from in(2) edge since in(1) is memory edge.
for (uint i = 2; i < n->req(); i++) {
Node* adr = n->in(i);
const Type* at = _igvn->type(adr);
@@ -2720,21 +2728,38 @@
Node* mem = result->in(0);
Node* adr = NULL;
if (mem->is_LoadStore()) {
adr = mem->in(MemNode::Address);
} else {
- assert(mem->Opcode() == Op_EncodeISOArray, "sanity");
+ assert(mem->Opcode() == Op_EncodeISOArray ||
+ mem->Opcode() == Op_StrCompressedCopy, "sanity");
adr = mem->in(3); // Memory edge corresponds to destination array
}
const Type *at = igvn->type(adr);
if (at != Type::TOP) {
- assert (at->isa_ptr() != NULL, "pointer type required.");
+ assert(at->isa_ptr() != NULL, "pointer type required.");
int idx = C->get_alias_index(at->is_ptr());
- assert(idx != alias_idx, "Object is not scalar replaceable if a LoadStore node access its field");
- break;
+ if (idx == alias_idx) {
+ // Assert in debug mode
+ assert(false, "Object is not scalar replaceable if a LoadStore node accesses its field");
+ break; // In product mode return SCMemProj node
+ }
}
result = mem->in(MemNode::Memory);
+ } else if (result->Opcode() == Op_StrInflatedCopy) {
+ Node* adr = result->in(3); // Memory edge corresponds to destination array
+ const Type *at = igvn->type(adr);
+ if (at != Type::TOP) {
+ assert(at->isa_ptr() != NULL, "pointer type required.");
+ int idx = C->get_alias_index(at->is_ptr());
+ if (idx == alias_idx) {
+ // Assert in debug mode
+ assert(false, "Object is not scalar replaceable if a StrInflatedCopy node accesses its field");
+ break; // In product mode return SCMemProj node
+ }
+ }
+ result = result->in(MemNode::Memory);
}
}
if (result->is_Phi()) {
PhiNode *mphi = result->as_Phi();
assert(mphi->bottom_type() == Type::MEMORY, "memory phi required");
@@ -3094,14 +3119,19 @@
// EncodeISOArray overwrites destination array
memnode_worklist.append_if_missing(use);
}
} else {
uint op = use->Opcode();
- if (!(op == Op_CmpP || op == Op_Conv2B ||
+ if ((use->in(MemNode::Memory) == n) &&
+ (op == Op_StrCompressedCopy || op == Op_StrInflatedCopy)) {
+ // They overwrite memory edge corresponding to destination array,
+ memnode_worklist.append_if_missing(use);
+ } else if (!(op == Op_CmpP || op == Op_Conv2B ||
op == Op_CastP2X || op == Op_StoreCM ||
- op == Op_FastLock || op == Op_AryEq || op == Op_StrComp ||
- op == Op_StrEquals || op == Op_StrIndexOf)) {
+ op == Op_FastLock || op == Op_AryEq || op == Op_StrComp || op == Op_HasNegatives ||
+ op == Op_StrCompressedCopy || op == Op_StrInflatedCopy ||
+ op == Op_StrEquals || op == Op_StrIndexOf || op == Op_StrIndexOfChar)) {
n->dump();
use->dump();
assert(false, "EA: missing allocation reference path");
}
#endif
@@ -3159,11 +3189,12 @@
} else if (n->is_MemBar()) { // Initialize, MemBar nodes
// we don't need to do anything, but the users must be pushed
n = n->as_MemBar()->proj_out(TypeFunc::Memory);
if (n == NULL)
continue;
- } else if (n->Opcode() == Op_EncodeISOArray) {
+ } else if (n->Opcode() == Op_StrCompressedCopy ||
+ n->Opcode() == Op_EncodeISOArray) {
// get the memory projection
n = n->find_out_with(Op_SCMemProj);
assert(n->Opcode() == Op_SCMemProj, "memory projection required");
} else {
assert(n->is_Mem(), "memory node required.");
@@ -3214,15 +3245,20 @@
// EncodeISOArray overwrites destination array
memnode_worklist.append_if_missing(use);
}
} else {
uint op = use->Opcode();
- if (!(op == Op_StoreCM ||
+ if ((use->in(MemNode::Memory) == n) &&
+ (op == Op_StrCompressedCopy || op == Op_StrInflatedCopy)) {
+ // They overwrite memory edge corresponding to destination array,
+ memnode_worklist.append_if_missing(use);
+ } else if (!(op == Op_StoreCM ||
(op == Op_CallLeaf && use->as_CallLeaf()->_name != NULL &&
strcmp(use->as_CallLeaf()->_name, "g1_wb_pre") == 0) ||
- op == Op_AryEq || op == Op_StrComp ||
- op == Op_StrEquals || op == Op_StrIndexOf)) {
+ op == Op_AryEq || op == Op_StrComp || op == Op_HasNegatives ||
+ op == Op_StrCompressedCopy || op == Op_StrInflatedCopy ||
+ op == Op_StrEquals || op == Op_StrIndexOf || op == Op_StrIndexOfChar)) {
n->dump();
use->dump();
assert(false, "EA: missing memory path");
}
#endif
< prev index next >