static jobject CreateCookieFromOatFileManagerResult( JNIEnv* env, std::vector<std::unique_ptr<const DexFile>>& dex_files, const OatFile* oat_file, conststd::vector<std::string>& error_msgs) { // 获取classLinker ClassLinker* linker = Runtime::Current()->GetClassLinker(); if (dex_files.empty()) { ScopedObjectAccess soa(env); CHECK(!error_msgs.empty()); // The most important message is at the end. So set up nesting by going forward, which will // wrap the existing exception as a cause for the following one. auto it = error_msgs.begin(); auto itEnd = error_msgs.end(); for ( ; it != itEnd; ++it) { ThrowWrappedIOException("%s", it->c_str()); } return nullptr; } // jlongArray就是mCookie,存储DexFile对象指针的数组 jlongArray array = ConvertDexFilesToJavaArray(env, oat_file, dex_files); if (array == nullptr) { ScopedObjectAccess soa(env); // 遍历dex_files数组 for (auto& dex_file : dex_files) { if (linker->IsDexFileRegistered(soa.Self(), *dex_file)) { dex_file.release(); // NOLINT } } } returnarray; }
structDexCacheData { // Construct an invalid data object. DexCacheData() : weak_root(nullptr), dex_file(nullptr), class_table(nullptr) { }
// Check if the data is valid. boolIsValid()const { return dex_file != nullptr; }
// Weak root to the DexCache. Note: Do not decode this unnecessarily or else class unloading may // not work properly. jweak weak_root; // The following field caches the DexCache's field here to avoid unnecessary jweak decode that // triggers read barriers (and marks them alive unnecessarily and messes with class unloading.) const DexFile* dex_file; // Identify the associated class loader's class table. This is used to make sure that // the Java call to native DexCache.setResolvedType() inserts the resolved type in that // class table. It is also used to make sure we don't register the same dex cache with // multiple class loaders. ClassTable* class_table; };