Rewrite Class init entrypoint to take a Class arg.
Fixes invalid type index being passed to the entrypoint for
class init check across dex files when the target type does
not have a TypeId in the compilation unit's DexFile.
The size of the aosp_taimen-userdebug prebuilts:
- before:
arm/boot*.oat: 16782748
arm64/boot*.oat: 19764400
oat/arm64/services.odex: 20162432
- after:
arm/boot*.oat: 16811692 (+28.3KiB, +0.17%)
arm64/boot*.oat: 19801032 (+35.8KiB, +0.19%)
oat/arm64/services.odex: 20232208 (+68.1KiB, +0.35%)
This increase comes from doing two runtime calls instead of
one for HLoadClass/kBssEntry that MustGenerateClinitCheck().
Test: Additional test in 476-clinit-inline-static-invoke
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing --jit
Test: Pixel 2 XL boots.
Test: testrunner.py --target --optimizing --jit
Test: testrunner.py --jvm
Bug: 111433619
Change-Id: I2fccd6944480ab4dac514f60d38e72c1014ae7b2
diff --git a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
index 85d633f..c46ea35 100644
--- a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
@@ -95,7 +95,7 @@
static inline void StoreStringInBss(ArtMethod* outer_method,
dex::StringIndex string_idx,
ObjPtr<mirror::String> resolved_string)
- REQUIRES_SHARED(Locks::mutator_lock_) __attribute__((optnone)) {
+ REQUIRES_SHARED(Locks::mutator_lock_) {
const DexFile* dex_file = outer_method->GetDexFile();
DCHECK(dex_file != nullptr);
const OatDexFile* oat_dex_file = dex_file->GetOatDexFile();
@@ -129,24 +129,22 @@
return outer_method->GetDexFile() == caller->GetDexFile();
}
-extern "C" mirror::Class* artInitializeStaticStorageFromCode(uint32_t type_idx, Thread* self)
+extern "C" mirror::Class* artInitializeStaticStorageFromCode(mirror::Class* klass, Thread* self)
REQUIRES_SHARED(Locks::mutator_lock_) {
// Called to ensure static storage base is initialized for direct static field reads and writes.
// A class may be accessing another class' fields when it doesn't have access, as access has been
// given by inheritance.
ScopedQuickEntrypointChecks sqec(self);
- auto caller_and_outer = GetCalleeSaveMethodCallerAndOuterMethod(
- self, CalleeSaveType::kSaveEverythingForClinit);
- ArtMethod* caller = caller_and_outer.caller;
- ObjPtr<mirror::Class> result = ResolveVerifyAndClinit(dex::TypeIndex(type_idx),
- caller,
- self,
- /* can_run_clinit */ true,
- /* verify_access */ false);
- if (LIKELY(result != nullptr) && CanReferenceBss(caller_and_outer.outer_method, caller)) {
- StoreTypeInBss(caller_and_outer.outer_method, dex::TypeIndex(type_idx), result);
+ DCHECK(klass != nullptr);
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ StackHandleScope<1> hs(self);
+ Handle<mirror::Class> h_klass = hs.NewHandle(klass);
+ bool success = class_linker->EnsureInitialized(
+ self, h_klass, /* can_init_fields */ true, /* can_init_parents */ true);
+ if (UNLIKELY(!success)) {
+ return nullptr;
}
- return result.Ptr();
+ return h_klass.Get();
}
extern "C" mirror::Class* artInitializeTypeFromCode(uint32_t type_idx, Thread* self)