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