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++) {
|