< prev index next >

src/share/vm/opto/graphKit.cpp

Print this page

        

@@ -4264,87 +4264,127 @@
   final_sync(ideal);
 }
 #undef __
 
 
-
-Node* GraphKit::load_String_offset(Node* ctrl, Node* str) {
-  if (java_lang_String::has_offset_field()) {
-    int offset_offset = java_lang_String::offset_offset_in_bytes();
-    const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
-                                                       false, NULL, 0);
-    const TypePtr* offset_field_type = string_type->add_offset(offset_offset);
-    int offset_field_idx = C->get_alias_index(offset_field_type);
-    return make_load(ctrl,
-                     basic_plus_adr(str, str, offset_offset),
-                     TypeInt::INT, T_INT, offset_field_idx, MemNode::unordered);
-  } else {
-    return intcon(0);
-  }
-}
-
 Node* GraphKit::load_String_length(Node* ctrl, Node* str) {
-  if (java_lang_String::has_count_field()) {
-    int count_offset = java_lang_String::count_offset_in_bytes();
-    const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
-                                                       false, NULL, 0);
-    const TypePtr* count_field_type = string_type->add_offset(count_offset);
-    int count_field_idx = C->get_alias_index(count_field_type);
-    return make_load(ctrl,
-                     basic_plus_adr(str, str, count_offset),
-                     TypeInt::INT, T_INT, count_field_idx, MemNode::unordered);
-  } else {
-    return load_array_length(load_String_value(ctrl, str));
-  }
+  Node* len = load_array_length(load_String_value(ctrl, str));
+  Node* coder = load_String_coder(ctrl, str);
+  // Divide length by 2 if coder is UTF16
+  return _gvn.transform(new RShiftINode(len, coder));
 }
 
 Node* GraphKit::load_String_value(Node* ctrl, Node* str) {
   int value_offset = java_lang_String::value_offset_in_bytes();
   const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
                                                      false, NULL, 0);
   const TypePtr* value_field_type = string_type->add_offset(value_offset);
   const TypeAryPtr*  value_type = TypeAryPtr::make(TypePtr::NotNull,
-                                                   TypeAry::make(TypeInt::CHAR,TypeInt::POS),
-                                                   ciTypeArrayKlass::make(T_CHAR), true, 0);
+                                                  TypeAry::make(TypeInt::BYTE, TypeInt::POS),
+                                                  ciTypeArrayKlass::make(T_BYTE), true, 0);
   int value_field_idx = C->get_alias_index(value_field_type);
   Node* load = make_load(ctrl, basic_plus_adr(str, str, value_offset),
                          value_type, T_OBJECT, value_field_idx, MemNode::unordered);
   // String.value field is known to be @Stable.
   if (UseImplicitStableValues) {
     load = cast_array_to_stable(load, value_type);
   }
   return load;
 }
 
-void GraphKit::store_String_offset(Node* ctrl, Node* str, Node* value) {
-  int offset_offset = java_lang_String::offset_offset_in_bytes();
+Node* GraphKit::load_String_coder(Node* ctrl, Node* str) {
+  if (java_lang_String::has_coder_field()) {
+    if (!CompactStrings) {
+      return intcon(java_lang_String::CODER_UTF16);
+    }
+    int coder_offset = java_lang_String::coder_offset_in_bytes();
   const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
                                                      false, NULL, 0);
-  const TypePtr* offset_field_type = string_type->add_offset(offset_offset);
-  int offset_field_idx = C->get_alias_index(offset_field_type);
-  store_to_memory(ctrl, basic_plus_adr(str, offset_offset),
-                  value, T_INT, offset_field_idx, MemNode::unordered);
+    const TypePtr* coder_field_type = string_type->add_offset(coder_offset);
+    int coder_field_idx = C->get_alias_index(coder_field_type);
+    return make_load(ctrl, basic_plus_adr(str, str, coder_offset),
+                     TypeInt::BYTE, T_BYTE, coder_field_idx, MemNode::unordered);
+  } else {
+    return intcon(0); // false
+  }
 }
 
 void GraphKit::store_String_value(Node* ctrl, Node* str, Node* value) {
   int value_offset = java_lang_String::value_offset_in_bytes();
   const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
                                                      false, NULL, 0);
   const TypePtr* value_field_type = string_type->add_offset(value_offset);
-
   store_oop_to_object(ctrl, str,  basic_plus_adr(str, value_offset), value_field_type,
-      value, TypeAryPtr::CHARS, T_OBJECT, MemNode::unordered);
+      value, TypeAryPtr::BYTES, T_OBJECT, MemNode::unordered);
 }
 
