src/share/vm/opto/macro.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6799693 Sdiff src/share/vm/opto

src/share/vm/opto/macro.cpp

Print this page




 935 // code shape produced here, so if you are changing this code shape
 936 // make sure the GC info for the heap-top is correct in and around the
 937 // slow-path call.
 938 //
 939 
 940 void PhaseMacroExpand::expand_allocate_common(
 941             AllocateNode* alloc, // allocation node to be expanded
 942             Node* length,  // array length for an array allocation
 943             const TypeFunc* slow_call_type, // Type of slow call
 944             address slow_call_address  // Address of slow call
 945     )
 946 {
 947 
 948   Node* ctrl = alloc->in(TypeFunc::Control);
 949   Node* mem  = alloc->in(TypeFunc::Memory);
 950   Node* i_o  = alloc->in(TypeFunc::I_O);
 951   Node* size_in_bytes     = alloc->in(AllocateNode::AllocSize);
 952   Node* klass_node        = alloc->in(AllocateNode::KlassNode);
 953   Node* initial_slow_test = alloc->in(AllocateNode::InitialTest);
 954 
 955   // With escape analysis, the entire memory state was needed to be able to
 956   // eliminate the allocation.  Since the allocations cannot be eliminated,
 957   // optimize it to the raw slice.
 958   if (mem->is_MergeMem()) {
 959     mem = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw);
 960   }
 961 
 962   assert(ctrl != NULL, "must have control");
 963   // We need a Region and corresponding Phi's to merge the slow-path and fast-path results.
 964   // they will not be used if "always_slow" is set
 965   enum { slow_result_path = 1, fast_result_path = 2 };
 966   Node *result_region;
 967   Node *result_phi_rawmem;
 968   Node *result_phi_rawoop;
 969   Node *result_phi_i_o;
 970 
 971   // The initial slow comparison is a size check, the comparison
 972   // we want to do is a BoolTest::gt
 973   bool always_slow = false;
 974   int tv = _igvn.find_int_con(initial_slow_test, -1);
 975   if (tv >= 0) {
 976     always_slow = (tv == 1);
 977     initial_slow_test = NULL;
 978   } else {
 979     initial_slow_test = BoolNode::make_predicate(initial_slow_test, &_igvn);
 980   }
 981 


 999 
