Update java.lang.String* from jdk-11.0.13-ga

1. String(byte[], byte) constructor is added.
2. StringFactory.newStringFromBytes(byte[], int, int, int) is allowlisted
  to be called in the unstarted runtime.

Bug: 247773125
Test: art/test/testrunner/testrunner.py -b --host
Change-Id: I9386b3529a94a122654574e3110d08222be7f282
diff --git a/dex2oat/linker/oat_writer_test.cc b/dex2oat/linker/oat_writer_test.cc
index b688e49..6742cf7 100644
--- a/dex2oat/linker/oat_writer_test.cc
+++ b/dex2oat/linker/oat_writer_test.cc
@@ -508,7 +508,7 @@
   EXPECT_EQ(68U, sizeof(OatHeader));
   EXPECT_EQ(4U, sizeof(OatMethodOffsets));
   EXPECT_EQ(4U, sizeof(OatQuickMethodHeader));
-  EXPECT_EQ(168 * static_cast<size_t>(GetInstructionSetPointerSize(kRuntimeISA)),
+  EXPECT_EQ(170 * static_cast<size_t>(GetInstructionSetPointerSize(kRuntimeISA)),
             sizeof(QuickEntryPoints));
 }
 
diff --git a/runtime/entrypoints/quick/quick_entrypoints_list.h b/runtime/entrypoints/quick/quick_entrypoints_list.h
index 4534bba..aa3360e 100644
--- a/runtime/entrypoints/quick/quick_entrypoints_list.h
+++ b/runtime/entrypoints/quick/quick_entrypoints_list.h
@@ -151,6 +151,7 @@
 \
   V(NewEmptyString, void, void) \
   V(NewStringFromBytes_B, void, void) \
+  V(NewStringFromBytes_BB, void, void) \
   V(NewStringFromBytes_BI, void, void) \
   V(NewStringFromBytes_BII, void, void) \
   V(NewStringFromBytes_BIII, void, void) \
@@ -165,6 +166,7 @@
   V(NewStringFromString, void, void) \
   V(NewStringFromStringBuffer, void, void) \
   V(NewStringFromStringBuilder, void, void) \
+  V(NewStringFromUtf16Bytes_BII, void, void) \
 \
   V(StringBuilderAppend, void*, uint32_t) \
 \
diff --git a/runtime/entrypoints_order_test.cc b/runtime/entrypoints_order_test.cc
index 2cd58db..e969652 100644
--- a/runtime/entrypoints_order_test.cc
+++ b/runtime/entrypoints_order_test.cc
@@ -301,7 +301,9 @@
 
     EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pA64Store, pNewEmptyString, sizeof(void*));
     EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pNewEmptyString, pNewStringFromBytes_B, sizeof(void*));
-    EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pNewStringFromBytes_B, pNewStringFromBytes_BI,
+    EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pNewStringFromBytes_B, pNewStringFromBytes_BB,
+                         sizeof(void*));
+    EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pNewStringFromBytes_BB, pNewStringFromBytes_BI,
                          sizeof(void*));
     EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pNewStringFromBytes_BI, pNewStringFromBytes_BII,
                          sizeof(void*));
@@ -329,7 +331,9 @@
                          sizeof(void*));
     EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pNewStringFromStringBuffer, pNewStringFromStringBuilder,
                          sizeof(void*));
-    EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pNewStringFromStringBuilder, pStringBuilderAppend,
+    EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pNewStringFromStringBuilder, pNewStringFromUtf16Bytes_BII,
+                         sizeof(void*));
+    EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pNewStringFromUtf16Bytes_BII, pStringBuilderAppend,
                          sizeof(void*));
     EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pStringBuilderAppend, pUpdateInlineCache,
                          sizeof(void*));
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 4e5ef4f..d097ff2 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -1367,6 +1367,22 @@
 }
 
 // This allows creating the new style of String objects during compilation.
+void UnstartedRuntime::UnstartedStringFactoryNewStringFromBytes(
+    Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
+  jint high = shadow_frame->GetVReg(arg_offset + 1);
+  jint offset = shadow_frame->GetVReg(arg_offset + 2);
+  jint byte_count = shadow_frame->GetVReg(arg_offset + 3);
+  DCHECK_GE(byte_count, 0);
+  StackHandleScope<1> hs(self);
+  Handle<mirror::ByteArray> h_byte_array(
+      hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsByteArray()));
+  Runtime* runtime = Runtime::Current();
+  gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
+  result->SetL(
+      mirror::String::AllocFromByteArray(self, byte_count, h_byte_array, offset, high, allocator));
+}
+
+// This allows creating the new style of String objects during compilation.
 void UnstartedRuntime::UnstartedStringFactoryNewStringFromChars(
     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
   jint offset = shadow_frame->GetVReg(arg_offset);
@@ -1921,6 +1937,30 @@
   result->SetI(receiver->AsString()->CompareTo(rhs->AsString()));
 }
 
+void UnstartedRuntime::UnstartedJNIStringFillBytesLatin1(
+    Thread* self, ArtMethod* method ATTRIBUTE_UNUSED,
+    mirror::Object* receiver, uint32_t* args, JValue* ATTRIBUTE_UNUSED) {
+  StackHandleScope<2> hs(self);
+  Handle<mirror::String> h_receiver(hs.NewHandle(
+      reinterpret_cast<mirror::String*>(receiver)->AsString()));
+  Handle<mirror::ByteArray> h_buffer(hs.NewHandle(
+      reinterpret_cast<mirror::ByteArray*>(args[0])->AsByteArray()));
+  int32_t index = static_cast<int32_t>(args[1]);
+  h_receiver->FillBytesLatin1(h_buffer, index);
+}
+
+void UnstartedRuntime::UnstartedJNIStringFillBytesUTF16(
+    Thread* self, ArtMethod* method ATTRIBUTE_UNUSED,
+    mirror::Object* receiver, uint32_t* args, JValue* ATTRIBUTE_UNUSED) {
+  StackHandleScope<2> hs(self);
+  Handle<mirror::String> h_receiver(hs.NewHandle(
+      reinterpret_cast<mirror::String*>(receiver)->AsString()));
+  Handle<mirror::ByteArray> h_buffer(hs.NewHandle(
+      reinterpret_cast<mirror::ByteArray*>(args[0])->AsByteArray()));
+  int32_t index = static_cast<int32_t>(args[1]);
+  h_receiver->FillBytesUTF16(h_buffer, index);
+}
+
 void UnstartedRuntime::UnstartedJNIStringIntern(
     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
     uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
diff --git a/runtime/interpreter/unstarted_runtime_list.h b/runtime/interpreter/unstarted_runtime_list.h
index 5f8add0..dd2028a 100644
--- a/runtime/interpreter/unstarted_runtime_list.h
+++ b/runtime/interpreter/unstarted_runtime_list.h
@@ -67,6 +67,7 @@
   V(StringGetCharsNoCheck, "Ljava/lang/String;", "getCharsNoCheck", "(II[CI)V") \
   V(StringCharAt, "Ljava/lang/String;", "charAt", "(I)C") \
   V(StringDoReplace, "Ljava/lang/String;", "doReplace", "(CC)Ljava/lang/String;") \
+  V(StringFactoryNewStringFromBytes, "Ljava/lang/StringFactory;", "newStringFromBytes", "([BIII)Ljava/lang/String;") \
   V(StringFactoryNewStringFromChars, "Ljava/lang/StringFactory;", "newStringFromChars", "(II[C)Ljava/lang/String;") \
   V(StringFactoryNewStringFromString, "Ljava/lang/StringFactory;", "newStringFromString", "(Ljava/lang/String;)Ljava/lang/String;") \
   V(StringFastSubstring, "Ljava/lang/String;", "fastSubstring", "(II)Ljava/lang/String;") \
@@ -105,6 +106,8 @@
   V(ObjectInternalClone, "Ljava/lang/Object;", "internalClone", "()Ljava/lang/Object;") \
   V(ObjectNotifyAll, "Ljava/lang/Object;", "notifyAll", "()V") \
   V(StringCompareTo, "Ljava/lang/String;", "compareTo", "(Ljava/lang/String;)I") \
+  V(StringFillBytesLatin1, "Ljava/lang/String;", "fillBytesLatin1", "([BI)V") \
+  V(StringFillBytesUTF16, "Ljava/lang/String;", "fillBytesUTF16", "([BI)V") \
   V(StringIntern, "Ljava/lang/String;", "intern", "()Ljava/lang/String;") \
   V(ArrayCreateMultiArray, "Ljava/lang/reflect/Array;", "createMultiArray", "(Ljava/lang/Class;[I)Ljava/lang/Object;") \
   V(ArrayCreateObjectArray, "Ljava/lang/reflect/Array;", "createObjectArray", "(Ljava/lang/Class;I)Ljava/lang/Object;") \
diff --git a/runtime/mirror/string-alloc-inl.h b/runtime/mirror/string-alloc-inl.h
index 925427a..cb2dcb2 100644
--- a/runtime/mirror/string-alloc-inl.h
+++ b/runtime/mirror/string-alloc-inl.h
@@ -18,6 +18,7 @@
 
 #include "string-inl.h"
 
+#include "android-base/endian.h"
 #include "android-base/stringprintf.h"
 
 #include "array.h"
@@ -89,6 +90,41 @@
 };
 
 // Sets string count and value in the allocation code path to ensure it is guarded by a CAS.
