0%

class加载的几个阶段

加载 - 链接(验证,准备,解析)- 初始化 - 使用 - 卸载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ClassStatus: uint8_t {
kNotReady = 0//零初始化类对象在此状态开始。
kRetired = 1//退役,不应该使用。请使用新克隆的那个。
kErrorResolved = 2
kErrorUnresolved = 3
kIdx = 4//已加载,DEX idx在super_class_type_idx_和interfaces_type_idx_中。
kLoaded = 5// DEX idx值解析。
kResolving = 6//从临时类对象克隆。
kResolved = 7// 链接部分
kVerifying = 8//正在验证。
kRetryVerificationAtRuntime = 9//编译时验证失败,运行时重试。
kVerifyingAtRuntime = 10//运行时重试验证。
kVerified = 11//链接的逻辑部分;pre-init完成。
kSuperclassValidated = 12// init的超类验证部分已经完成。
kInitializing = 13// 类初始化正在进行。
kInitialized = 14// Ready to go。
kLast = kInitialized
};
  • kNotReady - kIdx

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    void ClassLinker::SetupClass(const DexFile& dex_file,
    const dex::ClassDef& dex_class_def,
    Handle<mirror::Class> klass,
    ObjPtr<mirror::ClassLoader> class_loader) {
    CHECK(klass != nullptr);
    CHECK(klass->GetDexCache() != nullptr);
    CHECK_EQ(ClassStatus::kNotReady, klass->GetStatus()); // 校验是否kNotReady
    const char* descriptor = dex_file.GetClassDescriptor(dex_class_def);
    CHECK(descriptor != nullptr);
    //给Class赋值
    klass->SetClass(GetClassRoot<mirror::Class>(this));
    uint32_t access_flags = dex_class_def.GetJavaAccessFlags();
    CHECK_EQ(access_flags & ~kAccJavaFlagsMask, 0U);
    klass->SetAccessFlags(access_flags);
    klass->SetClassLoader(class_loader);
    DCHECK_EQ(klass->GetPrimitiveType(), Primitive::kPrimNot);
    mirror::Class::SetStatus(klass, ClassStatus::kIdx, nullptr); // 设置为kIdx

    klass->SetDexClassDefIndex(dex_file.GetIndexForClassDef(dex_class_def));
    klass->SetDexTypeIndex(dex_class_def.class_idx_);
    }
  • kIdx - kLoaded

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    LoadClass(self, *new_dex_file, *new_class_def, klass);

    bool ClassLinker::LoadSuperAndInterfaces(Handle<mirror::Class> klass, const DexFile& dex_file) {
    CHECK_EQ(ClassStatus::kIdx, klass->GetStatus());
    const dex::ClassDef& class_def = dex_file.GetClassDef(klass->GetDexClassDefIndex());
    dex::TypeIndex super_class_idx = class_def.superclass_idx_;
    if (super_class_idx.IsValid()) {
    // Check that a class does not inherit from itself directly.
    //
    // TODO: This is a cheap check to detect the straightforward case
    // of a class extending itself (b/28685551), but we should do a
    // proper cycle detection on loaded classes, to detect all cases
    // of class circularity errors (b/28830038).
    if (super_class_idx == class_def.class_idx_) {
    ThrowClassCircularityError(klass.Get(),
    "Class %s extends itself",
    klass->PrettyDescriptor().c_str());
    return false;
    }

    ObjPtr<mirror::Class> super_class = ResolveType(super_class_idx, klass.Get());
    if (super_class == nullptr) {
    DCHECK(Thread::Current()->IsExceptionPending());
    return false;
    }
    // Verify
    if (!klass->CanAccess(super_class)) {
    ThrowIllegalAccessError(klass.Get(), "Class %s extended by class %s is inaccessible",
    super_class->PrettyDescriptor().c_str(),
    klass->PrettyDescriptor().c_str());
    return false;
    }
    CHECK(super_class->IsResolved());
    klass->SetSuperClass(super_class);
    }
    const dex::TypeList* interfaces = dex_file.GetInterfacesList(class_def);
    if (interfaces != nullptr) {
    for (size_t i = 0; i < interfaces->Size(); i++) {
    dex::TypeIndex idx = interfaces->GetTypeItem(i).type_idx_;
    ObjPtr<mirror::Class> interface = ResolveType(idx, klass.Get());
    if (interface == nullptr) {
    DCHECK(Thread::Current()->IsExceptionPending());
    return false;
    }
    // Verify
    if (!klass->CanAccess(interface)) {
    // TODO: the RI seemed to ignore this in my testing.
    ThrowIllegalAccessError(klass.Get(),
    "Interface %s implemented by class %s is inaccessible",
    interface->PrettyDescriptor().c_str(),
    klass->PrettyDescriptor().c_str());
    return false;
    }
    }
    }
    // Mark the class as loaded.
    mirror::Class::SetStatus(klass, ClassStatus::kLoaded, nullptr); // 设置加载完成的标记
    return true;
    }



  • kLoaded - kResolving - kResolved

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    bool ClassLinker::LinkClass(Thread* self,
    const char* descriptor,
    Handle<mirror::Class> klass,
    Handle<mirror::ObjectArray<mirror::Class>> interfaces,
    MutableHandle<mirror::Class>* h_new_class_out) {
    CHECK_EQ(ClassStatus::kLoaded, klass->GetStatus());

    if (!LinkSuperClass(klass)) {
    return false;
    }
    ArtMethod* imt_data[ImTable::kSize];
    // If there are any new conflicts compared to super class.
    bool new_conflict = false;
    std::fill_n(imt_data, arraysize(imt_data), Runtime::Current()->GetImtUnimplementedMethod());
    if (!LinkMethods(self, klass, interfaces, &new_conflict, imt_data)) {
    return false;
    }
    if (!LinkInstanceFields(self, klass)) {
    return false;
    }
    size_t class_size;
    if (!LinkStaticFields(self, klass, &class_size)) {
    return false;
    }
    CreateReferenceInstanceOffsets(klass);
    CHECK_EQ(ClassStatus::kLoaded, klass->GetStatus());

    ImTable* imt = nullptr;
    if (klass->ShouldHaveImt()) {
    // If there are any new conflicts compared to the super class we can not make a copy. There
    // can be cases where both will have a conflict method at the same slot without having the same
    // set of conflicts. In this case, we can not share the IMT since the conflict table slow path
    // will possibly create a table that is incorrect for either of the classes.
    // Same IMT with new_conflict does not happen very often.
    if (!new_conflict) {
    ImTable* super_imt = FindSuperImt(klass.Get(), image_pointer_size_);
    if (super_imt != nullptr) {
    bool imt_equals = true;
    for (size_t i = 0; i < ImTable::kSize && imt_equals; ++i) {
    imt_equals = imt_equals && (super_imt->Get(i, image_pointer_size_) == imt_data[i]);
    }
    if (imt_equals) {
    imt = super_imt;
    }
    }
    }
    if (imt == nullptr) {
    LinearAlloc* allocator = GetAllocatorForClassLoader(klass->GetClassLoader());
    imt = reinterpret_cast<ImTable*>(
    allocator->Alloc(self, ImTable::SizeInBytes(image_pointer_size_)));
    if (imt == nullptr) {
    return false;
    }
    imt->Populate(imt_data, image_pointer_size_);
    }
    }

    if (!klass->IsTemp() || (!init_done_ && klass->GetClassSize() == class_size)) {
    // We don't need to retire this class as it has no embedded tables or it was created the
    // correct size during class linker initialization.
    CHECK_EQ(klass->GetClassSize(), class_size) << klass->PrettyDescriptor();

    if (klass->ShouldHaveEmbeddedVTable()) {
    klass->PopulateEmbeddedVTable(image_pointer_size_);
    }
    if (klass->ShouldHaveImt()) {
    klass->SetImt(imt, image_pointer_size_);
    }

    // Update CHA info based on whether we override methods.
    // Have to do this before setting the class as resolved which allows
    // instantiation of klass.
    if (cha_ != nullptr) {
    cha_->UpdateAfterLoadingOf(klass);
    }

    // This will notify waiters on klass that saw the not yet resolved
    // class in the class_table_ during EnsureResolved.
    mirror::Class::SetStatus(klass, ClassStatus::kResolved, self);
    h_new_class_out->Assign(klass.Get());
    } else { // 如果目标类是可以实例化的
    CHECK(!klass->IsResolved());
    // Retire the temporary class and create the correctly sized resolved class.
    StackHandleScope<1> hs(self);
    // CopyOf 时将状态设置为 kResolving
    auto h_new_class = hs.NewHandle(klass->CopyOf(self, class_size, imt, image_pointer_size_));
    // Set arrays to null since we don't want to have multiple classes with the same ArtField or
    // ArtMethod array pointers. If this occurs, it causes bugs in remembered sets since the GC
    // may not see any references to the target space and clean the card for a class if another
    // class had the same array pointer.
    klass->SetMethodsPtrUnchecked(nullptr, 0, 0);
    klass->SetSFieldsPtrUnchecked(nullptr);
    klass->SetIFieldsPtrUnchecked(nullptr);
    if (UNLIKELY(h_new_class == nullptr)) {
    self->AssertPendingOOMException();
    mirror::Class::SetStatus(klass, ClassStatus::kErrorUnresolved, self);
    return false;
    }

    CHECK_EQ(h_new_class->GetClassSize(), class_size);
    ObjectLock<mirror::Class> lock(self, h_new_class);
    FixupTemporaryDeclaringClass(klass.Get(), h_new_class.Get());

    {
    WriterMutexLock mu(self, *Locks::classlinker_classes_lock_);
    const ObjPtr<mirror::ClassLoader> class_loader = h_new_class.Get()->GetClassLoader();
    ClassTable* const table = InsertClassTableForClassLoader(class_loader);
    const ObjPtr<mirror::Class> existing =
    table->UpdateClass(descriptor, h_new_class.Get(), ComputeModifiedUtf8Hash(descriptor));
    if (class_loader != nullptr) {
    // We updated the class in the class table, perform the write barrier so that the GC knows
    // about the change.
    WriteBarrier::ForEveryFieldWrite(class_loader);
    }
    CHECK_EQ(existing, klass.Get());
    if (log_new_roots_) {
    new_class_roots_.push_back(GcRoot<mirror::Class>(h_new_class.Get()));
    }
    }

    // Update CHA info based on whether we override methods.
    // Have to do this before setting the class as resolved which allows
    // instantiation of klass.
    if (cha_ != nullptr) {
    cha_->UpdateAfterLoadingOf(h_new_class);
    }

    // This will notify waiters on temp class that saw the not yet resolved class in the
    // class_table_ during EnsureResolved.

    // 旧的class设置为kRetired
    mirror::Class::SetStatus(klass, ClassStatus::kRetired, self);

    CHECK_EQ(h_new_class->GetStatus(), ClassStatus::kResolving);
    // This will notify waiters on new_class that saw the not yet resolved
    // class in the class_table_ during EnsureResolved.
    // 设置为解析完成状态
    mirror::Class::SetStatus(h_new_class, ClassStatus::kResolved, self);
    // Return the new class.
    h_new_class_out->Assign(h_new_class.Get());
    }
    return true;
    }
  • kResolved - kVerifying - kVerified

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    verifier::FailureKind ClassLinker::VerifyClass(
    Thread* self, Handle<mirror::Class> klass, verifier::HardFailLogMode log_level) {
    {
    // TODO: assert that the monitor on the Class is held
    ObjectLock<mirror::Class> lock(self, klass);

    // Is somebody verifying this now?
    ClassStatus old_status = klass->GetStatus();
    while (old_status == ClassStatus::kVerifying ||
    old_status == ClassStatus::kVerifyingAtRuntime) {
    lock.WaitIgnoringInterrupts();
    // WaitIgnoringInterrupts can still receive an interrupt and return early, in this
    // case we may see the same status again. b/62912904. This is why the check is
    // greater or equal.
    CHECK(klass->IsErroneous() || (klass->GetStatus() >= old_status))
    << "Class '" << klass->PrettyClass()
    << "' performed an illegal verification state transition from " << old_status
    << " to " << klass->GetStatus();
    old_status = klass->GetStatus();
    }

    // The class might already be erroneous, for example at compile time if we attempted to verify
    // this class as a parent to another.
    if (klass->IsErroneous()) {
    ThrowEarlierClassFailure(klass.Get());
    return verifier::FailureKind::kHardFailure;
    }

    // Don't attempt to re-verify if already verified.
    if (klass->IsVerified()) {
    EnsureSkipAccessChecksMethods(klass, image_pointer_size_);
    return verifier::FailureKind::kNoFailure;
    }

    // For AOT, don't attempt to re-verify if we have already found we should
    // verify at runtime.
    if (Runtime::Current()->IsAotCompiler() && klass->ShouldVerifyAtRuntime()) {
    return verifier::FailureKind::kSoftFailure;
    }

    if (klass->GetStatus() == ClassStatus::kResolved) {
    mirror::Class::SetStatus(klass, ClassStatus::kVerifying, self);
    } else {
    CHECK_EQ(klass->GetStatus(), ClassStatus::kRetryVerificationAtRuntime)
    << klass->PrettyClass();
    CHECK(!Runtime::Current()->IsAotCompiler());
    mirror::Class::SetStatus(klass, ClassStatus::kVerifyingAtRuntime, self);
    }

    // Skip verification if disabled.
    if (!Runtime::Current()->IsVerificationEnabled()) {
    mirror::Class::SetStatus(klass, ClassStatus::kVerified, self);
    EnsureSkipAccessChecksMethods(klass, image_pointer_size_);
    return verifier::FailureKind::kNoFailure;
    }
    }

    VLOG(class_linker) << "Beginning verification for class: "
    << klass->PrettyDescriptor()
    << " in " << klass->GetDexCache()->GetLocation()->ToModifiedUtf8();

    // Verify super class.
    StackHandleScope<2> hs(self);
    MutableHandle<mirror::Class> supertype(hs.NewHandle(klass->GetSuperClass()));
    // If we have a superclass and we get a hard verification failure we can return immediately.
    if (supertype != nullptr && !AttemptSupertypeVerification(self, klass, supertype)) {
    CHECK(self->IsExceptionPending()) << "Verification error should be pending.";
    return verifier::FailureKind::kHardFailure;
    }

    // Verify all default super-interfaces.
    //
    // (1) Don't bother if the superclass has already had a soft verification failure.
    //
    // (2) Interfaces shouldn't bother to do this recursive verification because they cannot cause
    // recursive initialization by themselves. This is because when an interface is initialized
    // directly it must not initialize its superinterfaces. We are allowed to verify regardless
    // but choose not to for an optimization. If the interfaces is being verified due to a class
    // initialization (which would need all the default interfaces to be verified) the class code
    // will trigger the recursive verification anyway.
    if ((supertype == nullptr || supertype->IsVerified()) // See (1)
    && !klass->IsInterface()) { // See (2)
    int32_t iftable_count = klass->GetIfTableCount();
    MutableHandle<mirror::Class> iface(hs.NewHandle<mirror::Class>(nullptr));
    // Loop through all interfaces this class has defined. It doesn't matter the order.
    for (int32_t i = 0; i < iftable_count; i++) {
    iface.Assign(klass->GetIfTable()->GetInterface(i));
    DCHECK(iface != nullptr);
    // We only care if we have default interfaces and can skip if we are already verified...
    if (LIKELY(!iface->HasDefaultMethods() || iface->IsVerified())) {
    continue;
    } else if (UNLIKELY(!AttemptSupertypeVerification(self, klass, iface))) {
    // We had a hard failure while verifying this interface. Just return immediately.
    CHECK(self->IsExceptionPending()) << "Verification error should be pending.";
    return verifier::FailureKind::kHardFailure;
    } else if (UNLIKELY(!iface->IsVerified())) {
    // We softly failed to verify the iface. Stop checking and clean up.
    // Put the iface into the supertype handle so we know what caused us to fail.
    supertype.Assign(iface.Get());
    break;
    }
    }
    }

    // At this point if verification failed, then supertype is the "first" supertype that failed
    // verification (without a specific order). If verification succeeded, then supertype is either
    // null or the original superclass of klass and is verified.
    DCHECK(supertype == nullptr ||
    supertype.Get() == klass->GetSuperClass() ||
    !supertype->IsVerified());

    // Try to use verification information from the oat file, otherwise do runtime verification.
    const DexFile& dex_file = *klass->GetDexCache()->GetDexFile();
    ClassStatus oat_file_class_status(ClassStatus::kNotReady);
    bool preverified = VerifyClassUsingOatFile(dex_file, klass.Get(), oat_file_class_status);

    VLOG(class_linker) << "Class preverified status for class "
    << klass->PrettyDescriptor()
    << " in " << klass->GetDexCache()->GetLocation()->ToModifiedUtf8()
    << ": "
    << preverified;

    // If the oat file says the class had an error, re-run the verifier. That way we will get a
    // precise error message. To ensure a rerun, test:
    // mirror::Class::IsErroneous(oat_file_class_status) => !preverified
    DCHECK(!mirror::Class::IsErroneous(oat_file_class_status) || !preverified);

    std::string error_msg;
    verifier::FailureKind verifier_failure = verifier::FailureKind::kNoFailure;
    if (!preverified) {
    verifier_failure = PerformClassVerification(self, klass, log_level, &error_msg);
    }

    // Verification is done, grab the lock again.
    ObjectLock<mirror::Class> lock(self, klass);

    if (preverified || verifier_failure != verifier::FailureKind::kHardFailure) {
    if (!preverified && verifier_failure != verifier::FailureKind::kNoFailure) {
    VLOG(class_linker) << "Soft verification failure in class "
    << klass->PrettyDescriptor()
    << " in " << klass->GetDexCache()->GetLocation()->ToModifiedUtf8()
    << " because: " << error_msg;
    }
    self->AssertNoPendingException();
    // Make sure all classes referenced by catch blocks are resolved.
    ResolveClassExceptionHandlerTypes(klass);
    if (verifier_failure == verifier::FailureKind::kNoFailure) {
    // Even though there were no verifier failures we need to respect whether the super-class and
    // super-default-interfaces were verified or requiring runtime reverification.
    if (supertype == nullptr || supertype->IsVerified()) {
    mirror::Class::SetStatus(klass, ClassStatus::kVerified, self);
    } else {
    CHECK_EQ(supertype->GetStatus(), ClassStatus::kRetryVerificationAtRuntime);
    mirror::Class::SetStatus(klass, ClassStatus::kRetryVerificationAtRuntime, self);
    // Pretend a soft failure occurred so that we don't consider the class verified below.
    verifier_failure = verifier::FailureKind::kSoftFailure;
    }
    } else {
    CHECK_EQ(verifier_failure, verifier::FailureKind::kSoftFailure);
    // Soft failures at compile time should be retried at runtime. Soft
    // failures at runtime will be handled by slow paths in the generated
    // code. Set status accordingly.
    if (Runtime::Current()->IsAotCompiler()) {
    mirror::Class::SetStatus(klass, ClassStatus::kRetryVerificationAtRuntime, self);
    } else {
    mirror::Class::SetStatus(klass, ClassStatus::kVerified, self);
    // As this is a fake verified status, make sure the methods are _not_ marked
    // kAccSkipAccessChecks later.
    klass->SetVerificationAttempted();
    }
    }
    } else {
    VLOG(verifier) << "Verification failed on class " << klass->PrettyDescriptor()
    << " in " << klass->GetDexCache()->GetLocation()->ToModifiedUtf8()
    << " because: " << error_msg;
    self->AssertNoPendingException();
    ThrowVerifyError(klass.Get(), "%s", error_msg.c_str());
    mirror::Class::SetStatus(klass, ClassStatus::kErrorResolved, self);
    }
    if (preverified || verifier_failure == verifier::FailureKind::kNoFailure) {
    // Class is verified so we don't need to do any access check on its methods.
    // Let the interpreter know it by setting the kAccSkipAccessChecks flag onto each
    // method.
    // Note: we're going here during compilation and at runtime. When we set the
    // kAccSkipAccessChecks flag when compiling image classes, the flag is recorded
    // in the image and is set when loading the image.

    if (UNLIKELY(Runtime::Current()->IsVerificationSoftFail())) {
    // Never skip access checks if the verification soft fail is forced.
    // Mark the class as having a verification attempt to avoid re-running the verifier.
    klass->SetVerificationAttempted();
    } else {
    EnsureSkipAccessChecksMethods(klass, image_pointer_size_);
    }
    }
    // Done verifying. Notify the compiler about the verification status, in case the class
    // was verified implicitly (eg super class of a compiled class).
    if (Runtime::Current()->IsAotCompiler()) {
    Runtime::Current()->GetCompilerCallbacks()->UpdateClassState(
    ClassReference(&klass->GetDexFile(), klass->GetDexClassDefIndex()), klass->GetStatus());
    }
    return verifier_failure;
    }
  • kVerified - kInitializing - kInitialized

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    bool ClassLinker::InitializeClass(Thread* self, Handle<mirror::Class> klass,
    bool can_init_statics, bool can_init_parents) {
    // see JLS 3rd edition, 12.4.2 "Detailed Initialization Procedure" for the locking protocol

    // Are we already initialized and therefore done?
    // Note: we differ from the JLS here as we don't do this under the lock, this is benign as
    // an initialized class will never change its state.
    if (klass->IsInitialized()) {
    return true;
    }

    // Fast fail if initialization requires a full runtime. Not part of the JLS.
    if (!CanWeInitializeClass(klass.Get(), can_init_statics, can_init_parents)) {
    return false;
    }

    self->AllowThreadSuspension();
    uint64_t t0;
    {
    ObjectLock<mirror::Class> lock(self, klass);

    // Re-check under the lock in case another thread initialized ahead of us.
    if (klass->IsInitialized()) {
    return true;
    }

    // Was the class already found to be erroneous? Done under the lock to match the JLS.
    if (klass->IsErroneous()) {
    ThrowEarlierClassFailure(klass.Get(), true, /* log= */ true);
    VlogClassInitializationFailure(klass);
    return false;
    }

    CHECK(klass->IsResolved() && !klass->IsErroneousResolved())
    << klass->PrettyClass() << ": state=" << klass->GetStatus();

    if (!klass->IsVerified()) {
    VerifyClass(self, klass);
    if (!klass->IsVerified()) {
    // We failed to verify, expect either the klass to be erroneous or verification failed at
    // compile time.
    if (klass->IsErroneous()) {
    // The class is erroneous. This may be a verifier error, or another thread attempted
    // verification and/or initialization and failed. We can distinguish those cases by
    // whether an exception is already pending.
    if (self->IsExceptionPending()) {
    // Check that it's a VerifyError.
    DCHECK_EQ("java.lang.Class<java.lang.VerifyError>",
    mirror::Class::PrettyClass(self->GetException()->GetClass()));
    } else {
    // Check that another thread attempted initialization.
    DCHECK_NE(0, klass->GetClinitThreadId());
    DCHECK_NE(self->GetTid(), klass->GetClinitThreadId());
    // Need to rethrow the previous failure now.
    ThrowEarlierClassFailure(klass.Get(), true);
    }
    VlogClassInitializationFailure(klass);
    } else {
    CHECK(Runtime::Current()->IsAotCompiler());
    CHECK_EQ(klass->GetStatus(), ClassStatus::kRetryVerificationAtRuntime);
    self->AssertNoPendingException();
    self->SetException(Runtime::Current()->GetPreAllocatedNoClassDefFoundError());
    }
    self->AssertPendingException();
    return false;
    } else {
    self->AssertNoPendingException();
    }

    // A separate thread could have moved us all the way to initialized. A "simple" example
    // involves a subclass of the current class being initialized at the same time (which
    // will implicitly initialize the superclass, if scheduled that way). b/28254258
    DCHECK(!klass->IsErroneous()) << klass->GetStatus();
    if (klass->IsInitialized()) {
    return true;
    }
    }

    // If the class is ClassStatus::kInitializing, either this thread is
    // initializing higher up the stack or another thread has beat us
    // to initializing and we need to wait. Either way, this
    // invocation of InitializeClass will not be responsible for
    // running <clinit> and will return.
    if (klass->GetStatus() == ClassStatus::kInitializing) {
    // Could have got an exception during verification.
    if (self->IsExceptionPending()) {
    VlogClassInitializationFailure(klass);
    return false;
    }
    // We caught somebody else in the act; was it us?
    if (klass->GetClinitThreadId() == self->GetTid()) {
    // Yes. That's fine. Return so we can continue initializing.
    return true;
    }
    // No. That's fine. Wait for another thread to finish initializing.
    return WaitForInitializeClass(klass, self, lock);
    }

    // Try to get the oat class's status for this class if the oat file is present. The compiler
    // tries to validate superclass descriptors, and writes the result into the oat file.
    // Runtime correctness is guaranteed by classpath checks done on loading. If the classpath
    // is different at runtime than it was at compile time, the oat file is rejected. So if the
    // oat file is present, the classpaths must match, and the runtime time check can be skipped.
    bool has_oat_class = false;
    const Runtime* runtime = Runtime::Current();
    const OatFile::OatClass oat_class = (runtime->IsStarted() && !runtime->IsAotCompiler())
    ? OatFile::FindOatClass(klass->GetDexFile(), klass->GetDexClassDefIndex(), &has_oat_class)
    : OatFile::OatClass::Invalid();
    if (oat_class.GetStatus() < ClassStatus::kSuperclassValidated &&
    !ValidateSuperClassDescriptors(klass)) {
    mirror::Class::SetStatus(klass, ClassStatus::kErrorResolved, self);
    return false;
    }
    self->AllowThreadSuspension();

    CHECK_EQ(klass->GetStatus(), ClassStatus::kVerified) << klass->PrettyClass()
    << " self.tid=" << self->GetTid() << " clinit.tid=" << klass->GetClinitThreadId();

    // From here out other threads may observe that we're initializing and so changes of state
    // require the a notification.
    klass->SetClinitThreadId(self->GetTid());
    // 初始化中
    mirror::Class::SetStatus(klass, ClassStatus::kInitializing, self);

    t0 = NanoTime();
    }

    // Initialize super classes, must be done while initializing for the JLS.
    if (!klass->IsInterface() && klass->HasSuperClass()) {
    ObjPtr<mirror::Class> super_class = klass->GetSuperClass();
    if (!super_class->IsInitialized()) {
    CHECK(!super_class->IsInterface());
    CHECK(can_init_parents);
    StackHandleScope<1> hs(self);
    Handle<mirror::Class> handle_scope_super(hs.NewHandle(super_class));
    bool super_initialized = InitializeClass(self, handle_scope_super, can_init_statics, true);
    if (!super_initialized) {
    // The super class was verified ahead of entering initializing, we should only be here if
    // the super class became erroneous due to initialization.
    // For the case of aot compiler, the super class might also be initializing but we don't
    // want to process circular dependencies in pre-compile.
    CHECK(self->IsExceptionPending())
    << "Super class initialization failed for "
    << handle_scope_super->PrettyDescriptor()
    << " that has unexpected status " << handle_scope_super->GetStatus()
    << "\nPending exception:\n"
    << (self->GetException() != nullptr ? self->GetException()->Dump() : "");
    ObjectLock<mirror::Class> lock(self, klass);
    // Initialization failed because the super-class is erroneous.
    mirror::Class::SetStatus(klass, ClassStatus::kErrorResolved, self);
    return false;
    }
    }
    }

    if (!klass->IsInterface()) {
    // Initialize interfaces with default methods for the JLS.
    size_t num_direct_interfaces = klass->NumDirectInterfaces();
    // Only setup the (expensive) handle scope if we actually need to.
    if (UNLIKELY(num_direct_interfaces > 0)) {
    StackHandleScope<1> hs_iface(self);
    MutableHandle<mirror::Class> handle_scope_iface(hs_iface.NewHandle<mirror::Class>(nullptr));
    for (size_t i = 0; i < num_direct_interfaces; i++) {
    handle_scope_iface.Assign(mirror::Class::GetDirectInterface(self, klass.Get(), i));
    CHECK(handle_scope_iface != nullptr) << klass->PrettyDescriptor() << " iface #" << i;
    CHECK(handle_scope_iface->IsInterface());
    if (handle_scope_iface->HasBeenRecursivelyInitialized()) {
    // We have already done this for this interface. Skip it.
    continue;
    }
    // We cannot just call initialize class directly because we need to ensure that ALL
    // interfaces with default methods are initialized. Non-default interface initialization
    // will not affect other non-default super-interfaces.
    bool iface_initialized = InitializeDefaultInterfaceRecursive(self,
    handle_scope_iface,
    can_init_statics,
    can_init_parents);
    if (!iface_initialized) {
    ObjectLock<mirror::Class> lock(self, klass);
    // Initialization failed because one of our interfaces with default methods is erroneous.
    mirror::Class::SetStatus(klass, ClassStatus::kErrorResolved, self);
    return false;
    }
    }
    }
    }

    const size_t num_static_fields = klass->NumStaticFields();
    if (num_static_fields > 0) {
    const dex::ClassDef* dex_class_def = klass->GetClassDef();
    CHECK(dex_class_def != nullptr);
    StackHandleScope<3> hs(self);
    Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
    Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));

    // Eagerly fill in static fields so that the we don't have to do as many expensive
    // Class::FindStaticField in ResolveField.
    for (size_t i = 0; i < num_static_fields; ++i) {
    ArtField* field = klass->GetStaticField(i);
    const uint32_t field_idx = field->GetDexFieldIndex();
    ArtField* resolved_field = dex_cache->GetResolvedField(field_idx, image_pointer_size_);
    if (resolved_field == nullptr) {
    // Populating cache of a dex file which defines `klass` should always be allowed.
    DCHECK(!hiddenapi::ShouldDenyAccessToMember(
    field,
    hiddenapi::AccessContext(class_loader.Get(), dex_cache.Get()),
    hiddenapi::AccessMethod::kNone));
    dex_cache->SetResolvedField(field_idx, field, image_pointer_size_);
    } else {
    DCHECK_EQ(field, resolved_field);
    }
    }

    annotations::RuntimeEncodedStaticFieldValueIterator value_it(dex_cache,
    class_loader,
    this,
    *dex_class_def);
    const DexFile& dex_file = *dex_cache->GetDexFile();

    if (value_it.HasNext()) {
    ClassAccessor accessor(dex_file, *dex_class_def);
    CHECK(can_init_statics);
    for (const ClassAccessor::Field& field : accessor.GetStaticFields()) {
    if (!value_it.HasNext()) {
    break;
    }
    ArtField* art_field = ResolveField(field.GetIndex(),
    dex_cache,
    class_loader,
    /* is_static= */ true);
    if (Runtime::Current()->IsActiveTransaction()) {
    value_it.ReadValueToField<true>(art_field);
    } else {
    value_it.ReadValueToField<false>(art_field);
    }
    if (self->IsExceptionPending()) {
    break;
    }
    value_it.Next();
    }
    DCHECK(self->IsExceptionPending() || !value_it.HasNext());
    }
    }


    if (!self->IsExceptionPending()) {
    ArtMethod* clinit = klass->FindClassInitializer(image_pointer_size_);
    if (clinit != nullptr) {
    CHECK(can_init_statics);
    JValue result;
    clinit->Invoke(self, nullptr, 0, &result, "V");
    }
    }
    self->AllowThreadSuspension();
    uint64_t t1 = NanoTime();

    bool success = true;
    {
    ObjectLock<mirror::Class> lock(self, klass);

    if (self->IsExceptionPending()) {
    WrapExceptionInInitializer(klass);
    mirror::Class::SetStatus(klass, ClassStatus::kErrorResolved, self);
    success = false;
    } else if (Runtime::Current()->IsTransactionAborted()) {
    // The exception thrown when the transaction aborted has been caught and cleared
    // so we need to throw it again now.
    VLOG(compiler) << "Return from class initializer of "
    << mirror::Class::PrettyDescriptor(klass.Get())
    << " without exception while transaction was aborted: re-throw it now.";
    Runtime::Current()->ThrowTransactionAbortError(self);
    mirror::Class::SetStatus(klass, ClassStatus::kErrorResolved, self);
    success = false;
    } else {
    RuntimeStats* global_stats = Runtime::Current()->GetStats();
    RuntimeStats* thread_stats = self->GetStats();
    ++global_stats->class_init_count;
    ++thread_stats->class_init_count;
    global_stats->class_init_time_ns += (t1 - t0);
    thread_stats->class_init_time_ns += (t1 - t0);
    // Set the class as initialized except if failed to initialize static fields.
    // 初始化完成
    mirror::Class::SetStatus(klass, ClassStatus::kInitialized, self);
    if (VLOG_IS_ON(class_linker)) {
    std::string temp;
    LOG(INFO) << "Initialized class " << klass->GetDescriptor(&temp) << " from " <<
    klass->GetLocation();
    }
    // Opportunistically set static method trampolines to their destination.
    FixupStaticTrampolines(klass.Get());
    }
    }
    return success;
    }