diff options
-rw-r--r-- | compiler/driver/compiler_driver.cc | 6 | ||||
-rw-r--r-- | compiler/image_writer.cc | 6 | ||||
-rw-r--r-- | runtime/class_linker.cc | 143 | ||||
-rw-r--r-- | runtime/class_linker.h | 13 | ||||
-rw-r--r-- | runtime/class_table-inl.h | 16 | ||||
-rw-r--r-- | runtime/class_table.cc | 19 | ||||
-rw-r--r-- | runtime/class_table.h | 17 | ||||
-rw-r--r-- | runtime/debugger.cc | 2 | ||||
-rw-r--r-- | runtime/gc/space/image_space.cc | 8 | ||||
-rw-r--r-- | runtime/image.cc | 2 | ||||
-rw-r--r-- | runtime/instrumentation.cc | 2 | ||||
-rw-r--r-- | runtime/jit/jit.cc | 4 | ||||
-rw-r--r-- | runtime/utils/dex_cache_arrays_layout-inl.h | 6 |
13 files changed, 158 insertions, 86 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index f1b745895f..6bc2a13299 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -921,7 +921,7 @@ class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor { std::set<std::pair<uint16_t, const DexFile*>>& exceptions_to_resolve) : exceptions_to_resolve_(exceptions_to_resolve) {} - virtual bool Visit(mirror::Class* c) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { + virtual bool operator()(mirror::Class* c) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { const auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); for (auto& m : c->GetMethods(pointer_size)) { ResolveExceptionsForMethod(&m, pointer_size); @@ -975,7 +975,7 @@ class RecordImageClassesVisitor : public ClassVisitor { explicit RecordImageClassesVisitor(std::unordered_set<std::string>* image_classes) : image_classes_(image_classes) {} - bool Visit(mirror::Class* klass) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { + bool operator()(mirror::Class* klass) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { std::string temp; image_classes_->insert(klass->GetDescriptor(&temp)); return true; @@ -1142,7 +1142,7 @@ class ClinitImageUpdate { public: explicit FindImageClassesVisitor(ClinitImageUpdate* data) : data_(data) {} - bool Visit(mirror::Class* klass) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { + bool operator()(mirror::Class* klass) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { std::string temp; const char* name = klass->GetDescriptor(&temp); if (data_->image_class_descriptors_->find(name) != data_->image_class_descriptors_->end()) { diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index 60dfcfb508..d63fed5257 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -714,7 +714,7 @@ bool ImageWriter::AllocMemory() { class ComputeLazyFieldsForClassesVisitor : public ClassVisitor { public: - bool Visit(Class* c) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { + bool operator()(Class* c) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { StackHandleScope<1> hs(Thread::Current()); mirror::Class::ComputeName(hs.NewHandle(c)); return true; @@ -852,14 +852,14 @@ class NonImageClassesVisitor : public ClassVisitor { public: explicit NonImageClassesVisitor(ImageWriter* image_writer) : image_writer_(image_writer) {} - bool Visit(Class* klass) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { + bool operator()(Class* klass) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { if (!image_writer_->KeepClass(klass)) { classes_to_prune_.insert(klass); } return true; } - std::unordered_set<mirror::Class*> classes_to_prune_; + mutable std::unordered_set<mirror::Class*> classes_to_prune_; ImageWriter* const image_writer_; }; diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 5ef199cb60..c73949088b 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1182,11 +1182,15 @@ class VerifyClassInTableArtMethodVisitor : public ArtMethodVisitor { ClassTable* const table_; }; -void ClassLinker::UpdateAppImageClassLoadersAndDexCaches( +bool ClassLinker::UpdateAppImageClassLoadersAndDexCaches( gc::space::ImageSpace* space, Handle<mirror::ClassLoader> class_loader, Handle<mirror::ObjectArray<mirror::DexCache>> dex_caches, - bool added_class_table) { + bool added_class_table, + bool* out_forward_dex_cache_array, + std::string* out_error_msg) { + DCHECK(out_forward_dex_cache_array != nullptr); + DCHECK(out_error_msg != nullptr); Thread* const self = Thread::Current(); gc::Heap* const heap = Runtime::Current()->GetHeap(); const ImageHeader& header = space->GetImageHeader(); @@ -1194,8 +1198,11 @@ void ClassLinker::UpdateAppImageClassLoadersAndDexCaches( // class loader fields. WriterMutexLock mu(self, *Locks::classlinker_classes_lock_); ClassTable* table = InsertClassTableForClassLoader(class_loader.Get()); - // TODO: Store class table in the image to avoid manually adding the classes. - for (int32_t i = 0, num_dex_caches = dex_caches->GetLength(); i < num_dex_caches; i++) { + // Dex cache array fixup is all or nothing, we must reject app images that have mixed since we + // rely on clobering the dex cache arrays in the image to forward to bss. + size_t num_dex_caches_with_bss_arrays = 0; + const size_t num_dex_caches = dex_caches->GetLength(); + for (size_t i = 0; i < num_dex_caches; i++) { mirror::DexCache* const dex_cache = dex_caches->Get(i); const DexFile* const dex_file = dex_cache->GetDexFile(); // If the oat file expects the dex cache arrays to be in the BSS, then allocate there and @@ -1209,22 +1216,23 @@ void ClassLinker::UpdateAppImageClassLoadersAndDexCaches( CHECK_EQ(num_types, dex_cache->NumResolvedTypes()); CHECK_EQ(num_methods, dex_cache->NumResolvedMethods()); CHECK_EQ(num_fields, dex_cache->NumResolvedFields()); - if (dex_file->GetOatDexFile() != nullptr && - dex_file->GetOatDexFile()->GetDexCacheArrays() != nullptr) { + const OatFile::OatDexFile* oat_dex_file = dex_file->GetOatDexFile(); + if (oat_dex_file != nullptr && oat_dex_file->GetDexCacheArrays() != nullptr) { + ++num_dex_caches_with_bss_arrays; DexCacheArraysLayout layout(image_pointer_size_, dex_file); - uint8_t* const raw_arrays = dex_file->GetOatDexFile()->GetDexCacheArrays(); - // The space is not yet visible to the GC, we can avoid the read barriers and use - // std::copy_n. + uint8_t* const raw_arrays = oat_dex_file->GetDexCacheArrays(); + // The space is not yet visible to the GC, we can avoid the read barriers and use std::copy_n. if (num_strings != 0u) { + GcRoot<mirror::String>* const image_resolved_strings = dex_cache->GetStrings(); GcRoot<mirror::String>* const strings = reinterpret_cast<GcRoot<mirror::String>*>(raw_arrays + layout.StringsOffset()); for (size_t j = 0; kIsDebugBuild && j < num_strings; ++j) { DCHECK(strings[j].IsNull()); } - std::copy_n(dex_cache->GetStrings(), num_strings, strings); + std::copy_n(image_resolved_strings, num_strings, strings); + *reinterpret_cast<GcRoot<mirror::String>**>(image_resolved_strings) = strings; dex_cache->SetStrings(strings); } - if (num_types != 0u) { GcRoot<mirror::Class>* const image_resolved_types = dex_cache->GetResolvedTypes(); GcRoot<mirror::Class>* const types = @@ -1282,6 +1290,9 @@ void ClassLinker::UpdateAppImageClassLoadersAndDexCaches( // Update the class loader from the one in the image class loader to the one that loaded // the app image. klass->SetClassLoader(class_loader.Get()); + // The resolved type could be from another dex cache, go through the dex cache just in + // case. + klass->SetDexCacheStrings(klass->GetDexCache()->GetStrings()); // If there are multiple dex caches, there may be the same class multiple times // in different dex caches. Check for this since inserting will add duplicates // otherwise. @@ -1326,7 +1337,6 @@ void ClassLinker::UpdateAppImageClassLoadersAndDexCaches( CHECK_EQ(table->LookupByDescriptor(super_class), super_class); } } - DCHECK_EQ(klass->GetClassLoader(), class_loader.Get()); if (kIsDebugBuild) { for (ArtMethod& m : klass->GetDirectMethods(sizeof(void*))) { const void* code = m.GetEntryPointFromQuickCompiledCode(); @@ -1354,20 +1364,66 @@ void ClassLinker::UpdateAppImageClassLoadersAndDexCaches( } } } - { + *out_forward_dex_cache_array = num_dex_caches_with_bss_arrays != 0; + if (*out_forward_dex_cache_array) { + if (num_dex_caches_with_bss_arrays != num_dex_caches) { + // Reject application image since we cannot forward only some of the dex cache arrays. + // TODO: We could get around this by having a dedicated forwarding slot. It should be an + // uncommon case. + *out_error_msg = StringPrintf("Dex caches in bss does not match total: %zu vs %zu", + num_dex_caches_with_bss_arrays, + num_dex_caches); + return false; + } FixupArtMethodArrayVisitor visitor(header); header.GetImageSection(ImageHeader::kSectionArtMethods).VisitPackedArtMethods( - &visitor, space->Begin(), sizeof(void*)); + &visitor, + space->Begin(), + sizeof(void*)); Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(class_loader.Get()); } if (kIsDebugBuild) { ClassTable* const class_table = class_loader.Get()->GetClassTable(); VerifyClassInTableArtMethodVisitor visitor2(class_table); header.GetImageSection(ImageHeader::kSectionArtMethods).VisitPackedArtMethods( - &visitor2, space->Begin(), sizeof(void*)); + &visitor2, + space->Begin(), + sizeof(void*)); } + return true; } +class UpdateClassLoaderAndResolvedStringsVisitor { + public: + UpdateClassLoaderAndResolvedStringsVisitor(gc::space::ImageSpace* space, + mirror::ClassLoader* class_loader, + bool forward_strings) + : space_(space), + class_loader_(class_loader), + forward_strings_(forward_strings) {} + + bool operator()(mirror::Class* klass) const SHARED_REQUIRES(Locks::mutator_lock_) { + if (forward_strings_) { + GcRoot<mirror::String>* strings = klass->GetDexCacheStrings(); + if (strings != nullptr) { + DCHECK(space_->GetImageHeader().GetImageSection(ImageHeader::kSectionDexCacheArrays).Contains( + reinterpret_cast<uint8_t*>(strings) - space_->Begin())) + << "String dex cache array for " << PrettyClass(klass) << " is not in app image"; + GcRoot<mirror::String>* new_strings = *reinterpret_cast<GcRoot<mirror::String>**>(strings); + DCHECK_NE(strings, new_strings); + klass->SetDexCacheStrings(new_strings); + } + } + // Finally, update class loader. + klass->SetClassLoader(class_loader_); + return true; + } + + gc::space::ImageSpace* const space_; + mirror::ClassLoader* const class_loader_; + const bool forward_strings_; +}; + bool ClassLinker::AddImageSpace( gc::space::ImageSpace* space, Handle<mirror::ClassLoader> class_loader, @@ -1576,21 +1632,39 @@ bool ClassLinker::AddImageSpace( if (app_image) { GetOrCreateAllocatorForClassLoader(class_loader.Get()); // Make sure we have a linear alloc. } - if (class_table_section.Size() > 0u) { - const uint64_t start_time2 = NanoTime(); + ClassTable* class_table = nullptr; + { WriterMutexLock mu(self, *Locks::classlinker_classes_lock_); - ClassTable* const class_table = InsertClassTableForClassLoader(class_loader.Get()); - class_table->ReadFromMemory(space->Begin() + class_table_section.Offset()); - if (app_image) { - class_table->SetClassLoader(class_loader.Get()); - } else { - dex_cache_boot_image_class_lookup_required_ = false; + class_table = InsertClassTableForClassLoader(class_loader.Get()); + if (class_table_section.Size() > 0u) { + const uint64_t start_time2 = NanoTime(); + class_table->ReadFromMemory(space->Begin() + class_table_section.Offset()); + if (!app_image) { + dex_cache_boot_image_class_lookup_required_ = false; + } + VLOG(image) << "Adding class table classes took " << PrettyDuration(NanoTime() - start_time2); + added_class_table = true; } - VLOG(image) << "Adding class table classes took " << PrettyDuration(NanoTime() - start_time2); - added_class_table = true; } if (app_image) { - UpdateAppImageClassLoadersAndDexCaches(space, class_loader, dex_caches, added_class_table); + bool forward_dex_cache_arrays = false; + if (!UpdateAppImageClassLoadersAndDexCaches(space, + class_loader, + dex_caches, + added_class_table, + /*out*/&forward_dex_cache_arrays, + /*out*/error_msg)) { + return false; + } + if (added_class_table) { + WriterMutexLock mu(self, *Locks::classlinker_classes_lock_); + // Update class loader and resolved strings. If added_class_table is false, the resolved + // strings were already updated in UpdateAppImageClassLoadersAndDexCaches. + UpdateClassLoaderAndResolvedStringsVisitor visitor(space, + class_loader.Get(), + forward_dex_cache_arrays); + class_table->Visit(visitor); + } } VLOG(class_linker) << "Adding image space took " << PrettyDuration(NanoTime() - start_time); return true; @@ -1677,7 +1751,7 @@ class VisitClassLoaderClassesVisitor : public ClassLoaderVisitor { void Visit(mirror::ClassLoader* class_loader) SHARED_REQUIRES(Locks::classlinker_classes_lock_, Locks::mutator_lock_) OVERRIDE { ClassTable* const class_table = class_loader->GetClassTable(); - if (!done_ && class_table != nullptr && !class_table->Visit(visitor_)) { + if (!done_ && class_table != nullptr && !class_table->Visit(*visitor_)) { // If the visitor ClassTable returns false it means that we don't need to continue. done_ = true; } @@ -1690,7 +1764,7 @@ class VisitClassLoaderClassesVisitor : public ClassLoaderVisitor { }; void ClassLinker::VisitClassesInternal(ClassVisitor* visitor) { - if (boot_class_table_.Visit(visitor)) { + if (boot_class_table_.Visit(*visitor)) { VisitClassLoaderClassesVisitor loader_visitor(visitor); VisitClassLoaders(&loader_visitor); } @@ -1713,7 +1787,7 @@ void ClassLinker::VisitClasses(ClassVisitor* visitor) { class GetClassesInToVector : public ClassVisitor { public: - bool Visit(mirror::Class* klass) OVERRIDE { + bool operator()(mirror::Class* klass) OVERRIDE { classes_.push_back(klass); return true; } @@ -1725,7 +1799,7 @@ class GetClassInToObjectArray : public ClassVisitor { explicit GetClassInToObjectArray(mirror::ObjectArray<mirror::Class>* arr) : arr_(arr), index_(0) {} - bool Visit(mirror::Class* klass) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { + bool operator()(mirror::Class* klass) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { ++index_; if (index_ <= arr_->GetLength()) { arr_->Set(index_ - 1, klass); @@ -1746,16 +1820,17 @@ class GetClassInToObjectArray : public ClassVisitor { void ClassLinker::VisitClassesWithoutClassesLock(ClassVisitor* visitor) { // TODO: it may be possible to avoid secondary storage if we iterate over dex caches. The problem // is avoiding duplicates. + Thread* const self = Thread::Current(); if (!kMovingClasses) { + ScopedAssertNoThreadSuspension nts(self, __FUNCTION__); GetClassesInToVector accumulator; VisitClasses(&accumulator); for (mirror::Class* klass : accumulator.classes_) { - if (!visitor->Visit(klass)) { + if (!visitor->operator()(klass)) { return; } } } else { - Thread* const self = Thread::Current(); StackHandleScope<1> hs(self); auto classes = hs.NewHandle<mirror::ObjectArray<mirror::Class>>(nullptr); // We size the array assuming classes won't be added to the class table during the visit. @@ -1783,7 +1858,7 @@ void ClassLinker::VisitClassesWithoutClassesLock(ClassVisitor* visitor) { // the class table grew then the loop repeats. If classes are created after the loop has // finished then we don't visit. mirror::Class* klass = classes->Get(i); - if (klass != nullptr && !visitor->Visit(klass)) { + if (klass != nullptr && !visitor->operator()(klass)) { return; } } @@ -7157,7 +7232,7 @@ class DumpClassVisitor : public ClassVisitor { public: explicit DumpClassVisitor(int flags) : flags_(flags) {} - bool Visit(mirror::Class* klass) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { + bool operator()(mirror::Class* klass) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { klass->DumpClass(LOG(ERROR), flags_); return true; } diff --git a/runtime/class_linker.h b/runtime/class_linker.h index 5176cbd3ea..9217c32fe7 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -60,6 +60,13 @@ template<size_t kNumReferences> class PACKED(4) StackHandleScope; enum VisitRootFlags : uint8_t; +class ClassVisitor { + public: + virtual ~ClassVisitor() {} + // Return true to continue visiting. + virtual bool operator()(mirror::Class* klass) = 0; +}; + class ClassLoaderVisitor { public: virtual ~ClassLoaderVisitor() {} @@ -1007,11 +1014,13 @@ class ClassLinker { SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Locks::classlinker_classes_lock_); - void UpdateAppImageClassLoadersAndDexCaches( + bool UpdateAppImageClassLoadersAndDexCaches( gc::space::ImageSpace* space, Handle<mirror::ClassLoader> class_loader, Handle<mirror::ObjectArray<mirror::DexCache>> dex_caches, - bool added_class_table) + bool added_class_table, + bool* out_forward_dex_cache_array, + std::string* out_error_msg) REQUIRES(!dex_lock_) SHARED_REQUIRES(Locks::mutator_lock_); diff --git a/runtime/class_table-inl.h b/runtime/class_table-inl.h index aef02b6d5d..e512906507 100644 --- a/runtime/class_table-inl.h +++ b/runtime/class_table-inl.h @@ -28,6 +28,9 @@ void ClassTable::VisitRoots(Visitor& visitor) { visitor.VisitRoot(root.AddressWithoutBarrier()); } } + for (GcRoot<mirror::Object>& root : dex_files_) { + visitor.VisitRoot(root.AddressWithoutBarrier()); + } } template<class Visitor> @@ -42,6 +45,19 @@ void ClassTable::VisitRoots(const Visitor& visitor) { } } +template <typename Visitor> +bool ClassTable::Visit(Visitor& visitor) { + for (ClassSet& class_set : classes_) { + for (GcRoot<mirror::Class>& root : class_set) { + if (!visitor(root.Read())) { + return false; + } + } + } + return true; +} + + } // namespace art #endif // ART_RUNTIME_CLASS_TABLE_INL_H_ diff --git a/runtime/class_table.cc b/runtime/class_table.cc index 2a4f0e01af..afb0556e1e 100644 --- a/runtime/class_table.cc +++ b/runtime/class_table.cc @@ -73,17 +73,6 @@ mirror::Class* ClassTable::UpdateClass(const char* descriptor, mirror::Class* kl return existing; } -bool ClassTable::Visit(ClassVisitor* visitor) { - for (ClassSet& class_set : classes_) { - for (GcRoot<mirror::Class>& root : class_set) { - if (!visitor->Visit(root.Read())) { - return false; - } - } - } - return true; -} - size_t ClassTable::NumZygoteClasses() const { size_t sum = 0; for (size_t i = 0; i < classes_.size() - 1; ++i) { @@ -183,12 +172,4 @@ size_t ClassTable::ReadFromMemory(uint8_t* ptr) { return read_count; } -void ClassTable::SetClassLoader(mirror::ClassLoader* class_loader) { - for (const ClassSet& class_set : classes_) { - for (const GcRoot<mirror::Class>& root : class_set) { - root.Read()->SetClassLoader(class_loader); - } - } -} - } // namespace art diff --git a/runtime/class_table.h b/runtime/class_table.h index 0b420352c3..5f2eb48d55 100644 --- a/runtime/class_table.h +++ b/runtime/class_table.h @@ -36,13 +36,6 @@ namespace mirror { class ClassLoader; } // namespace mirror -class ClassVisitor { - public: - virtual ~ClassVisitor() {} - // Return true to continue visiting. - virtual bool Visit(mirror::Class* klass) = 0; -}; - // Each loader has a ClassTable class ClassTable { public: @@ -80,8 +73,9 @@ class ClassTable { NO_THREAD_SAFETY_ANALYSIS SHARED_REQUIRES(Locks::classlinker_classes_lock_, Locks::mutator_lock_); - // Return false if the callback told us to exit. - bool Visit(ClassVisitor* visitor) + // Stops visit if the visitor returns false. + template <typename Visitor> + bool Visit(Visitor& visitor) SHARED_REQUIRES(Locks::classlinker_classes_lock_, Locks::mutator_lock_); // Return the first class that matches the descriptor. Returns null if there are none. @@ -118,11 +112,6 @@ class ClassTable { REQUIRES(Locks::classlinker_classes_lock_) SHARED_REQUIRES(Locks::mutator_lock_); - // Change the class loader of all the contained classes. - void SetClassLoader(mirror::ClassLoader* class_loader) - REQUIRES(Locks::classlinker_classes_lock_) - SHARED_REQUIRES(Locks::mutator_lock_); - private: class ClassDescriptorHashEquals { public: diff --git a/runtime/debugger.cc b/runtime/debugger.cc index a0f875d6b8..904490aa8c 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -983,7 +983,7 @@ class ClassListCreator : public ClassVisitor { public: explicit ClassListCreator(std::vector<JDWP::RefTypeId>* classes) : classes_(classes) {} - bool Visit(mirror::Class* c) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { + bool operator()(mirror::Class* c) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { if (!c->IsPrimitive()) { classes_->push_back(Dbg::GetObjectRegistry()->AddRefType(c)); } diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index 998db5271a..08b1a0090d 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -1047,7 +1047,7 @@ static bool RelocateInPlace(ImageHeader& image_header, if (strings != nullptr) { GcRoot<mirror::String>* new_strings = fixup_adapter.ForwardObject(strings); if (strings != new_strings) { - dex_cache->SetFieldPtr64<false>(mirror::DexCache::StringsOffset(), new_strings); + dex_cache->SetStrings(new_strings); } dex_cache->FixupStrings<kWithoutReadBarrier>(new_strings, fixup_adapter); } @@ -1055,7 +1055,7 @@ static bool RelocateInPlace(ImageHeader& image_header, if (types != nullptr) { GcRoot<mirror::Class>* new_types = fixup_adapter.ForwardObject(types); if (types != new_types) { - dex_cache->SetFieldPtr64<false>(mirror::DexCache::ResolvedTypesOffset(), new_types); + dex_cache->SetResolvedTypes(new_types); } dex_cache->FixupResolvedTypes<kWithoutReadBarrier>(new_types, fixup_adapter); } @@ -1063,7 +1063,7 @@ static bool RelocateInPlace(ImageHeader& image_header, if (methods != nullptr) { ArtMethod** new_methods = fixup_adapter.ForwardObject(methods); if (methods != new_methods) { - dex_cache->SetFieldPtr64<false>(mirror::DexCache::ResolvedMethodsOffset(), new_methods); + dex_cache->SetResolvedMethods(new_methods); } for (size_t j = 0, num = dex_cache->NumResolvedMethods(); j != num; ++j) { ArtMethod* orig = mirror::DexCache::GetElementPtrSize(new_methods, j, sizeof(void*)); @@ -1077,7 +1077,7 @@ static bool RelocateInPlace(ImageHeader& image_header, if (fields != nullptr) { ArtField** new_fields = fixup_adapter.ForwardObject(fields); if (fields != new_fields) { - dex_cache->SetFieldPtr64<false>(mirror::DexCache::ResolvedFieldsOffset(), new_fields); + dex_cache->SetResolvedFields(new_fields); } for (size_t j = 0, num = dex_cache->NumResolvedFields(); j != num; ++j) { ArtField* orig = mirror::DexCache::GetElementPtrSize(new_fields, j, sizeof(void*)); diff --git a/runtime/image.cc b/runtime/image.cc index de00343451..1f54e3e6ae 100644 --- a/runtime/image.cc +++ b/runtime/image.cc @@ -24,7 +24,7 @@ namespace art { const uint8_t ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' }; -const uint8_t ImageHeader::kImageVersion[] = { '0', '2', '6', '\0' }; +const uint8_t ImageHeader::kImageVersion[] = { '0', '2', '7', '\0' }; ImageHeader::ImageHeader(uint32_t image_begin, uint32_t image_size, diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc index c57b1bbf2d..748463529e 100644 --- a/runtime/instrumentation.cc +++ b/runtime/instrumentation.cc @@ -55,7 +55,7 @@ class InstallStubsClassVisitor : public ClassVisitor { explicit InstallStubsClassVisitor(Instrumentation* instrumentation) : instrumentation_(instrumentation) {} - bool Visit(mirror::Class* klass) OVERRIDE REQUIRES(Locks::mutator_lock_) { + bool operator()(mirror::Class* klass) OVERRIDE REQUIRES(Locks::mutator_lock_) { instrumentation_->InstallStubsForClass(klass); return true; // we visit all classes. } diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc index 4e0146c603..b7111815e4 100644 --- a/runtime/jit/jit.cc +++ b/runtime/jit/jit.cc @@ -239,11 +239,11 @@ void Jit::NewTypeLoadedIfUsingJit(mirror::Class* type) { void Jit::DumpTypeInfoForLoadedTypes(ClassLinker* linker) { struct CollectClasses : public ClassVisitor { - bool Visit(mirror::Class* klass) override { + bool operator()(mirror::Class* klass) override { classes_.push_back(klass); return true; } - std::vector<mirror::Class*> classes_; + mutable std::vector<mirror::Class*> classes_; }; if (generate_debug_info_) { diff --git a/runtime/utils/dex_cache_arrays_layout-inl.h b/runtime/utils/dex_cache_arrays_layout-inl.h index f6ee6a2b1a..d63083c5c4 100644 --- a/runtime/utils/dex_cache_arrays_layout-inl.h +++ b/runtime/utils/dex_cache_arrays_layout-inl.h @@ -87,11 +87,13 @@ inline size_t DexCacheArraysLayout::StringOffset(uint32_t string_idx) const { } inline size_t DexCacheArraysLayout::StringsSize(size_t num_elements) const { - return ArraySize(sizeof(GcRoot<mirror::String>), num_elements); + // App image patching relies on having enough room for a forwarding pointer in the types array. + return std::max(ArraySize(sizeof(GcRoot<mirror::String>), num_elements), pointer_size_); } inline size_t DexCacheArraysLayout::StringsAlignment() const { - return alignof(GcRoot<mirror::String>); + // App image patching relies on having enough room for a forwarding pointer in the strings array. + return pointer_size_; } inline size_t DexCacheArraysLayout::FieldOffset(uint32_t field_idx) const { |