diff options
author | 2024-10-11 17:24:46 +0100 | |
---|---|---|
committer | 2024-11-12 09:08:01 +0000 | |
commit | 8666596312768c91d5d031468dfc61ed5cfe5483 (patch) | |
tree | f10fee8e2b47c9e3946f206f23ce8ef7498c9a44 | |
parent | 918a1812f609c3d380f088ea95b4d8ce967d9b50 (diff) |
Add an extra bit for intrinsics in ArtMethod
This increases the number of intrinsics from 255 to 511.
Bug: 370367478
Test: art/test/testrunner/testrunner.py --host --64 -b --optimizing
Change-Id: I9104dab59b06f4fb72c44ec9e004566cc28e668f
-rw-r--r-- | libdexfile/dex/modifiers.h | 2 | ||||
-rw-r--r-- | runtime/art_method.h | 10 | ||||
-rw-r--r-- | runtime/class_linker.cc | 13 | ||||
-rw-r--r-- | runtime/oat/image.cc | 4 |
4 files changed, 23 insertions, 6 deletions
diff --git a/libdexfile/dex/modifiers.h b/libdexfile/dex/modifiers.h index 5e5e859dc9..94e25e8e6e 100644 --- a/libdexfile/dex/modifiers.h +++ b/libdexfile/dex/modifiers.h @@ -129,7 +129,7 @@ static constexpr uint32_t kAccHiddenapiBits = kAccPublicApi | kAccCorePlatformAp // which overlap are not valid when kAccIntrinsic is set. static constexpr uint32_t kAccIntrinsicBits = kAccHiddenapiBits | kAccSingleImplementation | kAccMustCountLocks | kAccCompileDontBother | kAccCopied | - kAccPreviouslyWarm | kAccMemorySharedMethod; + kAccPreviouslyWarm | kAccMemorySharedMethod | kAccDefault; // Valid (meaningful) bits for a field. static constexpr uint32_t kAccValidFieldFlags = kAccPublic | kAccPrivate | kAccProtected | diff --git a/runtime/art_method.h b/runtime/art_method.h index 51520ddd4c..ee11328385 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -421,9 +421,13 @@ class EXPORT ArtMethod final { } static bool IsDefault(uint32_t access_flags) { - static_assert((kAccDefault & (kAccIntrinsic | kAccIntrinsicBits)) == 0, - "kAccDefault conflicts with intrinsic modifier"); - return (access_flags & kAccDefault) != 0; + // The intrinsic bits use `kAccDefault`. However, we don't generate intrinsics for default + // methods. Therefore, we check that both `kAccDefault` is set and `kAccIntrinsic` unset. + static_assert((kAccDefault & kAccIntrinsicBits) != 0, + "kAccDefault deliberately overlaps intrinsic bits"); + static constexpr uint32_t kMask = kAccIntrinsic | kAccDefault; + static constexpr uint32_t kValue = kAccDefault; + return (access_flags & kMask) == kValue; } // Returns true if the method is obsolete. diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index b4c2e4a54d..6d247a6d7a 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -77,6 +77,7 @@ #include "dex/dex_file_annotations.h" #include "dex/dex_file_exception_helpers.h" #include "dex/dex_file_loader.h" +#include "dex/modifiers.h" #include "dex/signature-inl.h" #include "dex/utf.h" #include "entrypoints/entrypoint_utils-inl.h" @@ -5530,6 +5531,9 @@ void ClassLinker::CreateProxyMethod(Handle<mirror::Class> klass, ArtMethod* prot // Clear the abstract and default flags to ensure that defaults aren't picked in // preference to the invocation handler. const uint32_t kRemoveFlags = kAccAbstract | kAccDefault; + static_assert((kAccDefault & kAccIntrinsicBits) != 0); + DCHECK(!out->IsIntrinsic()) << "Removing kAccDefault from an intrinsic would be a mistake as it " + << "overlaps with kAccIntrinsicBits."; // Make the method final. // Mark kAccCompileDontBother so that we don't take JIT samples for the method. b/62349349 const uint32_t kAddFlags = kAccFinal | kAccCompileDontBother; @@ -8200,6 +8204,9 @@ void ClassLinker::LinkMethodsHelper<kPointerSize>::ReallocMethods(ObjPtr<mirror: // TODO This is rather arbitrary. We should maybe support classes where only some of its // methods are skip_access_checks. DCHECK_EQ(new_method.GetAccessFlags() & kAccNative, 0u); + static_assert((kAccDefault & kAccIntrinsicBits) != 0); + DCHECK(!new_method.IsIntrinsic()) << "Adding kAccDefault to an intrinsic would be a " + << "mistake as it overlaps with kAccIntrinsicBits."; constexpr uint32_t kSetFlags = kAccDefault | kAccCopied; constexpr uint32_t kMaskFlags = ~kAccSkipAccessChecks; new_method.SetAccessFlags((new_method.GetAccessFlags() | kSetFlags) & kMaskFlags); @@ -8216,6 +8223,9 @@ void ClassLinker::LinkMethodsHelper<kPointerSize>::ReallocMethods(ObjPtr<mirror: uint32_t access_flags = new_method.GetAccessFlags(); DCHECK_EQ(access_flags & (kAccNative | kAccIntrinsic), 0u); constexpr uint32_t kSetFlags = kAccDefault | kAccAbstract | kAccCopied; + static_assert((kAccDefault & kAccIntrinsicBits) != 0); + DCHECK(!new_method.IsIntrinsic()) << "Adding kAccDefault to an intrinsic would be a " + << "mistake as it overlaps with kAccIntrinsicBits."; constexpr uint32_t kMaskFlags = ~(kAccSkipAccessChecks | kAccSingleImplementation); new_method.SetAccessFlags((access_flags | kSetFlags) & kMaskFlags); new_method.SetDataPtrSize(nullptr, kPointerSize); @@ -8843,6 +8853,9 @@ bool ClassLinker::LinkMethodsHelper<kPointerSize>::LinkMethods( << "This will be a fatal error in subsequent versions of android. " << "Continuing anyway."; } + static_assert((kAccDefault & kAccIntrinsicBits) != 0); + DCHECK(!m->IsIntrinsic()) << "Adding kAccDefault to an intrinsic would be a mistake as it " + << "overlaps with kAccIntrinsicBits."; m->SetAccessFlags(access_flags | kAccDefault); has_defaults = true; } diff --git a/runtime/oat/image.cc b/runtime/oat/image.cc index 1c8517bc77..77eb7df6e6 100644 --- a/runtime/oat/image.cc +++ b/runtime/oat/image.cc @@ -34,8 +34,8 @@ namespace art HIDDEN { const uint8_t ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' }; -// Use arrays for resolved methods and resolved fields in DexCache. -const uint8_t ImageHeader::kImageVersion[] = { '1', '1', '6', '\0' }; +// Last change: Add kAccDefault as an intrinsic bit. +const uint8_t ImageHeader::kImageVersion[] = { '1', '1', '7', '\0' }; ImageHeader::ImageHeader(uint32_t image_reservation_size, uint32_t component_count, |