diff options
author | 2014-06-18 16:07:20 -0700 | |
---|---|---|
committer | 2014-06-18 16:39:29 -0700 | |
commit | 6c5cb212fa7010ae7caf9dc765533aa967c95342 (patch) | |
tree | c31c46eb7b284b317455fdab48317de92b81dd28 | |
parent | 241fd1192dfc0f7322660343179f9fc0591ed9ff (diff) |
Ensure classes are initialized rather than initializing.
A class can be being initialized on a different thread, in that case other
threads should block trying to access the class. The initializing state shows
the class is being initialized but not that its safe for other threads to
access. Change occurances of IsInitializing to IsInitialized primarily in
slow-path code.
Bug: 15347354
Change-Id: Ib586d0a385be6086a890dfbf8868d76f16767fac
-rw-r--r-- | runtime/entrypoints/entrypoint_utils.h | 23 | ||||
-rw-r--r-- | runtime/entrypoints/interpreter/interpreter_entrypoints.cc | 2 | ||||
-rw-r--r-- | runtime/entrypoints/portable/portable_trampoline_entrypoints.cc | 2 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 2 | ||||
-rw-r--r-- | runtime/interpreter/interpreter.cc | 4 | ||||
-rw-r--r-- | runtime/jni_internal.cc | 3 |
6 files changed, 19 insertions, 17 deletions
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h index 3d8b29fd24..ff836a4745 100644 --- a/runtime/entrypoints/entrypoint_utils.h +++ b/runtime/entrypoints/entrypoint_utils.h @@ -511,13 +511,8 @@ static inline mirror::ArtField* FindFieldFast(uint32_t field_idx, SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { mirror::ArtField* resolved_field = referrer->GetDeclaringClass()->GetDexCache()->GetResolvedField(field_idx); - if (UNLIKELY(resolved_field == NULL)) { - return NULL; - } - mirror::Class* fields_class = resolved_field->GetDeclaringClass(); - // Check class is initiliazed or initializing. - if (UNLIKELY(!fields_class->IsInitializing())) { - return NULL; + if (UNLIKELY(resolved_field == nullptr)) { + return nullptr; } // Check for incompatible class change. bool is_primitive; @@ -541,7 +536,15 @@ static inline mirror::ArtField* FindFieldFast(uint32_t field_idx, } if (UNLIKELY(resolved_field->IsStatic() != is_static)) { // Incompatible class change. - return NULL; + return nullptr; + } + mirror::Class* fields_class = resolved_field->GetDeclaringClass(); + if (is_static) { + // Check class is initialized else fail so that we can contend to initialize the class with + // other threads that may be racing to do this. + if (UNLIKELY(!fields_class->IsInitialized())) { + return nullptr; + } } mirror::Class* referring_class = referrer->GetDeclaringClass(); if (UNLIKELY(!referring_class->CanAccess(fields_class) || @@ -549,11 +552,11 @@ static inline mirror::ArtField* FindFieldFast(uint32_t field_idx, resolved_field->GetAccessFlags()) || (is_set && resolved_field->IsFinal() && (fields_class != referring_class)))) { // Illegal access. - return NULL; + return nullptr; } if (UNLIKELY(resolved_field->IsPrimitiveType() != is_primitive || resolved_field->FieldSize() != expected_size)) { - return NULL; + return nullptr; } return resolved_field; } diff --git a/runtime/entrypoints/interpreter/interpreter_entrypoints.cc b/runtime/entrypoints/interpreter/interpreter_entrypoints.cc index f2e2bf7aa9..329c175986 100644 --- a/runtime/entrypoints/interpreter/interpreter_entrypoints.cc +++ b/runtime/entrypoints/interpreter/interpreter_entrypoints.cc @@ -33,7 +33,7 @@ extern "C" void artInterpreterToCompiledCodeBridge(Thread* self, MethodHelper& m // Ensure static methods are initialized. if (method->IsStatic()) { mirror::Class* declaringClass = method->GetDeclaringClass(); - if (UNLIKELY(!declaringClass->IsInitializing())) { + if (UNLIKELY(!declaringClass->IsInitialized())) { self->PushShadowFrame(shadow_frame); StackHandleScope<1> hs(self); Handle<mirror::Class> h_class(hs.NewHandle(declaringClass)); diff --git a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc b/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc index 6825e783a7..2da016f798 100644 --- a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc +++ b/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc @@ -213,7 +213,7 @@ extern "C" uint64_t artPortableToInterpreterBridge(mirror::ArtMethod* method, Th self->PushShadowFrame(shadow_frame); self->EndAssertNoThreadSuspension(old_cause); - if (method->IsStatic() && !method->GetDeclaringClass()->IsInitializing()) { + if (method->IsStatic() && !method->GetDeclaringClass()->IsInitialized()) { // Ensure static method's class is initialized. Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass())); if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(h_class, true, true)) { diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 514d1aa26d..7a144b6d72 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -484,7 +484,7 @@ extern "C" uint64_t artQuickToInterpreterBridge(mirror::ArtMethod* method, Threa self->PushShadowFrame(shadow_frame); self->EndAssertNoThreadSuspension(old_cause); - if (method->IsStatic() && !method->GetDeclaringClass()->IsInitializing()) { + if (method->IsStatic() && !method->GetDeclaringClass()->IsInitialized()) { // Ensure static method's class is initialized. StackHandleScope<1> hs(self); Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass())); diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc index 6dbc6a05ea..cb4d444517 100644 --- a/runtime/interpreter/interpreter.cc +++ b/runtime/interpreter/interpreter.cc @@ -454,7 +454,7 @@ void EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, Object* receive } self->EndAssertNoThreadSuspension(old_cause); // Do this after populating the shadow frame in case EnsureInitialized causes a GC. - if (method->IsStatic() && UNLIKELY(!method->GetDeclaringClass()->IsInitializing())) { + if (method->IsStatic() && UNLIKELY(!method->GetDeclaringClass()->IsInitialized())) { ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); StackHandleScope<1> hs(self); Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass())); @@ -527,7 +527,7 @@ extern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper& mh // Ensure static methods are initialized. if (method->IsStatic()) { mirror::Class* declaring_class = method->GetDeclaringClass(); - if (UNLIKELY(!declaring_class->IsInitializing())) { + if (UNLIKELY(!declaring_class->IsInitialized())) { StackHandleScope<1> hs(self); HandleWrapper<Class> h_declaring_class(hs.NewHandleWrapper(&declaring_class)); if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized( diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc index fc5d5905cb..5606d47832 100644 --- a/runtime/jni_internal.cc +++ b/runtime/jni_internal.cc @@ -3314,8 +3314,7 @@ bool JavaVMExt::LoadNativeLibrary(const std::string& path, void* JavaVMExt::FindCodeForNativeMethod(mirror::ArtMethod* m) { CHECK(m->IsNative()); mirror::Class* c = m->GetDeclaringClass(); - // If this is a static method, it could be called before the class - // has been initialized. + // If this is a static method, it could be called before the class has been initialized. if (m->IsStatic()) { c = EnsureInitialized(Thread::Current(), c); if (c == nullptr) { |