diff options
| -rw-r--r-- | runtime/class_linker.cc | 15 | ||||
| -rw-r--r-- | runtime/well_known_classes.cc | 38 | ||||
| -rw-r--r-- | runtime/well_known_classes.h | 6 |
3 files changed, 43 insertions, 16 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index be9e08fbec..b88aa5e07a 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -828,9 +828,24 @@ bool ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b return true; } +static void CreateStringInitBindings(Thread* self, ClassLinker* class_linker) + REQUIRES_SHARED(Locks::mutator_lock_) { + // Find String.<init> -> StringFactory bindings. + ObjPtr<mirror::Class> string_factory_class = + class_linker->FindSystemClass(self, "Ljava/lang/StringFactory;"); + CHECK(string_factory_class != nullptr); + ObjPtr<mirror::Class> string_class = + class_linker->GetClassRoot(ClassLinker::ClassRoot::kJavaLangString); + WellKnownClasses::InitStringInit(string_class, string_factory_class); + // Update the primordial thread. + self->InitStringEntryPoints(); +} + void ClassLinker::FinishInit(Thread* self) { VLOG(startup) << "ClassLinker::FinishInit entering"; + CreateStringInitBindings(self, this); + // Let the heap know some key offsets into java.lang.ref instances // Note: we hard code the field indexes here rather than using FindInstanceField // as the types of the field can't be resolved prior to the runtime being diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc index 4843061be6..f7cdf3920a 100644 --- a/runtime/well_known_classes.cc +++ b/runtime/well_known_classes.cc @@ -23,6 +23,8 @@ #include <android-base/logging.h> #include <android-base/stringprintf.h> +#include "base/enums.h" +#include "class_linker.h" #include "entrypoints/quick/quick_entrypoints_enum.h" #include "hidden_api.h" #include "jni/jni_internal.h" @@ -30,6 +32,7 @@ #include "mirror/throwable.h" #include "nativehelper/scoped_local_ref.h" #include "obj_ptr-inl.h" +#include "runtime.h" #include "scoped_thread_state_change-inl.h" #include "thread-current-inl.h" @@ -231,19 +234,28 @@ static jmethodID CachePrimitiveBoxingMethod(JNIEnv* env, char prim_name, const c 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; + static ArtMethod* init_runtime_name = nullptr; \ + static ArtMethod* new_runtime_name = nullptr; 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 = jni::DecodeArtMethod( \ - CacheMethod(env, java_lang_String, false, "<init>", init_signature)); \ - new_runtime_name = jni::DecodeArtMethod( \ - CacheMethod(env, java_lang_StringFactory, true, new_java_name, new_signature)); +void WellKnownClasses::InitStringInit(ObjPtr<mirror::Class> string_class, + ObjPtr<mirror::Class> string_builder_class) { + PointerSize p_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); + auto find_method = [p_size](ObjPtr<mirror::Class> klass, + const char* name, + const char* sig, + bool expext_static) REQUIRES_SHARED(Locks::mutator_lock_) { + ArtMethod* ret = klass->FindClassMethod(name, sig, p_size); + CHECK(ret != nullptr); + CHECK_EQ(expext_static, ret->IsStatic()); + return ret; + }; + + #define LOAD_STRING_INIT(init_runtime_name, init_signature, new_runtime_name, \ + new_java_name, new_signature, ...) \ + init_runtime_name = find_method(string_class, "<init>", init_signature, false); \ + new_runtime_name = find_method(string_builder_class, new_java_name, new_signature, true); STRING_INIT_LIST(LOAD_STRING_INIT) #undef LOAD_STRING_INIT } @@ -252,6 +264,7 @@ 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) \ + DCHECK(!Runtime::Current()->IsStarted() || (new_runtime_name) != nullptr); \ qpoints->p ## entry_point_name = reinterpret_cast<void(*)()>(new_runtime_name); STRING_INIT_LIST(SET_ENTRY_POINT) #undef SET_ENTRY_POINT @@ -260,7 +273,9 @@ void Thread::InitStringEntryPoints() { 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) \ + DCHECK((init_runtime_name) != nullptr); \ if (string_init == (init_runtime_name)) { \ + DCHECK((new_runtime_name) != nullptr); \ return (new_runtime_name); \ } STRING_INIT_LIST(TO_STRING_FACTORY) @@ -410,9 +425,6 @@ void WellKnownClasses::Init(JNIEnv* env) { java_lang_Integer_valueOf = CachePrimitiveBoxingMethod(env, 'I', "java/lang/Integer"); 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(); } void WellKnownClasses::LateInit(JNIEnv* env) { diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h index 25c07b27de..c06e4a71ce 100644 --- a/runtime/well_known_classes.h +++ b/runtime/well_known_classes.h @@ -40,6 +40,9 @@ struct WellKnownClasses { static void Clear(); + static void InitStringInit(ObjPtr<mirror::Class> string_class, + ObjPtr<mirror::Class> string_builder_class) + REQUIRES_SHARED(Locks::mutator_lock_); static ArtMethod* StringInitToStringFactory(ArtMethod* method); static uint32_t StringInitToEntryPoint(ArtMethod* method); @@ -168,9 +171,6 @@ struct WellKnownClasses { 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 |