-void GraphKit::store_String_length(Node* ctrl, Node* str, Node* value) {
-  int count_offset = java_lang_String::count_offset_in_bytes();
+void GraphKit::store_String_coder(Node* ctrl, Node* str, Node* value) {
+  int coder_offset = java_lang_String::coder_offset_in_bytes();
   const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
                                                      false, NULL, 0);
-  const TypePtr* count_field_type = string_type->add_offset(count_offset);
-  int count_field_idx = C->get_alias_index(count_field_type);
-  store_to_memory(ctrl, basic_plus_adr(str, count_offset),
-                  value, T_INT, count_field_idx, MemNode::unordered);
+  const TypePtr* coder_field_type = string_type->add_offset(coder_offset);
+  int coder_field_idx = C->get_alias_index(coder_field_type);
+  store_to_memory(ctrl, basic_plus_adr(str, coder_offset),
+                  value, T_BYTE, coder_field_idx, MemNode::unordered);
+}
+
+Node* GraphKit::compress_string(Node* src, Node* dst, Node* count) {
+  assert(Matcher::match_rule_supported(Op_StrCompressedCopy), "Intrinsic not supported");
+  uint idx = C->get_alias_index(TypeAryPtr::BYTES);
+  StrCompressedCopyNode* str = new StrCompressedCopyNode(control(), memory(idx), src, dst, count);
+  Node* res_mem = _gvn.transform(new SCMemProjNode(str));
+  set_memory(res_mem, idx);
+  return str;
+}
+
+void GraphKit::inflate_string(Node* src, Node* dst, Node* count) {
+  assert(Matcher::match_rule_supported(Op_StrInflatedCopy), "Intrinsic not supported");
+  uint idx = C->get_alias_index(TypeAryPtr::BYTES);
+  StrInflatedCopyNode* str = new StrInflatedCopyNode(control(), memory(idx), src, dst, count);
+  set_memory(_gvn.transform(str), idx);
+}
+
+void GraphKit::inflate_string_slow(Node* src, Node* dst, Node* start, Node* count) {
+  /**
+   * int i_char = start;
+   * for (int i_byte = 0; i_byte < count; i_byte++) {
+   *   dst[i_char++] = (char)(src[i_byte] & 0xff);
+   * }
+   */
+  add_predicate();
+  RegionNode* head = new RegionNode(3);
+  head->init_req(1, control());
+  gvn().set_type(head, Type::CONTROL);
+  record_for_igvn(head);
+
+  Node* i_byte = new PhiNode(head, TypeInt::INT);
+  i_byte->init_req(1, intcon(0));
+  gvn().set_type(i_byte, TypeInt::INT);
+  record_for_igvn(i_byte);
+
+  Node* i_char = new PhiNode(head, TypeInt::INT);
+  i_char->init_req(1, start);
+  gvn().set_type(i_char, TypeInt::INT);
+  record_for_igvn(i_char);
+
+  Node* mem = PhiNode::make(head, memory(TypeAryPtr::BYTES), Type::MEMORY, TypeAryPtr::BYTES);
+  gvn().set_type(mem, Type::MEMORY);
+  record_for_igvn(mem);
+  set_control(head);
+  set_memory(mem, TypeAryPtr::BYTES);
+  Node* ch = load_array_element(control(), src, i_byte, TypeAryPtr::BYTES);
+  Node* st = store_to_memory(control(), array_element_address(dst, i_char, T_BYTE),
+                             AndI(ch, intcon(0xff)), T_CHAR, TypeAryPtr::BYTES, MemNode::unordered);
+
+  IfNode* iff = create_and_map_if(head, Bool(CmpI(i_byte, count), BoolTest::lt), PROB_FAIR, COUNT_UNKNOWN);
+  head->init_req(2, IfTrue(iff));
+  mem->init_req(2, st);
+  i_byte->init_req(2, AddI(i_byte, intcon(1)));
+  i_char->init_req(2, AddI(i_char, intcon(2)));
+
+  set_control(IfFalse(iff));
+  set_memory(st, TypeAryPtr::BYTES);
 }
 
 Node* GraphKit::cast_array_to_stable(Node* ary, const TypeAryPtr* ary_type) {
   // Reify the property as a CastPP node in Ideal graph to comply with monotonicity
   // assumption of CCP analysis.
< prev index next >