Cleanup String.<init> handling.

Move everything to one place (currently well_known_classes.cc, but
no strong preference) and define a macro to easily handle the list
of affected methods.

test: m test-art-host
test: m test-art-target
Change-Id: Ib8372d130d5458516a1f1ae31014afc76037fc34
diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc
index 8d53dbf..6750554 100644
--- a/compiler/dex/quick/dex_file_method_inliner.cc
+++ b/compiler/dex/quick/dex_file_method_inliner.cc
@@ -640,28 +640,6 @@
     INTRINSIC(JavaLangLong, RotateLeft, JI_J, kIntrinsicRotateLeft, k64),
 
 #undef INTRINSIC
-
-#define SPECIAL(c, n, p, o, d) \
-    { { kClassCache ## c, kNameCache ## n, kProtoCache ## p }, { o, kInlineSpecial, { d } } }
-
-    SPECIAL(JavaLangString, Init, _V, kInlineStringInit, 0),
-    SPECIAL(JavaLangString, Init, ByteArray_V, kInlineStringInit, 1),
-    SPECIAL(JavaLangString, Init, ByteArrayI_V, kInlineStringInit, 2),
-    SPECIAL(JavaLangString, Init, ByteArrayII_V, kInlineStringInit, 3),
-    SPECIAL(JavaLangString, Init, ByteArrayIII_V, kInlineStringInit, 4),
-    SPECIAL(JavaLangString, Init, ByteArrayIIString_V, kInlineStringInit, 5),
-    SPECIAL(JavaLangString, Init, ByteArrayString_V, kInlineStringInit, 6),
-    SPECIAL(JavaLangString, Init, ByteArrayIICharset_V, kInlineStringInit, 7),
-    SPECIAL(JavaLangString, Init, ByteArrayCharset_V, kInlineStringInit, 8),
-    SPECIAL(JavaLangString, Init, CharArray_V, kInlineStringInit, 9),
-    SPECIAL(JavaLangString, Init, CharArrayII_V, kInlineStringInit, 10),
-    SPECIAL(JavaLangString, Init, IICharArray_V, kInlineStringInit, 11),
-    SPECIAL(JavaLangString, Init, IntArrayII_V, kInlineStringInit, 12),
-    SPECIAL(JavaLangString, Init, String_V, kInlineStringInit, 13),
-    SPECIAL(JavaLangString, Init, StringBuffer_V, kInlineStringInit, 14),
-    SPECIAL(JavaLangString, Init, StringBuilder_V, kInlineStringInit, 15),
-
-#undef SPECIAL
 };
 
 DexFileMethodInliner::DexFileMethodInliner()
@@ -843,22 +821,4 @@
   }
 }
 
-uint32_t DexFileMethodInliner::GetOffsetForStringInit(uint32_t method_index,
-                                                      PointerSize pointer_size) {
-  ReaderMutexLock mu(Thread::Current(), lock_);
-  auto it = inline_methods_.find(method_index);
-  if (it != inline_methods_.end() && (it->second.opcode == kInlineStringInit)) {
-    uint32_t string_init_base_offset = Thread::QuickEntryPointOffsetWithSize(
-              OFFSETOF_MEMBER(QuickEntryPoints, pNewEmptyString), pointer_size);
-    return string_init_base_offset + it->second.d.data * static_cast<size_t>(pointer_size);
-  }
-  return 0;
-}
-
-bool DexFileMethodInliner::IsStringInitMethodIndex(uint32_t method_index) {
-  ReaderMutexLock mu(Thread::Current(), lock_);
-  auto it = inline_methods_.find(method_index);
-  return (it != inline_methods_.end()) && (it->second.opcode == kInlineStringInit);
-}
-
 }  // namespace art
