--- a/hotspot/src/share/vm/opto/graphKit.cpp Mon Nov 02 12:34:27 2015 +0000
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Tue Nov 03 09:41:03 2015 +0100
@@ -4266,35 +4266,11 @@
#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) {
@@ -4302,9 +4278,9 @@
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);
+ const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull,
+ 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);
@@ -4315,14 +4291,21 @@
return load;
}
-void GraphKit::store_String_offset(Node* ctrl, Node* str, Node* value) {
- 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);
- store_to_memory(ctrl, basic_plus_adr(str, offset_offset),
- value, T_INT, offset_field_idx, MemNode::unordered);
+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* 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) {
@@ -4330,19 +4313,76 @@
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) {