1000     // Now make the initial failure test.  Usually a too-big test but
1001     // might be a TRUE for finalizers or a fancy class check for
1002     // newInstance0.
1003     IfNode *toobig_iff = new (C, 2) IfNode(ctrl, initial_slow_test, PROB_MIN, COUNT_UNKNOWN);
1004     transform_later(toobig_iff);
1005     // Plug the failing-too-big test into the slow-path region
1006     Node *toobig_true = new (C, 1) IfTrueNode( toobig_iff );
1007     transform_later(toobig_true);
1008     slow_region    ->init_req( too_big_or_final_path, toobig_true );
1009     toobig_false = new (C, 1) IfFalseNode( toobig_iff );
1010     transform_later(toobig_false);
1011   } else {         // No initial test, just fall into next case
1012     toobig_false = ctrl;
1013     debug_only(slow_region = NodeSentinel);
1014   }
1015 
1016   Node *slow_mem = mem;  // save the current memory state for slow path
1017   // generate the fast allocation code unless we know that the initial test will always go slow
1018   if (!always_slow) {





1019     Node* eden_top_adr;
1020     Node* eden_end_adr;
1021 
1022     set_eden_pointers(eden_top_adr, eden_end_adr);
1023 
1024     // Load Eden::end.  Loop invariant and hoisted.
1025     //
1026     // Note: We set the control input on "eden_end" and "old_eden_top" when using
1027     //       a TLAB to work around a bug where these values were being moved across
1028     //       a safepoint.  These are not oops, so they cannot be include in the oop
1029     //       map, but the can be changed by a GC.   The proper way to fix this would
1030     //       be to set the raw memory state when generating a  SafepointNode.  However
1031     //       this will require extensive changes to the loop optimization in order to
1032     //       prevent a degradation of the optimization.
1033     //       See comment in memnode.hpp, around line 227 in class LoadPNode.
1034     Node *eden_end = make_load(ctrl, mem, eden_end_adr, 0, TypeRawPtr::BOTTOM, T_ADDRESS);
1035 
1036     // allocate the Region and Phi nodes for the result
1037     result_region = new (C, 3) RegionNode(3);
1038     result_phi_rawmem = new (C, 3) PhiNode( result_region, Type::MEMORY, TypeRawPtr::BOTTOM );


1222       --i;
1223     }
1224   }
1225   // Now change uses of _memproj_catchall to use _memproj_fallthrough and delete _memproj_catchall so
1226   // we end up with a call that has only 1 memory projection
1227   if (_memproj_catchall != NULL ) {
1228     if (_memproj_fallthrough == NULL) {
1229       _memproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::Memory);
1230       transform_later(_memproj_fallthrough);
1231     }
1232     for (DUIterator_Fast imax, i = _memproj_catchall->fast_outs(imax); i < imax; i++) {
1233       Node *use = _memproj_catchall->fast_out(i);
1234       _igvn.hash_delete(use);
1235       imax -= replace_input(use, _memproj_catchall, _memproj_fallthrough);
1236       _igvn._worklist.push(use);
1237       // back up iterator
1238       --i;
1239     }
1240   }
1241 
1242   mem = result_phi_rawmem;
1243 
1244   // An allocate node has separate i_o projections for the uses on the control and i_o paths
1245   // Replace uses of the control i_o projection with result_phi_i_o (unless we are only generating a slow call)
1246   if (_ioproj_fallthrough == NULL) {
1247     _ioproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::I_O);
1248     transform_later(_ioproj_fallthrough);
1249   } else if (!always_slow) {
1250     for (DUIterator_Fast imax, i = _ioproj_fallthrough->fast_outs(imax); i < imax; i++) {
1251       Node *use = _ioproj_fallthrough->fast_out(i);
1252 
1253       _igvn.hash_delete(use);
1254       imax -= replace_input(use, _ioproj_fallthrough, result_phi_i_o);
1255       _igvn._worklist.push(use);
1256       // back up iterator
1257       --i;
1258     }
1259   }
1260   // Now change uses of _ioproj_catchall to use _ioproj_fallthrough and delete _ioproj_catchall so
1261   // we end up with a call that has only 1 control projection
1262   if (_ioproj_catchall != NULL ) {
1263     for (DUIterator_Fast imax, i = _ioproj_catchall->fast_outs(imax); i < imax; i++) {




 935 // code shape produced here, so if you are changing this code shape
 936 // make sure the GC info for the heap-top is correct in and around the
 937 // slow-path call.
 938 //
 939 
 940 void PhaseMacroExpand::expand_allocate_common(
 941             AllocateNode* alloc, // allocation node to be expanded
 942             Node* length,  // array length for an array allocation
 943             const TypeFunc* slow_call_type, // Type of slow call
 944             address slow_call_address  // Address of slow call
 945     )
 946 {
 947 
 948   Node* ctrl = alloc->in(TypeFunc::Control);
 949   Node* mem  = alloc->in(TypeFunc::Memory);
 950   Node* i_o  = alloc->in(TypeFunc::I_O);
 951   Node* size_in_bytes     = alloc->in(AllocateNode::AllocSize);
 952   Node* klass_node        = alloc->in(AllocateNode::KlassNode);
 953   Node* initial_slow_test = alloc->in(AllocateNode::InitialTest);
 954 







 955   assert(ctrl != NULL, "must have control");
 956   // We need a Region and corresponding Phi's to merge the slow-path and fast-path results.
 957   // they will not be used if "always_slow" is set
 958   enum { slow_result_path = 1, fast_result_path = 2 };
 959   Node *result_region;
 960   Node *result_phi_rawmem;
 961   Node *result_phi_rawoop;
 962   Node *result_phi_i_o;
 963 
 964   // The initial slow comparison is a size check, the comparison
 965   // we want to do is a BoolTest::gt
 966   bool always_slow = false;
 967   int tv = _igvn.find_int_con(initial_slow_test, -1);
 968   if (tv >= 0) {
 969     always_slow = (tv == 1);
 970     initial_slow_test = NULL;
 971   } else {
 972     initial_slow_test = BoolNode::make_predicate(initial_slow_test, &_igvn);
 973   }
 974 


 992 
 993     // Now make the initial failure test.  Usually a too-big test but
 994     // might be a TRUE for finalizers or a fancy class check for
 995     // newInstance0.
 996     IfNode *toobig_iff = new (C, 2) IfNode(ctrl, initial_slow_test, PROB_MIN, COUNT_UNKNOWN);
 997     transform_later(toobig_iff);
 998     // Plug the failing-too-big test into the slow-path region
 999     Node *toobig_true = new (C, 1) IfTrueNode( toobig_iff );
1000     transform_later(toobig_true);
1001     slow_region    ->init_req( too_big_or_final_path, toobig_true );
1002     toobig_false = new (C, 1) IfFalseNode( toobig_iff );
1003     transform_later(toobig_false);
1004   } else {         // No initial test, just fall into next case
1005     toobig_false = ctrl;
1006     debug_only(slow_region = NodeSentinel);
1007   }
1008 
1009   Node *slow_mem = mem;  // save the current memory state for slow path
1010   // generate the fast allocation code unless we know that the initial test will always go slow
1011   if (!always_slow) {
1012     // Fast path modifies only raw memory.
1013     if (mem->is_MergeMem()) {
1014       mem = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw);
1015     }
1016 
1017     Node* eden_top_adr;
1018     Node* eden_end_adr;
1019 
1020     set_eden_pointers(eden_top_adr, eden_end_adr);
1021 
1022     // Load Eden::end.  Loop invariant and hoisted.
1023     //
1024     // Note: We set the control input on "eden_end" and "old_eden_top" when using
1025     //       a TLAB to work around a bug where these values were being moved across
1026     //       a safepoint.  These are not oops, so they cannot be include in the oop
1027     //       map, but the can be changed by a GC.   The proper way to fix this would
1028     //       be to set the raw memory state when generating a  SafepointNode.  However
1029     //       this will require extensive changes to the loop optimization in order to
1030     //       prevent a degradation of the optimization.
1031     //       See comment in memnode.hpp, around line 227 in class LoadPNode.
1032     Node *eden_end = make_load(ctrl, mem, eden_end_adr, 0, TypeRawPtr::BOTTOM, T_ADDRESS);
1033 
1034     // allocate the Region and Phi nodes for the result
1035     result_region = new (C, 3) RegionNode(3);
1036     result_phi_rawmem = new (C, 3) PhiNode( result_region, Type::MEMORY, TypeRawPtr::BOTTOM );


1220       --i;
1221     }
1222   }
1223   // Now change uses of _memproj_catchall to use _memproj_fallthrough and delete _memproj_catchall so
1224   // we end up with a call that has only 1 memory projection
1225   if (_memproj_catchall != NULL ) {
1226     if (_memproj_fallthrough == NULL) {
1227       _memproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::Memory);
1228       transform_later(_memproj_fallthrough);
1229     }
1230     for (DUIterator_Fast imax, i = _memproj_catchall->fast_outs(imax); i < imax; i++) {
1231       Node *use = _memproj_catchall->fast_out(i);
1232       _igvn.hash_delete(use);
1233       imax -= replace_input(use, _memproj_catchall, _memproj_fallthrough);
1234       _igvn._worklist.push(use);
1235       // back up iterator
1236       --i;
1237     }
1238   }
1239 


1240   // An allocate node has separate i_o projections for the uses on the control and i_o paths
1241   // Replace uses of the control i_o projection with result_phi_i_o (unless we are only generating a slow call)
1242   if (_ioproj_fallthrough == NULL) {
1243     _ioproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::I_O);
1244     transform_later(_ioproj_fallthrough);
1245   } else if (!always_slow) {
1246     for (DUIterator_Fast imax, i = _ioproj_fallthrough->fast_outs(imax); i < imax; i++) {
1247       Node *use = _ioproj_fallthrough->fast_out(i);
1248 
1249       _igvn.hash_delete(use);
1250       imax -= replace_input(use, _ioproj_fallthrough, result_phi_i_o);
1251       _igvn._worklist.push(use);
1252       // back up iterator
1253       --i;
1254     }
1255   }
1256   // Now change uses of _ioproj_catchall to use _ioproj_fallthrough and delete _ioproj_catchall so
1257   // we end up with a call that has only 1 control projection
1258   if (_ioproj_catchall != NULL ) {
1259     for (DUIterator_Fast imax, i = _ioproj_catchall->fast_outs(imax); i < imax; i++) {


src/share/vm/opto/macro.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File