+class SetStringCountAndUtf16BytesVisitor {
+ public:
+  SetStringCountAndUtf16BytesVisitor(int32_t count, Handle<ByteArray> src_array, int32_t offset)
+      : count_(count), src_array_(src_array), offset_(offset) {
+  }
+
+  void operator()(ObjPtr<Object> obj, size_t usable_size ATTRIBUTE_UNUSED) const
+      REQUIRES_SHARED(Locks::mutator_lock_) {
+    // Avoid AsString as object is not yet in live bitmap or allocation stack.
+    ObjPtr<String> string = ObjPtr<String>::DownCast(obj);
+    string->SetCount(count_);
+    DCHECK_IMPLIES(string->IsCompressed(), kUseStringCompression);
+    uint32_t length = String::GetLengthFromCount(count_);
+    const uint8_t* const src = reinterpret_cast<uint8_t*>(src_array_->GetData()) + offset_;
+    if (UNLIKELY(string->IsCompressed())) {
+      uint8_t* valueCompressed = string->GetValueCompressed();
+      for (uint32_t i = 0; i < length; i++) {
+        valueCompressed[i] = (src[i << 1] & 0xFF);
+      }
+    } else {
+      uint16_t* value = string->GetValue();
+      for (uint32_t i = 0; i < length; i++) {
+        uint32_t index = (i << 1);
+        value[i] = (src[index] & 0xFF) + ((src[index + 1] & 0xFF) << 8);
+      }
+    }
+  }
+
+ private:
+  const int32_t count_;
+  Handle<ByteArray> src_array_;
+  const int32_t offset_;
+};
+
+// Sets string count and value in the allocation code path to ensure it is guarded by a CAS.
 class SetStringCountAndValueVisitorFromCharArray {
  public:
   SetStringCountAndValueVisitorFromCharArray(int32_t count, Handle<CharArray> src_array,
@@ -225,6 +261,30 @@
 }
 
 template <bool kIsInstrumented>
+inline ObjPtr<String> String::AllocFromUtf16ByteArray(Thread* self,
+                                                      int32_t char_count,
+                                                      Handle<ByteArray> array,
+                                                      int32_t offset,
+                                                      gc::AllocatorType allocator_type) {
+  static_assert(__BYTE_ORDER == __LITTLE_ENDIAN,
+      "Please update this function and java-side callers to support big endian.");
+  const uint8_t* const src = reinterpret_cast<uint8_t*>(array->GetData()) + offset;
+  bool compressible = kUseStringCompression;
+  if (compressible) {
+    uint32_t byte_count = (static_cast<uint32_t>(char_count) << 1);
+    for (uint32_t i = 0; i < byte_count; i += 2) {
+      if (!IsASCII((src[i] & 0xff) + ((src[i + 1] & 0xff) << 8))) {
+        compressible = false;
+        break;
+      }
+    }
+  }
+  const int32_t length_with_flag = String::GetFlaggedCount(char_count, compressible);
+  SetStringCountAndUtf16BytesVisitor visitor(length_with_flag, array, offset);
+  return Alloc<kIsInstrumented>(self, length_with_flag, allocator_type, visitor);
+}
+
+template <bool kIsInstrumented>
 inline ObjPtr<String> String::AllocFromCharArray(Thread* self,
                                                  int32_t count,
                                                  Handle<CharArray> array,
diff --git a/runtime/mirror/string-inl.h b/runtime/mirror/string-inl.h
index 8fb4415..0b59840 100644
--- a/runtime/mirror/string-inl.h
+++ b/runtime/mirror/string-inl.h
@@ -35,11 +35,11 @@
   //   lambda$codePoints$1$CharSequence
   // which were virtual functions in standalone desugar, becomes
   // direct functions with D8 desugaring.
-  uint32_t vtable_entries = Object::kVTableLength + 64;
-#else
   uint32_t vtable_entries = Object::kVTableLength + 66;
+#else
+  uint32_t vtable_entries = Object::kVTableLength + 68;
 #endif
-  return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 1, 2, pointer_size);
+  return Class::ComputeClassSize(true, vtable_entries, 3, 0, 0, 1, 2, pointer_size);
 }
 
 inline uint16_t String::CharAt(int32_t index) {
diff --git a/runtime/mirror/string.cc b/runtime/mirror/string.cc
index d059278..4961776 100644
--- a/runtime/mirror/string.cc
+++ b/runtime/mirror/string.cc
@@ -19,6 +19,7 @@
 #include "arch/memcmp16.h"
 #include "array-alloc-inl.h"
 #include "base/array_ref.h"
+#include "base/casts.h"
 #include "base/stl_util.h"
 #include "class-inl.h"
 #include "dex/descriptors_names.h"
@@ -396,6 +397,38 @@
   }
 }
 
+void String::FillBytesLatin1(Handle<ByteArray> array, int32_t index) {
+  int8_t* data = array->GetData() + index;
+  int32_t length = GetLength();
+  if (IsCompressed()) {
+    const uint8_t* value = GetValueCompressed();
+    memcpy(data, value, length * sizeof(uint8_t));
+  } else {
+    // Drop the high byte of the characters.
+    // The caller should check that all dropped high bytes are zeros.
+    const uint16_t* value = GetValue();
+    for (int32_t i = 0; i < length; ++i) {
+      data[i] = static_cast<int8_t>(dchecked_integral_cast<uint8_t>(value[i]));
+    }
+  }
+}
+
+void String::FillBytesUTF16(Handle<ByteArray> array, int32_t index) {
+  int8_t* data = array->GetData() + index;
+  int32_t length = GetLength();
+  if (IsCompressed()) {
+    const uint8_t* value = GetValueCompressed();
+    uint32_t d_index = 0;
+    for (int i = 0; i < length; ++i) {
+      data[d_index++] = static_cast<int8_t>(value[i]);
+      data[d_index++] = 0;
+    }
+  } else {
+    const uint16_t* value = GetValue();
+    memcpy(data, value, length * sizeof(uint16_t));
+  }
+}
+
 bool String::IsValueNull() {
   return (IsCompressed()) ? (GetValueCompressed() == nullptr) : (GetValue() == nullptr);
 }