diff --git a/compiler/dex/quick/dex_file_method_inliner.h b/compiler/dex/quick/dex_file_method_inliner.h
index 43fc687..f4ae5a5 100644
--- a/compiler/dex/quick/dex_file_method_inliner.h
+++ b/compiler/dex/quick/dex_file_method_inliner.h
@@ -82,17 +82,6 @@
     bool IsSpecial(uint32_t method_index) REQUIRES(!lock_);
 
     /**
-     * Gets the thread pointer entrypoint offset for a string init method index and pointer size.
-     */
-    uint32_t GetOffsetForStringInit(uint32_t method_index, PointerSize pointer_size)
-        REQUIRES(!lock_);
-
-    /**
-     * Check whether a particular method index is a string init.
-     */
-    bool IsStringInitMethodIndex(uint32_t method_index) REQUIRES(!lock_);
-
-    /**
      * To avoid multiple lookups of a class by its descriptor, we cache its
      * type index in the IndexCache. These are the indexes into the IndexCache
      * class_indexes array.
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index adbf9fd..79828d8 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -2789,18 +2789,6 @@
   return oss.str();
 }
 
-bool CompilerDriver::IsStringTypeIndex(uint16_t type_index, const DexFile* dex_file) {
-  const char* type = dex_file->GetTypeDescriptor(dex_file->GetTypeId(type_index));
-  return strcmp(type, "Ljava/lang/String;") == 0;
-}
-
-bool CompilerDriver::IsStringInit(uint32_t method_index, const DexFile* dex_file, int32_t* offset) {
-  DexFileMethodInliner* inliner = GetMethodInlinerMap()->GetMethodInliner(dex_file);
-  const PointerSize pointer_size = InstructionSetPointerSize(GetInstructionSet());
-  *offset = inliner->GetOffsetForStringInit(method_index, pointer_size);
-  return inliner->IsStringInitMethodIndex(method_index);
-}
-
 bool CompilerDriver::MayInlineInternal(const DexFile* inlined_from,
                                        const DexFile* inlined_into) const {
   // We're not allowed to inline across dex files if we're the no-inline-from dex file.
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 1f4c3ac..41f0d36 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -432,9 +432,6 @@
   // Get memory usage during compilation.
   std::string GetMemoryUsageString(bool extended) const;
 
-  bool IsStringTypeIndex(uint16_t type_index, const DexFile* dex_file);
-  bool IsStringInit(uint32_t method_index, const DexFile* dex_file, int32_t* offset);
-
   void SetHadHardVerifierFailure() {
     had_hard_verifier_failure_ = true;
   }
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 6be458c..55e1221 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -6748,10 +6748,13 @@
 
   Location callee_method = temp;  // For all kinds except kRecursive, callee will be in temp.
   switch (invoke->GetMethodLoadKind()) {
-    case HInvokeStaticOrDirect::MethodLoadKind::kStringInit:
+    case HInvokeStaticOrDirect::MethodLoadKind::kStringInit: {
+      uint32_t offset =
+          GetThreadOffset<kArmPointerSize>(invoke->GetStringInitEntryPoint()).Int32Value();
       // temp = thread->string_init_entrypoint
-      __ LoadFromOffset(kLoadWord, temp.AsRegister<Register>(), TR, invoke->GetStringInitOffset());
+      __ LoadFromOffset(kLoadWord, temp.AsRegister<Register>(), TR, offset);
       break;
+    }
     case HInvokeStaticOrDirect::MethodLoadKind::kRecursive:
       callee_method = invoke->GetLocations()->InAt(invoke->GetSpecialInputIndex());
       break;
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index 7160607..a2a2e42 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -3570,10 +3570,13 @@
   // Make sure that ArtMethod* is passed in kArtMethodRegister as per the calling convention.
   Location callee_method = temp;  // For all kinds except kRecursive, callee will be in temp.
   switch (invoke->GetMethodLoadKind()) {
-    case HInvokeStaticOrDirect::MethodLoadKind::kStringInit:
+    case HInvokeStaticOrDirect::MethodLoadKind::kStringInit: {
+      uint32_t offset =
+          GetThreadOffset<kArm64PointerSize>(invoke->GetStringInitEntryPoint()).Int32Value();
       // temp = thread->string_init_entrypoint
-      __ Ldr(XRegisterFrom(temp), MemOperand(tr, invoke->GetStringInitOffset()));
+      __ Ldr(XRegisterFrom(temp), MemOperand(tr, offset));
       break;
+    }
     case HInvokeStaticOrDirect::MethodLoadKind::kRecursive:
       callee_method = invoke->GetLocations()->InAt(invoke->GetSpecialInputIndex());
       break;
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index f560207..5c0ca85 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -4396,13 +4396,16 @@
   }
 
   switch (method_load_kind) {
-    case HInvokeStaticOrDirect::MethodLoadKind::kStringInit:
+    case HInvokeStaticOrDirect::MethodLoadKind::kStringInit: {
       // temp = thread->string_init_entrypoint
+      uint32_t offset =
+          GetThreadOffset<kMipsPointerSize>(invoke->GetStringInitEntryPoint()).Int32Value();
       __ LoadFromOffset(kLoadWord,
                         temp.AsRegister<Register>(),
                         TR,
-                        invoke->GetStringInitOffset());
+                        offset);
       break;
+    }
     case HInvokeStaticOrDirect::MethodLoadKind::kRecursive:
       callee_method = invoke->GetLocations()->InAt(invoke->GetSpecialInputIndex());
       break;
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc
index a5e2351..02576bd 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -3006,13 +3006,16 @@
 
   Location callee_method = temp;  // For all kinds except kRecursive, callee will be in temp.
   switch (invoke->GetMethodLoadKind()) {
-    case HInvokeStaticOrDirect::MethodLoadKind::kStringInit:
+    case HInvokeStaticOrDirect::MethodLoadKind::kStringInit: {
       // temp = thread->string_init_entrypoint
+      uint32_t offset =
+          GetThreadOffset<kMips64PointerSize>(invoke->GetStringInitEntryPoint()).Int32Value();
       __ LoadFromOffset(kLoadDoubleword,
                         temp.AsRegister<GpuRegister>(),
                         TR,
-                        invoke->GetStringInitOffset());
+                        offset);
       break;
+    }
     case HInvokeStaticOrDirect::MethodLoadKind::kRecursive:
       callee_method = invoke->GetLocations()->InAt(invoke->GetSpecialInputIndex());
       break;
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 47dfb2e..c300080 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -4276,10 +4276,13 @@
                                                                   Location temp) {
   Location callee_method = temp;  // For all kinds except kRecursive, callee will be in temp.
   switch (invoke->GetMethodLoadKind()) {
-    case HInvokeStaticOrDirect::MethodLoadKind::kStringInit:
+    case HInvokeStaticOrDirect::MethodLoadKind::kStringInit: {
       // temp = thread->string_init_entrypoint
-      __ fs()->movl(temp.AsRegister<Register>(), Address::Absolute(invoke->GetStringInitOffset()));
+      uint32_t offset =
+          GetThreadOffset<kX86PointerSize>(invoke->GetStringInitEntryPoint()).Int32Value();
+      __ fs()->movl(temp.AsRegister<Register>(), Address::Absolute(offset));
       break;
+    }
     case HInvokeStaticOrDirect::MethodLoadKind::kRecursive:
       callee_method = invoke->GetLocations()->InAt(invoke->GetSpecialInputIndex());
       break;
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 59c0ca4..f9a3e42 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -754,11 +754,13 @@
   // All registers are assumed to be correctly set up.
   Location callee_method = temp;  // For all kinds except kRecursive, callee will be in temp.
   switch (invoke->GetMethodLoadKind()) {
-    case HInvokeStaticOrDirect::MethodLoadKind::kStringInit:
+    case HInvokeStaticOrDirect::MethodLoadKind::kStringInit: {
       // temp = thread->string_init_entrypoint
-      __ gs()->movq(temp.AsRegister<CpuRegister>(),
-                    Address::Absolute(invoke->GetStringInitOffset(), /* no_rip */ true));
+      uint32_t offset =
+          GetThreadOffset<kX86_64PointerSize>(invoke->GetStringInitEntryPoint()).Int32Value();
+      __ gs()->movq(temp.AsRegister<CpuRegister>(), Address::Absolute(offset, /* no_rip */ true));
       break;
