< prev index next >

src/share/vm/opto/stringopts.cpp

Print this page




  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "compiler/compileLog.hpp"
  27 #include "opto/addnode.hpp"
  28 #include "opto/callGenerator.hpp"
  29 #include "opto/callnode.hpp"
  30 #include "opto/divnode.hpp"
  31 #include "opto/graphKit.hpp"
  32 #include "opto/idealKit.hpp"
  33 #include "opto/rootnode.hpp"
  34 #include "opto/runtime.hpp"

  35 #include "opto/stringopts.hpp"
  36 #include "opto/subnode.hpp"
  37 
  38 #define __ kit.
  39 
  40 class StringConcat : public ResourceObj {
  41  private:
  42   PhaseStringOpts*    _stringopts;
  43   Node*               _string_alloc;
  44   AllocateNode*       _begin;          // The allocation the begins the pattern
  45   CallStaticJavaNode* _end;            // The final call of the pattern.  Will either be
  46                                        // SB.toString or or String.<init>(SB.toString)
  47   bool                _multiple;       // indicates this is a fusion of two or more
  48                                        // separate StringBuilders
  49 
  50   Node*               _arguments;      // The list of arguments to be concatenated
  51   GrowableArray<int>  _mode;           // into a String along with a mode flag
  52                                        // indicating how to treat the value.
  53   Node_List           _constructors;   // List of constructors (many in case of stacked concat)
  54   Node_List           _control;        // List of control nodes that will be deleted


1169     C->record_for_igvn(phi);
1170     C->record_for_igvn(size);
1171 
1172     // for (int i=0; ; i++)
1173     //   if (x <= sizeTable[i])
1174     //     return i+1;
1175 
1176     // Add loop predicate first.
1177     kit.add_predicate();
1178 
1179     RegionNode *loop = new (C) RegionNode(3);
1180     loop->init_req(1, kit.control());
1181     kit.gvn().set_type(loop, Type::CONTROL);
1182 
1183     Node *index = new (C) PhiNode(loop, TypeInt::INT);
1184     index->init_req(1, __ intcon(0));
1185     kit.gvn().set_type(index, TypeInt::INT);
1186     kit.set_control(loop);
1187     Node* sizeTable = fetch_static_field(kit, size_table_field);
1188 


1189     Node* value = kit.load_array_element(NULL, sizeTable, index, TypeAryPtr::INTS);
1190     C->record_for_igvn(value);
1191     Node* limit = __ CmpI(phi, value);
1192     Node* limitb = __ Bool(limit, BoolTest::le);
1193     IfNode* iff2 = kit.create_and_map_if(kit.control(), limitb, PROB_MIN, COUNT_UNKNOWN);
1194     Node* lessEqual = __ IfTrue(iff2);
1195     Node* greater = __ IfFalse(iff2);
1196 
1197     loop->init_req(2, greater);
1198     index->init_req(2, __ AddI(index, __ intcon(1)));
1199 
1200     kit.set_control(lessEqual);
1201     C->record_for_igvn(loop);
1202     C->record_for_igvn(index);
1203 
1204     final_merge->init_req(2, kit.control());
1205     final_size->init_req(2, __ AddI(__ AddI(index, size), __ intcon(1)));
1206   }
1207 
1208   kit.set_control(final_merge);


