src/share/vm/opto/macro.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
6934604 Cdiff src/share/vm/opto/macro.cpp
src/share/vm/opto/macro.cpp
Print this page
*** 664,674 ****
tty->print("Scalar ");
if (res == NULL)
alloc->dump();
else
res->dump();
! } else {
tty->print("NotScalar (%s)", fail_eliminate);
if (res == NULL)
alloc->dump();
else
res->dump();
--- 664,674 ----
tty->print("Scalar ");
if (res == NULL)
alloc->dump();
else
res->dump();
! } else if (alloc->_is_scalar_replaceable) {
tty->print("NotScalar (%s)", fail_eliminate);
if (res == NULL)
alloc->dump();
else
res->dump();
*** 843,864 ****
jvms->set_endoff(sfpt->req());
// Now make a pass over the debug information replacing any references
// to the allocated object with "sobj"
int start = jvms->debug_start();
int end = jvms->debug_end();
! for (int i = start; i < end; i++) {
! if (sfpt->in(i) == res) {
! sfpt->set_req(i, sobj);
! }
! }
safepoints_done.append_if_missing(sfpt); // keep it for rollback
}
return true;
}
// Process users of eliminated allocation.
! void PhaseMacroExpand::process_users_of_allocation(AllocateNode *alloc) {
Node* res = alloc->result_cast();
if (res != NULL) {
for (DUIterator_Last jmin, j = res->last_outs(jmin); j >= jmin; ) {
Node *use = res->last_out(j);
uint oc1 = res->outcnt();
--- 843,860 ----
jvms->set_endoff(sfpt->req());
// Now make a pass over the debug information replacing any references
// to the allocated object with "sobj"
int start = jvms->debug_start();
int end = jvms->debug_end();
! sfpt->replace_edges_in_range(res, sobj, start, end);
safepoints_done.append_if_missing(sfpt); // keep it for rollback
}
return true;
}
// Process users of eliminated allocation.
! void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) {
Node* res = alloc->result_cast();
if (res != NULL) {
for (DUIterator_Last jmin, j = res->last_outs(jmin); j >= jmin; ) {
Node *use = res->last_out(j);
uint oc1 = res->outcnt();
*** 897,906 ****
--- 893,913 ----
//
// Process other users of allocation's projections
//
if (_resproj != NULL && _resproj->outcnt() != 0) {
+ // First disconnect stores captured by Initialize node.
+ // If Initialize node is eliminated first in the following code,
+ // it will kill such stores and DUIterator_Last will assert.
+ for (DUIterator_Fast jmax, j = _resproj->fast_outs(jmax); j < jmax; j++) {
+ Node *use = _resproj->fast_out(j);
+ if (use->is_AddP()) {
+ // raw memory addresses used only by the initialization
+ _igvn.replace_node(use, C->top());
+ --j; --jmax;
+ }
+ }
for (DUIterator_Last jmin, j = _resproj->last_outs(jmin); j >= jmin; ) {
Node *use = _resproj->last_out(j);
uint oc1 = _resproj->outcnt();
if (use->is_Initialize()) {
// Eliminate Initialize node.
*** 921,933 ****
assert(mem == _memproj_fallthrough, "allocation memory projection");
}
#endif
_igvn.replace_node(mem_proj, mem);
}
- } else if (use->is_AddP()) {
- // raw memory addresses used only by the initialization
- _igvn.replace_node(use, C->top());
} else {
assert(false, "only Initialize or AddP expected");
}
j -= (oc1 - _resproj->outcnt());
}
--- 928,937 ----
*** 951,980 ****
_igvn.replace_node(_catchallcatchproj, C->top());
}
}
bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) {
!
! if (!EliminateAllocations || !alloc->_is_scalar_replaceable) {
return false;
}
extract_call_projections(alloc);
GrowableArray <SafePointNode *> safepoints;
if (!can_eliminate_allocation(alloc, safepoints)) {
return false;
}
if (!scalar_replacement(alloc, safepoints)) {
return false;
}
CompileLog* log = C->log();
if (log != NULL) {
- Node* klass = alloc->in(AllocateNode::KlassNode);
- const TypeKlassPtr* tklass = _igvn.type(klass)->is_klassptr();
log->head("eliminate_allocation type='%d'",
log->identify(tklass->klass()));
JVMState* p = alloc->jvms();
while (p != NULL) {
log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
--- 955,1002 ----
_igvn.replace_node(_catchallcatchproj, C->top());
}
}
bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) {
! if (!EliminateAllocations || !alloc->_is_non_escaping) {
! return false;
! }
! Node* klass = alloc->in(AllocateNode::KlassNode);
! const TypeKlassPtr* tklass = _igvn.type(klass)->is_klassptr();
! Node* res = alloc->result_cast();
! // Eliminate boxing allocations which are not used
! // regardless scalar replacable status.
! bool boxing_alloc = C->eliminate_boxing() &&
! tklass->klass()->is_instance_klass() &&
! tklass->klass()->as_instance_klass()->is_box_klass();
! if (!alloc->_is_scalar_replaceable && (!boxing_alloc || (res != NULL))) {
return false;
}
extract_call_projections(alloc);
GrowableArray <SafePointNode *> safepoints;
if (!can_eliminate_allocation(alloc, safepoints)) {
return false;
}
+ if (!alloc->_is_scalar_replaceable) {
+ assert(res == NULL, "sanity");
+ // We can only eliminate allocation if all debug info references
+ // are already replaced with SafePointScalarObject because
+ // we can't search for a fields value without instance_id.
+ if (safepoints.length() > 0) {
+ return false;
+ }
+ }
+
if (!scalar_replacement(alloc, safepoints)) {
return false;
}
CompileLog* log = C->log();
if (log != NULL) {
log->head("eliminate_allocation type='%d'",
log->identify(tklass->klass()));
JVMState* p = alloc->jvms();
while (p != NULL) {
log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
*** 995,1004 ****
--- 1017,1063 ----
#endif
return true;
}
+ bool PhaseMacroExpand::eliminate_boxing_node(CallStaticJavaNode *boxing) {
+ // EA should remove all uses of non-escaping boxing node.
+ if (!C->eliminate_boxing() || boxing->proj_out(TypeFunc::Parms) != NULL) {
+ return false;
+ }
+
+ extract_call_projections(boxing);
+
+ const TypeTuple* r = boxing->tf()->range();
+ assert(r->cnt() > TypeFunc::Parms, "sanity");
+ const TypeInstPtr* t = r->field_at(TypeFunc::Parms)->isa_instptr();
+ assert(t != NULL, "sanity");
+
+ CompileLog* log = C->log();
+ if (log != NULL) {
+ log->head("eliminate_boxing type='%d'",
+ log->identify(t->klass()));
+ JVMState* p = boxing->jvms();
+ while (p != NULL) {
+ log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
+ p = p->caller();
+ }
+ log->tail("eliminate_boxing");
+ }
+
+ process_users_of_allocation(boxing);
+
+ #ifndef PRODUCT
+ if (PrintEliminateAllocations) {
+ tty->print("++++ Eliminated: %d ", boxing->_idx);
+ boxing->method()->print_short_name(tty);
+ tty->cr();
+ }
+ #endif
+
+ return true;
+ }
//---------------------------set_eden_pointers-------------------------
void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_adr) {
if (UseTLAB) { // Private allocation: load from TLS
Node* thread = transform_later(new (C) ThreadLocalNode());
*** 2382,2391 ****
--- 2441,2453 ----
switch (n->class_id()) {
case Node::Class_Allocate:
case Node::Class_AllocateArray:
success = eliminate_allocate_node(n->as_Allocate());
break;
+ case Node::Class_CallStaticJava:
+ success = eliminate_boxing_node(n->as_CallStaticJava());
+ break;
case Node::Class_Lock:
case Node::Class_Unlock:
assert(!n->as_AbstractLock()->is_eliminated(), "sanity");
break;
default:
*** 2422,2431 ****
--- 2484,2498 ----
if (n->Opcode() == Op_LoopLimit) {
// Remove it from macro list and put on IGVN worklist to optimize.
C->remove_macro_node(n);
_igvn._worklist.push(n);
success = true;
+ } else if (n->Opcode() == Op_CallStaticJava) {
+ // Remove it from macro list and put on IGVN worklist to optimize.
+ C->remove_macro_node(n);
+ _igvn._worklist.push(n);
+ success = true;
} else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
_igvn.replace_node(n, n->in(1));
success = true;
}
assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
src/share/vm/opto/macro.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File