+    }
     case HInvokeStaticOrDirect::MethodLoadKind::kRecursive:
       callee_method = invoke->GetLocations()->InAt(invoke->GetSpecialInputIndex());
       break;
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index 5a6a212..62c6051 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -767,6 +767,11 @@
   return resolved_method;
 }
 
+static bool IsStringConstructor(ArtMethod* method) {
+  ScopedObjectAccess soa(Thread::Current());
+  return method->GetDeclaringClass()->IsStringClass() && method->IsConstructor();
+}
+
 bool HInstructionBuilder::BuildInvoke(const Instruction& instruction,
                                       uint32_t dex_pc,
                                       uint32_t method_idx,
@@ -785,39 +790,6 @@
     number_of_arguments++;
   }
 
-  // Special handling for string init.
-  int32_t string_init_offset = 0;
-  bool is_string_init = compiler_driver_->IsStringInit(method_idx,
-                                                       dex_file_,
-                                                       &string_init_offset);
-  // Replace calls to String.<init> with StringFactory.
-  if (is_string_init) {
-    HInvokeStaticOrDirect::DispatchInfo dispatch_info = {
-        HInvokeStaticOrDirect::MethodLoadKind::kStringInit,
-        HInvokeStaticOrDirect::CodePtrLocation::kCallArtMethod,
-        dchecked_integral_cast<uint64_t>(string_init_offset),
-        0U
-    };
-    MethodReference target_method(dex_file_, method_idx);
-    HInvoke* invoke = new (arena_) HInvokeStaticOrDirect(
-        arena_,
-        number_of_arguments - 1,
-        Primitive::kPrimNot /*return_type */,
-        dex_pc,
-        method_idx,
-        nullptr,
-        dispatch_info,
-        invoke_type,
-        target_method,
-        HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit);
-    return HandleStringInit(invoke,
-                            number_of_vreg_arguments,
-                            args,
-                            register_index,
-                            is_range,
-                            descriptor);
-  }
-
   ArtMethod* resolved_method = ResolveMethod(method_idx, invoke_type);
 
   if (UNLIKELY(resolved_method == nullptr)) {
@@ -838,6 +810,35 @@
                         true /* is_unresolved */);
   }
 
+  // Replace calls to String.<init> with StringFactory.
+  if (IsStringConstructor(resolved_method)) {
+    uint32_t string_init_entry_point = WellKnownClasses::StringInitToEntryPoint(resolved_method);
+    HInvokeStaticOrDirect::DispatchInfo dispatch_info = {
+        HInvokeStaticOrDirect::MethodLoadKind::kStringInit,
+        HInvokeStaticOrDirect::CodePtrLocation::kCallArtMethod,
+        dchecked_integral_cast<uint64_t>(string_init_entry_point),
+        0U
+    };
+    MethodReference target_method(dex_file_, method_idx);
+    HInvoke* invoke = new (arena_) HInvokeStaticOrDirect(
+        arena_,
+        number_of_arguments - 1,
+        Primitive::kPrimNot /*return_type */,
+        dex_pc,
+        method_idx,
+        nullptr,
+        dispatch_info,
+        invoke_type,
+        target_method,
+        HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit);
+    return HandleStringInit(invoke,
+                            number_of_vreg_arguments,
+                            args,
+                            register_index,
+                            is_range,
+                            descriptor);
+  }
+
   // Potential class initialization check, in the case of a static method call.
   HClinitCheck* clinit_check = nullptr;
   HInvoke* invoke = nullptr;
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 57ae555..4dc4c20 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -4044,9 +4044,9 @@
   }
   bool HasDirectCodePtr() const { return GetCodePtrLocation() == CodePtrLocation::kCallDirect; }
 