diff --git a/runtime/mirror/string.h b/runtime/mirror/string.h
index 2eb8e0a..3ce2d4c 100644
--- a/runtime/mirror/string.h
+++ b/runtime/mirror/string.h
@@ -142,6 +142,14 @@
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
   template <bool kIsInstrumented = true>
+  ALWAYS_INLINE static ObjPtr<String> AllocFromUtf16ByteArray(Thread* self,
+                                                         int32_t char_count,
+                                                         Handle<ByteArray> array,
+                                                         int32_t offset,
+                                                         gc::AllocatorType allocator_type)
+      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
+
+  template <bool kIsInstrumented = true>
   ALWAYS_INLINE static ObjPtr<String> AllocFromCharArray(Thread* self,
                                                          int32_t count,
                                                          Handle<CharArray> array,
@@ -209,6 +217,12 @@
   void GetChars(int32_t start, int32_t end, Handle<CharArray> array, int32_t index)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
+  void FillBytesLatin1(Handle<ByteArray> array, int32_t index)
+      REQUIRES_SHARED(Locks::mutator_lock_);
+
+  void FillBytesUTF16(Handle<ByteArray> array, int32_t index)
+      REQUIRES_SHARED(Locks::mutator_lock_);
+
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
   bool IsCompressed() REQUIRES_SHARED(Locks::mutator_lock_) {
     return kUseStringCompression && IsCompressed(GetCount());
diff --git a/runtime/native/java_lang_String.cc b/runtime/native/java_lang_String.cc
index 94ca5b5..f70a188 100644
--- a/runtime/native/java_lang_String.cc
+++ b/runtime/native/java_lang_String.cc
@@ -88,6 +88,22 @@
   soa.Decode<mirror::String>(java_this)->GetChars(start, end, char_array, index);
 }
 
+static void String_fillBytesLatin1(JNIEnv* env, jobject java_this,
+                                   jbyteArray buffer, jint byteIndex) {
+  ScopedFastNativeObjectAccess soa(env);
+  StackHandleScope<1> hs(soa.Self());
+  Handle<mirror::ByteArray> byte_array(hs.NewHandle(soa.Decode<mirror::ByteArray>(buffer)));
+  soa.Decode<mirror::String>(java_this)->FillBytesLatin1(byte_array, byteIndex);
+}
+
+static void String_fillBytesUTF16(JNIEnv* env, jobject java_this,
+                                   jbyteArray buffer, jint byteIndex) {
+  ScopedFastNativeObjectAccess soa(env);
+  StackHandleScope<1> hs(soa.Self());
+  Handle<mirror::ByteArray> byte_array(hs.NewHandle(soa.Decode<mirror::ByteArray>(buffer)));
+  soa.Decode<mirror::String>(java_this)->FillBytesUTF16(byte_array, byteIndex);
+}
+
 static jstring String_intern(JNIEnv* env, jobject java_this) {
   ScopedFastNativeObjectAccess soa(env);
   ObjPtr<mirror::String> result = soa.Decode<mirror::String>(java_this)->Intern();
@@ -125,6 +141,8 @@
   FAST_NATIVE_METHOD(String, doReplace, "(CC)Ljava/lang/String;"),
   FAST_NATIVE_METHOD(String, fastSubstring, "(II)Ljava/lang/String;"),
   FAST_NATIVE_METHOD(String, getCharsNoCheck, "(II[CI)V"),
+  FAST_NATIVE_METHOD(String, fillBytesLatin1, "([BI)V"),
+  FAST_NATIVE_METHOD(String, fillBytesUTF16, "([BI)V"),
   FAST_NATIVE_METHOD(String, intern, "()Ljava/lang/String;"),
   FAST_NATIVE_METHOD(String, toCharArray, "()[C"),
 };
diff --git a/runtime/native/java_lang_StringFactory.cc b/runtime/native/java_lang_StringFactory.cc
index 9086ee9..2fbebc0 100644
--- a/runtime/native/java_lang_StringFactory.cc
+++ b/runtime/native/java_lang_StringFactory.cc
@@ -56,6 +56,36 @@
   return soa.AddLocalReference<jstring>(result);
 }
 
