843 jvms->set_endoff(sfpt->req()); |
843 jvms->set_endoff(sfpt->req()); |
844 // Now make a pass over the debug information replacing any references |
844 // Now make a pass over the debug information replacing any references |
845 // to the allocated object with "sobj" |
845 // to the allocated object with "sobj" |
846 int start = jvms->debug_start(); |
846 int start = jvms->debug_start(); |
847 int end = jvms->debug_end(); |
847 int end = jvms->debug_end(); |
848 for (int i = start; i < end; i++) { |
848 sfpt->replace_edges_in_range(res, sobj, start, end); |
849 if (sfpt->in(i) == res) { |
|
850 sfpt->set_req(i, sobj); |
|
851 } |
|
852 } |
|
853 safepoints_done.append_if_missing(sfpt); // keep it for rollback |
849 safepoints_done.append_if_missing(sfpt); // keep it for rollback |
854 } |
850 } |
855 return true; |
851 return true; |
856 } |
852 } |
857 |
853 |
858 // Process users of eliminated allocation. |
854 // Process users of eliminated allocation. |
859 void PhaseMacroExpand::process_users_of_allocation(AllocateNode *alloc) { |
855 void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) { |
860 Node* res = alloc->result_cast(); |
856 Node* res = alloc->result_cast(); |
861 if (res != NULL) { |
857 if (res != NULL) { |
862 for (DUIterator_Last jmin, j = res->last_outs(jmin); j >= jmin; ) { |
858 for (DUIterator_Last jmin, j = res->last_outs(jmin); j >= jmin; ) { |
863 Node *use = res->last_out(j); |
859 Node *use = res->last_out(j); |
864 uint oc1 = res->outcnt(); |
860 uint oc1 = res->outcnt(); |
897 |
893 |
898 // |
894 // |
899 // Process other users of allocation's projections |
895 // Process other users of allocation's projections |
900 // |
896 // |
901 if (_resproj != NULL && _resproj->outcnt() != 0) { |
897 if (_resproj != NULL && _resproj->outcnt() != 0) { |
|
898 // First disconnect stores captured by Initialize node. |
|
899 // If Initialize node is eliminated first in the following code, |
|
900 // it will kill such stores and DUIterator_Last will assert. |
|
901 for (DUIterator_Fast jmax, j = _resproj->fast_outs(jmax); j < jmax; j++) { |
|
902 Node *use = _resproj->fast_out(j); |
|
903 if (use->is_AddP()) { |
|
904 // raw memory addresses used only by the initialization |
|
905 _igvn.replace_node(use, C->top()); |
|
906 --j; --jmax; |
|
907 } |
|
908 } |
902 for (DUIterator_Last jmin, j = _resproj->last_outs(jmin); j >= jmin; ) { |
909 for (DUIterator_Last jmin, j = _resproj->last_outs(jmin); j >= jmin; ) { |
903 Node *use = _resproj->last_out(j); |
910 Node *use = _resproj->last_out(j); |
904 uint oc1 = _resproj->outcnt(); |
911 uint oc1 = _resproj->outcnt(); |
905 if (use->is_Initialize()) { |
912 if (use->is_Initialize()) { |
906 // Eliminate Initialize node. |
913 // Eliminate Initialize node. |
921 assert(mem == _memproj_fallthrough, "allocation memory projection"); |
928 assert(mem == _memproj_fallthrough, "allocation memory projection"); |
922 } |
929 } |
923 #endif |
930 #endif |
924 _igvn.replace_node(mem_proj, mem); |
931 _igvn.replace_node(mem_proj, mem); |
925 } |
932 } |
926 } else if (use->is_AddP()) { |
|
927 // raw memory addresses used only by the initialization |
|
928 _igvn.replace_node(use, C->top()); |
|
929 } else { |
933 } else { |
930 assert(false, "only Initialize or AddP expected"); |
934 assert(false, "only Initialize or AddP expected"); |
931 } |
935 } |
932 j -= (oc1 - _resproj->outcnt()); |
936 j -= (oc1 - _resproj->outcnt()); |
933 } |
937 } |
951 _igvn.replace_node(_catchallcatchproj, C->top()); |
955 _igvn.replace_node(_catchallcatchproj, C->top()); |
952 } |
956 } |
953 } |
957 } |
954 |
958 |
955 bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) { |
959 bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) { |
956 |
960 if (!EliminateAllocations || !alloc->_is_non_escaping) { |
957 if (!EliminateAllocations || !alloc->_is_scalar_replaceable) { |
961 return false; |
|
962 } |
|
963 Node* klass = alloc->in(AllocateNode::KlassNode); |
|
964 const TypeKlassPtr* tklass = _igvn.type(klass)->is_klassptr(); |
|
965 Node* res = alloc->result_cast(); |
|
966 // Eliminate boxing allocations which are not used |
|
967 // regardless scalar replacable status. |
|
968 bool boxing_alloc = C->eliminate_boxing() && |
|
969 tklass->klass()->is_instance_klass() && |
|
970 tklass->klass()->as_instance_klass()->is_box_klass(); |
|
971 if (!alloc->_is_scalar_replaceable && (!boxing_alloc || (res != NULL))) { |
958 return false; |
972 return false; |
959 } |
973 } |
960 |
974 |
961 extract_call_projections(alloc); |
975 extract_call_projections(alloc); |
962 |
976 |
963 GrowableArray <SafePointNode *> safepoints; |
977 GrowableArray <SafePointNode *> safepoints; |
964 if (!can_eliminate_allocation(alloc, safepoints)) { |
978 if (!can_eliminate_allocation(alloc, safepoints)) { |
965 return false; |
979 return false; |
966 } |
980 } |
967 |
981 |
|
982 if (!alloc->_is_scalar_replaceable) { |
|
983 assert(res == NULL, "sanity"); |
|
984 // We can only eliminate allocation if all debug info references |
|
985 // are already replaced with SafePointScalarObject because |
|
986 // we can't search for a fields value without instance_id. |
|
987 if (safepoints.length() > 0) { |
|
988 return false; |
|
989 } |
|
990 } |
|
991 |
968 if (!scalar_replacement(alloc, safepoints)) { |
992 if (!scalar_replacement(alloc, safepoints)) { |
969 return false; |
993 return false; |
970 } |
994 } |
971 |
995 |
972 CompileLog* log = C->log(); |
996 CompileLog* log = C->log(); |
973 if (log != NULL) { |
997 if (log != NULL) { |
974 Node* klass = alloc->in(AllocateNode::KlassNode); |
|
975 const TypeKlassPtr* tklass = _igvn.type(klass)->is_klassptr(); |
|
976 log->head("eliminate_allocation type='%d'", |
998 log->head("eliminate_allocation type='%d'", |
977 log->identify(tklass->klass())); |
999 log->identify(tklass->klass())); |
978 JVMState* p = alloc->jvms(); |
1000 JVMState* p = alloc->jvms(); |
979 while (p != NULL) { |
1001 while (p != NULL) { |
980 log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method())); |
1002 log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method())); |
995 #endif |
1017 #endif |
996 |
1018 |
997 return true; |
1019 return true; |
998 } |
1020 } |
999 |
1021 |
|
1022 bool PhaseMacroExpand::eliminate_boxing_node(CallStaticJavaNode *boxing) { |
|
1023 // EA should remove all uses of non-escaping boxing node. |
|
1024 if (!C->eliminate_boxing() || boxing->proj_out(TypeFunc::Parms) != NULL) { |
|
1025 return false; |
|
1026 } |
|
1027 |
|
1028 extract_call_projections(boxing); |
|
1029 |
|
1030 const TypeTuple* r = boxing->tf()->range(); |
|
1031 assert(r->cnt() > TypeFunc::Parms, "sanity"); |
|
1032 const TypeInstPtr* t = r->field_at(TypeFunc::Parms)->isa_instptr(); |
|
1033 assert(t != NULL, "sanity"); |
|
1034 |
|
1035 CompileLog* log = C->log(); |
|
1036 if (log != NULL) { |
|
1037 log->head("eliminate_boxing type='%d'", |
|
1038 log->identify(t->klass())); |
|
1039 JVMState* p = boxing->jvms(); |
|
1040 while (p != NULL) { |
|
1041 log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method())); |
|
1042 p = p->caller(); |
|
1043 } |
|
1044 log->tail("eliminate_boxing"); |
|
1045 } |
|
1046 |
|
1047 process_users_of_allocation(boxing); |
|
1048 |
|
1049 #ifndef PRODUCT |
|
1050 if (PrintEliminateAllocations) { |
|
1051 tty->print("++++ Eliminated: %d ", boxing->_idx); |
|
1052 boxing->method()->print_short_name(tty); |
|
1053 tty->cr(); |
|
1054 } |
|
1055 #endif |
|
1056 |
|
1057 return true; |
|
1058 } |
1000 |
1059 |
1001 //---------------------------set_eden_pointers------------------------- |
1060 //---------------------------set_eden_pointers------------------------- |
1002 void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_adr) { |
1061 void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_adr) { |
1003 if (UseTLAB) { // Private allocation: load from TLS |
1062 if (UseTLAB) { // Private allocation: load from TLS |
1004 Node* thread = transform_later(new (C) ThreadLocalNode()); |
1063 Node* thread = transform_later(new (C) ThreadLocalNode()); |
2382 switch (n->class_id()) { |
2441 switch (n->class_id()) { |
2383 case Node::Class_Allocate: |
2442 case Node::Class_Allocate: |
2384 case Node::Class_AllocateArray: |
2443 case Node::Class_AllocateArray: |
2385 success = eliminate_allocate_node(n->as_Allocate()); |
2444 success = eliminate_allocate_node(n->as_Allocate()); |
2386 break; |
2445 break; |
|
2446 case Node::Class_CallStaticJava: |
|
2447 success = eliminate_boxing_node(n->as_CallStaticJava()); |
|
2448 break; |
2387 case Node::Class_Lock: |
2449 case Node::Class_Lock: |
2388 case Node::Class_Unlock: |
2450 case Node::Class_Unlock: |
2389 assert(!n->as_AbstractLock()->is_eliminated(), "sanity"); |
2451 assert(!n->as_AbstractLock()->is_eliminated(), "sanity"); |
2390 break; |
2452 break; |
2391 default: |
2453 default: |
2418 for (int i = C->macro_count(); i > 0; i--) { |
2480 for (int i = C->macro_count(); i > 0; i--) { |
2419 Node * n = C->macro_node(i-1); |
2481 Node * n = C->macro_node(i-1); |
2420 bool success = false; |
2482 bool success = false; |
2421 debug_only(int old_macro_count = C->macro_count();); |
2483 debug_only(int old_macro_count = C->macro_count();); |
2422 if (n->Opcode() == Op_LoopLimit) { |
2484 if (n->Opcode() == Op_LoopLimit) { |
|
2485 // Remove it from macro list and put on IGVN worklist to optimize. |
|
2486 C->remove_macro_node(n); |
|
2487 _igvn._worklist.push(n); |
|
2488 success = true; |
|
2489 } else if (n->Opcode() == Op_CallStaticJava) { |
2423 // Remove it from macro list and put on IGVN worklist to optimize. |
2490 // Remove it from macro list and put on IGVN worklist to optimize. |
2424 C->remove_macro_node(n); |
2491 C->remove_macro_node(n); |
2425 _igvn._worklist.push(n); |
2492 _igvn._worklist.push(n); |
2426 success = true; |
2493 success = true; |
2427 } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) { |
2494 } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) { |