-  int32_t GetStringInitOffset() const {
+  QuickEntrypointEnum GetStringInitEntryPoint() const {
     DCHECK(IsStringInit());
-    return dispatch_info_.method_load_data;
+    return static_cast<QuickEntrypointEnum>(dispatch_info_.method_load_data);
   }
 
   uint64_t GetMethodAddress() const {
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 77c3f0f..5934f13 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -576,9 +576,7 @@
   // Replace calls to String.<init> with equivalent StringFactory call.
   if (UNLIKELY(called_method->GetDeclaringClass()->IsStringClass()
                && called_method->IsConstructor())) {
-    ScopedObjectAccessUnchecked soa(self);
-    jmethodID mid = soa.EncodeMethod(called_method);
-    called_method = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid));
+    called_method = WellKnownClasses::StringInitToStringFactory(called_method);
     string_init = true;
   }
 
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index d9cb1c6..8b904da 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -618,7 +618,8 @@
     }
     if (c->IsStringClass()) {
       // Replace calls to String.<init> with equivalent StringFactory call.
-      jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
+      jmethodID sf_mid = soa.EncodeMethod(
+          WellKnownClasses::StringInitToStringFactory(soa.DecodeMethod(mid)));
       return CallStaticObjectMethodV(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
     }
     mirror::Object* result = c->AllocObject(soa.Self());
@@ -643,7 +644,8 @@
     }
     if (c->IsStringClass()) {
       // Replace calls to String.<init> with equivalent StringFactory call.
-      jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
+      jmethodID sf_mid = soa.EncodeMethod(
+          WellKnownClasses::StringInitToStringFactory(soa.DecodeMethod(mid)));
       return CallStaticObjectMethodA(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
     }
     mirror::Object* result = c->AllocObject(soa.Self());
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index c69e98c..30b10d8 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -455,7 +455,7 @@
   bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor();
   if (is_string_init) {
     // Replace calls to String.<init> with equivalent StringFactory call.
-    method = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid));
+    method = WellKnownClasses::StringInitToStringFactory(method);
   }
   mirror::Object* receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object*>(obj);
   uint32_t shorty_len = 0;
@@ -486,7 +486,7 @@
   bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor();
   if (is_string_init) {
     // Replace calls to String.<init> with equivalent StringFactory call.
-    method = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid));
+    method = WellKnownClasses::StringInitToStringFactory(method);
   }
   mirror::Object* receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object*>(obj);
   uint32_t shorty_len = 0;
@@ -518,7 +518,7 @@
   bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor();
   if (is_string_init) {
     // Replace calls to String.<init> with equivalent StringFactory call.
-    method = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid));
+    method = WellKnownClasses::StringInitToStringFactory(method);
     receiver = nullptr;
   }
   uint32_t shorty_len = 0;
@@ -550,7 +550,7 @@
   bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor();
   if (is_string_init) {
     // Replace calls to String.<init> with equivalent StringFactory call.
-    method = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid));
+    method = WellKnownClasses::StringInitToStringFactory(method);
     receiver = nullptr;
   }
   uint32_t shorty_len = 0;
@@ -596,8 +596,7 @@
   if (!m->IsStatic()) {
     // Replace calls to String.<init> with equivalent StringFactory call.
     if (declaring_class->IsStringClass() && m->IsConstructor()) {
-      jmethodID mid = soa.EncodeMethod(m);
-      m = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid));
+      m = WellKnownClasses::StringInitToStringFactory(m);
       CHECK(javaReceiver == nullptr);
     } else {
       // Check that the receiver is non-null and an instance of the field's declaring class.
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 8940354..6b0611f 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -127,43 +127,6 @@
   InitEntryPoints(&tlsPtr_.jni_entrypoints, &tlsPtr_.quick_entrypoints);
 }
 
-void Thread::InitStringEntryPoints() {
-  ScopedObjectAccess soa(this);
-  QuickEntryPoints* qpoints = &tlsPtr_.quick_entrypoints;
-  qpoints->pNewEmptyString = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newEmptyString));
-  qpoints->pNewStringFromBytes_B = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_B));
-  qpoints->pNewStringFromBytes_BI = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BI));
-  qpoints->pNewStringFromBytes_BII = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BII));
-  qpoints->pNewStringFromBytes_BIII = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BIII));
-  qpoints->pNewStringFromBytes_BIIString = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BIIString));
-  qpoints->pNewStringFromBytes_BString = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BString));
-  qpoints->pNewStringFromBytes_BIICharset = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BIICharset));
-  qpoints->pNewStringFromBytes_BCharset = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BCharset));
-  qpoints->pNewStringFromChars_C = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromChars_C));
-  qpoints->pNewStringFromChars_CII = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromChars_CII));
-  qpoints->pNewStringFromChars_IIC = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromChars_IIC));
-  qpoints->pNewStringFromCodePoints = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromCodePoints));
-  qpoints->pNewStringFromString = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromString));
-  qpoints->pNewStringFromStringBuffer = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromStringBuffer));
-  qpoints->pNewStringFromStringBuilder = reinterpret_cast<void(*)()>(
-      soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromStringBuilder));
-}
-
 void Thread::ResetQuickAllocEntryPointsForThread() {
   ResetQuickAllocEntryPoints(&tlsPtr_.quick_entrypoints);
 }
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 16c7f77..1982199 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -21,6 +21,7 @@
 #include <sstream>
 
 #include "base/logging.h"
