src/share/vm/opto/macro.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** old/src/share/vm/opto/macro.cpp	Tue Apr 30 19:32:16 2013
--- new/src/share/vm/opto/macro.cpp	Tue Apr 30 19:32:16 2013

*** 664,674 **** --- 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 **** --- 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(); for (int i = start; i < end; i++) { if (sfpt->in(i) == res) { sfpt->set_req(i, sobj); } } + 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(AllocateNode *alloc) { ! 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 **** --- 928,937 ---- 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()); }
*** 951,980 **** --- 955,1002 ---- _igvn.replace_node(_catchallcatchproj, C->top()); } } bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) { if (!EliminateAllocations || !alloc->_is_scalar_replaceable) { + 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_autobox() && + 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) { 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()));
*** 995,1004 **** --- 1017,1063 ---- #endif return true; } + bool PhaseMacroExpand::eliminate_autobox_node(CallStaticJavaNode *autobox) { + // EA should remove all uses of non-escaping autobox node. + if (!C->eliminate_autobox() || autobox->proj_out(TypeFunc::Parms) != NULL) { + return false; + } + + extract_call_projections(autobox); + + const TypeTuple* r = autobox->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_autobox type='%d'", + log->identify(t->klass())); + JVMState* p = autobox->jvms(); + while (p != NULL) { + log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method())); + p = p->caller(); + } + log->tail("eliminate_autobox"); + } + + process_users_of_allocation(autobox); + + #ifndef PRODUCT + if (PrintEliminateAllocations) { + tty->print("++++ Eliminated: %d ", autobox->_idx); + autobox->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_autobox_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