diff options
author | 2014-06-18 16:07:20 -0700 | |
---|---|---|
committer | 2014-06-18 16:39:29 -0700 | |
commit | 6c5cb212fa7010ae7caf9dc765533aa967c95342 (patch) | |
tree | c31c46eb7b284b317455fdab48317de92b81dd28 /runtime/entrypoints/entrypoint_utils.h | |
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
Diffstat (limited to 'runtime/entrypoints/entrypoint_utils.h')
-rw-r--r-- | runtime/entrypoints/entrypoint_utils.h | 23 |
1 files changed, 13 insertions, 10 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; } |