+#include "entrypoints/quick/quick_entrypoints_enum.h"
 #include "mirror/class.h"
 #include "mirror/throwable.h"
 #include "ScopedLocalRef.h"
@@ -89,38 +90,6 @@
 jmethodID WellKnownClasses::java_lang_reflect_Proxy_invoke;
 jmethodID WellKnownClasses::java_lang_Runtime_nativeLoad;
 jmethodID WellKnownClasses::java_lang_Short_valueOf;
-jmethodID WellKnownClasses::java_lang_String_init;
-jmethodID WellKnownClasses::java_lang_String_init_B;
-jmethodID WellKnownClasses::java_lang_String_init_BI;
-jmethodID WellKnownClasses::java_lang_String_init_BII;
-jmethodID WellKnownClasses::java_lang_String_init_BIII;
-jmethodID WellKnownClasses::java_lang_String_init_BIIString;
-jmethodID WellKnownClasses::java_lang_String_init_BString;
-jmethodID WellKnownClasses::java_lang_String_init_BIICharset;
-jmethodID WellKnownClasses::java_lang_String_init_BCharset;
-jmethodID WellKnownClasses::java_lang_String_init_C;
-jmethodID WellKnownClasses::java_lang_String_init_CII;
-jmethodID WellKnownClasses::java_lang_String_init_IIC;
-jmethodID WellKnownClasses::java_lang_String_init_String;
-jmethodID WellKnownClasses::java_lang_String_init_StringBuffer;
-jmethodID WellKnownClasses::java_lang_String_init_III;
-jmethodID WellKnownClasses::java_lang_String_init_StringBuilder;
-jmethodID WellKnownClasses::java_lang_StringFactory_newEmptyString;
-jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromBytes_B;
-jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BI;
-jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BII;
-jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BIII;
-jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BIIString;
-jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BString;
-jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BIICharset;
-jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BCharset;
-jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromChars_C;
-jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromChars_CII;
-jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromChars_IIC;
-jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromString;
-jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromStringBuffer;
-jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromCodePoints;
-jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromStringBuilder;
 jmethodID WellKnownClasses::java_lang_System_runFinalization = nullptr;
 jmethodID WellKnownClasses::java_lang_Thread_dispatchUncaughtException;
 jmethodID WellKnownClasses::java_lang_Thread_init;
@@ -215,6 +184,76 @@
                      StringPrintf("(%c)L%s;", prim_name, boxed_name).c_str());
 }
 