+static jstring StringFactory_newStringFromUtf16Bytes(
+    JNIEnv* env, jclass, jbyteArray java_data, jint offset, jint char_count) {
+  ScopedFastNativeObjectAccess soa(env);
+  if (UNLIKELY(java_data == nullptr)) {
+    ThrowNullPointerException("data == null");
+    return nullptr;
+  }
+  StackHandleScope<1> hs(soa.Self());
+  Handle<mirror::ByteArray> byte_array(hs.NewHandle(soa.Decode<mirror::ByteArray>(java_data)));
+  int32_t data_size = byte_array->GetLength();
+  DCHECK_GE(data_size, 0);
+  if (offset < 0 ||
+      offset > data_size ||
+      static_cast<uint32_t>(char_count) > (static_cast<uint32_t>(data_size - offset) >> 1)) {
+    soa.Self()->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
+                                   "length=%d; regionStart=%d; bytePairLength=%d",
+                                   data_size,
+                                   offset,
+                                   char_count);
+    return nullptr;
+  }
+  gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
+  ObjPtr<mirror::String> result = mirror::String::AllocFromUtf16ByteArray(soa.Self(),
+                                                                          char_count,
+                                                                          byte_array,
+                                                                          offset,
+                                                                          allocator_type);
+  return soa.AddLocalReference<jstring>(result);
+}
+
 // The char array passed as `java_data` must not be a null reference.
 static jstring StringFactory_newStringFromChars(JNIEnv* env, jclass, jint offset,
                                                 jint char_count, jcharArray java_data) {
@@ -269,6 +299,7 @@
   FAST_NATIVE_METHOD(StringFactory, newStringFromChars, "(II[C)Ljava/lang/String;"),
   FAST_NATIVE_METHOD(StringFactory, newStringFromString, "(Ljava/lang/String;)Ljava/lang/String;"),
   FAST_NATIVE_METHOD(StringFactory, newStringFromUtf8Bytes, "([BII)Ljava/lang/String;"),
+  FAST_NATIVE_METHOD(StringFactory, newStringFromUtf16Bytes, "([BII)Ljava/lang/String;"),
 };
 
 void register_java_lang_StringFactory(JNIEnv* env) {
diff --git a/runtime/oat.h b/runtime/oat.h
index 32034f6..20d32cb 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -32,8 +32,8 @@
 class PACKED(4) OatHeader {
  public:
   static constexpr std::array<uint8_t, 4> kOatMagic { { 'o', 'a', 't', '\n' } };
-  // Last oat version changed reason: Try catch inlining.
-  static constexpr std::array<uint8_t, 4> kOatVersion { { '2', '2', '8', '\0' } };
+  // Last oat version changed reason: Add a new QuickEntryPoint for a String constructor.
+  static constexpr std::array<uint8_t, 4> kOatVersion { { '2', '2', '9', '\0' } };
 
   static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";
   static constexpr const char* kDebuggableKey = "debuggable";
diff --git a/runtime/thread.cc b/runtime/thread.cc
index c9a0a15..ad6b8c6 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -3825,6 +3825,7 @@
   QUICK_ENTRY_POINT_INFO(pA64Store)
   QUICK_ENTRY_POINT_INFO(pNewEmptyString)
   QUICK_ENTRY_POINT_INFO(pNewStringFromBytes_B)
+  QUICK_ENTRY_POINT_INFO(pNewStringFromBytes_BB)
   QUICK_ENTRY_POINT_INFO(pNewStringFromBytes_BI)
   QUICK_ENTRY_POINT_INFO(pNewStringFromBytes_BII)
   QUICK_ENTRY_POINT_INFO(pNewStringFromBytes_BIII)
@@ -3839,6 +3840,7 @@
   QUICK_ENTRY_POINT_INFO(pNewStringFromString)
   QUICK_ENTRY_POINT_INFO(pNewStringFromStringBuffer)
   QUICK_ENTRY_POINT_INFO(pNewStringFromStringBuilder)
+  QUICK_ENTRY_POINT_INFO(pNewStringFromUtf16Bytes_BII)
   QUICK_ENTRY_POINT_INFO(pJniReadBarrier)
   QUICK_ENTRY_POINT_INFO(pReadBarrierMarkReg00)
   QUICK_ENTRY_POINT_INFO(pReadBarrierMarkReg01)
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index fc79149..888a2ed 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -254,6 +254,7 @@
 #define STRING_INIT_LIST(V) \
   V(java_lang_String_init, "()V", newEmptyString, "newEmptyString", "()Ljava/lang/String;", NewEmptyString) \
   V(java_lang_String_init_B, "([B)V", newStringFromBytes_B, "newStringFromBytes", "([B)Ljava/lang/String;", NewStringFromBytes_B) \
+  V(java_lang_String_init_BB, "([BB)V", newStringFromBytes_BB, "newStringFromBytes", "([BB)Ljava/lang/String;", NewStringFromBytes_BB) \
   V(java_lang_String_init_BI, "([BI)V", newStringFromBytes_BI, "newStringFromBytes", "([BI)Ljava/lang/String;", NewStringFromBytes_BI) \
   V(java_lang_String_init_BII, "([BII)V", newStringFromBytes_BII, "newStringFromBytes", "([BII)Ljava/lang/String;", NewStringFromBytes_BII) \
   V(java_lang_String_init_BIII, "([BIII)V", newStringFromBytes_BIII, "newStringFromBytes", "([BIII)Ljava/lang/String;", NewStringFromBytes_BIII) \
diff --git a/test/100-reflect2/expected-stdout.txt b/test/100-reflect2/expected-stdout.txt
index 4b885e4..6fdfeae 100644
--- a/test/100-reflect2/expected-stdout.txt
+++ b/test/100-reflect2/expected-stdout.txt
@@ -31,9 +31,9 @@
 30 (class java.lang.Integer)
 62 (class java.lang.Long)
 14 (class java.lang.Short)
-[java.lang.String(int,int,char[]), public java.lang.String(), public java.lang.String(byte[]), public java.lang.String(byte[],int), public java.lang.String(byte[],int,int), public java.lang.String(byte[],int,int,int), public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException, public java.lang.String(byte[],int,int,java.nio.charset.Charset), public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException, public java.lang.String(byte[],java.nio.charset.Charset), public java.lang.String(char[]), public java.lang.String(char[],int,int), public java.lang.String(int[],int,int), public java.lang.String(java.lang.String), public java.lang.String(java.lang.StringBuffer), public java.lang.String(java.lang.StringBuilder)]
-[private final int java.lang.String.count, private int java.lang.String.hash, private static final java.io.ObjectStreamField[] java.lang.String.serialPersistentFields, private static final long java.lang.String.serialVersionUID, public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER]
-[native void java.lang.String.getCharsNoCheck(int,int,char[],int), private boolean java.lang.String.nonSyncContentEquals(java.lang.AbstractStringBuilder), private int java.lang.String.indexOfNonWhitespace(), private int java.lang.String.indexOfSupplementary(int,int), private int java.lang.String.lastIndexOfNonWhitespace(), private int java.lang.String.lastIndexOfSupplementary(int,int), private native java.lang.String java.lang.String.doRepeat(int), private native java.lang.String java.lang.String.doReplace(char,char), private native java.lang.String java.lang.String.fastSubstring(int,int), private static int java.lang.String.indexOf(java.lang.String,java.lang.String,int), private static int java.lang.String.lastIndexOf(java.lang.String,java.lang.String,int), private static int java.lang.String.outdent(java.util.List), public boolean java.lang.String.contains(java.lang.CharSequence), public boolean java.lang.String.contentEquals(java.lang.CharSequence), public boolean java.lang.String.contentEquals(java.lang.StringBuffer), public boolean java.lang.String.endsWith(java.lang.String), public boolean java.lang.String.equals(java.lang.Object), public boolean java.lang.String.equalsIgnoreCase(java.lang.String), public boolean java.lang.String.isBlank(), public boolean java.lang.String.isEmpty(), public boolean java.lang.String.matches(java.lang.String), public boolean java.lang.String.regionMatches(boolean,int,java.lang.String,int,int), public boolean java.lang.String.regionMatches(int,java.lang.String,int,int), public boolean java.lang.String.startsWith(java.lang.String), public boolean java.lang.String.startsWith(java.lang.String,int), public byte[] java.lang.String.getBytes(), public byte[] java.lang.String.getBytes(java.lang.String) throws java.io.UnsupportedEncodingException, public byte[] java.lang.String.getBytes(java.nio.charset.Charset), public int java.lang.String.codePointAt(int), public int java.lang.String.codePointBefore(int), public int java.lang.String.codePointCount(int,int), public int java.lang.String.compareTo(java.lang.Object), public int java.lang.String.compareToIgnoreCase(java.lang.String), public int java.lang.String.hashCode(), public int java.lang.String.indexOf(int), public int java.lang.String.indexOf(int,int), public int java.lang.String.indexOf(java.lang.String), public int java.lang.String.indexOf(java.lang.String,int), public int java.lang.String.lastIndexOf(int), public int java.lang.String.lastIndexOf(int,int), public int java.lang.String.lastIndexOf(java.lang.String), public int java.lang.String.lastIndexOf(java.lang.String,int), public int java.lang.String.length(), public int java.lang.String.offsetByCodePoints(int,int), public java.lang.CharSequence java.lang.String.subSequence(int,int), public java.lang.String java.lang.String.formatted(java.lang.Object[]), public java.lang.String java.lang.String.indent(int), public java.lang.String java.lang.String.repeat(int), public java.lang.String java.lang.String.replace(char,char), public java.lang.String java.lang.String.replace(java.lang.CharSequence,java.lang.CharSequence), public java.lang.String java.lang.String.replaceAll(java.lang.String,java.lang.String), public java.lang.String java.lang.String.replaceFirst(java.lang.String,java.lang.String), public java.lang.String java.lang.String.strip(), public java.lang.String java.lang.String.stripIndent(), public java.lang.String java.lang.String.stripLeading(), public java.lang.String java.lang.String.stripTrailing(), public java.lang.String java.lang.String.substring(int), public java.lang.String java.lang.String.substring(int,int), public java.lang.String java.lang.String.toLowerCase(), public java.lang.String java.lang.String.toLowerCase(java.util.Locale), public java.lang.String java.lang.String.toString(), public java.lang.String java.lang.String.toUpperCase(), public java.lang.String java.lang.String.toUpperCase(java.util.Locale), public java.lang.String java.lang.String.translateEscapes(), public java.lang.String java.lang.String.trim(), public java.lang.String[] java.lang.String.split(java.lang.String), public java.lang.String[] java.lang.String.split(java.lang.String,int), public java.util.stream.IntStream java.lang.String.chars(), public java.util.stream.IntStream java.lang.String.codePoints(), public java.util.stream.Stream java.lang.String.lines(), public native char java.lang.String.charAt(int), public native char[] java.lang.String.toCharArray(), public native int java.lang.String.compareTo(java.lang.String), public native java.lang.String java.lang.String.concat(java.lang.String), public native java.lang.String java.lang.String.intern(), public static java.lang.String java.lang.String.copyValueOf(char[]), public static java.lang.String java.lang.String.copyValueOf(char[],int,int), public static java.lang.String java.lang.String.format(java.lang.String,java.lang.Object[]), public static java.lang.String java.lang.String.format(java.util.Locale,java.lang.String,java.lang.Object[]), public static java.lang.String java.lang.String.join(java.lang.CharSequence,java.lang.CharSequence[]), public static java.lang.String java.lang.String.join(java.lang.CharSequence,java.lang.Iterable), public static java.lang.String java.lang.String.valueOf(boolean), public static java.lang.String java.lang.String.valueOf(char), public static java.lang.String java.lang.String.valueOf(char[]), public static java.lang.String java.lang.String.valueOf(char[],int,int), public static java.lang.String java.lang.String.valueOf(double), public static java.lang.String java.lang.String.valueOf(float), public static java.lang.String java.lang.String.valueOf(int), public static java.lang.String java.lang.String.valueOf(java.lang.Object), public static java.lang.String java.lang.String.valueOf(long), public void java.lang.String.getBytes(int,int,byte[],int), public void java.lang.String.getChars(int,int,char[],int), static int java.lang.String.indexOf(char[],int,int,char[],int,int,int), static int java.lang.String.indexOf(char[],int,int,java.lang.String,int), static int java.lang.String.lastIndexOf(char[],int,int,char[],int,int,int), static int java.lang.String.lastIndexOf(char[],int,int,java.lang.String,int), static java.lang.String java.lang.String.lambda$indent$0(java.lang.String,java.lang.String), static java.lang.String java.lang.String.lambda$indent$1(java.lang.String), static java.lang.String java.lang.String.lambda$indent$2(int,java.lang.String), static java.lang.String java.lang.String.lambda$stripIndent$3(int,java.lang.String), static void java.lang.String.checkBoundsBeginEnd(int,int,int), static void java.lang.String.checkBoundsOffCount(int,int,int), static void java.lang.String.checkIndex(int,int), void java.lang.String.getChars(char[],int)]
+[java.lang.String(byte[],byte), java.lang.String(int,int,char[]), public java.lang.String(), public java.lang.String(byte[]), public java.lang.String(byte[],int), public java.lang.String(byte[],int,int), public java.lang.String(byte[],int,int,int), public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException, public java.lang.String(byte[],int,int,java.nio.charset.Charset), public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException, public java.lang.String(byte[],java.nio.charset.Charset), public java.lang.String(char[]), public java.lang.String(char[],int,int), public java.lang.String(int[],int,int), public java.lang.String(java.lang.String), public java.lang.String(java.lang.StringBuffer), public java.lang.String(java.lang.StringBuilder)]
+[private final int java.lang.String.count, private int java.lang.String.hash, private static final java.io.ObjectStreamField[] java.lang.String.serialPersistentFields, private static final long java.lang.String.serialVersionUID, public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER, static final boolean java.lang.String.COMPACT_STRINGS, static final byte java.lang.String.LATIN1, static final byte java.lang.String.UTF16]
+[byte java.lang.String.coder(), native void java.lang.String.getCharsNoCheck(int,int,char[],int), private boolean java.lang.String.nonSyncContentEquals(java.lang.AbstractStringBuilder), private int java.lang.String.indexOfNonWhitespace(), private int java.lang.String.indexOfSupplementary(int,int), private int java.lang.String.lastIndexOfNonWhitespace(), private int java.lang.String.lastIndexOfSupplementary(int,int), private native java.lang.String java.lang.String.doRepeat(int), private native java.lang.String java.lang.String.doReplace(char,char), private native java.lang.String java.lang.String.fastSubstring(int,int), private native void java.lang.String.fillBytesLatin1(byte[],int), private native void java.lang.String.fillBytesUTF16(byte[],int), private static int java.lang.String.indexOf(java.lang.String,java.lang.String,int), private static int java.lang.String.lastIndexOf(java.lang.String,java.lang.String,int), private static int java.lang.String.outdent(java.util.List), public boolean java.lang.String.contains(java.lang.CharSequence), public boolean java.lang.String.contentEquals(java.lang.CharSequence), public boolean java.lang.String.contentEquals(java.lang.StringBuffer), public boolean java.lang.String.endsWith(java.lang.String), public boolean java.lang.String.equals(java.lang.Object), public boolean java.lang.String.equalsIgnoreCase(java.lang.String), public boolean java.lang.String.isBlank(), public boolean java.lang.String.isEmpty(), public boolean java.lang.String.matches(java.lang.String), public boolean java.lang.String.regionMatches(boolean,int,java.lang.String,int,int), public boolean java.lang.String.regionMatches(int,java.lang.String,int,int), public boolean java.lang.String.startsWith(java.lang.String), public boolean java.lang.String.startsWith(java.lang.String,int), public byte[] java.lang.String.getBytes(), public byte[] java.lang.String.getBytes(java.lang.String) throws java.io.UnsupportedEncodingException, public byte[] java.lang.String.getBytes(java.nio.charset.Charset), public int java.lang.String.codePointAt(int), public int java.lang.String.codePointBefore(int), public int java.lang.String.codePointCount(int,int), public int java.lang.String.compareTo(java.lang.Object), public int java.lang.String.compareToIgnoreCase(java.lang.String), public int java.lang.String.hashCode(), public int java.lang.String.indexOf(int), public int java.lang.String.indexOf(int,int), public int java.lang.String.indexOf(java.lang.String), public int java.lang.String.indexOf(java.lang.String,int), public int java.lang.String.lastIndexOf(int), public int java.lang.String.lastIndexOf(int,int), public int java.lang.String.lastIndexOf(java.lang.String), public int java.lang.String.lastIndexOf(java.lang.String,int), public int java.lang.String.length(), public int java.lang.String.offsetByCodePoints(int,int), public java.lang.CharSequence java.lang.String.subSequence(int,int), public java.lang.String java.lang.String.formatted(java.lang.Object[]), public java.lang.String java.lang.String.indent(int), public java.lang.String java.lang.String.repeat(int), public java.lang.String java.lang.String.replace(char,char), public java.lang.String java.lang.String.replace(java.lang.CharSequence,java.lang.CharSequence), public java.lang.String java.lang.String.replaceAll(java.lang.String,java.lang.String), public java.lang.String java.lang.String.replaceFirst(java.lang.String,java.lang.String), public java.lang.String java.lang.String.strip(), public java.lang.String java.lang.String.stripIndent(), public java.lang.String java.lang.String.stripLeading(), public java.lang.String java.lang.String.stripTrailing(), public java.lang.String java.lang.String.substring(int), public java.lang.String java.lang.String.substring(int,int), public java.lang.String java.lang.String.toLowerCase(), public java.lang.String java.lang.String.toLowerCase(java.util.Locale), public java.lang.String java.lang.String.toString(), public java.lang.String java.lang.String.toUpperCase(), public java.lang.String java.lang.String.toUpperCase(java.util.Locale), public java.lang.String java.lang.String.translateEscapes(), public java.lang.String java.lang.String.trim(), public java.lang.String[] java.lang.String.split(java.lang.String), public java.lang.String[] java.lang.String.split(java.lang.String,int), public java.util.stream.IntStream java.lang.String.chars(), public java.util.stream.IntStream java.lang.String.codePoints(), public java.util.stream.Stream java.lang.String.lines(), public native char java.lang.String.charAt(int), public native char[] java.lang.String.toCharArray(), public native int java.lang.String.compareTo(java.lang.String), public native java.lang.String java.lang.String.concat(java.lang.String), public native java.lang.String java.lang.String.intern(), public static java.lang.String java.lang.String.copyValueOf(char[]), public static java.lang.String java.lang.String.copyValueOf(char[],int,int), public static java.lang.String java.lang.String.format(java.lang.String,java.lang.Object[]), public static java.lang.String java.lang.String.format(java.util.Locale,java.lang.String,java.lang.Object[]), public static java.lang.String java.lang.String.join(java.lang.CharSequence,java.lang.CharSequence[]), public static java.lang.String java.lang.String.join(java.lang.CharSequence,java.lang.Iterable), public static java.lang.String java.lang.String.valueOf(boolean), public static java.lang.String java.lang.String.valueOf(char), public static java.lang.String java.lang.String.valueOf(char[]), public static java.lang.String java.lang.String.valueOf(char[],int,int), public static java.lang.String java.lang.String.valueOf(double), public static java.lang.String java.lang.String.valueOf(float), public static java.lang.String java.lang.String.valueOf(int), public static java.lang.String java.lang.String.valueOf(java.lang.Object), public static java.lang.String java.lang.String.valueOf(long), public void java.lang.String.getBytes(int,int,byte[],int), public void java.lang.String.getChars(int,int,char[],int), static int java.lang.String.indexOf(byte[],byte,int,java.lang.String,int), static int java.lang.String.lastIndexOf(byte[],byte,int,java.lang.String,int), static int java.lang.String.lastIndexOf(char[],int,int,char[],int,int,int), static java.lang.String java.lang.String.lambda$indent$0(java.lang.String,java.lang.String), static java.lang.String java.lang.String.lambda$indent$1(java.lang.String), static java.lang.String java.lang.String.lambda$indent$2(int,java.lang.String), static java.lang.String java.lang.String.lambda$stripIndent$3(int,java.lang.String), static void java.lang.String.checkBoundsBeginEnd(int,int,int), static void java.lang.String.checkBoundsOffCount(int,int,int), static void java.lang.String.checkIndex(int,int), static void java.lang.String.checkOffset(int,int), void java.lang.String.getBytes(byte[],int,byte), void java.lang.String.getChars(char[],int)]
 []
 [interface java.io.Serializable, interface java.lang.Comparable, interface java.lang.CharSequence]
 0
diff --git a/test/988-method-trace/expected-stdout.txt b/test/988-method-trace/expected-stdout.txt
index 3038651..79ee0d8 100644
--- a/test/988-method-trace/expected-stdout.txt
+++ b/test/988-method-trace/expected-stdout.txt
@@ -113,32 +113,44 @@
 .....<= public int java.lang.String.length() -> <class java.lang.Integer: 14>
 .....=> private void java.lang.AbstractStringBuilder.ensureCapacityInternal(int)
 .....<= private void java.lang.AbstractStringBuilder.ensureCapacityInternal(int) -> <null: null>
-.....=> public void java.lang.String.getChars(int,int,char[],int)
-......=> public int java.lang.String.length()
-......<= public int java.lang.String.length() -> <class java.lang.Integer: 14>
-......=> static void java.lang.String.checkBoundsBeginEnd(int,int,int)
-......<= static void java.lang.String.checkBoundsBeginEnd(int,int,int) -> <null: null>
-......=> native void java.lang.String.getCharsNoCheck(int,int,char[],int)
-......<= native void java.lang.String.getCharsNoCheck(int,int,char[],int) -> <null: null>
-.....<= public void java.lang.String.getChars(int,int,char[],int) -> <null: null>
+.....=> private final void java.lang.AbstractStringBuilder.putStringAt(int,java.lang.String)
+......=> final byte java.lang.AbstractStringBuilder.getCoder()
+......<= final byte java.lang.AbstractStringBuilder.getCoder() -> <class java.lang.Byte: 0>
+......=> byte java.lang.String.coder()
+......<= byte java.lang.String.coder() -> <class java.lang.Byte: 0>
+......=> void java.lang.String.getBytes(byte[],int,byte)
+.......=> byte java.lang.String.coder()
+.......<= byte java.lang.String.coder() -> <class java.lang.Byte: 0>
+.......=> public int java.lang.String.length()
+.......<= public int java.lang.String.length() -> <class java.lang.Integer: 14>
+.......=> public static int java.util.Objects.checkFromIndexSize(int,int,int)
+........=> public static int jdk.internal.util.Preconditions.checkFromIndexSize(int,int,int,java.util.function.BiFunction)
+........<= public static int jdk.internal.util.Preconditions.checkFromIndexSize(int,int,int,java.util.function.BiFunction) -> <class java.lang.Integer: 0>
+.......<= public static int java.util.Objects.checkFromIndexSize(int,int,int) -> <class java.lang.Integer: 0>
+.......=> private void java.lang.String.fillBytesLatin1(byte[],int)
+.......<= private void java.lang.String.fillBytesLatin1(byte[],int) -> <null: null>
+......<= void java.lang.String.getBytes(byte[],int,byte) -> <null: null>
+.....<= private final void java.lang.AbstractStringBuilder.putStringAt(int,java.lang.String) -> <null: null>
 ....<= public java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder.append(java.lang.String) -> <class java.lang.StringBuilder: Bad argument: -19 < 0>
 ...<= public java.lang.StringBuilder java.lang.StringBuilder.append(java.lang.String) -> <class java.lang.StringBuilder: Bad argument: -19 < 0>
 ...=> public java.lang.StringBuilder java.lang.StringBuilder.append(int)
 ....=> public java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder.append(int)
 .....=> static int java.lang.Integer.stringSize(int)
-.....<= static int java.lang.Integer.stringSize(int) -> <class java.lang.Integer: 2>
+.....<= static int java.lang.Integer.stringSize(int) -> <class java.lang.Integer: 3>
 .....=> private void java.lang.AbstractStringBuilder.ensureCapacityInternal(int)
 ......=> private int java.lang.AbstractStringBuilder.newCapacity(int)
 ......<= private int java.lang.AbstractStringBuilder.newCapacity(int) -> <class java.lang.Integer: 34>
-......=> public static char[] java.util.Arrays.copyOf(char[],int)
+......=> public static byte[] java.util.Arrays.copyOf(byte[],int)
 .......=> public static int java.lang.Math.min(int,int)
 .......<= public static int java.lang.Math.min(int,int) -> <class java.lang.Integer: 16>
 .......=> public static void java.lang.System.arraycopy(java.lang.Object,int,java.lang.Object,int,int)
 .......<= public static void java.lang.System.arraycopy(java.lang.Object,int,java.lang.Object,int,int) -> <null: null>
-......<= public static char[] java.util.Arrays.copyOf(char[],int) -> <class [C: [B, a, d,  , a, r, g, u, m, e, n, t, :,  , -, 1, 9,  , <,  , 0, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>]>
+......<= public static byte[] java.util.Arrays.copyOf(byte[],int) -> <class [B: [66, 97, 100, 32, 97, 114, 103, 117, 109, 101, 110, 116, 58, 32, 45, 49, 57, 32, 60, 32, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]>
 .....<= private void java.lang.AbstractStringBuilder.ensureCapacityInternal(int) -> <null: null>
-.....=> static int java.lang.Integer.getChars(int,int,char[])
-.....<= static int java.lang.Integer.getChars(int,int,char[]) -> <class java.lang.Integer: 14>
+.....=> final boolean java.lang.AbstractStringBuilder.isLatin1()
+.....<= final boolean java.lang.AbstractStringBuilder.isLatin1() -> <class java.lang.Boolean: true>
+.....=> static int java.lang.Integer.getChars(int,int,byte[])
+.....<= static int java.lang.Integer.getChars(int,int,byte[]) -> <class java.lang.Integer: 14>
 ....<= public java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder.append(int) -> <class java.lang.StringBuilder: Bad argument: -19 < 0>
 ...<= public java.lang.StringBuilder java.lang.StringBuilder.append(int) -> <class java.lang.StringBuilder: Bad argument: -19 < 0>
 ...=> public java.lang.StringBuilder java.lang.StringBuilder.append(java.lang.String)
@@ -147,21 +159,33 @@
 .....<= public int java.lang.String.length() -> <class java.lang.Integer: 4>
 .....=> private void java.lang.AbstractStringBuilder.ensureCapacityInternal(int)
 .....<= private void java.lang.AbstractStringBuilder.ensureCapacityInternal(int) -> <null: null>
-.....=> public void java.lang.String.getChars(int,int,char[],int)
-......=> public int java.lang.String.length()
-......<= public int java.lang.String.length() -> <class java.lang.Integer: 4>
-......=> static void java.lang.String.checkBoundsBeginEnd(int,int,int)
-......<= static void java.lang.String.checkBoundsBeginEnd(int,int,int) -> <null: null>
-......=> native void java.lang.String.getCharsNoCheck(int,int,char[],int)
-......<= native void java.lang.String.getCharsNoCheck(int,int,char[],int) -> <null: null>
-.....<= public void java.lang.String.getChars(int,int,char[],int) -> <null: null>
+.....=> private final void java.lang.AbstractStringBuilder.putStringAt(int,java.lang.String)
+......=> final byte java.lang.AbstractStringBuilder.getCoder()
+......<= final byte java.lang.AbstractStringBuilder.getCoder() -> <class java.lang.Byte: 0>
+......=> byte java.lang.String.coder()
+......<= byte java.lang.String.coder() -> <class java.lang.Byte: 0>
+......=> void java.lang.String.getBytes(byte[],int,byte)
+.......=> byte java.lang.String.coder()
+.......<= byte java.lang.String.coder() -> <class java.lang.Byte: 0>
+.......=> public int java.lang.String.length()
+.......<= public int java.lang.String.length() -> <class java.lang.Integer: 4>
+.......=> public static int java.util.Objects.checkFromIndexSize(int,int,int)
+........=> public static int jdk.internal.util.Preconditions.checkFromIndexSize(int,int,int,java.util.function.BiFunction)
+........<= public static int jdk.internal.util.Preconditions.checkFromIndexSize(int,int,int,java.util.function.BiFunction) -> <class java.lang.Integer: 17>
+.......<= public static int java.util.Objects.checkFromIndexSize(int,int,int) -> <class java.lang.Integer: 17>
+.......=> private void java.lang.String.fillBytesLatin1(byte[],int)
+.......<= private void java.lang.String.fillBytesLatin1(byte[],int) -> <null: null>
+......<= void java.lang.String.getBytes(byte[],int,byte) -> <null: null>
+.....<= private final void java.lang.AbstractStringBuilder.putStringAt(int,java.lang.String) -> <null: null>
 ....<= public java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder.append(java.lang.String) -> <class java.lang.StringBuilder: Bad argument: -19 < 0>
 ...<= public java.lang.StringBuilder java.lang.StringBuilder.append(java.lang.String) -> <class java.lang.StringBuilder: Bad argument: -19 < 0>
 ...=> public java.lang.String java.lang.StringBuilder.toString()
-....=> public static java.lang.String java.lang.StringFactory.newStringFromChars(char[],int,int)
-.....=> static java.lang.String java.lang.StringFactory.newStringFromChars(int,int,char[])
-.....<= static java.lang.String java.lang.StringFactory.newStringFromChars(int,int,char[]) -> <class java.lang.String: Bad argument: -19 < 0>
-....<= public static java.lang.String java.lang.StringFactory.newStringFromChars(char[],int,int) -> <class java.lang.String: Bad argument: -19 < 0>
+....=> final boolean java.lang.AbstractStringBuilder.isLatin1()
+....<= final boolean java.lang.AbstractStringBuilder.isLatin1() -> <class java.lang.Boolean: true>
+....=> public static java.lang.String java.lang.StringLatin1.newString(byte[],int,int)
+.....=> public static java.lang.String java.lang.StringFactory.newStringFromBytes(byte[],int,int,int)
+.....<= public static java.lang.String java.lang.StringFactory.newStringFromBytes(byte[],int,int,int) -> <class java.lang.String: Bad argument: -19 < 0>
+....<= public static java.lang.String java.lang.StringLatin1.newString(byte[],int,int) -> <class java.lang.String: Bad argument: -19 < 0>
 ...<= public java.lang.String java.lang.StringBuilder.toString() -> <class java.lang.String: Bad argument: -19 < 0>
 ...=> public java.lang.Error(java.lang.String)
 ....=> public java.lang.Throwable(java.lang.String)
@@ -221,32 +245,44 @@
 .....<= public int java.lang.String.length() -> <class java.lang.Integer: 14>
 .....=> private void java.lang.AbstractStringBuilder.ensureCapacityInternal(int)
 .....<= private void java.lang.AbstractStringBuilder.ensureCapacityInternal(int) -> <null: null>
-.....=> public void java.lang.String.getChars(int,int,char[],int)
-......=> public int java.lang.String.length()
-......<= public int java.lang.String.length() -> <class java.lang.Integer: 14>
-......=> static void java.lang.String.checkBoundsBeginEnd(int,int,int)
-......<= static void java.lang.String.checkBoundsBeginEnd(int,int,int) -> <null: null>
-......=> native void java.lang.String.getCharsNoCheck(int,int,char[],int)
-......<= native void java.lang.String.getCharsNoCheck(int,int,char[],int) -> <null: null>
-.....<= public void java.lang.String.getChars(int,int,char[],int) -> <null: null>
+.....=> private final void java.lang.AbstractStringBuilder.putStringAt(int,java.lang.String)
+......=> final byte java.lang.AbstractStringBuilder.getCoder()
+......<= final byte java.lang.AbstractStringBuilder.getCoder() -> <class java.lang.Byte: 0>
+......=> byte java.lang.String.coder()
+......<= byte java.lang.String.coder() -> <class java.lang.Byte: 0>
+......=> void java.lang.String.getBytes(byte[],int,byte)
+.......=> byte java.lang.String.coder()
+.......<= byte java.lang.String.coder() -> <class java.lang.Byte: 0>
+.......=> public int java.lang.String.length()
+.......<= public int java.lang.String.length() -> <class java.lang.Integer: 14>
+.......=> public static int java.util.Objects.checkFromIndexSize(int,int,int)
+........=> public static int jdk.internal.util.Preconditions.checkFromIndexSize(int,int,int,java.util.function.BiFunction)
+........<= public static int jdk.internal.util.Preconditions.checkFromIndexSize(int,int,int,java.util.function.BiFunction) -> <class java.lang.Integer: 0>
+.......<= public static int java.util.Objects.checkFromIndexSize(int,int,int) -> <class java.lang.Integer: 0>
+.......=> private void java.lang.String.fillBytesLatin1(byte[],int)
+.......<= private void java.lang.String.fillBytesLatin1(byte[],int) -> <null: null>
+......<= void java.lang.String.getBytes(byte[],int,byte) -> <null: null>
+.....<= private final void java.lang.AbstractStringBuilder.putStringAt(int,java.lang.String) -> <null: null>
 ....<= public java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder.append(java.lang.String) -> <class java.lang.StringBuilder: Bad argument: -19 < 0>
 ...<= public java.lang.StringBuilder java.lang.StringBuilder.append(java.lang.String) -> <class java.lang.StringBuilder: Bad argument: -19 < 0>
 ...=> public java.lang.StringBuilder java.lang.StringBuilder.append(int)
 ....=> public java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder.append(int)
 .....=> static int java.lang.Integer.stringSize(int)
-.....<= static int java.lang.Integer.stringSize(int) -> <class java.lang.Integer: 2>
+.....<= static int java.lang.Integer.stringSize(int) -> <class java.lang.Integer: 3>
 .....=> private void java.lang.AbstractStringBuilder.ensureCapacityInternal(int)
 ......=> private int java.lang.AbstractStringBuilder.newCapacity(int)
 ......<= private int java.lang.AbstractStringBuilder.newCapacity(int) -> <class java.lang.Integer: 34>
-......=> public static char[] java.util.Arrays.copyOf(char[],int)
+......=> public static byte[] java.util.Arrays.copyOf(byte[],int)
 .......=> public static int java.lang.Math.min(int,int)
 .......<= public static int java.lang.Math.min(int,int) -> <class java.lang.Integer: 16>
 .......=> public static void java.lang.System.arraycopy(java.lang.Object,int,java.lang.Object,int,int)
 .......<= public static void java.lang.System.arraycopy(java.lang.Object,int,java.lang.Object,int,int) -> <null: null>
-......<= public static char[] java.util.Arrays.copyOf(char[],int) -> <class [C: [B, a, d,  , a, r, g, u, m, e, n, t, :,  , -, 1, 9,  , <,  , 0, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>, <control-0000>]>
+......<= public static byte[] java.util.Arrays.copyOf(byte[],int) -> <class [B: [66, 97, 100, 32, 97, 114, 103, 117, 109, 101, 110, 116, 58, 32, 45, 49, 57, 32, 60, 32, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]>
 .....<= private void java.lang.AbstractStringBuilder.ensureCapacityInternal(int) -> <null: null>
-.....=> static int java.lang.Integer.getChars(int,int,char[])
-.....<= static int java.lang.Integer.getChars(int,int,char[]) -> <class java.lang.Integer: 14>
+.....=> final boolean java.lang.AbstractStringBuilder.isLatin1()
+.....<= final boolean java.lang.AbstractStringBuilder.isLatin1() -> <class java.lang.Boolean: true>
+.....=> static int java.lang.Integer.getChars(int,int,byte[])
+.....<= static int java.lang.Integer.getChars(int,int,byte[]) -> <class java.lang.Integer: 14>
 ....<= public java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder.append(int) -> <class java.lang.StringBuilder: Bad argument: -19 < 0>
 ...<= public java.lang.StringBuilder java.lang.StringBuilder.append(int) -> <class java.lang.StringBuilder: Bad argument: -19 < 0>
 ...=> public java.lang.StringBuilder java.lang.StringBuilder.append(java.lang.String)
@@ -255,21 +291,33 @@
 .....<= public int java.lang.String.length() -> <class java.lang.Integer: 4>
 .....=> private void java.lang.AbstractStringBuilder.ensureCapacityInternal(int)
 .....<= private void java.lang.AbstractStringBuilder.ensureCapacityInternal(int) -> <null: null>
-.....=> public void java.lang.String.getChars(int,int,char[],int)
-......=> public int java.lang.String.length()
-......<= public int java.lang.String.length() -> <class java.lang.Integer: 4>
-......=> static void java.lang.String.checkBoundsBeginEnd(int,int,int)
-......<= static void java.lang.String.checkBoundsBeginEnd(int,int,int) -> <null: null>
-......=> native void java.lang.String.getCharsNoCheck(int,int,char[],int)
-......<= native void java.lang.String.getCharsNoCheck(int,int,char[],int) -> <null: null>
-.....<= public void java.lang.String.getChars(int,int,char[],int) -> <null: null>
+.....=> private final void java.lang.AbstractStringBuilder.putStringAt(int,java.lang.String)
+......=> final byte java.lang.AbstractStringBuilder.getCoder()
+......<= final byte java.lang.AbstractStringBuilder.getCoder() -> <class java.lang.Byte: 0>
+......=> byte java.lang.String.coder()
+......<= byte java.lang.String.coder() -> <class java.lang.Byte: 0>
+......=> void java.lang.String.getBytes(byte[],int,byte)
+.......=> byte java.lang.String.coder()
+.......<= byte java.lang.String.coder() -> <class java.lang.Byte: 0>
+.......=> public int java.lang.String.length()
+.......<= public int java.lang.String.length() -> <class java.lang.Integer: 4>
+.......=> public static int java.util.Objects.checkFromIndexSize(int,int,int)
+........=> public static int jdk.internal.util.Preconditions.checkFromIndexSize(int,int,int,java.util.function.BiFunction)
+........<= public static int jdk.internal.util.Preconditions.checkFromIndexSize(int,int,int,java.util.function.BiFunction) -> <class java.lang.Integer: 17>
+.......<= public static int java.util.Objects.checkFromIndexSize(int,int,int) -> <class java.lang.Integer: 17>
+.......=> private void java.lang.String.fillBytesLatin1(byte[],int)
+.......<= private void java.lang.String.fillBytesLatin1(byte[],int) -> <null: null>
+......<= void java.lang.String.getBytes(byte[],int,byte) -> <null: null>
+.....<= private final void java.lang.AbstractStringBuilder.putStringAt(int,java.lang.String) -> <null: null>
 ....<= public java.lang.AbstractStringBuilder java.lang.AbstractStringBuilder.append(java.lang.String) -> <class java.lang.StringBuilder: Bad argument: -19 < 0>
 ...<= public java.lang.StringBuilder java.lang.StringBuilder.append(java.lang.String) -> <class java.lang.StringBuilder: Bad argument: -19 < 0>
 ...=> public java.lang.String java.lang.StringBuilder.toString()
-....=> public static java.lang.String java.lang.StringFactory.newStringFromChars(char[],int,int)
-.....=> static java.lang.String java.lang.StringFactory.newStringFromChars(int,int,char[])
-.....<= static java.lang.String java.lang.StringFactory.newStringFromChars(int,int,char[]) -> <class java.lang.String: Bad argument: -19 < 0>
-....<= public static java.lang.String java.lang.StringFactory.newStringFromChars(char[],int,int) -> <class java.lang.String: Bad argument: -19 < 0>
+....=> final boolean java.lang.AbstractStringBuilder.isLatin1()
+....<= final boolean java.lang.AbstractStringBuilder.isLatin1() -> <class java.lang.Boolean: true>
+....=> public static java.lang.String java.lang.StringLatin1.newString(byte[],int,int)
+.....=> public static java.lang.String java.lang.StringFactory.newStringFromBytes(byte[],int,int,int)
+.....<= public static java.lang.String java.lang.StringFactory.newStringFromBytes(byte[],int,int,int) -> <class java.lang.String: Bad argument: -19 < 0>
+....<= public static java.lang.String java.lang.StringLatin1.newString(byte[],int,int) -> <class java.lang.String: Bad argument: -19 < 0>
 ...<= public java.lang.String java.lang.StringBuilder.toString() -> <class java.lang.String: Bad argument: -19 < 0>
 ...=> public java.lang.Error(java.lang.String)
 ....=> public java.lang.Throwable(java.lang.String)