1361                                     sign, T_CHAR, char_adr_idx, MemNode::unordered);
1362 
1363       final_merge->init_req(1, kit.control());
1364       final_mem->init_req(1, st);
1365     }
1366 
1367     kit.set_control(final_merge);
1368     kit.set_memory(final_mem, char_adr_idx);
1369 
1370     C->record_for_igvn(final_merge);
1371     C->record_for_igvn(final_mem);
1372   }
1373 }
1374 
1375 
1376 Node* PhaseStringOpts::copy_string(GraphKit& kit, Node* str, Node* char_array, Node* start) {
1377   Node* string = str;
1378   Node* offset = kit.load_String_offset(kit.control(), string);
1379   Node* count  = kit.load_String_length(kit.control(), string);
1380   Node* value  = kit.load_String_value (kit.control(), string);


1381 
1382   // copy the contents
1383   if (offset->is_Con() && count->is_Con() && value->is_Con() && count->get_int() < unroll_string_copy_length) {
1384     // For small constant strings just emit individual stores.
1385     // A length of 6 seems like a good space/speed tradeof.
1386     int c = count->get_int();
1387     int o = offset->get_int();
1388     const TypeOopPtr* t = kit.gvn().type(value)->isa_oopptr();
1389     ciTypeArray* value_array = t->const_oop()->as_type_array();
1390     for (int e = 0; e < c; e++) {
1391       __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
1392                          __ intcon(value_array->char_at(o + e)), T_CHAR, char_adr_idx,
1393                          MemNode::unordered);
1394       start = __ AddI(start, __ intcon(1));
1395     }
1396   } else {
1397     Node* src_ptr = kit.array_element_address(value, offset, T_CHAR);
1398     Node* dst_ptr = kit.array_element_address(char_array, start, T_CHAR);
1399     Node* c = count;
1400     Node* extra = NULL;




  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "compiler/compileLog.hpp"
  27 #include "opto/addnode.hpp"
  28 #include "opto/callGenerator.hpp"
  29 #include "opto/callnode.hpp"
  30 #include "opto/divnode.hpp"
  31 #include "opto/graphKit.hpp"
  32 #include "opto/idealKit.hpp"
  33 #include "opto/rootnode.hpp"
  34 #include "opto/runtime.hpp"
  35 #include "opto/shenandoahSupport.hpp"
  36 #include "opto/stringopts.hpp"
  37 #include "opto/subnode.hpp"
  38 
  39 #define __ kit.
  40 
  41 class StringConcat : public ResourceObj {
  42  private:
  43   PhaseStringOpts*    _stringopts;
  44   Node*               _string_alloc;
  45   AllocateNode*       _begin;          // The allocation the begins the pattern
  46   CallStaticJavaNode* _end;            // The final call of the pattern.  Will either be
  47                                        // SB.toString or or String.<init>(SB.toString)
  48   bool                _multiple;       // indicates this is a fusion of two or more
  49                                        // separate StringBuilders
  50 
  51   Node*               _arguments;      // The list of arguments to be concatenated
  52   GrowableArray<int>  _mode;           // into a String along with a mode flag
  53                                        // indicating how to treat the value.
  54   Node_List           _constructors;   // List of constructors (many in case of stacked concat)
  55   Node_List           _control;        // List of control nodes that will be deleted


1170     C->record_for_igvn(phi);
1171     C->record_for_igvn(size);
1172 
1173     // for (int i=0; ; i++)
1174     //   if (x <= sizeTable[i])
1175     //     return i+1;
1176 
1177     // Add loop predicate first.
1178     kit.add_predicate();
1179 
1180     RegionNode *loop = new (C) RegionNode(3);
1181     loop->init_req(1, kit.control());
1182     kit.gvn().set_type(loop, Type::CONTROL);
1183 
1184     Node *index = new (C) PhiNode(loop, TypeInt::INT);
1185     index->init_req(1, __ intcon(0));
1186     kit.gvn().set_type(index, TypeInt::INT);
1187     kit.set_control(loop);
1188     Node* sizeTable = fetch_static_field(kit, size_table_field);
1189 
1190     sizeTable = kit.shenandoah_read_barrier(sizeTable);
1191 
1192     Node* value = kit.load_array_element(NULL, sizeTable, index, TypeAryPtr::INTS);
1193     C->record_for_igvn(value);
1194     Node* limit = __ CmpI(phi, value);
1195     Node* limitb = __ Bool(limit, BoolTest::le);
1196     IfNode* iff2 = kit.create_and_map_if(kit.control(), limitb, PROB_MIN, COUNT_UNKNOWN);
1197     Node* lessEqual = __ IfTrue(iff2);
1198     Node* greater = __ IfFalse(iff2);
1199 
1200     loop->init_req(2, greater);
1201     index->init_req(2, __ AddI(index, __ intcon(1)));
1202 
1203     kit.set_control(lessEqual);
1204     C->record_for_igvn(loop);
1205     C->record_for_igvn(index);
1206 
1207     final_merge->init_req(2, kit.control());
1208     final_size->init_req(2, __ AddI(__ AddI(index, size), __ intcon(1)));
1209   }
1210 
1211   kit.set_control(final_merge);


1364                                     sign, T_CHAR, char_adr_idx, MemNode::unordered);
1365 
1366       final_merge->init_req(1, kit.control());
1367       final_mem->init_req(1, st);
1368     }
1369 
1370     kit.set_control(final_merge);
1371     kit.set_memory(final_mem, char_adr_idx);
1372 
1373     C->record_for_igvn(final_merge);
1374     C->record_for_igvn(final_mem);
1375   }
1376 }
1377 
1378 
1379 Node* PhaseStringOpts::copy_string(GraphKit& kit, Node* str, Node* char_array, Node* start) {
1380   Node* string = str;
1381   Node* offset = kit.load_String_offset(kit.control(), string);
1382   Node* count  = kit.load_String_length(kit.control(), string);
1383   Node* value  = kit.load_String_value (kit.control(), string);
1384 
1385   value = kit.shenandoah_read_barrier(value);
1386 
1387   // copy the contents
1388   if (offset->is_Con() && count->is_Con() && value->is_Con() && count->get_int() < unroll_string_copy_length) {
1389     // For small constant strings just emit individual stores.
1390     // A length of 6 seems like a good space/speed tradeof.
1391     int c = count->get_int();
1392     int o = offset->get_int();
1393     const TypeOopPtr* t = kit.gvn().type(value)->isa_oopptr();
1394     ciTypeArray* value_array = t->const_oop()->as_type_array();
1395     for (int e = 0; e < c; e++) {
1396       __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
1397                          __ intcon(value_array->char_at(o + e)), T_CHAR, char_adr_idx,
1398                          MemNode::unordered);
1399       start = __ AddI(start, __ intcon(1));
1400     }
1401   } else {
1402     Node* src_ptr = kit.array_element_address(value, offset, T_CHAR);
1403     Node* dst_ptr = kit.array_element_address(char_array, start, T_CHAR);
1404     Node* c = count;
1405     Node* extra = NULL;


< prev index next >