+#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_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) \
+  V(java_lang_String_init_BIIString, "([BIILjava/lang/String;)V", newStringFromBytes_BIIString, "newStringFromBytes", "([BIILjava/lang/String;)Ljava/lang/String;", NewStringFromBytes_BIIString) \
+  V(java_lang_String_init_BString, "([BLjava/lang/String;)V", newStringFromBytes_BString, "newStringFromBytes", "([BLjava/lang/String;)Ljava/lang/String;", NewStringFromBytes_BString) \
+  V(java_lang_String_init_BIICharset, "([BIILjava/nio/charset/Charset;)V", newStringFromBytes_BIICharset, "newStringFromBytes", "([BIILjava/nio/charset/Charset;)Ljava/lang/String;", NewStringFromBytes_BIICharset) \
+  V(java_lang_String_init_BCharset, "([BLjava/nio/charset/Charset;)V", newStringFromBytes_BCharset, "newStringFromBytes", "([BLjava/nio/charset/Charset;)Ljava/lang/String;", NewStringFromBytes_BCharset) \
+  V(java_lang_String_init_C, "([C)V", newStringFromChars_C, "newStringFromChars", "([C)Ljava/lang/String;", NewStringFromChars_C) \
+  V(java_lang_String_init_CII, "([CII)V", newStringFromChars_CII, "newStringFromChars", "([CII)Ljava/lang/String;", NewStringFromChars_CII) \
+  V(java_lang_String_init_IIC, "(II[C)V", newStringFromChars_IIC, "newStringFromChars", "(II[C)Ljava/lang/String;", NewStringFromChars_IIC) \
+  V(java_lang_String_init_String, "(Ljava/lang/String;)V", newStringFromString, "newStringFromString", "(Ljava/lang/String;)Ljava/lang/String;", NewStringFromString) \
+  V(java_lang_String_init_StringBuffer, "(Ljava/lang/StringBuffer;)V", newStringFromStringBuffer, "newStringFromStringBuffer", "(Ljava/lang/StringBuffer;)Ljava/lang/String;", NewStringFromStringBuffer) \
+  V(java_lang_String_init_III, "([III)V", newStringFromCodePoints, "newStringFromCodePoints", "([III)Ljava/lang/String;", NewStringFromCodePoints) \
+  V(java_lang_String_init_StringBuilder, "(Ljava/lang/StringBuilder;)V", newStringFromStringBuilder, "newStringFromStringBuilder", "(Ljava/lang/StringBuilder;)Ljava/lang/String;", NewStringFromStringBuilder) \
+
+#define STATIC_STRING_INIT(init_runtime_name, init_signature, new_runtime_name, ...) \
+    static ArtMethod* init_runtime_name; \
+    static ArtMethod* new_runtime_name;
+    STRING_INIT_LIST(STATIC_STRING_INIT)
+#undef STATIC_STRING_INIT
+
+void WellKnownClasses::InitStringInit(JNIEnv* env) {
+  ScopedObjectAccess soa(Thread::Current());
+  #define LOAD_STRING_INIT(init_runtime_name, init_signature, new_runtime_name,             \
+                           new_java_name, new_signature, ...)                               \
+      init_runtime_name = soa.DecodeMethod(                                                 \
+          CacheMethod(env, java_lang_String, false, "<init>", init_signature));             \
+      new_runtime_name = soa.DecodeMethod(                                                  \
+          CacheMethod(env, java_lang_StringFactory, true, new_java_name, new_signature));
+      STRING_INIT_LIST(LOAD_STRING_INIT)
+  #undef LOAD_STRING_INIT
+}
+
+void Thread::InitStringEntryPoints() {
+  QuickEntryPoints* qpoints = &tlsPtr_.quick_entrypoints;
+  #define SET_ENTRY_POINT(init_runtime_name, init_signature, new_runtime_name,              \
+                          new_java_name, new_signature, entry_point_name)                   \
+      qpoints->p ## entry_point_name = reinterpret_cast<void(*)()>(new_runtime_name);
+      STRING_INIT_LIST(SET_ENTRY_POINT)
+  #undef SET_ENTRY_POINT
+}
+
+ArtMethod* WellKnownClasses::StringInitToStringFactory(ArtMethod* string_init) {
+  #define TO_STRING_FACTORY(init_runtime_name, init_signature, new_runtime_name,            \
+                            new_java_name, new_signature, entry_point_name)                 \
+      if (string_init == init_runtime_name) {                                               \
+        return new_runtime_name;                                                            \
+      }
+      STRING_INIT_LIST(TO_STRING_FACTORY)
+  #undef TO_STRING_FACTORY
+  LOG(FATAL) << "Could not find StringFactory method for String.<init>";
+  return nullptr;
+}
+
+uint32_t WellKnownClasses::StringInitToEntryPoint(ArtMethod* string_init) {
+  #define TO_ENTRY_POINT(init_runtime_name, init_signature, new_runtime_name,               \
+                         new_java_name, new_signature, entry_point_name)                    \
+      if (string_init == init_runtime_name) {                                               \
+        return kQuick ## entry_point_name;                                                  \
+      }
+      STRING_INIT_LIST(TO_ENTRY_POINT)
+  #undef TO_STRING_FACTORY
+  LOG(FATAL) << "Could not find StringFactory method for String.<init>";
+  return 0;
+}
+#undef STRING_INIT_LIST
+
 void WellKnownClasses::Init(JNIEnv* env) {
   com_android_dex_Dex = CacheClass(env, "com/android/dex/Dex");
   dalvik_annotation_optimization_CriticalNative =
@@ -284,62 +323,6 @@
   org_apache_harmony_dalvik_ddmc_DdmServer_broadcast = CacheMethod(env, org_apache_harmony_dalvik_ddmc_DdmServer, true, "broadcast", "(I)V");
   org_apache_harmony_dalvik_ddmc_DdmServer_dispatch = CacheMethod(env, org_apache_harmony_dalvik_ddmc_DdmServer, true, "dispatch", "(I[BII)Lorg/apache/harmony/dalvik/ddmc/Chunk;");
 
-  java_lang_String_init = CacheMethod(env, java_lang_String, false, "<init>", "()V");
-  java_lang_String_init_B = CacheMethod(env, java_lang_String, false, "<init>", "([B)V");
-  java_lang_String_init_BI = CacheMethod(env, java_lang_String, false, "<init>", "([BI)V");
-  java_lang_String_init_BII = CacheMethod(env, java_lang_String, false, "<init>", "([BII)V");
-  java_lang_String_init_BIII = CacheMethod(env, java_lang_String, false, "<init>", "([BIII)V");
-  java_lang_String_init_BIIString = CacheMethod(env, java_lang_String, false, "<init>",
-      "([BIILjava/lang/String;)V");
-  java_lang_String_init_BString = CacheMethod(env, java_lang_String, false, "<init>",
-      "([BLjava/lang/String;)V");
-  java_lang_String_init_BIICharset = CacheMethod(env, java_lang_String, false, "<init>",
-      "([BIILjava/nio/charset/Charset;)V");
-  java_lang_String_init_BCharset = CacheMethod(env, java_lang_String, false, "<init>",
-      "([BLjava/nio/charset/Charset;)V");
-  java_lang_String_init_C = CacheMethod(env, java_lang_String, false, "<init>", "([C)V");
-  java_lang_String_init_CII = CacheMethod(env, java_lang_String, false, "<init>", "([CII)V");
-  java_lang_String_init_IIC = CacheMethod(env, java_lang_String, false, "<init>", "(II[C)V");
-  java_lang_String_init_String = CacheMethod(env, java_lang_String, false, "<init>",
-      "(Ljava/lang/String;)V");
-  java_lang_String_init_StringBuffer = CacheMethod(env, java_lang_String, false, "<init>",
-      "(Ljava/lang/StringBuffer;)V");
-  java_lang_String_init_III = CacheMethod(env, java_lang_String, false, "<init>", "([III)V");
-  java_lang_String_init_StringBuilder = CacheMethod(env, java_lang_String, false, "<init>",
-       "(Ljava/lang/StringBuilder;)V");
-  java_lang_StringFactory_newEmptyString = CacheMethod(env, java_lang_StringFactory, true,
-       "newEmptyString", "()Ljava/lang/String;");
-  java_lang_StringFactory_newStringFromBytes_B = CacheMethod(env, java_lang_StringFactory, true,
-       "newStringFromBytes", "([B)Ljava/lang/String;");
-  java_lang_StringFactory_newStringFromBytes_BI = CacheMethod(env, java_lang_StringFactory, true,
-       "newStringFromBytes", "([BI)Ljava/lang/String;");
-  java_lang_StringFactory_newStringFromBytes_BII = CacheMethod(env, java_lang_StringFactory, true,
-       "newStringFromBytes", "([BII)Ljava/lang/String;");
-  java_lang_StringFactory_newStringFromBytes_BIII = CacheMethod(env, java_lang_StringFactory, true,
-       "newStringFromBytes", "([BIII)Ljava/lang/String;");
-  java_lang_StringFactory_newStringFromBytes_BIIString = CacheMethod(env, java_lang_StringFactory,
-       true, "newStringFromBytes", "([BIILjava/lang/String;)Ljava/lang/String;");
-  java_lang_StringFactory_newStringFromBytes_BString = CacheMethod(env, java_lang_StringFactory,
-       true, "newStringFromBytes", "([BLjava/lang/String;)Ljava/lang/String;");
-  java_lang_StringFactory_newStringFromBytes_BIICharset = CacheMethod(env, java_lang_StringFactory,
-       true, "newStringFromBytes", "([BIILjava/nio/charset/Charset;)Ljava/lang/String;");
-  java_lang_StringFactory_newStringFromBytes_BCharset = CacheMethod(env, java_lang_StringFactory,
-       true, "newStringFromBytes", "([BLjava/nio/charset/Charset;)Ljava/lang/String;");
-  java_lang_StringFactory_newStringFromChars_C = CacheMethod(env, java_lang_StringFactory, true,
-       "newStringFromChars", "([C)Ljava/lang/String;");
-  java_lang_StringFactory_newStringFromChars_CII = CacheMethod(env, java_lang_StringFactory, true,
-       "newStringFromChars", "([CII)Ljava/lang/String;");
-  java_lang_StringFactory_newStringFromChars_IIC = CacheMethod(env, java_lang_StringFactory, true,
-       "newStringFromChars", "(II[C)Ljava/lang/String;");
-  java_lang_StringFactory_newStringFromString = CacheMethod(env, java_lang_StringFactory, true,
-       "newStringFromString", "(Ljava/lang/String;)Ljava/lang/String;");
-  java_lang_StringFactory_newStringFromStringBuffer = CacheMethod(env, java_lang_StringFactory,
-       true, "newStringFromStringBuffer", "(Ljava/lang/StringBuffer;)Ljava/lang/String;");
-  java_lang_StringFactory_newStringFromCodePoints = CacheMethod(env, java_lang_StringFactory,
-       true, "newStringFromCodePoints", "([III)Ljava/lang/String;");
-  java_lang_StringFactory_newStringFromStringBuilder = CacheMethod(env, java_lang_StringFactory,
-       true, "newStringFromStringBuilder", "(Ljava/lang/StringBuilder;)Ljava/lang/String;");
-
   dalvik_system_DexFile_cookie = CacheField(env, dalvik_system_DexFile, false, "mCookie", "Ljava/lang/Object;");
   dalvik_system_DexFile_fileName = CacheField(env, dalvik_system_DexFile, false, "mFileName", "Ljava/lang/String;");
   dalvik_system_PathClassLoader_pathList = CacheField(env, dalvik_system_PathClassLoader, false, "pathList", "Ldalvik/system/DexPathList;");
@@ -384,6 +367,7 @@
   java_lang_Long_valueOf = CachePrimitiveBoxingMethod(env, 'J', "java/lang/Long");
   java_lang_Short_valueOf = CachePrimitiveBoxingMethod(env, 'S', "java/lang/Short");
 
+  InitStringInit(env);
   Thread::Current()->InitStringEntryPoints();
 }
 
