diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/dex/dex_to_dex_compiler.cc | 2 | ||||
-rw-r--r-- | compiler/dex/mir_field_info.cc | 4 | ||||
-rw-r--r-- | compiler/dex/verified_method.cc | 2 | ||||
-rw-r--r-- | compiler/driver/compiler_driver-inl.h | 23 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.cc | 41 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.h | 22 | ||||
-rw-r--r-- | compiler/driver/compiler_driver_test.cc | 2 | ||||
-rw-r--r-- | compiler/image_test.cc | 1 | ||||
-rw-r--r-- | compiler/image_writer.cc | 256 | ||||
-rw-r--r-- | compiler/image_writer.h | 29 | ||||
-rw-r--r-- | compiler/optimizing/builder.cc | 22 | ||||
-rw-r--r-- | compiler/utils/dex_cache_arrays_layout-inl.h | 50 | ||||
-rw-r--r-- | compiler/utils/dex_cache_arrays_layout.h | 18 |
13 files changed, 328 insertions, 144 deletions
diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc index 548b6f8b63..ef94d8b66f 100644 --- a/compiler/dex/dex_to_dex_compiler.cc +++ b/compiler/dex/dex_to_dex_compiler.cc @@ -14,13 +14,13 @@ * limitations under the License. */ +#include "art_field-inl.h" #include "base/logging.h" #include "base/mutex.h" #include "dex_file-inl.h" #include "dex_instruction-inl.h" #include "driver/compiler_driver.h" #include "driver/dex_compilation_unit.h" -#include "mirror/art_field-inl.h" #include "mirror/art_method-inl.h" #include "mirror/class-inl.h" #include "mirror/dex_cache.h" diff --git a/compiler/dex/mir_field_info.cc b/compiler/dex/mir_field_info.cc index a9ab3bb0d4..4dfec176af 100644 --- a/compiler/dex/mir_field_info.cc +++ b/compiler/dex/mir_field_info.cc @@ -56,7 +56,7 @@ void MirIFieldLoweringInfo::Resolve(CompilerDriver* compiler_driver, // definition) we still want to resolve fields and record all available info. for (auto it = field_infos, end = field_infos + count; it != end; ++it) { uint32_t field_idx; - mirror::ArtField* resolved_field; + ArtField* resolved_field; if (!it->IsQuickened()) { field_idx = it->field_idx_; resolved_field = compiler_driver->ResolveField(soa, dex_cache, class_loader, mUnit, @@ -121,7 +121,7 @@ void MirSFieldLoweringInfo::Resolve(CompilerDriver* compiler_driver, for (auto it = field_infos, end = field_infos + count; it != end; ++it) { uint32_t field_idx = it->field_idx_; - mirror::ArtField* resolved_field = + ArtField* resolved_field = compiler_driver->ResolveField(soa, dex_cache, class_loader, mUnit, field_idx, true); if (UNLIKELY(resolved_field == nullptr)) { continue; diff --git a/compiler/dex/verified_method.cc b/compiler/dex/verified_method.cc index 5b90ba92e0..ae814b4029 100644 --- a/compiler/dex/verified_method.cc +++ b/compiler/dex/verified_method.cc @@ -222,7 +222,7 @@ bool VerifiedMethod::GenerateDequickenMap(verifier::MethodVerifier* method_verif } else if (IsInstructionIGetQuickOrIPutQuick(inst->Opcode())) { uint32_t dex_pc = inst->GetDexPc(insns); verifier::RegisterLine* line = method_verifier->GetRegLine(dex_pc); - mirror::ArtField* field = method_verifier->GetQuickFieldAccess(inst, line); + ArtField* field = method_verifier->GetQuickFieldAccess(inst, line); if (field == nullptr) { // It can be null if the line wasn't verified since it was unreachable. return false; diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h index 8babc28db9..b4d46954f1 100644 --- a/compiler/driver/compiler_driver-inl.h +++ b/compiler/driver/compiler_driver-inl.h @@ -19,12 +19,11 @@ #include "compiler_driver.h" +#include "art_field-inl.h" #include "dex_compilation_unit.h" -#include "mirror/art_field-inl.h" #include "mirror/art_method-inl.h" #include "mirror/class_loader.h" #include "mirror/dex_cache-inl.h" -#include "mirror/art_field-inl.h" #include "scoped_thread_state_change.h" #include "handle_scope-inl.h" @@ -65,12 +64,12 @@ inline mirror::Class* CompilerDriver::ResolveCompilingMethodsClass( return ResolveClass(soa, dex_cache, class_loader, referrer_method_id.class_idx_, mUnit); } -inline mirror::ArtField* CompilerDriver::ResolveFieldWithDexFile( +inline ArtField* CompilerDriver::ResolveFieldWithDexFile( const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexFile* dex_file, uint32_t field_idx, bool is_static) { DCHECK_EQ(dex_cache->GetDexFile(), dex_file); - mirror::ArtField* resolved_field = Runtime::Current()->GetClassLinker()->ResolveField( + ArtField* resolved_field = Runtime::Current()->GetClassLinker()->ResolveField( *dex_file, field_idx, dex_cache, class_loader, is_static); DCHECK_EQ(resolved_field == nullptr, soa.Self()->IsExceptionPending()); if (UNLIKELY(resolved_field == nullptr)) { @@ -90,7 +89,7 @@ inline mirror::DexCache* CompilerDriver::FindDexCache(const DexFile* dex_file) { return Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file); } -inline mirror::ArtField* CompilerDriver::ResolveField( +inline ArtField* CompilerDriver::ResolveField( const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, uint32_t field_idx, bool is_static) { @@ -100,7 +99,7 @@ inline mirror::ArtField* CompilerDriver::ResolveField( } inline void CompilerDriver::GetResolvedFieldDexFileLocation( - mirror::ArtField* resolved_field, const DexFile** declaring_dex_file, + ArtField* resolved_field, const DexFile** declaring_dex_file, uint16_t* declaring_class_idx, uint16_t* declaring_field_idx) { mirror::Class* declaring_class = resolved_field->GetDeclaringClass(); *declaring_dex_file = declaring_class->GetDexCache()->GetDexFile(); @@ -108,17 +107,17 @@ inline void CompilerDriver::GetResolvedFieldDexFileLocation( *declaring_field_idx = resolved_field->GetDexFieldIndex(); } -inline bool CompilerDriver::IsFieldVolatile(mirror::ArtField* field) { +inline bool CompilerDriver::IsFieldVolatile(ArtField* field) { return field->IsVolatile(); } -inline MemberOffset CompilerDriver::GetFieldOffset(mirror::ArtField* field) { +inline MemberOffset CompilerDriver::GetFieldOffset(ArtField* field) { return field->GetOffset(); } inline std::pair<bool, bool> CompilerDriver::IsFastInstanceField( mirror::DexCache* dex_cache, mirror::Class* referrer_class, - mirror::ArtField* resolved_field, uint16_t field_idx) { + ArtField* resolved_field, uint16_t field_idx) { DCHECK(!resolved_field->IsStatic()); mirror::Class* fields_class = resolved_field->GetDeclaringClass(); bool fast_get = referrer_class != nullptr && @@ -130,7 +129,7 @@ inline std::pair<bool, bool> CompilerDriver::IsFastInstanceField( inline std::pair<bool, bool> CompilerDriver::IsFastStaticField( mirror::DexCache* dex_cache, mirror::Class* referrer_class, - mirror::ArtField* resolved_field, uint16_t field_idx, uint32_t* storage_index) { + ArtField* resolved_field, uint16_t field_idx, uint32_t* storage_index) { DCHECK(resolved_field->IsStatic()); if (LIKELY(referrer_class != nullptr)) { mirror::Class* fields_class = resolved_field->GetDeclaringClass(); @@ -177,14 +176,14 @@ inline std::pair<bool, bool> CompilerDriver::IsFastStaticField( } inline bool CompilerDriver::IsStaticFieldInReferrerClass(mirror::Class* referrer_class, - mirror::ArtField* resolved_field) { + ArtField* resolved_field) { DCHECK(resolved_field->IsStatic()); mirror::Class* fields_class = resolved_field->GetDeclaringClass(); return referrer_class == fields_class; } inline bool CompilerDriver::IsStaticFieldsClassInitialized(mirror::Class* referrer_class, - mirror::ArtField* resolved_field) { + ArtField* resolved_field) { DCHECK(resolved_field->IsStatic()); mirror::Class* fields_class = resolved_field->GetDeclaringClass(); return fields_class == referrer_class || fields_class->IsInitialized(); diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index f263f6d329..6d7924890e 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -27,6 +27,7 @@ #include <malloc.h> // For mallinfo #endif +#include "art_field-inl.h" #include "base/stl_util.h" #include "base/timing_logger.h" #include "class_linker.h" @@ -48,7 +49,6 @@ #include "gc/accounting/card_table-inl.h" #include "gc/accounting/heap_bitmap.h" #include "gc/space/space.h" -#include "mirror/art_field-inl.h" #include "mirror/art_method-inl.h" #include "mirror/class_loader.h" #include "mirror/class-inl.h" @@ -1183,7 +1183,7 @@ uint32_t CompilerDriver::GetReferenceDisableFlagOffset() const { DexCacheArraysLayout CompilerDriver::GetDexCacheArraysLayout(const DexFile* dex_file) { // Currently only image dex caches have fixed array layout. return IsImage() && GetSupportBootImageFixup() - ? DexCacheArraysLayout(dex_file) + ? DexCacheArraysLayout(GetInstructionSetPointerSize(instruction_set_), dex_file) : DexCacheArraysLayout(); } @@ -1209,12 +1209,11 @@ void CompilerDriver::ProcessedInvoke(InvokeType invoke_type, int flags) { stats_->ProcessedInvoke(invoke_type, flags); } -mirror::ArtField* CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, - const DexCompilationUnit* mUnit, - bool is_put, - const ScopedObjectAccess& soa) { +ArtField* CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, + const DexCompilationUnit* mUnit, bool is_put, + const ScopedObjectAccess& soa) { // Try to resolve the field and compiling method's class. - mirror::ArtField* resolved_field; + ArtField* resolved_field; mirror::Class* referrer_class; mirror::DexCache* dex_cache; { @@ -1223,11 +1222,10 @@ mirror::ArtField* CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, hs.NewHandle(mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()))); Handle<mirror::ClassLoader> class_loader_handle( hs.NewHandle(soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()))); - Handle<mirror::ArtField> resolved_field_handle(hs.NewHandle( - ResolveField(soa, dex_cache_handle, class_loader_handle, mUnit, field_idx, false))); - referrer_class = (resolved_field_handle.Get() != nullptr) + resolved_field = + ResolveField(soa, dex_cache_handle, class_loader_handle, mUnit, field_idx, false); + referrer_class = resolved_field != nullptr ? ResolveCompilingMethodsClass(soa, dex_cache_handle, class_loader_handle, mUnit) : nullptr; - resolved_field = resolved_field_handle.Get(); dex_cache = dex_cache_handle.Get(); } bool can_link = false; @@ -1244,11 +1242,9 @@ bool CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompi bool is_put, MemberOffset* field_offset, bool* is_volatile) { ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<1> hs(soa.Self()); - Handle<mirror::ArtField> resolved_field = - hs.NewHandle(ComputeInstanceFieldInfo(field_idx, mUnit, is_put, soa)); + ArtField* resolved_field = ComputeInstanceFieldInfo(field_idx, mUnit, is_put, soa); - if (resolved_field.Get() == nullptr) { + if (resolved_field == nullptr) { // Conservative defaults. *is_volatile = true; *field_offset = MemberOffset(static_cast<size_t>(-1)); @@ -1267,20 +1263,19 @@ bool CompilerDriver::ComputeStaticFieldInfo(uint32_t field_idx, const DexCompila Primitive::Type* type) { ScopedObjectAccess soa(Thread::Current()); // Try to resolve the field and compiling method's class. - mirror::ArtField* resolved_field; + ArtField* resolved_field; mirror::Class* referrer_class; mirror::DexCache* dex_cache; { - StackHandleScope<3> hs(soa.Self()); + StackHandleScope<2> hs(soa.Self()); Handle<mirror::DexCache> dex_cache_handle( hs.NewHandle(mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()))); Handle<mirror::ClassLoader> class_loader_handle( hs.NewHandle(soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()))); - Handle<mirror::ArtField> resolved_field_handle(hs.NewHandle( - ResolveField(soa, dex_cache_handle, class_loader_handle, mUnit, field_idx, true))); - referrer_class = (resolved_field_handle.Get() != nullptr) + resolved_field = + ResolveField(soa, dex_cache_handle, class_loader_handle, mUnit, field_idx, true); + referrer_class = resolved_field != nullptr ? ResolveCompilingMethodsClass(soa, dex_cache_handle, class_loader_handle, mUnit) : nullptr; - resolved_field = resolved_field_handle.Get(); dex_cache = dex_cache_handle.Get(); } bool result = false; @@ -1728,7 +1723,7 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manag ClassDataItemIterator it(dex_file, class_data); while (it.HasNextStaticField()) { if (resolve_fields_and_methods) { - mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), + ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, class_loader, true); if (field == nullptr) { CheckAndClearResolveException(soa.Self()); @@ -1743,7 +1738,7 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manag requires_constructor_barrier = true; } if (resolve_fields_and_methods) { - mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), + ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, class_loader, false); if (field == nullptr) { CheckAndClearResolveException(soa.Self()); diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index a6ed5590dc..f1066a5005 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -239,14 +239,14 @@ class CompilerDriver { // Resolve a field. Returns nullptr on failure, including incompatible class change. // NOTE: Unlike ClassLinker's ResolveField(), this method enforces is_static. - mirror::ArtField* ResolveField( + ArtField* ResolveField( const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, uint32_t field_idx, bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Resolve a field with a given dex file. - mirror::ArtField* ResolveFieldWithDexFile( + ArtField* ResolveFieldWithDexFile( const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexFile* dex_file, uint32_t field_idx, bool is_static) @@ -254,12 +254,12 @@ class CompilerDriver { // Get declaration location of a resolved field. void GetResolvedFieldDexFileLocation( - mirror::ArtField* resolved_field, const DexFile** declaring_dex_file, + ArtField* resolved_field, const DexFile** declaring_dex_file, uint16_t* declaring_class_idx, uint16_t* declaring_field_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool IsFieldVolatile(mirror::ArtField* field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - MemberOffset GetFieldOffset(mirror::ArtField* field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool IsFieldVolatile(ArtField* field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + MemberOffset GetFieldOffset(ArtField* field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Find a dex cache for a dex file. inline mirror::DexCache* FindDexCache(const DexFile* dex_file) @@ -268,23 +268,23 @@ class CompilerDriver { // Can we fast-path an IGET/IPUT access to an instance field? If yes, compute the field offset. std::pair<bool, bool> IsFastInstanceField( mirror::DexCache* dex_cache, mirror::Class* referrer_class, - mirror::ArtField* resolved_field, uint16_t field_idx) + ArtField* resolved_field, uint16_t field_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Can we fast-path an SGET/SPUT access to a static field? If yes, compute the type index // of the declaring class in the referrer's dex file. std::pair<bool, bool> IsFastStaticField( mirror::DexCache* dex_cache, mirror::Class* referrer_class, - mirror::ArtField* resolved_field, uint16_t field_idx, uint32_t* storage_index) + ArtField* resolved_field, uint16_t field_idx, uint32_t* storage_index) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Is static field's in referrer's class? - bool IsStaticFieldInReferrerClass(mirror::Class* referrer_class, mirror::ArtField* resolved_field) + bool IsStaticFieldInReferrerClass(mirror::Class* referrer_class, ArtField* resolved_field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Is static field's class initialized? bool IsStaticFieldsClassInitialized(mirror::Class* referrer_class, - mirror::ArtField* resolved_field) + ArtField* resolved_field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Resolve a method. Returns nullptr on failure, including incompatible class change. @@ -331,7 +331,7 @@ class CompilerDriver { void ComputeFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, const ScopedObjectAccess& soa, bool is_static, - mirror::ArtField** resolved_field, + ArtField** resolved_field, mirror::Class** referrer_class, mirror::DexCache** dex_cache) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -341,7 +341,7 @@ class CompilerDriver { MemberOffset* field_offset, bool* is_volatile) LOCKS_EXCLUDED(Locks::mutator_lock_); - mirror::ArtField* ComputeInstanceFieldInfo(uint32_t field_idx, + ArtField* ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, bool is_put, const ScopedObjectAccess& soa) diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc index 5ebc029fcf..7200cdaa9f 100644 --- a/compiler/driver/compiler_driver_test.cc +++ b/compiler/driver/compiler_driver_test.cc @@ -132,7 +132,7 @@ TEST_F(CompilerDriverTest, DISABLED_LARGE_CompileDexLibCore) { } EXPECT_EQ(dex.NumFieldIds(), dex_cache->NumResolvedFields()); for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) { - mirror::ArtField* field = dex_cache->GetResolvedField(i); + ArtField* field = Runtime::Current()->GetClassLinker()->GetResolvedField(i, dex_cache); EXPECT_TRUE(field != NULL) << "field_idx=" << i << " " << dex.GetFieldDeclaringClassDescriptor(dex.GetFieldId(i)) << " " << dex.GetFieldName(dex.GetFieldId(i)); diff --git a/compiler/image_test.cc b/compiler/image_test.cc index cf979430ad..627a42e8de 100644 --- a/compiler/image_test.cc +++ b/compiler/image_test.cc @@ -205,6 +205,7 @@ TEST_F(ImageTest, ImageHeaderIsValid) { uint32_t oat_file_end = ART_BASE_ADDRESS + (10 * KB); ImageHeader image_header(image_begin, image_size_, + 0u, 0u, image_bitmap_offset, image_bitmap_size, image_roots, diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index 1ede228c4f..6f8884a9ab 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -22,6 +22,7 @@ #include <numeric> #include <vector> +#include "art_field-inl.h" #include "base/logging.h" #include "base/unix_file/fd_file.h" #include "class_linker.h" @@ -40,8 +41,8 @@ #include "globals.h" #include "image.h" #include "intern_table.h" +#include "linear_alloc.h" #include "lock_word.h" -#include "mirror/art_field-inl.h" #include "mirror/art_method-inl.h" #include "mirror/array-inl.h" #include "mirror/class-inl.h" @@ -57,7 +58,6 @@ #include "handle_scope-inl.h" #include "utils/dex_cache_arrays_layout-inl.h" -using ::art::mirror::ArtField; using ::art::mirror::ArtMethod; using ::art::mirror::Class; using ::art::mirror::DexCache; @@ -164,6 +164,9 @@ bool ImageWriter::Write(const std::string& image_filename, Thread::Current()->TransitionFromSuspendedToRunnable(); CreateHeader(oat_loaded_size, oat_data_offset); + // TODO: heap validation can't handle these fix up passes. + Runtime::Current()->GetHeap()->DisableObjectValidation(); + CopyAndFixupNativeData(); CopyAndFixupObjects(); Thread::Current()->TransitionFromRunnableToSuspended(kNative); @@ -186,9 +189,10 @@ bool ImageWriter::Write(const std::string& image_filename, return EXIT_FAILURE; } - // Write out the image. + // Write out the image + fields. + const auto write_count = image_header->GetImageSize() + image_header->GetArtFieldsSize(); CHECK_EQ(image_end_, image_header->GetImageSize()); - if (!image_file->WriteFully(image_->Begin(), image_end_)) { + if (!image_file->WriteFully(image_->Begin(), write_count)) { PLOG(ERROR) << "Failed to write image file " << image_filename; image_file->Erase(); return false; @@ -204,6 +208,8 @@ bool ImageWriter::Write(const std::string& image_filename, return false; } + CHECK_EQ(image_header->GetImageBitmapOffset() + image_header->GetImageBitmapSize(), + static_cast<size_t>(image_file->GetLength())); if (image_file->FlushCloseOrErase() != 0) { PLOG(ERROR) << "Failed to flush and close image file " << image_filename; return false; @@ -219,6 +225,8 @@ void ImageWriter::SetImageOffset(mirror::Object* object, mirror::Object* obj = reinterpret_cast<mirror::Object*>(image_->Begin() + offset); DCHECK_ALIGNED(obj, kObjectAlignment); + static size_t max_offset = 0; + max_offset = std::max(max_offset, offset); image_bitmap_->Set(obj); // Mark the obj as mutated, since we will end up changing it. { // Remember the object-inside-of-the-image's hash code so we can restore it after the copy. @@ -302,13 +310,26 @@ void ImageWriter::PrepareDexCacheArraySlots() { DexCache* dex_cache = class_linker->GetDexCache(idx); const DexFile* dex_file = dex_cache->GetDexFile(); dex_cache_array_starts_.Put(dex_file, size); - DexCacheArraysLayout layout(dex_file); + DexCacheArraysLayout layout(target_ptr_size_, dex_file); DCHECK(layout.Valid()); - dex_cache_array_indexes_.Put(dex_cache->GetResolvedTypes(), size + layout.TypesOffset()); - dex_cache_array_indexes_.Put(dex_cache->GetResolvedMethods(), size + layout.MethodsOffset()); - dex_cache_array_indexes_.Put(dex_cache->GetResolvedFields(), size + layout.FieldsOffset()); - dex_cache_array_indexes_.Put(dex_cache->GetStrings(), size + layout.StringsOffset()); + auto types_size = layout.TypesSize(dex_file->NumTypeIds()); + auto methods_size = layout.MethodsSize(dex_file->NumMethodIds()); + auto fields_size = layout.FieldsSize(dex_file->NumFieldIds()); + auto strings_size = layout.StringsSize(dex_file->NumStringIds()); + dex_cache_array_indexes_.Put( + dex_cache->GetResolvedTypes(), + DexCacheArrayLocation {size + layout.TypesOffset(), types_size}); + dex_cache_array_indexes_.Put( + dex_cache->GetResolvedMethods(), + DexCacheArrayLocation {size + layout.MethodsOffset(), methods_size}); + dex_cache_array_indexes_.Put( + dex_cache->GetResolvedFields(), + DexCacheArrayLocation {size + layout.FieldsOffset(), fields_size}); + dex_cache_array_indexes_.Put( + dex_cache->GetStrings(), + DexCacheArrayLocation {size + layout.StringsOffset(), strings_size}); size += layout.Size(); + CHECK_EQ(layout.Size(), types_size + methods_size + fields_size + strings_size); } // Set the slot size early to avoid DCHECK() failures in IsImageBinSlotAssigned() // when AssignImageBinSlot() assigns their indexes out or order. @@ -405,12 +426,20 @@ void ImageWriter::AssignImageBinSlot(mirror::Object* object) { } } else if (object->GetClass<kVerifyNone>()->IsStringClass()) { bin = kBinString; // Strings are almost always immutable (except for object header). - } else if (object->IsObjectArray()) { - auto it = dex_cache_array_indexes_.find(object); - if (it != dex_cache_array_indexes_.end()) { - bin = kBinDexCacheArray; - current_offset = it->second; // Use prepared offset defined by the DexCacheLayout. - } // else bin = kBinRegular + } else if (object->IsArrayInstance()) { + mirror::Class* klass = object->GetClass<kVerifyNone>(); + auto* component_type = klass->GetComponentType(); + if (!component_type->IsPrimitive() || component_type->IsPrimitiveInt() || + component_type->IsPrimitiveLong()) { + auto it = dex_cache_array_indexes_.find(object); + if (it != dex_cache_array_indexes_.end()) { + bin = kBinDexCacheArray; + // Use prepared offset defined by the DexCacheLayout. + current_offset = it->second.offset_; + // Override incase of cross compilation. + object_size = it->second.length_; + } // else bin = kBinRegular + } } // else bin = kBinRegular } @@ -465,7 +494,10 @@ ImageWriter::BinSlot ImageWriter::GetImageBinSlot(mirror::Object* object) const } bool ImageWriter::AllocMemory() { - size_t length = RoundUp(Runtime::Current()->GetHeap()->GetTotalMemory(), kPageSize); + auto* runtime = Runtime::Current(); + const size_t heap_size = runtime->GetHeap()->GetTotalMemory(); + // Add linear alloc usage since we need to have room for the ArtFields. + const size_t length = RoundUp(heap_size + runtime->GetLinearAlloc()->GetUsedMemory(), kPageSize); std::string error_msg; image_.reset(MemMap::MapAnonymous("image writer image", nullptr, length, PROT_READ | PROT_WRITE, false, false, &error_msg)); @@ -476,7 +508,7 @@ bool ImageWriter::AllocMemory() { // Create the image bitmap. image_bitmap_.reset(gc::accounting::ContinuousSpaceBitmap::Create("image bitmap", image_->Begin(), - length)); + RoundUp(length, kPageSize))); if (image_bitmap_.get() == nullptr) { LOG(ERROR) << "Failed to allocate memory for image bitmap"; return false; @@ -698,9 +730,9 @@ void ImageWriter::PruneNonImageClasses() { } } for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) { - ArtField* field = dex_cache->GetResolvedField(i); - if (field != NULL && !IsImageClass(field->GetDeclaringClass())) { - dex_cache->SetResolvedField(i, NULL); + ArtField* field = dex_cache->GetResolvedField(i, sizeof(void*)); + if (field != nullptr && !IsImageClass(field->GetDeclaringClass())) { + dex_cache->SetResolvedField(i, nullptr, sizeof(void*)); } } // Clean the dex field. It might have been populated during the initialization phase, but @@ -786,7 +818,7 @@ ObjectArray<Object>* ImageWriter::CreateImageRoots() const { // caches. We check that the number of dex caches does not change. size_t dex_cache_count; { - ReaderMutexLock mu(Thread::Current(), *class_linker->DexLock()); + ReaderMutexLock mu(self, *class_linker->DexLock()); dex_cache_count = class_linker->GetDexCacheCount(); } Handle<ObjectArray<Object>> dex_caches( @@ -794,7 +826,7 @@ ObjectArray<Object>* ImageWriter::CreateImageRoots() const { dex_cache_count))); CHECK(dex_caches.Get() != nullptr) << "Failed to allocate a dex cache array."; { - ReaderMutexLock mu(Thread::Current(), *class_linker->DexLock()); + ReaderMutexLock mu(self, *class_linker->DexLock()); CHECK_EQ(dex_cache_count, class_linker->GetDexCacheCount()) << "The number of dex caches changed."; for (size_t i = 0; i < dex_cache_count; ++i) { @@ -861,9 +893,9 @@ void ImageWriter::WalkFieldsInOrder(mirror::Object* obj) { WalkInstanceFields(h_obj.Get(), klass.Get()); // Walk static fields of a Class. if (h_obj->IsClass()) { - size_t num_static_fields = klass->NumReferenceStaticFields(); + size_t num_reference_static_fields = klass->NumReferenceStaticFields(); MemberOffset field_offset = klass->GetFirstReferenceStaticFieldOffset(); - for (size_t i = 0; i < num_static_fields; ++i) { + for (size_t i = 0; i < num_reference_static_fields; ++i) { mirror::Object* value = h_obj->GetFieldObject<mirror::Object>(field_offset); if (value != nullptr) { WalkFieldsInOrder(value); @@ -871,6 +903,21 @@ void ImageWriter::WalkFieldsInOrder(mirror::Object* obj) { field_offset = MemberOffset(field_offset.Uint32Value() + sizeof(mirror::HeapReference<mirror::Object>)); } + + // Visit and assign offsets for fields. + ArtField* fields[2] = { h_obj->AsClass()->GetSFields(), h_obj->AsClass()->GetIFields() }; + size_t num_fields[2] = { h_obj->AsClass()->NumStaticFields(), + h_obj->AsClass()->NumInstanceFields() }; + for (size_t i = 0; i < 2; ++i) { + for (size_t j = 0; j < num_fields[i]; ++j) { + auto* field = fields[i] + j; + auto it = art_field_reloc_.find(field); + CHECK(it == art_field_reloc_.end()) << "Field at index " << i << ":" << j + << " already assigned " << PrettyField(field); + art_field_reloc_.emplace(field, bin_slot_sizes_[kBinArtField]); + bin_slot_sizes_[kBinArtField] += sizeof(ArtField); + } + } } else if (h_obj->IsObjectArray()) { // Walk elements of an object array. int32_t length = h_obj->AsObjectArray<mirror::Object>()->GetLength(); @@ -921,7 +968,6 @@ void ImageWriter::CalculateNewObjectOffsets() { // know where image_roots is going to end up image_end_ += RoundUp(sizeof(ImageHeader), kObjectAlignment); // 64-bit-alignment - // TODO: Image spaces only? DCHECK_LT(image_end_, image_->Size()); image_objects_offset_begin_ = image_end_; // Prepare bin slots for dex cache arrays. @@ -935,34 +981,47 @@ void ImageWriter::CalculateNewObjectOffsets() { previous_sizes += bin_slot_sizes_[i]; } DCHECK_EQ(previous_sizes, GetBinSizeSum()); + DCHECK_EQ(image_end_, GetBinSizeSum(kBinMirrorCount) + image_objects_offset_begin_); + // Transform each object's bin slot into an offset which will be used to do the final copy. heap->VisitObjects(UnbinObjectsIntoOffsetCallback, this); DCHECK(saved_hashes_map_.empty()); // All binslot hashes should've been put into vector by now. - DCHECK_GT(image_end_, GetBinSizeSum()); + DCHECK_EQ(image_end_, GetBinSizeSum(kBinMirrorCount) + image_objects_offset_begin_); image_roots_address_ = PointerToLowMemUInt32(GetImageAddress(image_roots.Get())); - // Note that image_end_ is left at end of used space + // Note that image_end_ is left at end of used mirror space } void ImageWriter::CreateHeader(size_t oat_loaded_size, size_t oat_data_offset) { CHECK_NE(0U, oat_loaded_size); const uint8_t* oat_file_begin = GetOatFileBegin(); const uint8_t* oat_file_end = oat_file_begin + oat_loaded_size; - oat_data_begin_ = oat_file_begin + oat_data_offset; const uint8_t* oat_data_end = oat_data_begin_ + oat_file_->Size(); - + // Write out sections. + size_t cur_pos = image_end_; + // Add fields. + auto fields_offset = cur_pos; + CHECK_EQ(image_objects_offset_begin_ + GetBinSizeSum(kBinArtField), fields_offset); + auto fields_size = bin_slot_sizes_[kBinArtField]; + cur_pos += fields_size; // Return to write header at start of image with future location of image_roots. At this point, - // image_end_ is the size of the image (excluding bitmaps). + // image_end_ is the size of the image (excluding bitmaps, ArtFields). + /* const size_t heap_bytes_per_bitmap_byte = kBitsPerByte * kObjectAlignment; const size_t bitmap_bytes = RoundUp(image_end_, heap_bytes_per_bitmap_byte) / heap_bytes_per_bitmap_byte; + */ + const size_t bitmap_bytes = image_bitmap_->Size(); + auto bitmap_offset = RoundUp(cur_pos, kPageSize); + auto bitmap_size = RoundUp(bitmap_bytes, kPageSize); + cur_pos += bitmap_size; new (image_->Begin()) ImageHeader(PointerToLowMemUInt32(image_begin_), static_cast<uint32_t>(image_end_), - RoundUp(image_end_, kPageSize), - RoundUp(bitmap_bytes, kPageSize), + fields_offset, fields_size, + bitmap_offset, bitmap_size, image_roots_address_, oat_file_->GetOatHeader().GetChecksum(), PointerToLowMemUInt32(oat_file_begin), @@ -972,11 +1031,21 @@ void ImageWriter::CreateHeader(size_t oat_loaded_size, size_t oat_data_offset) { compile_pic_); } +void ImageWriter::CopyAndFixupNativeData() { + // Copy ArtFields to their locations and update the array for convenience. + auto fields_offset = image_objects_offset_begin_ + GetBinSizeSum(kBinArtField); + for (auto& pair : art_field_reloc_) { + pair.second += fields_offset; + auto* dest = image_->Begin() + pair.second; + DCHECK_GE(dest, image_->Begin() + image_end_); + memcpy(dest, pair.first, sizeof(ArtField)); + reinterpret_cast<ArtField*>(dest)->SetDeclaringClass( + down_cast<Class*>(GetImageAddress(pair.first->GetDeclaringClass()))); + } +} + void ImageWriter::CopyAndFixupObjects() { gc::Heap* heap = Runtime::Current()->GetHeap(); - // TODO: heap validation can't handle this fix up pass - heap->DisableObjectValidation(); - // TODO: Image spaces only? heap->VisitObjects(CopyAndFixupObjectsCallback, this); // Fix up the object previously had hash codes. for (const std::pair<mirror::Object*, uint32_t>& hash_pair : saved_hashes_) { @@ -990,26 +1059,88 @@ void ImageWriter::CopyAndFixupObjects() { void ImageWriter::CopyAndFixupObjectsCallback(Object* obj, void* arg) { DCHECK(obj != nullptr); DCHECK(arg != nullptr); - ImageWriter* image_writer = reinterpret_cast<ImageWriter*>(arg); + reinterpret_cast<ImageWriter*>(arg)->CopyAndFixupObject(obj); +} + +bool ImageWriter::CopyAndFixupIfDexCacheFieldArray(mirror::Object* dst, mirror::Object* obj, + mirror::Class* klass) { + if (!klass->IsArrayClass()) { + return false; + } + auto* component_type = klass->GetComponentType(); + bool is_int_arr = component_type->IsPrimitiveInt(); + bool is_long_arr = component_type->IsPrimitiveLong(); + if (!is_int_arr && !is_long_arr) { + return false; + } + auto it = dex_cache_array_indexes_.find(obj); // Is this a dex cache array? + if (it == dex_cache_array_indexes_.end()) { + return false; + } + mirror::Array* arr = obj->AsArray(); + CHECK_EQ(reinterpret_cast<Object*>( + image_->Begin() + it->second.offset_ + image_objects_offset_begin_), dst); + dex_cache_array_indexes_.erase(it); + // Fixup int pointers for the field array. + CHECK(!arr->IsObjectArray()); + const size_t num_elements = arr->GetLength(); + if (target_ptr_size_ == 4) { + // Will get fixed up by fixup object. + dst->SetClass(down_cast<mirror::Class*>( + GetImageAddress(mirror::IntArray::GetArrayClass()))); + } else { + DCHECK_EQ(target_ptr_size_, 8u); + dst->SetClass(down_cast<mirror::Class*>( + GetImageAddress(mirror::LongArray::GetArrayClass()))); + } + mirror::Array* dest_array = down_cast<mirror::Array*>(dst); + dest_array->SetLength(num_elements); + for (size_t i = 0, count = num_elements; i < count; ++i) { + ArtField* field = reinterpret_cast<ArtField*>(is_int_arr ? + arr->AsIntArray()->GetWithoutChecks(i) : arr->AsLongArray()->GetWithoutChecks(i)); + uint8_t* fixup_location = nullptr; + if (field != nullptr) { + auto it2 = art_field_reloc_.find(field); + CHECK(it2 != art_field_reloc_.end()) << "No relocation for field " << PrettyField(field); + fixup_location = image_begin_ + it2->second; + } + if (target_ptr_size_ == 4) { + down_cast<mirror::IntArray*>(dest_array)->SetWithoutChecks<kVerifyNone>( + i, static_cast<uint32_t>(reinterpret_cast<uint64_t>(fixup_location))); + } else { + down_cast<mirror::LongArray*>(dest_array)->SetWithoutChecks<kVerifyNone>( + i, reinterpret_cast<uint64_t>(fixup_location)); + } + } + dst->SetLockWord(LockWord::Default(), false); + return true; +} + +void ImageWriter::CopyAndFixupObject(Object* obj) { // see GetLocalAddress for similar computation - size_t offset = image_writer->GetImageOffset(obj); - uint8_t* dst = image_writer->image_->Begin() + offset; + size_t offset = GetImageOffset(obj); + auto* dst = reinterpret_cast<Object*>(image_->Begin() + offset); const uint8_t* src = reinterpret_cast<const uint8_t*>(obj); size_t n; - if (obj->IsArtMethod()) { + mirror::Class* klass = obj->GetClass(); + + if (CopyAndFixupIfDexCacheFieldArray(dst, obj, klass)) { + return; + } + if (klass->IsArtMethodClass()) { // Size without pointer fields since we don't want to overrun the buffer if target art method // is 32 bits but source is 64 bits. - n = mirror::ArtMethod::SizeWithoutPointerFields(image_writer->target_ptr_size_); + n = mirror::ArtMethod::SizeWithoutPointerFields(target_ptr_size_); } else { n = obj->SizeOf(); } - DCHECK_LT(offset + n, image_writer->image_->Size()); + DCHECK_LE(offset + n, image_->Size()); memcpy(dst, src, n); - Object* copy = reinterpret_cast<Object*>(dst); + // Write in a hash code of objects which have inflated monitors or a hash code in their monitor // word. - copy->SetLockWord(LockWord::Default(), false); - image_writer->FixupObject(obj, copy); + dst->SetLockWord(LockWord::Default(), false); + FixupObject(obj, dst); } // Rewrite all the references in the copied object to point to their image address equivalent @@ -1045,15 +1176,10 @@ class FixupClassVisitor FINAL : public FixupVisitor { FixupClassVisitor(ImageWriter* image_writer, Object* copy) : FixupVisitor(image_writer, copy) { } - void operator()(Object* obj, MemberOffset offset, bool /*is_static*/) const + void operator()(Object* obj, MemberOffset offset, bool is_static ATTRIBUTE_UNUSED) const EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_) { DCHECK(obj->IsClass()); FixupVisitor::operator()(obj, offset, /*is_static*/false); - - // TODO: Remove dead code - if (offset.Uint32Value() < mirror::Class::EmbeddedVTableOffset().Uint32Value()) { - return; - } } void operator()(mirror::Class* klass ATTRIBUTE_UNUSED, @@ -1064,6 +1190,31 @@ class FixupClassVisitor FINAL : public FixupVisitor { } }; +void ImageWriter::FixupClass(mirror::Class* orig, mirror::Class* copy) { + // Copy and fix up ArtFields in the class. + ArtField* fields[2] = { orig->AsClass()->GetSFields(), orig->AsClass()->GetIFields() }; + size_t num_fields[2] = { orig->AsClass()->NumStaticFields(), + orig->AsClass()->NumInstanceFields() }; + // Update the arrays. + for (size_t i = 0; i < 2; ++i) { + if (num_fields[i] == 0) { + CHECK(fields[i] == nullptr); + continue; + } + auto it = art_field_reloc_.find(fields[i]); + CHECK(it != art_field_reloc_.end()) << PrettyClass(orig->AsClass()) << " : " + << PrettyField(fields[i]); + auto* image_fields = reinterpret_cast<ArtField*>(image_begin_ + it->second); + if (i == 0) { + down_cast<Class*>(copy)->SetSFieldsUnchecked(image_fields); + } else { + down_cast<Class*>(copy)->SetIFieldsUnchecked(image_fields); + } + } + FixupClassVisitor visitor(this, copy); + static_cast<mirror::Object*>(orig)->VisitReferences<true /*visit class*/>(visitor, visitor); +} + void ImageWriter::FixupObject(Object* orig, Object* copy) { DCHECK(orig != nullptr); DCHECK(copy != nullptr); @@ -1075,9 +1226,8 @@ void ImageWriter::FixupObject(Object* orig, Object* copy) { DCHECK_EQ(copy->GetReadBarrierPointer(), GetImageAddress(orig)); } } - if (orig->IsClass() && orig->AsClass()->ShouldHaveEmbeddedImtAndVTable()) { - FixupClassVisitor visitor(this, copy); - orig->VisitReferences<true /*visit class*/>(visitor, visitor); + if (orig->IsClass()) { + FixupClass(orig->AsClass<kVerifyNone>(), down_cast<mirror::Class*>(copy)); } else { FixupVisitor visitor(this, copy); orig->VisitReferences<true /*visit class*/>(visitor, visitor); diff --git a/compiler/image_writer.h b/compiler/image_writer.h index 71044f7b6e..a2d99eeb96 100644 --- a/compiler/image_writer.h +++ b/compiler/image_writer.h @@ -90,7 +90,7 @@ class ImageWriter FINAL { } uint8_t* GetOatFileBegin() const { - return image_begin_ + RoundUp(image_end_, kPageSize); + return image_begin_ + RoundUp(image_end_ + bin_slot_sizes_[kBinArtField], kPageSize); } bool Write(const std::string& image_filename, @@ -127,12 +127,16 @@ class ImageWriter FINAL { kBinArtMethodNative, // Art method that is actually native kBinArtMethodNotInitialized, // Art method with a declaring class that wasn't initialized // Add more bins here if we add more segregation code. + // Non mirror fields must be below. ArtFields should be always clean. + kBinArtField, kBinSize, + // Number of bins which are for mirror objects. + kBinMirrorCount = kBinArtField, }; friend std::ostream& operator<<(std::ostream& stream, const Bin& bin); - static constexpr size_t kBinBits = MinimumBitsToStore(kBinSize - 1); + static constexpr size_t kBinBits = MinimumBitsToStore(kBinMirrorCount - 1); // uint32 = typeof(lockword_) static constexpr size_t kBinShift = BitSizeOf<uint32_t>() - kBinBits; // 111000.....0 @@ -251,11 +255,18 @@ class ImageWriter FINAL { SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Creates the contiguous image in memory and adjusts pointers. + void CopyAndFixupNativeData() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void CopyAndFixupObjects() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); static void CopyAndFixupObjectsCallback(mirror::Object* obj, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void CopyAndFixupObject(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool CopyAndFixupIfDexCacheFieldArray(mirror::Object* dst, mirror::Object* obj, + mirror::Class* klass) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void FixupMethod(mirror::ArtMethod* orig, mirror::ArtMethod* copy) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void FixupClass(mirror::Class* orig, mirror::Class* copy) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void FixupObject(mirror::Object* orig, mirror::Object* copy) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -295,8 +306,13 @@ class ImageWriter FINAL { // Memory mapped for generating the image. std::unique_ptr<MemMap> image_; - // Indexes for dex cache arrays (objects are inside of the image so that they don't move). - SafeMap<mirror::Object*, size_t> dex_cache_array_indexes_; + // Indexes, lengths for dex cache arrays (objects are inside of the image so that they don't + // move). + struct DexCacheArrayLocation { + size_t offset_; + size_t length_; + }; + SafeMap<mirror::Object*, DexCacheArrayLocation> dex_cache_array_indexes_; // The start offsets of the dex cache arrays. SafeMap<const DexFile*, size_t> dex_cache_array_starts_; @@ -331,6 +347,11 @@ class ImageWriter FINAL { size_t bin_slot_previous_sizes_[kBinSize]; // Number of bytes in previous bins. size_t bin_slot_count_[kBinSize]; // Number of objects in a bin + // ArtField relocating map, ArtFields are allocated as array of structs but we want to have one + // entry per art field for convenience. + // ArtFields are placed right after the end of the image objects (aka sum of bin_slot_sizes_). + std::unordered_map<ArtField*, uintptr_t> art_field_reloc_; + void* string_data_array_; // The backing for the interned strings. friend class FixupVisitor; diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index a912d4ccc4..8a64d81485 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -16,16 +16,13 @@ #include "builder.h" +#include "art_field-inl.h" #include "base/logging.h" #include "class_linker.h" -#include "dex_file.h" #include "dex_file-inl.h" -#include "dex_instruction.h" #include "dex_instruction-inl.h" #include "driver/compiler_driver-inl.h" #include "driver/compiler_options.h" -#include "mirror/art_field.h" -#include "mirror/art_field-inl.h" #include "mirror/class_loader.h" #include "mirror/dex_cache.h" #include "nodes.h" @@ -656,11 +653,10 @@ bool HGraphBuilder::BuildInstanceFieldAccess(const Instruction& instruction, uint16_t field_index = instruction.VRegC_22c(); ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<1> hs(soa.Self()); - Handle<mirror::ArtField> resolved_field(hs.NewHandle( - compiler_driver_->ComputeInstanceFieldInfo(field_index, dex_compilation_unit_, is_put, soa))); + ArtField* resolved_field = + compiler_driver_->ComputeInstanceFieldInfo(field_index, dex_compilation_unit_, is_put, soa); - if (resolved_field.Get() == nullptr) { + if (resolved_field == nullptr) { MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedField); return false; } @@ -728,15 +724,15 @@ bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction, uint16_t field_index = instruction.VRegB_21c(); ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<5> hs(soa.Self()); + StackHandleScope<4> hs(soa.Self()); Handle<mirror::DexCache> dex_cache(hs.NewHandle( dex_compilation_unit_->GetClassLinker()->FindDexCache(*dex_compilation_unit_->GetDexFile()))); Handle<mirror::ClassLoader> class_loader(hs.NewHandle( soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader()))); - Handle<mirror::ArtField> resolved_field(hs.NewHandle(compiler_driver_->ResolveField( - soa, dex_cache, class_loader, dex_compilation_unit_, field_index, true))); + ArtField* resolved_field = compiler_driver_->ResolveField( + soa, dex_cache, class_loader, dex_compilation_unit_, field_index, true); - if (resolved_field.Get() == nullptr) { + if (resolved_field == nullptr) { MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedField); return false; } @@ -758,7 +754,7 @@ bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction, std::pair<bool, bool> pair = compiler_driver_->IsFastStaticField( outer_dex_cache.Get(), referrer_class.Get(), - resolved_field.Get(), + resolved_field, field_index, &storage_index); bool can_easily_access = is_put ? pair.second : pair.first; diff --git a/compiler/utils/dex_cache_arrays_layout-inl.h b/compiler/utils/dex_cache_arrays_layout-inl.h index 7d02ce35d8..2c50c96305 100644 --- a/compiler/utils/dex_cache_arrays_layout-inl.h +++ b/compiler/utils/dex_cache_arrays_layout-inl.h @@ -26,7 +26,6 @@ #include "utils.h" namespace mirror { -class ArtField; class ArtMethod; class Class; class String; @@ -34,40 +33,55 @@ class String; namespace art { -inline DexCacheArraysLayout::DexCacheArraysLayout(const DexFile* dex_file) +inline DexCacheArraysLayout::DexCacheArraysLayout(size_t pointer_size, const DexFile* dex_file) : /* types_offset_ is always 0u */ - methods_offset_(types_offset_ + ArraySize<mirror::Class>(dex_file->NumTypeIds())), - strings_offset_(methods_offset_ + ArraySize<mirror::ArtMethod>(dex_file->NumMethodIds())), - fields_offset_(strings_offset_ + ArraySize<mirror::String>(dex_file->NumStringIds())), - size_(fields_offset_ + ArraySize<mirror::ArtField>(dex_file->NumFieldIds())) { + pointer_size_(pointer_size), + methods_offset_(types_offset_ + TypesSize(dex_file->NumTypeIds())), + strings_offset_(methods_offset_ + MethodsSize(dex_file->NumMethodIds())), + fields_offset_(strings_offset_ + StringsSize(dex_file->NumStringIds())), + size_(fields_offset_ + FieldsSize(dex_file->NumFieldIds())) { + DCHECK(pointer_size == 4u || pointer_size == 8u); } inline size_t DexCacheArraysLayout::TypeOffset(uint32_t type_idx) const { - return types_offset_ + ElementOffset<mirror::Class>(type_idx); + return types_offset_ + ElementOffset(sizeof(mirror::HeapReference<mirror::Class>), type_idx); +} + +inline size_t DexCacheArraysLayout::TypesSize(size_t num_elements) const { + return ArraySize(sizeof(mirror::HeapReference<mirror::Class>), num_elements); } inline size_t DexCacheArraysLayout::MethodOffset(uint32_t method_idx) const { - return methods_offset_ + ElementOffset<mirror::ArtMethod>(method_idx); + return methods_offset_ + ElementOffset( + sizeof(mirror::HeapReference<mirror::ArtMethod>), method_idx); +} + +inline size_t DexCacheArraysLayout::MethodsSize(size_t num_elements) const { + return ArraySize(sizeof(mirror::HeapReference<mirror::ArtMethod>), num_elements); } inline size_t DexCacheArraysLayout::StringOffset(uint32_t string_idx) const { - return strings_offset_ + ElementOffset<mirror::String>(string_idx); + return strings_offset_ + ElementOffset(sizeof(mirror::HeapReference<mirror::String>), string_idx); +} + +inline size_t DexCacheArraysLayout::StringsSize(size_t num_elements) const { + return ArraySize(sizeof(mirror::HeapReference<mirror::String>), num_elements); } inline size_t DexCacheArraysLayout::FieldOffset(uint32_t field_idx) const { - return fields_offset_ + ElementOffset<mirror::ArtField>(field_idx); + return fields_offset_ + ElementOffset(pointer_size_, field_idx); +} + +inline size_t DexCacheArraysLayout::FieldsSize(size_t num_elements) const { + return ArraySize(pointer_size_, num_elements); } -template <typename MirrorType> -inline size_t DexCacheArraysLayout::ElementOffset(uint32_t idx) { - return mirror::Array::DataOffset(sizeof(mirror::HeapReference<MirrorType>)).Uint32Value() + - sizeof(mirror::HeapReference<MirrorType>) * idx; +inline size_t DexCacheArraysLayout::ElementOffset(size_t element_size, uint32_t idx) { + return mirror::Array::DataOffset(element_size).Uint32Value() + element_size * idx; } -template <typename MirrorType> -inline size_t DexCacheArraysLayout::ArraySize(uint32_t num_elements) { - size_t array_size = mirror::ComputeArraySize( - num_elements, ComponentSizeShiftWidth<sizeof(mirror::HeapReference<MirrorType>)>()); +inline size_t DexCacheArraysLayout::ArraySize(size_t element_size, uint32_t num_elements) { + size_t array_size = mirror::ComputeArraySize(num_elements, ComponentSizeShiftWidth(element_size)); DCHECK_NE(array_size, 0u); // No overflow expected for dex cache arrays. return RoundUp(array_size, kObjectAlignment); } diff --git a/compiler/utils/dex_cache_arrays_layout.h b/compiler/utils/dex_cache_arrays_layout.h index b461256f63..8f98ea11ba 100644 --- a/compiler/utils/dex_cache_arrays_layout.h +++ b/compiler/utils/dex_cache_arrays_layout.h @@ -29,6 +29,7 @@ class DexCacheArraysLayout { // Construct an invalid layout. DexCacheArraysLayout() : /* types_offset_ is always 0u */ + pointer_size_(0u), methods_offset_(0u), strings_offset_(0u), fields_offset_(0u), @@ -36,7 +37,7 @@ class DexCacheArraysLayout { } // Construct a layout for a particular dex file. - explicit DexCacheArraysLayout(const DexFile* dex_file); + explicit DexCacheArraysLayout(size_t pointer_size, const DexFile* dex_file); bool Valid() const { return Size() != 0u; @@ -52,36 +53,43 @@ class DexCacheArraysLayout { size_t TypeOffset(uint32_t type_idx) const; + size_t TypesSize(size_t num_elements) const; + size_t MethodsOffset() const { return methods_offset_; } size_t MethodOffset(uint32_t method_idx) const; + size_t MethodsSize(size_t num_elements) const; + size_t StringsOffset() const { return strings_offset_; } size_t StringOffset(uint32_t string_idx) const; + size_t StringsSize(size_t num_elements) const; + size_t FieldsOffset() const { return fields_offset_; } size_t FieldOffset(uint32_t field_idx) const; + size_t FieldsSize(size_t num_elements) const; + private: static constexpr size_t types_offset_ = 0u; + const size_t pointer_size_; // Must be first for construction initialization order. const size_t methods_offset_; const size_t strings_offset_; const size_t fields_offset_; const size_t size_; - template <typename MirrorType> - static size_t ElementOffset(uint32_t idx); + static size_t ElementOffset(size_t element_size, uint32_t idx); - template <typename MirrorType> - static size_t ArraySize(uint32_t num_elements); + static size_t ArraySize(size_t element_size, uint32_t num_elements); }; } // namespace art |