@@ -399,43 +383,4 @@
   return reinterpret_cast<mirror::Class*>(Thread::Current()->DecodeJObject(global_jclass));
 }
 
-jmethodID WellKnownClasses::StringInitToStringFactoryMethodID(jmethodID string_init) {
-  // TODO: Prioritize ordering.
-  if (string_init == java_lang_String_init) {
-    return java_lang_StringFactory_newEmptyString;
-  } else if (string_init == java_lang_String_init_B) {
-    return java_lang_StringFactory_newStringFromBytes_B;
-  } else if (string_init == java_lang_String_init_BI) {
-    return java_lang_StringFactory_newStringFromBytes_BI;
-  } else if (string_init == java_lang_String_init_BII) {
-    return java_lang_StringFactory_newStringFromBytes_BII;
-  } else if (string_init == java_lang_String_init_BIII) {
-    return java_lang_StringFactory_newStringFromBytes_BIII;
-  } else if (string_init == java_lang_String_init_BIIString) {
-    return java_lang_StringFactory_newStringFromBytes_BIIString;
-  } else if (string_init == java_lang_String_init_BString) {
-    return java_lang_StringFactory_newStringFromBytes_BString;
-  } else if (string_init == java_lang_String_init_BIICharset) {
-    return java_lang_StringFactory_newStringFromBytes_BIICharset;
-  } else if (string_init == java_lang_String_init_BCharset) {
-    return java_lang_StringFactory_newStringFromBytes_BCharset;
-  } else if (string_init == java_lang_String_init_C) {
-    return java_lang_StringFactory_newStringFromChars_C;
-  } else if (string_init == java_lang_String_init_CII) {
-    return java_lang_StringFactory_newStringFromChars_CII;
-  } else if (string_init == java_lang_String_init_IIC) {
-    return java_lang_StringFactory_newStringFromChars_IIC;
-  } else if (string_init == java_lang_String_init_String) {
-    return java_lang_StringFactory_newStringFromString;
-  } else if (string_init == java_lang_String_init_StringBuffer) {
-    return java_lang_StringFactory_newStringFromStringBuffer;
-  } else if (string_init == java_lang_String_init_III) {
-    return java_lang_StringFactory_newStringFromCodePoints;
-  } else if (string_init == java_lang_String_init_StringBuilder) {
-    return java_lang_StringFactory_newStringFromStringBuilder;
-  }
-  LOG(FATAL) << "Could not find StringFactory method for String.<init>";
-  return nullptr;
-}
-
 }  // namespace art
diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h
index b4d179c..c9110e6 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -21,6 +21,9 @@
 #include "jni.h"
 
 namespace art {
+
+class ArtMethod;
+
 namespace mirror {
 class Class;
 }  // namespace mirror
@@ -35,7 +38,8 @@
  public:
   static void Init(JNIEnv* env);  // Run before native methods are registered.
   static void LateInit(JNIEnv* env);  // Run after native methods are registered.
-  static jmethodID StringInitToStringFactoryMethodID(jmethodID string_init);
+  static ArtMethod* StringInitToStringFactory(ArtMethod* method);
+  static uint32_t StringInitToEntryPoint(ArtMethod* method);
 
   static mirror::Class* ToClass(jclass global_jclass)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -100,38 +104,6 @@
   static jmethodID java_lang_reflect_Proxy_invoke;
   static jmethodID java_lang_Runtime_nativeLoad;
   static jmethodID java_lang_Short_valueOf;
-  static jmethodID java_lang_String_init;
-  static jmethodID java_lang_String_init_B;
-  static jmethodID java_lang_String_init_BI;
-  static jmethodID java_lang_String_init_BII;
-  static jmethodID java_lang_String_init_BIII;
-  static jmethodID java_lang_String_init_BIIString;
-  static jmethodID java_lang_String_init_BString;
-  static jmethodID java_lang_String_init_BIICharset;
-  static jmethodID java_lang_String_init_BCharset;
-  static jmethodID java_lang_String_init_C;
-  static jmethodID java_lang_String_init_CII;
-  static jmethodID java_lang_String_init_IIC;
-  static jmethodID java_lang_String_init_String;
-  static jmethodID java_lang_String_init_StringBuffer;
-  static jmethodID java_lang_String_init_III;
-  static jmethodID java_lang_String_init_StringBuilder;
-  static jmethodID java_lang_StringFactory_newEmptyString;
-  static jmethodID java_lang_StringFactory_newStringFromBytes_B;
-  static jmethodID java_lang_StringFactory_newStringFromBytes_BI;
-  static jmethodID java_lang_StringFactory_newStringFromBytes_BII;
-  static jmethodID java_lang_StringFactory_newStringFromBytes_BIII;
-  static jmethodID java_lang_StringFactory_newStringFromBytes_BIIString;
-  static jmethodID java_lang_StringFactory_newStringFromBytes_BString;
-  static jmethodID java_lang_StringFactory_newStringFromBytes_BIICharset;
-  static jmethodID java_lang_StringFactory_newStringFromBytes_BCharset;
-  static jmethodID java_lang_StringFactory_newStringFromChars_C;
-  static jmethodID java_lang_StringFactory_newStringFromChars_CII;
-  static jmethodID java_lang_StringFactory_newStringFromChars_IIC;
-  static jmethodID java_lang_StringFactory_newStringFromString;
-  static jmethodID java_lang_StringFactory_newStringFromStringBuffer;
-  static jmethodID java_lang_StringFactory_newStringFromCodePoints;
-  static jmethodID java_lang_StringFactory_newStringFromStringBuilder;
   static jmethodID java_lang_System_runFinalization;
   static jmethodID java_lang_Thread_dispatchUncaughtException;
   static jmethodID java_lang_Thread_init;
@@ -177,6 +149,9 @@
   static jfieldID org_apache_harmony_dalvik_ddmc_Chunk_length;
   static jfieldID org_apache_harmony_dalvik_ddmc_Chunk_offset;
   static jfieldID org_apache_harmony_dalvik_ddmc_Chunk_type;
+
+ private:
+  static void InitStringInit(JNIEnv* env);
 };
 
 }  // namespace art