diff options
89 files changed, 5946 insertions, 1371 deletions
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk index e5258087db..5c49f193a5 100644 --- a/build/Android.gtest.mk +++ b/build/Android.gtest.mk @@ -93,7 +93,7 @@ ART_GTEST_class_table_test_DEX_DEPS := XandY ART_GTEST_compiler_driver_test_DEX_DEPS := AbstractMethod StaticLeafMethods ProfileTestMultiDex ART_GTEST_dex_cache_test_DEX_DEPS := Main Packages MethodTypes ART_GTEST_dex_file_test_DEX_DEPS := GetMethodSignature Main Nested -ART_GTEST_dex2oat_test_DEX_DEPS := $(ART_GTEST_dex2oat_environment_tests_DEX_DEPS) Statics +ART_GTEST_dex2oat_test_DEX_DEPS := $(ART_GTEST_dex2oat_environment_tests_DEX_DEPS) Statics VerifierDeps ART_GTEST_exception_test_DEX_DEPS := ExceptionHandle ART_GTEST_image_test_DEX_DEPS := ImageLayoutA ImageLayoutB ART_GTEST_imtable_test_DEX_DEPS := IMTA IMTB diff --git a/compiler/compiler.h b/compiler/compiler.h index 2ca0b77a73..908d3669ed 100644 --- a/compiler/compiler.h +++ b/compiler/compiler.h @@ -27,6 +27,7 @@ namespace jit { class JitCodeCache; } namespace mirror { + class ClassLoader; class DexCache; } @@ -63,7 +64,7 @@ class Compiler { InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx, - jobject class_loader, + Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file, Handle<mirror::DexCache> dex_cache) const = 0; diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc index d4f6545c59..76aeaa55d7 100644 --- a/compiler/dex/dex_to_dex_compiler.cc +++ b/compiler/dex/dex_to_dex_compiler.cc @@ -284,16 +284,13 @@ void DexCompiler::CompileInvokeVirtual(Instruction* inst, uint32_t dex_pc, } uint32_t method_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c(); ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<1> hs(soa.Self()); - Handle<mirror::ClassLoader> class_loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader>(unit_.GetClassLoader()))); ClassLinker* class_linker = unit_.GetClassLinker(); ArtMethod* resolved_method = class_linker->ResolveMethod<ClassLinker::kForceICCECheck>( GetDexFile(), method_idx, unit_.GetDexCache(), - class_loader, + unit_.GetClassLoader(), /* referrer */ nullptr, kVirtual); @@ -330,7 +327,7 @@ CompiledMethod* ArtCompileDEX( InvokeType invoke_type ATTRIBUTE_UNUSED, uint16_t class_def_idx, uint32_t method_idx, - jobject class_loader, + Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file, DexToDexCompilationLevel dex_to_dex_compilation_level) { DCHECK(driver != nullptr); diff --git a/compiler/dex/dex_to_dex_compiler.h b/compiler/dex/dex_to_dex_compiler.h index 0a00d45297..00c596d60e 100644 --- a/compiler/dex/dex_to_dex_compiler.h +++ b/compiler/dex/dex_to_dex_compiler.h @@ -18,6 +18,7 @@ #define ART_COMPILER_DEX_DEX_TO_DEX_COMPILER_H_ #include "dex_file.h" +#include "handle.h" #include "invoke_type.h" namespace art { @@ -25,6 +26,10 @@ namespace art { class CompiledMethod; class CompilerDriver; +namespace mirror { +class ClassLoader; +} // namespace mirror + namespace optimizer { enum class DexToDexCompilationLevel { @@ -40,7 +45,7 @@ CompiledMethod* ArtCompileDEX(CompilerDriver* driver, InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx, - jobject class_loader, + Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file, DexToDexCompilationLevel dex_to_dex_compilation_level); diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h index f296851ebf..582330611d 100644 --- a/compiler/driver/compiler_driver-inl.h +++ b/compiler/driver/compiler_driver-inl.h @@ -31,17 +31,12 @@ namespace art { -inline mirror::ClassLoader* CompilerDriver::GetClassLoader(const ScopedObjectAccess& soa, - const DexCompilationUnit* mUnit) { - return soa.Decode<mirror::ClassLoader>(mUnit->GetClassLoader()).Ptr(); -} - inline mirror::Class* CompilerDriver::ResolveClass( const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, dex::TypeIndex cls_index, const DexCompilationUnit* mUnit) { DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); - DCHECK_EQ(class_loader.Get(), GetClassLoader(soa, mUnit)); + DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get()); mirror::Class* cls = mUnit->GetClassLinker()->ResolveType( *mUnit->GetDexFile(), cls_index, dex_cache, class_loader); DCHECK_EQ(cls == nullptr, soa.Self()->IsExceptionPending()); @@ -56,7 +51,7 @@ inline mirror::Class* CompilerDriver::ResolveCompilingMethodsClass( const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit) { DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); - DCHECK_EQ(class_loader.Get(), GetClassLoader(soa, mUnit)); + DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get()); const DexFile::MethodId& referrer_method_id = mUnit->GetDexFile()->GetMethodId(mUnit->GetDexMethodIndex()); return ResolveClass(soa, dex_cache, class_loader, referrer_method_id.class_idx_, mUnit); @@ -87,7 +82,7 @@ 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) { - DCHECK_EQ(class_loader.Get(), GetClassLoader(soa, mUnit)); + DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get()); return ResolveFieldWithDexFile(soa, dex_cache, class_loader, mUnit->GetDexFile(), field_idx, is_static); } @@ -139,7 +134,7 @@ inline ArtMethod* CompilerDriver::ResolveMethod( ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, uint32_t method_idx, InvokeType invoke_type, bool check_incompatible_class_change) { - DCHECK_EQ(class_loader.Get(), GetClassLoader(soa, mUnit)); + DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get()); ArtMethod* resolved_method = check_incompatible_class_change ? mUnit->GetClassLinker()->ResolveMethod<ClassLinker::kForceICCECheck>( diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 7af850a263..b738d5ce7e 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -583,7 +583,7 @@ static void CompileMethod(Thread* self, InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx, - jobject class_loader, + Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file, optimizer::DexToDexCompilationLevel dex_to_dex_compilation_level, bool compilation_enabled, @@ -624,9 +624,6 @@ static void CompileMethod(Thread* self, // Look-up the ArtMethod associated with this code_item (if any) // -- It is later used to lookup any [optimization] annotations for this method. ScopedObjectAccess soa(self); - StackHandleScope<1> hs(soa.Self()); - Handle<mirror::ClassLoader> class_loader_handle(hs.NewHandle( - soa.Decode<mirror::ClassLoader>(class_loader))); // TODO: Lookup annotation from DexFile directly without resolving method. ArtMethod* method = @@ -634,7 +631,7 @@ static void CompileMethod(Thread* self, dex_file, method_idx, dex_cache, - class_loader_handle, + class_loader, /* referrer */ nullptr, invoke_type); @@ -681,9 +678,14 @@ static void CompileMethod(Thread* self, if (compile) { // NOTE: if compiler declines to compile this method, it will return null. - compiled_method = driver->GetCompiler()->Compile(code_item, access_flags, invoke_type, - class_def_idx, method_idx, class_loader, - dex_file, dex_cache); + compiled_method = driver->GetCompiler()->Compile(code_item, + access_flags, + invoke_type, + class_def_idx, + method_idx, + class_loader, + dex_file, + dex_cache); } if (compiled_method == nullptr && dex_to_dex_compilation_level != optimizer::DexToDexCompilationLevel::kDontDexToDexCompile) { @@ -730,12 +732,14 @@ void CompilerDriver::CompileOne(Thread* self, ArtMethod* method, TimingLogger* t uint32_t method_idx = method->GetDexMethodIndex(); uint32_t access_flags = method->GetAccessFlags(); InvokeType invoke_type = method->GetInvokeType(); - StackHandleScope<1> hs(self); + StackHandleScope<2> hs(self); Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache())); + Handle<mirror::ClassLoader> class_loader( + hs.NewHandle(method->GetDeclaringClass()->GetClassLoader())); { ScopedObjectAccessUnchecked soa(self); ScopedLocalRef<jobject> local_class_loader( - soa.Env(), soa.AddLocalReference<jobject>(method->GetDeclaringClass()->GetClassLoader())); + soa.Env(), soa.AddLocalReference<jobject>(class_loader.Get())); jclass_loader = soa.Env()->NewGlobalRef(local_class_loader.get()); // Find the dex_file dex_file = method->GetDexFile(); @@ -769,7 +773,7 @@ void CompilerDriver::CompileOne(Thread* self, ArtMethod* method, TimingLogger* t invoke_type, class_def_idx, method_idx, - jclass_loader, + class_loader, *dex_file, dex_to_dex_compilation_level, true, @@ -795,7 +799,7 @@ void CompilerDriver::CompileOne(Thread* self, ArtMethod* method, TimingLogger* t invoke_type, class_def_idx, method_idx, - jclass_loader, + class_loader, *dex_file, dex_to_dex_compilation_level, true, @@ -1070,22 +1074,30 @@ bool CompilerDriver::ShouldCompileBasedOnProfile(const MethodReference& method_r class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor { public: - explicit ResolveCatchBlockExceptionsClassVisitor( - std::set<std::pair<dex::TypeIndex, const DexFile*>>& exceptions_to_resolve) - : exceptions_to_resolve_(exceptions_to_resolve) {} + ResolveCatchBlockExceptionsClassVisitor() : classes_() {} virtual bool operator()(ObjPtr<mirror::Class> c) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) { + classes_.push_back(c); + return true; + } + + void FindExceptionTypesToResolve( + std::set<std::pair<dex::TypeIndex, const DexFile*>>* exceptions_to_resolve) + REQUIRES_SHARED(Locks::mutator_lock_) { const auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); - for (auto& m : c->GetMethods(pointer_size)) { - ResolveExceptionsForMethod(&m); + for (ObjPtr<mirror::Class> klass : classes_) { + for (ArtMethod& method : klass->GetMethods(pointer_size)) { + FindExceptionTypesToResolveForMethod(&method, exceptions_to_resolve); + } } - return true; } private: - void ResolveExceptionsForMethod(ArtMethod* method_handle) + void FindExceptionTypesToResolveForMethod( + ArtMethod* method, + std::set<std::pair<dex::TypeIndex, const DexFile*>>* exceptions_to_resolve) REQUIRES_SHARED(Locks::mutator_lock_) { - const DexFile::CodeItem* code_item = method_handle->GetCodeItem(); + const DexFile::CodeItem* code_item = method->GetCodeItem(); if (code_item == nullptr) { return; // native or abstract method } @@ -1105,9 +1117,9 @@ class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor { dex::TypeIndex encoded_catch_handler_handlers_type_idx = dex::TypeIndex(DecodeUnsignedLeb128(&encoded_catch_handler_list)); // Add to set of types to resolve if not already in the dex cache resolved types - if (!method_handle->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx)) { - exceptions_to_resolve_.emplace(encoded_catch_handler_handlers_type_idx, - method_handle->GetDexFile()); + if (!method->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx)) { + exceptions_to_resolve->emplace(encoded_catch_handler_handlers_type_idx, + method->GetDexFile()); } // ignore address associated with catch handler DecodeUnsignedLeb128(&encoded_catch_handler_list); @@ -1119,7 +1131,7 @@ class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor { } } - std::set<std::pair<dex::TypeIndex, const DexFile*>>& exceptions_to_resolve_; + std::vector<ObjPtr<mirror::Class>> classes_; }; class RecordImageClassesVisitor : public ClassVisitor { @@ -1173,8 +1185,14 @@ void CompilerDriver::LoadImageClasses(TimingLogger* timings) { hs.NewHandle(class_linker->FindSystemClass(self, "Ljava/lang/Throwable;"))); do { unresolved_exception_types.clear(); - ResolveCatchBlockExceptionsClassVisitor visitor(unresolved_exception_types); - class_linker->VisitClasses(&visitor); + { + // Thread suspension is not allowed while ResolveCatchBlockExceptionsClassVisitor + // is using a std::vector<ObjPtr<mirror::Class>>. + ScopedAssertNoThreadSuspension ants(__FUNCTION__); + ResolveCatchBlockExceptionsClassVisitor visitor; + class_linker->VisitClasses(&visitor); + visitor.FindExceptionTypesToResolve(&unresolved_exception_types); + } for (const auto& exception_type : unresolved_exception_types) { dex::TypeIndex exception_type_idx = exception_type.first; const DexFile* dex_file = exception_type.second; @@ -1425,19 +1443,14 @@ void CompilerDriver::MarkForDexToDexCompilation(Thread* self, const MethodRefere dex_to_dex_references_.back().GetMethodIndexes().SetBit(method_ref.dex_method_index); } -bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, - Handle<mirror::DexCache> dex_cache, - dex::TypeIndex type_idx) { - // Get type from dex cache assuming it was populated by the verifier - mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); +bool CompilerDriver::CanAccessTypeWithoutChecks(ObjPtr<mirror::Class> referrer_class, + ObjPtr<mirror::Class> resolved_class) { if (resolved_class == nullptr) { stats_->TypeNeedsAccessCheck(); return false; // Unknown class needs access checks. } - const DexFile::MethodId& method_id = dex_cache->GetDexFile()->GetMethodId(referrer_idx); bool is_accessible = resolved_class->IsPublic(); // Public classes are always accessible. if (!is_accessible) { - mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); if (referrer_class == nullptr) { stats_->TypeNeedsAccessCheck(); return false; // Incomplete referrer knowledge needs access check. @@ -1454,12 +1467,9 @@ bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, return is_accessible; } -bool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx, - Handle<mirror::DexCache> dex_cache, - dex::TypeIndex type_idx, +bool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(ObjPtr<mirror::Class> referrer_class, + ObjPtr<mirror::Class> resolved_class, bool* finalizable) { - // Get type from dex cache assuming it was populated by the verifier. - mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); if (resolved_class == nullptr) { stats_->TypeNeedsAccessCheck(); // Be conservative. @@ -1467,10 +1477,8 @@ bool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_id return false; // Unknown class needs access checks. } *finalizable = resolved_class->IsFinalizable(); - const DexFile::MethodId& method_id = dex_cache->GetDexFile()->GetMethodId(referrer_idx); bool is_accessible = resolved_class->IsPublic(); // Public classes are always accessible. if (!is_accessible) { - mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_); if (referrer_class == nullptr) { stats_->TypeNeedsAccessCheck(); return false; // Incomplete referrer knowledge needs access check. @@ -1514,9 +1522,7 @@ ArtField* CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, mirror::Class* referrer_class; Handle<mirror::DexCache> dex_cache(mUnit->GetDexCache()); { - StackHandleScope<1> hs(soa.Self()); - Handle<mirror::ClassLoader> class_loader_handle( - hs.NewHandle(soa.Decode<mirror::ClassLoader>(mUnit->GetClassLoader()))); + Handle<mirror::ClassLoader> class_loader_handle = mUnit->GetClassLoader(); resolved_field = ResolveField(soa, dex_cache, class_loader_handle, mUnit, field_idx, false); referrer_class = resolved_field != nullptr ? ResolveCompilingMethodsClass(soa, dex_cache, class_loader_handle, mUnit) : nullptr; @@ -2588,10 +2594,18 @@ class CompileClassVisitor : public CompilationVisitor { continue; } previous_direct_method_idx = method_idx; - CompileMethod(soa.Self(), driver, it.GetMethodCodeItem(), it.GetMethodAccessFlags(), - it.GetMethodInvokeType(class_def), class_def_index, - method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level, - compilation_enabled, dex_cache); + CompileMethod(soa.Self(), + driver, + it.GetMethodCodeItem(), + it.GetMethodAccessFlags(), + it.GetMethodInvokeType(class_def), + class_def_index, + method_idx, + class_loader, + dex_file, + dex_to_dex_compilation_level, + compilation_enabled, + dex_cache); it.Next(); } // Compile virtual methods @@ -2605,10 +2619,17 @@ class CompileClassVisitor : public CompilationVisitor { continue; } previous_virtual_method_idx = method_idx; - CompileMethod(soa.Self(), driver, it.GetMethodCodeItem(), it.GetMethodAccessFlags(), - it.GetMethodInvokeType(class_def), class_def_index, - method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level, - compilation_enabled, dex_cache); + CompileMethod(soa.Self(), + driver, it.GetMethodCodeItem(), + it.GetMethodAccessFlags(), + it.GetMethodInvokeType(class_def), + class_def_index, + method_idx, + class_loader, + dex_file, + dex_to_dex_compilation_level, + compilation_enabled, + dex_cache); it.Next(); } DCHECK(!it.HasNext()); diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index 5b4c751c4a..1e5c43d833 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -187,16 +187,14 @@ class CompilerDriver { REQUIRES(!requires_constructor_barrier_lock_); // Are runtime access checks necessary in the compiled code? - bool CanAccessTypeWithoutChecks(uint32_t referrer_idx, - Handle<mirror::DexCache> dex_cache, - dex::TypeIndex type_idx) + bool CanAccessTypeWithoutChecks(ObjPtr<mirror::Class> referrer_class, + ObjPtr<mirror::Class> resolved_class) REQUIRES_SHARED(Locks::mutator_lock_); // Are runtime access and instantiable checks necessary in the code? // out_is_finalizable is set to whether the type is finalizable. - bool CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx, - Handle<mirror::DexCache> dex_cache, - dex::TypeIndex type_idx, + bool CanAccessInstantiableTypeWithoutChecks(ObjPtr<mirror::Class> referrer_class, + ObjPtr<mirror::Class> resolved_class, bool* out_is_finalizable) REQUIRES_SHARED(Locks::mutator_lock_); @@ -370,10 +368,6 @@ class CompilerDriver { uint32_t field_idx) REQUIRES_SHARED(Locks::mutator_lock_); - mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa, - const DexCompilationUnit* mUnit) - REQUIRES_SHARED(Locks::mutator_lock_); - private: void PreCompile(jobject class_loader, const std::vector<const DexFile*>& dex_files, diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc index 1e4ca16844..e4b66ebc5a 100644 --- a/compiler/driver/compiler_driver_test.cc +++ b/compiler/driver/compiler_driver_test.cc @@ -101,6 +101,7 @@ class CompilerDriverTest : public CommonCompilerTest { }; // Disabled due to 10 second runtime on host +// TODO: Update the test for hash-based dex cache arrays. Bug: 30627598 TEST_F(CompilerDriverTest, DISABLED_LARGE_CompileDexLibCore) { CompileAll(nullptr); diff --git a/compiler/driver/dex_compilation_unit.cc b/compiler/driver/dex_compilation_unit.cc index 47b19297e5..7e8e812c4a 100644 --- a/compiler/driver/dex_compilation_unit.cc +++ b/compiler/driver/dex_compilation_unit.cc @@ -21,7 +21,7 @@ namespace art { -DexCompilationUnit::DexCompilationUnit(jobject class_loader, +DexCompilationUnit::DexCompilationUnit(Handle<mirror::ClassLoader> class_loader, ClassLinker* class_linker, const DexFile& dex_file, const DexFile::CodeItem* code_item, diff --git a/compiler/driver/dex_compilation_unit.h b/compiler/driver/dex_compilation_unit.h index 854927d747..24a9a5b653 100644 --- a/compiler/driver/dex_compilation_unit.h +++ b/compiler/driver/dex_compilation_unit.h @@ -34,7 +34,7 @@ class VerifiedMethod; class DexCompilationUnit : public DeletableArenaObject<kArenaAllocMisc> { public: - DexCompilationUnit(jobject class_loader, + DexCompilationUnit(Handle<mirror::ClassLoader> class_loader, ClassLinker* class_linker, const DexFile& dex_file, const DexFile::CodeItem* code_item, @@ -44,7 +44,7 @@ class DexCompilationUnit : public DeletableArenaObject<kArenaAllocMisc> { const VerifiedMethod* verified_method, Handle<mirror::DexCache> dex_cache); - jobject GetClassLoader() const { + Handle<mirror::ClassLoader> GetClassLoader() const { return class_loader_; } @@ -113,7 +113,7 @@ class DexCompilationUnit : public DeletableArenaObject<kArenaAllocMisc> { } private: - const jobject class_loader_; + const Handle<mirror::ClassLoader> class_loader_; ClassLinker* const class_linker_; @@ -125,7 +125,7 @@ class DexCompilationUnit : public DeletableArenaObject<kArenaAllocMisc> { const uint32_t access_flags_; const VerifiedMethod* verified_method_; - Handle<mirror::DexCache> dex_cache_; + const Handle<mirror::DexCache> dex_cache_; std::string symbol_; }; diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index c72edb18a3..3e9ae0834c 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -940,9 +940,11 @@ void ImageWriter::PruneNonImageClasses() { } ObjPtr<mirror::DexCache> dex_cache = self->DecodeJObject(data.weak_root)->AsDexCache(); for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) { - Class* klass = dex_cache->GetResolvedType(dex::TypeIndex(i)); + mirror::TypeDexCachePair pair = + dex_cache->GetResolvedTypes()[i].load(std::memory_order_relaxed); + mirror::Class* klass = pair.object.Read(); if (klass != nullptr && !KeepClass(klass)) { - dex_cache->SetResolvedType(dex::TypeIndex(i), nullptr); + dex_cache->ClearResolvedType(dex::TypeIndex(pair.index)); } } ArtMethod** resolved_methods = dex_cache->GetResolvedMethods(); @@ -1922,8 +1924,7 @@ void ImageWriter::CopyAndFixupNativeData(size_t oat_index) { // above comment for intern tables. ClassTable temp_class_table; temp_class_table.ReadFromMemory(class_table_memory_ptr); - CHECK_EQ(class_loaders_.size(), compile_app_image_ ? 1u : 0u); - mirror::ClassLoader* class_loader = compile_app_image_ ? *class_loaders_.begin() : nullptr; + ObjPtr<mirror::ClassLoader> class_loader = GetClassLoader(); CHECK_EQ(temp_class_table.NumZygoteClasses(class_loader), table->NumNonZygoteClasses(class_loader) + table->NumZygoteClasses(class_loader)); UnbufferedRootVisitor visitor(&root_visitor, RootInfo(kRootUnknown)); @@ -2213,7 +2214,7 @@ void ImageWriter::FixupDexCache(mirror::DexCache* orig_dex_cache, orig_dex_cache->FixupStrings(NativeCopyLocation(orig_strings, orig_dex_cache), ImageAddressVisitor(this)); } - GcRoot<mirror::Class>* orig_types = orig_dex_cache->GetResolvedTypes(); + mirror::TypeDexCacheType* orig_types = orig_dex_cache->GetResolvedTypes(); if (orig_types != nullptr) { copy_dex_cache->SetFieldPtrWithSize<false>(mirror::DexCache::ResolvedTypesOffset(), NativeLocationInImage(orig_types), diff --git a/compiler/image_writer.h b/compiler/image_writer.h index cc7df1ce21..bdc7146632 100644 --- a/compiler/image_writer.h +++ b/compiler/image_writer.h @@ -51,8 +51,13 @@ class ImageSpace; } // namespace space } // namespace gc +namespace mirror { +class ClassLoader; +} // namespace mirror + class ClassLoaderVisitor; class ClassTable; +class ImtConflictTable; static constexpr int kInvalidFd = -1; @@ -79,6 +84,11 @@ class ImageWriter FINAL { return true; } + ObjPtr<mirror::ClassLoader> GetClassLoader() { + CHECK_EQ(class_loaders_.size(), compile_app_image_ ? 1u : 0u); + return compile_app_image_ ? *class_loaders_.begin() : nullptr; + } + template <typename T> T* GetImageAddress(T* object) const REQUIRES_SHARED(Locks::mutator_lock_) { if (object == nullptr || IsInBootImage(object)) { diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index 7c0cdbf270..0ea11255a8 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -1060,6 +1060,7 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { WriteCodeMethodVisitor(OatWriter* writer, OutputStream* out, const size_t file_offset, size_t relative_offset) SHARED_LOCK_FUNCTION(Locks::mutator_lock_) : OatDexMethodVisitor(writer, relative_offset), + class_loader_(writer->HasImage() ? writer->image_writer_->GetClassLoader() : nullptr), out_(out), file_offset_(file_offset), soa_(Thread::Current()), @@ -1245,6 +1246,7 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { } private: + ObjPtr<mirror::ClassLoader> class_loader_; OutputStream* const out_; const size_t file_offset_; const ScopedObjectAccess soa_; @@ -1303,10 +1305,12 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor { } mirror::Class* GetTargetType(const LinkerPatch& patch) REQUIRES_SHARED(Locks::mutator_lock_) { + DCHECK(writer_->HasImage()); ObjPtr<mirror::DexCache> dex_cache = GetDexCache(patch.TargetTypeDexFile()); - mirror::Class* type = dex_cache->GetResolvedType(patch.TargetTypeIndex()); + ObjPtr<mirror::Class> type = + ClassLinker::LookupResolvedType(patch.TargetTypeIndex(), dex_cache, class_loader_); CHECK(type != nullptr); - return type; + return type.Ptr(); } mirror::String* GetTargetString(const LinkerPatch& patch) REQUIRES_SHARED(Locks::mutator_lock_) { diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h index e4ad4222fb..3a4c9dbd16 100644 --- a/compiler/optimizing/builder.h +++ b/compiler/optimizing/builder.h @@ -54,7 +54,10 @@ class HGraphBuilder : public ValueObject { compiler_driver_(driver), compilation_stats_(compiler_stats), block_builder_(graph, dex_file, code_item), - ssa_builder_(graph, dex_compilation_unit->GetDexCache(), handles), + ssa_builder_(graph, + dex_compilation_unit->GetClassLoader(), + dex_compilation_unit->GetDexCache(), + handles), instruction_builder_(graph, &block_builder_, &ssa_builder_, @@ -80,10 +83,12 @@ class HGraphBuilder : public ValueObject { code_item_(code_item), dex_compilation_unit_(nullptr), compiler_driver_(nullptr), - null_dex_cache_(), compilation_stats_(nullptr), block_builder_(graph, nullptr, code_item), - ssa_builder_(graph, null_dex_cache_, handles), + ssa_builder_(graph, + handles->NewHandle<mirror::ClassLoader>(nullptr), + handles->NewHandle<mirror::DexCache>(nullptr), + handles), instruction_builder_(graph, &block_builder_, &ssa_builder_, @@ -96,7 +101,7 @@ class HGraphBuilder : public ValueObject { /* code_generator */ nullptr, /* interpreter_metadata */ nullptr, /* compiler_stats */ nullptr, - null_dex_cache_, + handles->NewHandle<mirror::DexCache>(nullptr), handles) {} GraphAnalysisResult BuildGraph(); @@ -117,8 +122,6 @@ class HGraphBuilder : public ValueObject { CompilerDriver* const compiler_driver_; - ScopedNullHandle<mirror::DexCache> null_dex_cache_; - OptimizingCompilerStats* compilation_stats_; HBasicBlockBuilder block_builder_; diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 27b42536ef..e6032d2381 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -34,6 +34,9 @@ #include "utils/stack_checks.h" using namespace vixl::aarch64; // NOLINT(build/namespaces) +using vixl::ExactAssemblyScope; +using vixl::CodeBufferCheckScope; +using vixl::EmissionCheckScope; #ifdef __ #error "ARM64 Codegen VIXL macro-assembler macro already defined." @@ -613,10 +616,9 @@ void JumpTableARM64::EmitTable(CodeGeneratorARM64* codegen) { // We are about to use the assembler to place literals directly. Make sure we have enough // underlying code buffer and we have generated the jump table with right size. - vixl::CodeBufferCheckScope scope(codegen->GetVIXLAssembler(), - num_entries * sizeof(int32_t), - vixl::CodeBufferCheckScope::kReserveBufferSpace, - vixl::CodeBufferCheckScope::kExactSize); + EmissionCheckScope scope(codegen->GetVIXLAssembler(), + num_entries * sizeof(int32_t), + CodeBufferCheckScope::kExactSize); __ Bind(&table_start_); const ArenaVector<HBasicBlock*>& successors = switch_instr_->GetBlock()->GetSuccessors(); @@ -1279,7 +1281,6 @@ void ParallelMoveResolverARM64::EmitMove(size_t index) { void CodeGeneratorARM64::GenerateFrameEntry() { MacroAssembler* masm = GetVIXLAssembler(); - BlockPoolsScope block_pools(masm); __ Bind(&frame_entry_label_); bool do_overflow_check = FrameNeedsStackCheck(GetFrameSize(), kArm64) || !IsLeafMethod(); @@ -1288,8 +1289,14 @@ void CodeGeneratorARM64::GenerateFrameEntry() { Register temp = temps.AcquireX(); DCHECK(GetCompilerOptions().GetImplicitStackOverflowChecks()); __ Sub(temp, sp, static_cast<int32_t>(GetStackOverflowReservedBytes(kArm64))); - __ Ldr(wzr, MemOperand(temp, 0)); - RecordPcInfo(nullptr, 0); + { + // Ensure that between load and RecordPcInfo there are no pools emitted. + ExactAssemblyScope eas(GetVIXLAssembler(), + kInstructionSize, + CodeBufferCheckScope::kExactSize); + __ ldr(wzr, MemOperand(temp, 0)); + RecordPcInfo(nullptr, 0); + } } if (!HasEmptyFrame()) { @@ -1324,7 +1331,6 @@ void CodeGeneratorARM64::GenerateFrameEntry() { } void CodeGeneratorARM64::GenerateFrameExit() { - BlockPoolsScope block_pools(GetVIXLAssembler()); GetAssembler()->cfi().RememberState(); if (!HasEmptyFrame()) { int frame_size = GetFrameSize(); @@ -1651,7 +1657,6 @@ void CodeGeneratorARM64::LoadAcquire(HInstruction* instruction, const MemOperand& src, bool needs_null_check) { MacroAssembler* masm = GetVIXLAssembler(); - BlockPoolsScope block_pools(masm); UseScratchRegisterScope temps(masm); Register temp_base = temps.AcquireX(); Primitive::Type type = instruction->GetType(); @@ -1661,58 +1666,79 @@ void CodeGeneratorARM64::LoadAcquire(HInstruction* instruction, // TODO(vixl): Let the MacroAssembler handle MemOperand. __ Add(temp_base, src.GetBaseRegister(), OperandFromMemOperand(src)); - MemOperand base = MemOperand(temp_base); - switch (type) { - case Primitive::kPrimBoolean: - __ Ldarb(Register(dst), base); - if (needs_null_check) { - MaybeRecordImplicitNullCheck(instruction); - } - break; - case Primitive::kPrimByte: - __ Ldarb(Register(dst), base); - if (needs_null_check) { - MaybeRecordImplicitNullCheck(instruction); - } - __ Sbfx(Register(dst), Register(dst), 0, Primitive::ComponentSize(type) * kBitsPerByte); - break; - case Primitive::kPrimChar: - __ Ldarh(Register(dst), base); - if (needs_null_check) { - MaybeRecordImplicitNullCheck(instruction); - } - break; - case Primitive::kPrimShort: - __ Ldarh(Register(dst), base); - if (needs_null_check) { - MaybeRecordImplicitNullCheck(instruction); - } - __ Sbfx(Register(dst), Register(dst), 0, Primitive::ComponentSize(type) * kBitsPerByte); - break; - case Primitive::kPrimInt: - case Primitive::kPrimNot: - case Primitive::kPrimLong: - DCHECK_EQ(dst.Is64Bits(), Primitive::Is64BitType(type)); - __ Ldar(Register(dst), base); - if (needs_null_check) { - MaybeRecordImplicitNullCheck(instruction); - } - break; - case Primitive::kPrimFloat: - case Primitive::kPrimDouble: { - DCHECK(dst.IsFPRegister()); - DCHECK_EQ(dst.Is64Bits(), Primitive::Is64BitType(type)); - - Register temp = dst.Is64Bits() ? temps.AcquireX() : temps.AcquireW(); - __ Ldar(temp, base); - if (needs_null_check) { - MaybeRecordImplicitNullCheck(instruction); + { + // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted. + MemOperand base = MemOperand(temp_base); + switch (type) { + case Primitive::kPrimBoolean: + { + ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); + __ ldarb(Register(dst), base); + if (needs_null_check) { + MaybeRecordImplicitNullCheck(instruction); + } + } + break; + case Primitive::kPrimByte: + { + ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); + __ ldarb(Register(dst), base); + if (needs_null_check) { + MaybeRecordImplicitNullCheck(instruction); + } + } + __ Sbfx(Register(dst), Register(dst), 0, Primitive::ComponentSize(type) * kBitsPerByte); + break; + case Primitive::kPrimChar: + { + ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); + __ ldarh(Register(dst), base); + if (needs_null_check) { + MaybeRecordImplicitNullCheck(instruction); + } + } + break; + case Primitive::kPrimShort: + { + ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); + __ ldarh(Register(dst), base); + if (needs_null_check) { + MaybeRecordImplicitNullCheck(instruction); + } + } + __ Sbfx(Register(dst), Register(dst), 0, Primitive::ComponentSize(type) * kBitsPerByte); + break; + case Primitive::kPrimInt: + case Primitive::kPrimNot: + case Primitive::kPrimLong: + DCHECK_EQ(dst.Is64Bits(), Primitive::Is64BitType(type)); + { + ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); + __ ldar(Register(dst), base); + if (needs_null_check) { + MaybeRecordImplicitNullCheck(instruction); + } + } + break; + case Primitive::kPrimFloat: + case Primitive::kPrimDouble: { + DCHECK(dst.IsFPRegister()); + DCHECK_EQ(dst.Is64Bits(), Primitive::Is64BitType(type)); + + Register temp = dst.Is64Bits() ? temps.AcquireX() : temps.AcquireW(); + { + ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); + __ ldar(temp, base); + if (needs_null_check) { + MaybeRecordImplicitNullCheck(instruction); + } + } + __ Fmov(FPRegister(dst), temp); + break; } - __ Fmov(FPRegister(dst), temp); - break; + case Primitive::kPrimVoid: + LOG(FATAL) << "Unreachable type " << type; } - case Primitive::kPrimVoid: - LOG(FATAL) << "Unreachable type " << type; } } @@ -1741,9 +1767,12 @@ void CodeGeneratorARM64::Store(Primitive::Type type, } } -void CodeGeneratorARM64::StoreRelease(Primitive::Type type, +void CodeGeneratorARM64::StoreRelease(HInstruction* instruction, + Primitive::Type type, CPURegister src, - const MemOperand& dst) { + const MemOperand& dst, + bool needs_null_check) { + MacroAssembler* masm = GetVIXLAssembler(); UseScratchRegisterScope temps(GetVIXLAssembler()); Register temp_base = temps.AcquireX(); @@ -1754,20 +1783,39 @@ void CodeGeneratorARM64::StoreRelease(Primitive::Type type, Operand op = OperandFromMemOperand(dst); __ Add(temp_base, dst.GetBaseRegister(), op); MemOperand base = MemOperand(temp_base); + // Ensure that between store and MaybeRecordImplicitNullCheck there are no pools emitted. switch (type) { case Primitive::kPrimBoolean: case Primitive::kPrimByte: - __ Stlrb(Register(src), base); + { + ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); + __ stlrb(Register(src), base); + if (needs_null_check) { + MaybeRecordImplicitNullCheck(instruction); + } + } break; case Primitive::kPrimChar: case Primitive::kPrimShort: - __ Stlrh(Register(src), base); + { + ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); + __ stlrh(Register(src), base); + if (needs_null_check) { + MaybeRecordImplicitNullCheck(instruction); + } + } break; case Primitive::kPrimInt: case Primitive::kPrimNot: case Primitive::kPrimLong: DCHECK_EQ(src.Is64Bits(), Primitive::Is64BitType(type)); - __ Stlr(Register(src), base); + { + ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); + __ stlr(Register(src), base); + if (needs_null_check) { + MaybeRecordImplicitNullCheck(instruction); + } + } break; case Primitive::kPrimFloat: case Primitive::kPrimDouble: { @@ -1781,8 +1829,13 @@ void CodeGeneratorARM64::StoreRelease(Primitive::Type type, temp_src = src.Is64Bits() ? temps.AcquireX() : temps.AcquireW(); __ Fmov(temp_src, FPRegister(src)); } - - __ Stlr(temp_src, base); + { + ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); + __ stlr(temp_src, base); + if (needs_null_check) { + MaybeRecordImplicitNullCheck(instruction); + } + } break; } case Primitive::kPrimVoid: @@ -1795,9 +1848,15 @@ void CodeGeneratorARM64::InvokeRuntime(QuickEntrypointEnum entrypoint, uint32_t dex_pc, SlowPathCode* slow_path) { ValidateInvokeRuntime(entrypoint, instruction, slow_path); - GenerateInvokeRuntime(GetThreadOffset<kArm64PointerSize>(entrypoint).Int32Value()); - if (EntrypointRequiresStackMap(entrypoint)) { - RecordPcInfo(instruction, dex_pc, slow_path); + + __ Ldr(lr, MemOperand(tr, GetThreadOffset<kArm64PointerSize>(entrypoint).Int32Value())); + { + // Ensure the pc position is recorded immediately after the `blr` instruction. + ExactAssemblyScope eas(GetVIXLAssembler(), kInstructionSize, CodeBufferCheckScope::kExactSize); + __ blr(lr); + if (EntrypointRequiresStackMap(entrypoint)) { + RecordPcInfo(instruction, dex_pc, slow_path); + } } } @@ -1805,11 +1864,6 @@ void CodeGeneratorARM64::InvokeRuntimeWithoutRecordingPcInfo(int32_t entry_point HInstruction* instruction, SlowPathCode* slow_path) { ValidateInvokeRuntimeWithoutRecordingPcInfo(instruction, slow_path); - GenerateInvokeRuntime(entry_point_offset); -} - -void CodeGeneratorARM64::GenerateInvokeRuntime(int32_t entry_point_offset) { - BlockPoolsScope block_pools(GetVIXLAssembler()); __ Ldr(lr, MemOperand(tr, entry_point_offset)); __ Blr(lr); } @@ -1976,7 +2030,6 @@ void InstructionCodeGeneratorARM64::HandleFieldGet(HInstruction* instruction, Location out = locations->Out(); uint32_t offset = field_info.GetFieldOffset().Uint32Value(); Primitive::Type field_type = field_info.GetFieldType(); - BlockPoolsScope block_pools(GetVIXLAssembler()); MemOperand field = HeapOperand(InputRegisterAt(instruction, 0), field_info.GetFieldOffset()); if (field_type == Primitive::kPrimNot && kEmitCompilerReadBarrier && kUseBakerReadBarrier) { @@ -2003,6 +2056,8 @@ void InstructionCodeGeneratorARM64::HandleFieldGet(HInstruction* instruction, codegen_->LoadAcquire( instruction, OutputCPURegister(instruction), field, /* needs_null_check */ true); } else { + // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted. + EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes); codegen_->Load(field_type, OutputCPURegister(instruction), field); codegen_->MaybeRecordImplicitNullCheck(instruction); } @@ -2032,7 +2087,6 @@ void InstructionCodeGeneratorARM64::HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info, bool value_can_be_null) { DCHECK(instruction->IsInstanceFieldSet() || instruction->IsStaticFieldSet()); - BlockPoolsScope block_pools(GetVIXLAssembler()); Register obj = InputRegisterAt(instruction, 0); CPURegister value = InputCPURegisterOrZeroRegAt(instruction, 1); @@ -2054,9 +2108,11 @@ void InstructionCodeGeneratorARM64::HandleFieldSet(HInstruction* instruction, } if (field_info.IsVolatile()) { - codegen_->StoreRelease(field_type, source, HeapOperand(obj, offset)); - codegen_->MaybeRecordImplicitNullCheck(instruction); + codegen_->StoreRelease( + instruction, field_type, source, HeapOperand(obj, offset), /* needs_null_check */ true); } else { + // Ensure that between store and MaybeRecordImplicitNullCheck there are no pools emitted. + EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes); codegen_->Store(field_type, source, HeapOperand(obj, offset)); codegen_->MaybeRecordImplicitNullCheck(instruction); } @@ -2342,10 +2398,7 @@ void InstructionCodeGeneratorARM64::VisitMultiplyAccumulate(HMultiplyAccumulate* masm->GetCursorAddress<vixl::aarch64::Instruction*>() - kInstructionSize; if (prev->IsLoadOrStore()) { // Make sure we emit only exactly one nop. - vixl::CodeBufferCheckScope scope(masm, - kInstructionSize, - vixl::CodeBufferCheckScope::kReserveBufferSpace, - vixl::CodeBufferCheckScope::kExactSize); + ExactAssemblyScope scope(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); __ nop(); } } @@ -2401,8 +2454,6 @@ void InstructionCodeGeneratorARM64::VisitArrayGet(HArrayGet* instruction) { instruction->IsStringCharAt(); MacroAssembler* masm = GetVIXLAssembler(); UseScratchRegisterScope temps(masm); - // Block pools between `Load` and `MaybeRecordImplicitNullCheck`. - BlockPoolsScope block_pools(masm); // The read barrier instrumentation of object ArrayGet instructions // does not support the HIntermediateAddress instruction. @@ -2424,15 +2475,21 @@ void InstructionCodeGeneratorARM64::VisitArrayGet(HArrayGet* instruction) { if (maybe_compressed_char_at) { uint32_t count_offset = mirror::String::CountOffset().Uint32Value(); length = temps.AcquireW(); - if (instruction->GetArray()->IsIntermediateAddress()) { - DCHECK_LT(count_offset, offset); - int64_t adjusted_offset = static_cast<int64_t>(count_offset) - static_cast<int64_t>(offset); - // Note that `adjusted_offset` is negative, so this will be a LDUR. - __ Ldr(length, MemOperand(obj.X(), adjusted_offset)); - } else { - __ Ldr(length, HeapOperand(obj, count_offset)); + { + // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted. + EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes); + + if (instruction->GetArray()->IsIntermediateAddress()) { + DCHECK_LT(count_offset, offset); + int64_t adjusted_offset = + static_cast<int64_t>(count_offset) - static_cast<int64_t>(offset); + // Note that `adjusted_offset` is negative, so this will be a LDUR. + __ Ldr(length, MemOperand(obj.X(), adjusted_offset)); + } else { + __ Ldr(length, HeapOperand(obj, count_offset)); + } + codegen_->MaybeRecordImplicitNullCheck(instruction); } - codegen_->MaybeRecordImplicitNullCheck(instruction); } if (index.IsConstant()) { if (maybe_compressed_char_at) { @@ -2482,6 +2539,8 @@ void InstructionCodeGeneratorARM64::VisitArrayGet(HArrayGet* instruction) { } } if (!maybe_compressed_char_at) { + // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted. + EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes); codegen_->Load(type, OutputCPURegister(instruction), source); codegen_->MaybeRecordImplicitNullCheck(instruction); } @@ -2509,9 +2568,12 @@ void LocationsBuilderARM64::VisitArrayLength(HArrayLength* instruction) { void InstructionCodeGeneratorARM64::VisitArrayLength(HArrayLength* instruction) { uint32_t offset = CodeGenerator::GetArrayLengthOffset(instruction); vixl::aarch64::Register out = OutputRegister(instruction); - BlockPoolsScope block_pools(GetVIXLAssembler()); - __ Ldr(out, HeapOperand(InputRegisterAt(instruction, 0), offset)); - codegen_->MaybeRecordImplicitNullCheck(instruction); + { + // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted. + EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes); + __ Ldr(out, HeapOperand(InputRegisterAt(instruction, 0), offset)); + codegen_->MaybeRecordImplicitNullCheck(instruction); + } // Mask out compression flag from String's array length. if (mirror::kUseStringCompression && instruction->IsStringLength()) { __ Lsr(out.W(), out.W(), 1u); @@ -2552,7 +2614,6 @@ void InstructionCodeGeneratorARM64::VisitArraySet(HArraySet* instruction) { size_t offset = mirror::Array::DataOffset(Primitive::ComponentSize(value_type)).Uint32Value(); MemOperand destination = HeapOperand(array); MacroAssembler* masm = GetVIXLAssembler(); - BlockPoolsScope block_pools(masm); if (!needs_write_barrier) { DCHECK(!may_need_runtime_call_for_type_check); @@ -2579,8 +2640,12 @@ void InstructionCodeGeneratorARM64::VisitArraySet(HArraySet* instruction) { LSL, Primitive::ComponentSizeShift(value_type)); } - codegen_->Store(value_type, value, destination); - codegen_->MaybeRecordImplicitNullCheck(instruction); + { + // Ensure that between store and MaybeRecordImplicitNullCheck there are no pools emitted. + EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes); + codegen_->Store(value_type, value, destination); + codegen_->MaybeRecordImplicitNullCheck(instruction); + } } else { DCHECK(!instruction->GetArray()->IsIntermediateAddress()); vixl::aarch64::Label done; @@ -2613,8 +2678,13 @@ void InstructionCodeGeneratorARM64::VisitArraySet(HArraySet* instruction) { if (!index.IsConstant()) { __ Add(temp, array, offset); } - __ Str(wzr, destination); - codegen_->MaybeRecordImplicitNullCheck(instruction); + { + // Ensure that between store and MaybeRecordImplicitNullCheck there are no pools + // emitted. + EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes); + __ Str(wzr, destination); + codegen_->MaybeRecordImplicitNullCheck(instruction); + } __ B(&done); __ Bind(&non_zero); } @@ -2629,8 +2699,12 @@ void InstructionCodeGeneratorARM64::VisitArraySet(HArraySet* instruction) { Register temp2 = temps.AcquireSameSizeAs(array); // /* HeapReference<Class> */ temp = array->klass_ - __ Ldr(temp, HeapOperand(array, class_offset)); - codegen_->MaybeRecordImplicitNullCheck(instruction); + { + // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted. + EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes); + __ Ldr(temp, HeapOperand(array, class_offset)); + codegen_->MaybeRecordImplicitNullCheck(instruction); + } GetAssembler()->MaybeUnpoisonHeapReference(temp); // /* HeapReference<Class> */ temp = temp->component_type_ @@ -2671,10 +2745,14 @@ void InstructionCodeGeneratorARM64::VisitArraySet(HArraySet* instruction) { if (!index.IsConstant()) { __ Add(temp, array, offset); } - __ Str(source, destination); + { + // Ensure that between store and MaybeRecordImplicitNullCheck there are no pools emitted. + EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes); + __ Str(source, destination); - if (!may_need_runtime_call_for_type_check) { - codegen_->MaybeRecordImplicitNullCheck(instruction); + if (!may_need_runtime_call_for_type_check) { + codegen_->MaybeRecordImplicitNullCheck(instruction); + } } } @@ -3969,19 +4047,25 @@ void InstructionCodeGeneratorARM64::VisitInvokeInterface(HInvokeInterface* invok // art_quick_imt_conflict_trampoline, so prevent VIXL from using it. MacroAssembler* masm = GetVIXLAssembler(); UseScratchRegisterScope scratch_scope(masm); - BlockPoolsScope block_pools(masm); scratch_scope.Exclude(ip1); __ Mov(ip1, invoke->GetDexMethodIndex()); + // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted. if (receiver.IsStackSlot()) { __ Ldr(temp.W(), StackOperandFrom(receiver)); - // /* HeapReference<Class> */ temp = temp->klass_ - __ Ldr(temp.W(), HeapOperand(temp.W(), class_offset)); + { + EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes); + // /* HeapReference<Class> */ temp = temp->klass_ + __ Ldr(temp.W(), HeapOperand(temp.W(), class_offset)); + codegen_->MaybeRecordImplicitNullCheck(invoke); + } } else { + EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes); // /* HeapReference<Class> */ temp = receiver->klass_ __ Ldr(temp.W(), HeapOperandFrom(receiver, class_offset)); + codegen_->MaybeRecordImplicitNullCheck(invoke); } - codegen_->MaybeRecordImplicitNullCheck(invoke); + // Instead of simply (possibly) unpoisoning `temp` here, we should // emit a read barrier for the previous class reference load. // However this is not required in practice, as this is an @@ -3998,10 +4082,16 @@ void InstructionCodeGeneratorARM64::VisitInvokeInterface(HInvokeInterface* invok __ Ldr(temp, MemOperand(temp, method_offset)); // lr = temp->GetEntryPoint(); __ Ldr(lr, MemOperand(temp, entry_point.Int32Value())); - // lr(); - __ Blr(lr); - DCHECK(!codegen_->IsLeafMethod()); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); + + { + // Ensure the pc position is recorded immediately after the `blr` instruction. + ExactAssemblyScope eas(GetVIXLAssembler(), kInstructionSize, CodeBufferCheckScope::kExactSize); + + // lr(); + __ blr(lr); + DCHECK(!codegen_->IsLeafMethod()); + codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); + } } void LocationsBuilderARM64::VisitInvokeVirtual(HInvokeVirtual* invoke) { @@ -4113,8 +4203,16 @@ void CodeGeneratorARM64::GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invok __ Ldr(lr, MemOperand( XRegisterFrom(callee_method), ArtMethod::EntryPointFromQuickCompiledCodeOffset(kArm64PointerSize).Int32Value())); - // lr() - __ Blr(lr); + { + // To ensure that the pc position is recorded immediately after the `blr` instruction + // BLR must be the last instruction emitted in this function. + // Recording the pc will occur right after returning from this function. + ExactAssemblyScope eas(GetVIXLAssembler(), + kInstructionSize, + CodeBufferCheckScope::kExactSize); + // lr() + __ blr(lr); + } break; } @@ -4134,12 +4232,15 @@ void CodeGeneratorARM64::GenerateVirtualCall(HInvokeVirtual* invoke, Location te Offset class_offset = mirror::Object::ClassOffset(); Offset entry_point = ArtMethod::EntryPointFromQuickCompiledCodeOffset(kArm64PointerSize); - BlockPoolsScope block_pools(GetVIXLAssembler()); - DCHECK(receiver.IsRegister()); - // /* HeapReference<Class> */ temp = receiver->klass_ - __ Ldr(temp.W(), HeapOperandFrom(LocationFrom(receiver), class_offset)); - MaybeRecordImplicitNullCheck(invoke); + + { + // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted. + EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes); + // /* HeapReference<Class> */ temp = receiver->klass_ + __ Ldr(temp.W(), HeapOperandFrom(LocationFrom(receiver), class_offset)); + MaybeRecordImplicitNullCheck(invoke); + } // Instead of simply (possibly) unpoisoning `temp` here, we should // emit a read barrier for the previous class reference load. // intermediate/temporary reference and because the current @@ -4151,8 +4252,14 @@ void CodeGeneratorARM64::GenerateVirtualCall(HInvokeVirtual* invoke, Location te __ Ldr(temp, MemOperand(temp, method_offset)); // lr = temp->GetEntryPoint(); __ Ldr(lr, MemOperand(temp, entry_point.SizeValue())); - // lr(); - __ Blr(lr); + { + // To ensure that the pc position is recorded immediately after the `blr` instruction + // BLR should be the last instruction emitted in this function. + // Recording the pc will occur right after returning from this function. + ExactAssemblyScope eas(GetVIXLAssembler(), kInstructionSize, CodeBufferCheckScope::kExactSize); + // lr(); + __ blr(lr); + } } void LocationsBuilderARM64::VisitInvokePolymorphic(HInvokePolymorphic* invoke) { @@ -4365,7 +4472,9 @@ void InstructionCodeGeneratorARM64::VisitInvokeStaticOrDirect(HInvokeStaticOrDir return; } - BlockPoolsScope block_pools(GetVIXLAssembler()); + // Ensure that between the BLR (emitted by GenerateStaticOrDirectCall) and RecordPcInfo there + // are no pools emitted. + EmissionCheckScope guard(GetVIXLAssembler(), kInvokeCodeMarginSizeInBytes); LocationSummary* locations = invoke->GetLocations(); codegen_->GenerateStaticOrDirectCall( invoke, locations->HasTemps() ? locations->GetTemp(0) : Location::NoLocation()); @@ -4377,6 +4486,9 @@ void InstructionCodeGeneratorARM64::VisitInvokeVirtual(HInvokeVirtual* invoke) { return; } + // Ensure that between the BLR (emitted by GenerateVirtualCall) and RecordPcInfo there + // are no pools emitted. + EmissionCheckScope guard(GetVIXLAssembler(), kInvokeCodeMarginSizeInBytes); codegen_->GenerateVirtualCall(invoke, invoke->GetLocations()->GetTemp(0)); DCHECK(!codegen_->IsLeafMethod()); codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); @@ -4872,8 +4984,15 @@ void InstructionCodeGeneratorARM64::VisitNewInstance(HNewInstance* instruction) MemberOffset code_offset = ArtMethod::EntryPointFromQuickCompiledCodeOffset(kArm64PointerSize); __ Ldr(XRegisterFrom(temp), MemOperand(tr, QUICK_ENTRY_POINT(pNewEmptyString))); __ Ldr(lr, MemOperand(XRegisterFrom(temp), code_offset.Int32Value())); - __ Blr(lr); - codegen_->RecordPcInfo(instruction, instruction->GetDexPc()); + + { + // Ensure the pc position is recorded immediately after the `blr` instruction. + ExactAssemblyScope eas(GetVIXLAssembler(), + kInstructionSize, + CodeBufferCheckScope::kExactSize); + __ blr(lr); + codegen_->RecordPcInfo(instruction, instruction->GetDexPc()); + } } else { codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>(); @@ -4917,11 +5036,13 @@ void CodeGeneratorARM64::GenerateImplicitNullCheck(HNullCheck* instruction) { if (CanMoveNullCheckToUser(instruction)) { return; } - - BlockPoolsScope block_pools(GetVIXLAssembler()); - Location obj = instruction->GetLocations()->InAt(0); - __ Ldr(wzr, HeapOperandFrom(obj, Offset(0))); - RecordPcInfo(instruction, instruction->GetDexPc()); + { + // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted. + EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes); + Location obj = instruction->GetLocations()->InAt(0); + __ Ldr(wzr, HeapOperandFrom(obj, Offset(0))); + RecordPcInfo(instruction, instruction->GetDexPc()); + } } void CodeGeneratorARM64::GenerateExplicitNullCheck(HNullCheck* instruction) { @@ -5658,10 +5779,14 @@ void CodeGeneratorARM64::GenerateReferenceLoadWithBakerReadBarrier(HInstruction* DCHECK(obj.IsW()); uint32_t monitor_offset = mirror::Object::MonitorOffset().Int32Value(); - // /* int32_t */ monitor = obj->monitor_ - __ Ldr(temp, HeapOperand(obj, monitor_offset)); - if (needs_null_check) { - MaybeRecordImplicitNullCheck(instruction); + { + // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted. + EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes); + // /* int32_t */ monitor = obj->monitor_ + __ Ldr(temp, HeapOperand(obj, monitor_offset)); + if (needs_null_check) { + MaybeRecordImplicitNullCheck(instruction); + } } // /* LockWord */ lock_word = LockWord(monitor) static_assert(sizeof(LockWord) == sizeof(int32_t), diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h index f6cb90a63a..5faf29a90f 100644 --- a/compiler/optimizing/code_generator_arm64.h +++ b/compiler/optimizing/code_generator_arm64.h @@ -43,6 +43,11 @@ class CodeGeneratorARM64; // Use a local definition to prevent copying mistakes. static constexpr size_t kArm64WordSize = static_cast<size_t>(kArm64PointerSize); +// These constants are used as an approximate margin when emission of veneer and literal pools +// must be blocked. +static constexpr int kMaxMacroInstructionSizeInBytes = 15 * vixl::aarch64::kInstructionSize; +static constexpr int kInvokeCodeMarginSizeInBytes = 6 * kMaxMacroInstructionSizeInBytes; + static const vixl::aarch64::Register kParameterCoreRegisters[] = { vixl::aarch64::x1, vixl::aarch64::x2, @@ -486,9 +491,11 @@ class CodeGeneratorARM64 : public CodeGenerator { vixl::aarch64::CPURegister dst, const vixl::aarch64::MemOperand& src, bool needs_null_check); - void StoreRelease(Primitive::Type type, + void StoreRelease(HInstruction* instruction, + Primitive::Type type, vixl::aarch64::CPURegister src, - const vixl::aarch64::MemOperand& dst); + const vixl::aarch64::MemOperand& dst, + bool needs_null_check); // Generate code to invoke a runtime entry point. void InvokeRuntime(QuickEntrypointEnum entrypoint, @@ -502,8 +509,6 @@ class CodeGeneratorARM64 : public CodeGenerator { HInstruction* instruction, SlowPathCode* slow_path); - void GenerateInvokeRuntime(int32_t entry_point_offset); - ParallelMoveResolverARM64* GetMoveResolver() OVERRIDE { return &move_resolver_; } bool NeedsTwoRegisters(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE { diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 0677dad078..c9dde7cc55 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -1914,6 +1914,8 @@ void InstructionCodeGeneratorMIPS::VisitArrayGet(HArrayGet* instruction) { auto null_checker = GetImplicitNullChecker(instruction); Primitive::Type type = instruction->GetType(); + const bool maybe_compressed_char_at = mirror::kUseStringCompression && + instruction->IsStringCharAt(); switch (type) { case Primitive::kPrimBoolean: { Register out = locations->Out().AsRegister<Register>(); @@ -1957,14 +1959,54 @@ void InstructionCodeGeneratorMIPS::VisitArrayGet(HArrayGet* instruction) { case Primitive::kPrimChar: { Register out = locations->Out().AsRegister<Register>(); + if (maybe_compressed_char_at) { + uint32_t count_offset = mirror::String::CountOffset().Uint32Value(); + __ LoadFromOffset(kLoadWord, TMP, obj, count_offset, null_checker); + __ Sll(TMP, TMP, 31); // Extract compression flag into the most significant bit of TMP. + static_assert(static_cast<uint32_t>(mirror::StringCompressionFlag::kCompressed) == 0u, + "Expecting 0=compressed, 1=uncompressed"); + } if (index.IsConstant()) { - size_t offset = - (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset; - __ LoadFromOffset(kLoadUnsignedHalfword, out, obj, offset, null_checker); + int32_t const_index = index.GetConstant()->AsIntConstant()->GetValue(); + if (maybe_compressed_char_at) { + MipsLabel uncompressed_load, done; + __ Bnez(TMP, &uncompressed_load); + __ LoadFromOffset(kLoadUnsignedByte, + out, + obj, + data_offset + (const_index << TIMES_1)); + __ B(&done); + __ Bind(&uncompressed_load); + __ LoadFromOffset(kLoadUnsignedHalfword, + out, + obj, + data_offset + (const_index << TIMES_2)); + __ Bind(&done); + } else { + __ LoadFromOffset(kLoadUnsignedHalfword, + out, + obj, + data_offset + (const_index << TIMES_2), + null_checker); + } } else { - __ Sll(TMP, index.AsRegister<Register>(), TIMES_2); - __ Addu(TMP, obj, TMP); - __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset, null_checker); + Register index_reg = index.AsRegister<Register>(); + if (maybe_compressed_char_at) { + MipsLabel uncompressed_load, done; + __ Bnez(TMP, &uncompressed_load); + __ Addu(TMP, obj, index_reg); + __ LoadFromOffset(kLoadUnsignedByte, out, TMP, data_offset); + __ B(&done); + __ Bind(&uncompressed_load); + __ Sll(TMP, index_reg, TIMES_2); + __ Addu(TMP, obj, TMP); + __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset); + __ Bind(&done); + } else { + __ Sll(TMP, index_reg, TIMES_2); + __ Addu(TMP, obj, TMP); + __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset, null_checker); + } } break; } @@ -2046,6 +2088,10 @@ void InstructionCodeGeneratorMIPS::VisitArrayLength(HArrayLength* instruction) { Register out = locations->Out().AsRegister<Register>(); __ LoadFromOffset(kLoadWord, out, obj, offset); codegen_->MaybeRecordImplicitNullCheck(instruction); + // Mask out compression flag from String's array length. + if (mirror::kUseStringCompression && instruction->IsStringLength()) { + __ Srl(out, out, 1u); + } } Location LocationsBuilderMIPS::RegisterOrZeroConstant(HInstruction* instruction) { diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index 4c8dabfede..5be0da4011 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -1490,6 +1490,8 @@ void InstructionCodeGeneratorMIPS64::VisitArrayGet(HArrayGet* instruction) { uint32_t data_offset = CodeGenerator::GetArrayDataOffset(instruction); Primitive::Type type = instruction->GetType(); + const bool maybe_compressed_char_at = mirror::kUseStringCompression && + instruction->IsStringCharAt(); switch (type) { case Primitive::kPrimBoolean: { GpuRegister out = locations->Out().AsRegister<GpuRegister>(); @@ -1533,14 +1535,54 @@ void InstructionCodeGeneratorMIPS64::VisitArrayGet(HArrayGet* instruction) { case Primitive::kPrimChar: { GpuRegister out = locations->Out().AsRegister<GpuRegister>(); + if (maybe_compressed_char_at) { + uint32_t count_offset = mirror::String::CountOffset().Uint32Value(); + __ LoadFromOffset(kLoadWord, TMP, obj, count_offset); + codegen_->MaybeRecordImplicitNullCheck(instruction); + __ Dext(TMP, TMP, 0, 1); + static_assert(static_cast<uint32_t>(mirror::StringCompressionFlag::kCompressed) == 0u, + "Expecting 0=compressed, 1=uncompressed"); + } if (index.IsConstant()) { - size_t offset = - (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset; - __ LoadFromOffset(kLoadUnsignedHalfword, out, obj, offset); + int32_t const_index = index.GetConstant()->AsIntConstant()->GetValue(); + if (maybe_compressed_char_at) { + Mips64Label uncompressed_load, done; + __ Bnezc(TMP, &uncompressed_load); + __ LoadFromOffset(kLoadUnsignedByte, + out, + obj, + data_offset + (const_index << TIMES_1)); + __ Bc(&done); + __ Bind(&uncompressed_load); + __ LoadFromOffset(kLoadUnsignedHalfword, + out, + obj, + data_offset + (const_index << TIMES_2)); + __ Bind(&done); + } else { + __ LoadFromOffset(kLoadUnsignedHalfword, + out, + obj, + data_offset + (const_index << TIMES_2)); + } } else { - __ Dsll(TMP, index.AsRegister<GpuRegister>(), TIMES_2); - __ Daddu(TMP, obj, TMP); - __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset); + GpuRegister index_reg = index.AsRegister<GpuRegister>(); + if (maybe_compressed_char_at) { + Mips64Label uncompressed_load, done; + __ Bnezc(TMP, &uncompressed_load); + __ Daddu(TMP, obj, index_reg); + __ LoadFromOffset(kLoadUnsignedByte, out, TMP, data_offset); + __ Bc(&done); + __ Bind(&uncompressed_load); + __ Dsll(TMP, index_reg, TIMES_2); + __ Daddu(TMP, obj, TMP); + __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset); + __ Bind(&done); + } else { + __ Dsll(TMP, index_reg, TIMES_2); + __ Daddu(TMP, obj, TMP); + __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset); + } } break; } @@ -1608,7 +1650,9 @@ void InstructionCodeGeneratorMIPS64::VisitArrayGet(HArrayGet* instruction) { LOG(FATAL) << "Unreachable type " << instruction->GetType(); UNREACHABLE(); } - codegen_->MaybeRecordImplicitNullCheck(instruction); + if (!maybe_compressed_char_at) { + codegen_->MaybeRecordImplicitNullCheck(instruction); + } } void LocationsBuilderMIPS64::VisitArrayLength(HArrayLength* instruction) { @@ -1624,6 +1668,10 @@ void InstructionCodeGeneratorMIPS64::VisitArrayLength(HArrayLength* instruction) GpuRegister out = locations->Out().AsRegister<GpuRegister>(); __ LoadFromOffset(kLoadWord, out, obj, offset); codegen_->MaybeRecordImplicitNullCheck(instruction); + // Mask out compression flag from String's array length. + if (mirror::kUseStringCompression && instruction->IsStringLength()) { + __ Srl(out, out, 1u); + } } void LocationsBuilderMIPS64::VisitArraySet(HArraySet* instruction) { diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index f0afccb782..b56ef0f866 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -198,9 +198,9 @@ static uint32_t FindMethodIndexIn(ArtMethod* method, } static dex::TypeIndex FindClassIndexIn(mirror::Class* cls, - const DexFile& dex_file, - Handle<mirror::DexCache> dex_cache) + const DexCompilationUnit& compilation_unit) REQUIRES_SHARED(Locks::mutator_lock_) { + const DexFile& dex_file = *compilation_unit.GetDexFile(); dex::TypeIndex index; if (cls->GetDexCache() == nullptr) { DCHECK(cls->IsArrayClass()) << cls->PrettyClass(); @@ -209,22 +209,19 @@ static dex::TypeIndex FindClassIndexIn(mirror::Class* cls, DCHECK(cls->IsProxyClass()) << cls->PrettyClass(); // TODO: deal with proxy classes. } else if (IsSameDexFile(cls->GetDexFile(), dex_file)) { - DCHECK_EQ(cls->GetDexCache(), dex_cache.Get()); + DCHECK_EQ(cls->GetDexCache(), compilation_unit.GetDexCache().Get()); index = cls->GetDexTypeIndex(); - // Update the dex cache to ensure the class is in. The generated code will - // consider it is. We make it safe by updating the dex cache, as other - // dex files might also load the class, and there is no guarantee the dex - // cache of the dex file of the class will be updated. - if (dex_cache->GetResolvedType(index) == nullptr) { - dex_cache->SetResolvedType(index, cls); - } } else { index = cls->FindTypeIndexInOtherDexFile(dex_file); - // We cannot guarantee the entry in the dex cache will resolve to the same class, + // We cannot guarantee the entry will resolve to the same class, // as there may be different class loaders. So only return the index if it's - // the right class in the dex cache already. - if (index.IsValid() && dex_cache->GetResolvedType(index) != cls) { - index = dex::TypeIndex::Invalid(); + // the right class already resolved with the class loader. + if (index.IsValid()) { + ObjPtr<mirror::Class> resolved = ClassLinker::LookupResolvedType( + index, compilation_unit.GetDexCache().Get(), compilation_unit.GetClassLoader().Get()); + if (resolved != cls) { + index = dex::TypeIndex::Invalid(); + } } } @@ -451,9 +448,8 @@ bool HInliner::TryInlineMonomorphicCall(HInvoke* invoke_instruction, DCHECK(invoke_instruction->IsInvokeVirtual() || invoke_instruction->IsInvokeInterface()) << invoke_instruction->DebugName(); - const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile(); dex::TypeIndex class_index = FindClassIndexIn( - GetMonomorphicType(classes), caller_dex_file, caller_compilation_unit_.GetDexCache()); + GetMonomorphicType(classes), caller_compilation_unit_); if (!class_index.IsValid()) { VLOG(compiler) << "Call to " << ArtMethod::PrettyMethod(resolved_method) << " from inline cache is not inlined because its class is not" @@ -496,6 +492,7 @@ bool HInliner::TryInlineMonomorphicCall(HInvoke* invoke_instruction, // Run type propagation to get the guard typed, and eventually propagate the // type of the receiver. ReferenceTypePropagation rtp_fixup(graph_, + outer_compilation_unit_.GetClassLoader(), outer_compilation_unit_.GetDexCache(), handles_, /* is_first_run */ false); @@ -590,7 +587,6 @@ bool HInliner::TryInlinePolymorphicCall(HInvoke* invoke_instruction, ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker(); PointerSize pointer_size = class_linker->GetImagePointerSize(); - const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile(); bool all_targets_inlined = true; bool one_target_inlined = false; @@ -612,8 +608,7 @@ bool HInliner::TryInlinePolymorphicCall(HInvoke* invoke_instruction, HInstruction* cursor = invoke_instruction->GetPrevious(); HBasicBlock* bb_cursor = invoke_instruction->GetBlock(); - dex::TypeIndex class_index = FindClassIndexIn( - handle.Get(), caller_dex_file, caller_compilation_unit_.GetDexCache()); + dex::TypeIndex class_index = FindClassIndexIn(handle.Get(), caller_compilation_unit_); HInstruction* return_replacement = nullptr; if (!class_index.IsValid() || !TryBuildAndInline(invoke_instruction, @@ -669,6 +664,7 @@ bool HInliner::TryInlinePolymorphicCall(HInvoke* invoke_instruction, // Run type propagation to get the guards typed. ReferenceTypePropagation rtp_fixup(graph_, + outer_compilation_unit_.GetClassLoader(), outer_compilation_unit_.GetDexCache(), handles_, /* is_first_run */ false); @@ -863,6 +859,7 @@ bool HInliner::TryInlinePolymorphicCallToSameTarget( // Run type propagation to get the guard typed. ReferenceTypePropagation rtp_fixup(graph_, + outer_compilation_unit_.GetClassLoader(), outer_compilation_unit_.GetDexCache(), handles_, /* is_first_run */ false); @@ -931,6 +928,7 @@ bool HInliner::TryInlineAndReplace(HInvoke* invoke_instruction, // Actual return value has a more specific type than the method's declared // return type. Run RTP again on the outer graph to propagate it. ReferenceTypePropagation(graph_, + outer_compilation_unit_.GetClassLoader(), outer_compilation_unit_.GetDexCache(), handles_, /* is_first_run */ false).Run(); @@ -1183,7 +1181,11 @@ HInstanceFieldGet* HInliner::CreateInstanceFieldGet(Handle<mirror::DexCache> dex /* dex_pc */ 0); if (iget->GetType() == Primitive::kPrimNot) { // Use the same dex_cache that we used for field lookup as the hint_dex_cache. - ReferenceTypePropagation rtp(graph_, dex_cache, handles_, /* is_first_run */ false); + ReferenceTypePropagation rtp(graph_, + outer_compilation_unit_.GetClassLoader(), + dex_cache, + handles_, + /* is_first_run */ false); rtp.Visit(iget); } return iget; @@ -1229,7 +1231,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, resolved_method->GetDeclaringClass()->GetClassLoader())); DexCompilationUnit dex_compilation_unit( - class_loader.ToJObject(), + class_loader, class_linker, callee_dex_file, code_item, @@ -1346,6 +1348,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, // are more specific than the declared ones, run RTP again on the inner graph. if (run_rtp || ArgumentTypesMoreSpecific(invoke_instruction, resolved_method)) { ReferenceTypePropagation(callee_graph, + outer_compilation_unit_.GetClassLoader(), dex_compilation_unit.GetDexCache(), handles_, /* is_first_run */ false).Run(); diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index a1c391f455..3aaf2ca102 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -669,11 +669,10 @@ static InvokeType GetInvokeTypeFromOpCode(Instruction::Code opcode) { ArtMethod* HInstructionBuilder::ResolveMethod(uint16_t method_idx, InvokeType invoke_type) { ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<3> hs(soa.Self()); + StackHandleScope<2> hs(soa.Self()); ClassLinker* class_linker = dex_compilation_unit_->GetClassLinker(); - Handle<mirror::ClassLoader> class_loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader>(dex_compilation_unit_->GetClassLoader()))); + Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader(); Handle<mirror::Class> compiling_class(hs.NewHandle(GetCompilingClass())); // We fetch the referenced class eagerly (that is, the class pointed by in the MethodId // at method_idx), as `CanAccessResolvedMethod` expects it be be in the dex cache. @@ -1260,9 +1259,7 @@ bool HInstructionBuilder::BuildInstanceFieldAccess(const Instruction& instructio static mirror::Class* GetClassFrom(CompilerDriver* driver, const DexCompilationUnit& compilation_unit) { ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<1> hs(soa.Self()); - Handle<mirror::ClassLoader> class_loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader>(compilation_unit.GetClassLoader()))); + Handle<mirror::ClassLoader> class_loader = compilation_unit.GetClassLoader(); Handle<mirror::DexCache> dex_cache = compilation_unit.GetDexCache(); return driver->ResolveCompilingMethodsClass(soa, dex_cache, class_loader, &compilation_unit); @@ -1278,10 +1275,9 @@ mirror::Class* HInstructionBuilder::GetCompilingClass() const { bool HInstructionBuilder::IsOutermostCompilingClass(dex::TypeIndex type_index) const { ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<3> hs(soa.Self()); + StackHandleScope<2> hs(soa.Self()); Handle<mirror::DexCache> dex_cache = dex_compilation_unit_->GetDexCache(); - Handle<mirror::ClassLoader> class_loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader>(dex_compilation_unit_->GetClassLoader()))); + Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader(); Handle<mirror::Class> cls(hs.NewHandle(compiler_driver_->ResolveClass( soa, dex_cache, class_loader, type_index, dex_compilation_unit_))); Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass())); @@ -1317,8 +1313,7 @@ ArtField* HInstructionBuilder::ResolveField(uint16_t field_idx, bool is_static, StackHandleScope<2> hs(soa.Self()); ClassLinker* class_linker = dex_compilation_unit_->GetClassLinker(); - Handle<mirror::ClassLoader> class_loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader>(dex_compilation_unit_->GetClassLoader()))); + Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader(); Handle<mirror::Class> compiling_class(hs.NewHandle(GetCompilingClass())); ArtField* resolved_field = class_linker->ResolveField(*dex_compilation_unit_->GetDexFile(), @@ -1635,10 +1630,8 @@ static TypeCheckKind ComputeTypeCheckKind(Handle<mirror::Class> cls) HLoadClass* HInstructionBuilder::BuildLoadClass(dex::TypeIndex type_index, uint32_t dex_pc) { ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<2> hs(soa.Self()); const DexFile& dex_file = *dex_compilation_unit_->GetDexFile(); - Handle<mirror::ClassLoader> class_loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader>(dex_compilation_unit_->GetClassLoader()))); + Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader(); Handle<mirror::Class> klass = handles_->NewHandle(compiler_driver_->ResolveClass( soa, dex_compilation_unit_->GetDexCache(), class_loader, type_index, dex_compilation_unit_)); @@ -1722,17 +1715,9 @@ void HInstructionBuilder::BuildTypeCheck(const Instruction& instruction, } } -bool HInstructionBuilder::NeedsAccessCheck(dex::TypeIndex type_index, - Handle<mirror::DexCache> dex_cache, - bool* finalizable) const { - return !compiler_driver_->CanAccessInstantiableTypeWithoutChecks( - dex_compilation_unit_->GetDexMethodIndex(), dex_cache, type_index, finalizable); -} - bool HInstructionBuilder::NeedsAccessCheck(dex::TypeIndex type_index, bool* finalizable) const { - ScopedObjectAccess soa(Thread::Current()); - Handle<mirror::DexCache> dex_cache = dex_compilation_unit_->GetDexCache(); - return NeedsAccessCheck(type_index, dex_cache, finalizable); + return !compiler_driver_->CanAccessInstantiableTypeWithoutChecks( + LookupReferrerClass(), LookupResolvedType(type_index, *dex_compilation_unit_), finalizable); } bool HInstructionBuilder::CanDecodeQuickenedInfo() const { @@ -2772,4 +2757,18 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, return true; } // NOLINT(readability/fn_size) +ObjPtr<mirror::Class> HInstructionBuilder::LookupResolvedType( + dex::TypeIndex type_index, + const DexCompilationUnit& compilation_unit) const { + return ClassLinker::LookupResolvedType( + type_index, compilation_unit.GetDexCache().Get(), compilation_unit.GetClassLoader().Get()); +} + +ObjPtr<mirror::Class> HInstructionBuilder::LookupReferrerClass() const { + // TODO: Cache the result in a Handle<mirror::Class>. + const DexFile::MethodId& method_id = + dex_compilation_unit_->GetDexFile()->GetMethodId(dex_compilation_unit_->GetDexMethodIndex()); + return LookupResolvedType(method_id.class_idx_, *dex_compilation_unit_); +} + } // namespace art diff --git a/compiler/optimizing/instruction_builder.h b/compiler/optimizing/instruction_builder.h index 3bb680ce44..e735a0c46d 100644 --- a/compiler/optimizing/instruction_builder.h +++ b/compiler/optimizing/instruction_builder.h @@ -106,11 +106,8 @@ class HInstructionBuilder : public ValueObject { // Returns whether the current method needs access check for the type. // Output parameter finalizable is set to whether the type is finalizable. - bool NeedsAccessCheck(dex::TypeIndex type_index, - Handle<mirror::DexCache> dex_cache, - /*out*/bool* finalizable) const + bool NeedsAccessCheck(dex::TypeIndex type_index, /*out*/bool* finalizable) const REQUIRES_SHARED(Locks::mutator_lock_); - bool NeedsAccessCheck(dex::TypeIndex type_index, /*out*/bool* finalizable) const; template<typename T> void Unop_12x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc); @@ -300,6 +297,12 @@ class HInstructionBuilder : public ValueObject { // be found. ArtField* ResolveField(uint16_t field_idx, bool is_static, bool is_put); + ObjPtr<mirror::Class> LookupResolvedType(dex::TypeIndex type_index, + const DexCompilationUnit& compilation_unit) const + REQUIRES_SHARED(Locks::mutator_lock_); + + ObjPtr<mirror::Class> LookupReferrerClass() const REQUIRES_SHARED(Locks::mutator_lock_); + ArenaAllocator* const arena_; HGraph* const graph_; VariableSizedHandleScope* handles_; diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc index bbf826ce7e..1047d3beb6 100644 --- a/compiler/optimizing/intrinsics_arm64.cc +++ b/compiler/optimizing/intrinsics_arm64.cc @@ -115,13 +115,18 @@ class IntrinsicSlowPathARM64 : public SlowPathCodeARM64 { MoveArguments(invoke_, codegen); - if (invoke_->IsInvokeStaticOrDirect()) { - codegen->GenerateStaticOrDirectCall(invoke_->AsInvokeStaticOrDirect(), - LocationFrom(kArtMethodRegister)); - } else { - codegen->GenerateVirtualCall(invoke_->AsInvokeVirtual(), LocationFrom(kArtMethodRegister)); + { + // Ensure that between the BLR (emitted by Generate*Call) and RecordPcInfo there + // are no pools emitted. + vixl::EmissionCheckScope guard(codegen->GetVIXLAssembler(), kInvokeCodeMarginSizeInBytes); + if (invoke_->IsInvokeStaticOrDirect()) { + codegen->GenerateStaticOrDirectCall(invoke_->AsInvokeStaticOrDirect(), + LocationFrom(kArtMethodRegister)); + } else { + codegen->GenerateVirtualCall(invoke_->AsInvokeVirtual(), LocationFrom(kArtMethodRegister)); + } + codegen->RecordPcInfo(invoke_, invoke_->GetDexPc(), this); } - codegen->RecordPcInfo(invoke_, invoke_->GetDexPc(), this); // Copy the result back to the expected output. Location out = invoke_->GetLocations()->Out(); @@ -980,11 +985,12 @@ void IntrinsicLocationsBuilderARM64::VisitUnsafePutLongVolatile(HInvoke* invoke) CreateIntIntIntIntToVoid(arena_, invoke); } -static void GenUnsafePut(LocationSummary* locations, +static void GenUnsafePut(HInvoke* invoke, Primitive::Type type, bool is_volatile, bool is_ordered, CodeGeneratorARM64* codegen) { + LocationSummary* locations = invoke->GetLocations(); MacroAssembler* masm = codegen->GetVIXLAssembler(); Register base = WRegisterFrom(locations->InAt(1)); // Object pointer. @@ -1007,7 +1013,7 @@ static void GenUnsafePut(LocationSummary* locations, } if (is_volatile || is_ordered) { - codegen->StoreRelease(type, source, mem_op); + codegen->StoreRelease(invoke, type, source, mem_op, /* needs_null_check */ false); } else { codegen->Store(type, source, mem_op); } @@ -1020,63 +1026,63 @@ static void GenUnsafePut(LocationSummary* locations, } void IntrinsicCodeGeneratorARM64::VisitUnsafePut(HInvoke* invoke) { - GenUnsafePut(invoke->GetLocations(), + GenUnsafePut(invoke, Primitive::kPrimInt, /* is_volatile */ false, /* is_ordered */ false, codegen_); } void IntrinsicCodeGeneratorARM64::VisitUnsafePutOrdered(HInvoke* invoke) { - GenUnsafePut(invoke->GetLocations(), + GenUnsafePut(invoke, Primitive::kPrimInt, /* is_volatile */ false, /* is_ordered */ true, codegen_); } void IntrinsicCodeGeneratorARM64::VisitUnsafePutVolatile(HInvoke* invoke) { - GenUnsafePut(invoke->GetLocations(), + GenUnsafePut(invoke, Primitive::kPrimInt, /* is_volatile */ true, /* is_ordered */ false, codegen_); } void IntrinsicCodeGeneratorARM64::VisitUnsafePutObject(HInvoke* invoke) { - GenUnsafePut(invoke->GetLocations(), + GenUnsafePut(invoke, Primitive::kPrimNot, /* is_volatile */ false, /* is_ordered */ false, codegen_); } void IntrinsicCodeGeneratorARM64::VisitUnsafePutObjectOrdered(HInvoke* invoke) { - GenUnsafePut(invoke->GetLocations(), + GenUnsafePut(invoke, Primitive::kPrimNot, /* is_volatile */ false, /* is_ordered */ true, codegen_); } void IntrinsicCodeGeneratorARM64::VisitUnsafePutObjectVolatile(HInvoke* invoke) { - GenUnsafePut(invoke->GetLocations(), + GenUnsafePut(invoke, Primitive::kPrimNot, /* is_volatile */ true, /* is_ordered */ false, codegen_); } void IntrinsicCodeGeneratorARM64::VisitUnsafePutLong(HInvoke* invoke) { - GenUnsafePut(invoke->GetLocations(), + GenUnsafePut(invoke, Primitive::kPrimLong, /* is_volatile */ false, /* is_ordered */ false, codegen_); } void IntrinsicCodeGeneratorARM64::VisitUnsafePutLongOrdered(HInvoke* invoke) { - GenUnsafePut(invoke->GetLocations(), + GenUnsafePut(invoke, Primitive::kPrimLong, /* is_volatile */ false, /* is_ordered */ true, codegen_); } void IntrinsicCodeGeneratorARM64::VisitUnsafePutLongVolatile(HInvoke* invoke) { - GenUnsafePut(invoke->GetLocations(), + GenUnsafePut(invoke, Primitive::kPrimLong, /* is_volatile */ true, /* is_ordered */ false, @@ -2825,9 +2831,13 @@ void IntrinsicCodeGeneratorARM64::VisitReferenceGetReferent(HInvoke* invoke) { } __ Cbnz(temp0, slow_path->GetEntryLabel()); - // Fast path. - __ Ldr(out, HeapOperand(obj, mirror::Reference::ReferentOffset().Int32Value())); - codegen_->MaybeRecordImplicitNullCheck(invoke); + { + // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted. + vixl::EmissionCheckScope guard(codegen_->GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes); + // Fast path. + __ Ldr(out, HeapOperand(obj, mirror::Reference::ReferentOffset().Int32Value())); + codegen_->MaybeRecordImplicitNullCheck(invoke); + } codegen_->GetAssembler()->MaybeUnpoisonHeapReference(out); __ Bind(slow_path->GetExitLabel()); } diff --git a/compiler/optimizing/intrinsics_mips.cc b/compiler/optimizing/intrinsics_mips.cc index 6cf9b83d44..64a68403e9 100644 --- a/compiler/optimizing/intrinsics_mips.cc +++ b/compiler/optimizing/intrinsics_mips.cc @@ -2004,31 +2004,48 @@ void IntrinsicCodeGeneratorMIPS::VisitStringEquals(HInvoke* invoke) { __ Lw(temp2, arg, class_offset); __ Bne(temp1, temp2, &return_false); - // Load lengths of this and argument strings. + // Load `count` fields of this and argument strings. __ Lw(temp1, str, count_offset); __ Lw(temp2, arg, count_offset); - // Check if lengths are equal, return false if they're not. + // Check if `count` fields are equal, return false if they're not. + // Also compares the compression style, if differs return false. __ Bne(temp1, temp2, &return_false); - // Return true if both strings are empty. + // Return true if both strings are empty. Even with string compression `count == 0` means empty. + static_assert(static_cast<uint32_t>(mirror::StringCompressionFlag::kCompressed) == 0u, + "Expecting 0=compressed, 1=uncompressed"); __ Beqz(temp1, &return_true); // Don't overwrite input registers __ Move(TMP, str); __ Move(temp3, arg); - // Assertions that must hold in order to compare strings 2 characters at a time. + // Assertions that must hold in order to compare strings 4 bytes at a time. DCHECK_ALIGNED(value_offset, 4); static_assert(IsAligned<4>(kObjectAlignment), "String of odd length is not zero padded"); - // Loop to compare strings 2 characters at a time starting at the beginning of the string. - // Ok to do this because strings are zero-padded. + // For string compression, calculate the number of bytes to compare (not chars). + if (mirror::kUseStringCompression) { + // Extract compression flag. + if (IsR2OrNewer()) { + __ Ext(temp2, temp1, 0, 1); + } else { + __ Sll(temp2, temp1, 31); + __ Srl(temp2, temp2, 31); + } + __ Srl(temp1, temp1, 1); // Extract length. + __ Sllv(temp1, temp1, temp2); // Double the byte count if uncompressed. + } + + // Loop to compare strings 4 bytes at a time starting at the beginning of the string. + // Ok to do this because strings are zero-padded to kObjectAlignment. __ Bind(&loop); __ Lw(out, TMP, value_offset); __ Lw(temp2, temp3, value_offset); __ Bne(out, temp2, &return_false); __ Addiu(TMP, TMP, 4); __ Addiu(temp3, temp3, 4); - __ Addiu(temp1, temp1, -2); + // With string compression, we have compared 4 bytes, otherwise 2 chars. + __ Addiu(temp1, temp1, mirror::kUseStringCompression ? -4 : -2); __ Bgtz(temp1, &loop); // Return true and exit the function. @@ -2578,6 +2595,30 @@ void IntrinsicCodeGeneratorMIPS::VisitStringGetCharsNoCheck(HInvoke* invoke) { __ Addu(dstPtr, dstPtr, AT); } + if (mirror::kUseStringCompression) { + MipsLabel uncompressed_copy, compressed_loop; + const uint32_t count_offset = mirror::String::CountOffset().Uint32Value(); + // Load count field and extract compression flag. + __ LoadFromOffset(kLoadWord, TMP, srcObj, count_offset); + __ Sll(TMP, TMP, 31); + + // If string is uncompressed, use memcpy() path. + __ Bnez(TMP, &uncompressed_copy); + + // Copy loop for compressed src, copying 1 character (8-bit) to (16-bit) at a time. + __ Addu(srcPtr, srcObj, srcBegin); + __ Bind(&compressed_loop); + __ LoadFromOffset(kLoadUnsignedByte, TMP, srcPtr, value_offset); + __ StoreToOffset(kStoreHalfword, TMP, dstPtr, 0); + __ Addiu(numChrs, numChrs, -1); + __ Addiu(srcPtr, srcPtr, 1); + __ Addiu(dstPtr, dstPtr, 2); + __ Bnez(numChrs, &compressed_loop); + + __ B(&done); + __ Bind(&uncompressed_copy); + } + // Calculate source address. __ Addiu(srcPtr, srcObj, value_offset); if (IsR6()) { diff --git a/compiler/optimizing/intrinsics_mips64.cc b/compiler/optimizing/intrinsics_mips64.cc index 00a1fa11bb..3888828722 100644 --- a/compiler/optimizing/intrinsics_mips64.cc +++ b/compiler/optimizing/intrinsics_mips64.cc @@ -1607,31 +1607,42 @@ void IntrinsicCodeGeneratorMIPS64::VisitStringEquals(HInvoke* invoke) { __ Lw(temp2, arg, class_offset); __ Bnec(temp1, temp2, &return_false); - // Load lengths of this and argument strings. + // Load `count` fields of this and argument strings. __ Lw(temp1, str, count_offset); __ Lw(temp2, arg, count_offset); - // Check if lengths are equal, return false if they're not. + // Check if `count` fields are equal, return false if they're not. + // Also compares the compression style, if differs return false. __ Bnec(temp1, temp2, &return_false); - // Return true if both strings are empty. + // Return true if both strings are empty. Even with string compression `count == 0` means empty. + static_assert(static_cast<uint32_t>(mirror::StringCompressionFlag::kCompressed) == 0u, + "Expecting 0=compressed, 1=uncompressed"); __ Beqzc(temp1, &return_true); // Don't overwrite input registers __ Move(TMP, str); __ Move(temp3, arg); - // Assertions that must hold in order to compare strings 4 characters at a time. + // Assertions that must hold in order to compare strings 8 bytes at a time. DCHECK_ALIGNED(value_offset, 8); static_assert(IsAligned<8>(kObjectAlignment), "String of odd length is not zero padded"); - // Loop to compare strings 4 characters at a time starting at the beginning of the string. - // Ok to do this because strings are zero-padded to be 8-byte aligned. + if (mirror::kUseStringCompression) { + // For string compression, calculate the number of bytes to compare (not chars). + __ Dext(temp2, temp1, 0, 1); // Extract compression flag. + __ Srl(temp1, temp1, 1); // Extract length. + __ Sllv(temp1, temp1, temp2); // Double the byte count if uncompressed. + } + + // Loop to compare strings 8 bytes at a time starting at the beginning of the string. + // Ok to do this because strings are zero-padded to kObjectAlignment. __ Bind(&loop); __ Ld(out, TMP, value_offset); __ Ld(temp2, temp3, value_offset); __ Bnec(out, temp2, &return_false); __ Daddiu(TMP, TMP, 8); __ Daddiu(temp3, temp3, 8); - __ Addiu(temp1, temp1, -4); + // With string compression, we have compared 8 bytes, otherwise 4 chars. + __ Addiu(temp1, temp1, mirror::kUseStringCompression ? -8 : -4); __ Bgtzc(temp1, &loop); // Return true and exit the function. @@ -1912,6 +1923,30 @@ void IntrinsicCodeGeneratorMIPS64::VisitStringGetCharsNoCheck(HInvoke* invoke) { __ Daddiu(dstPtr, dstObj, data_offset); __ Dlsa(dstPtr, dstBegin, dstPtr, char_shift); + if (mirror::kUseStringCompression) { + Mips64Label uncompressed_copy, compressed_loop; + const uint32_t count_offset = mirror::String::CountOffset().Uint32Value(); + // Load count field and extract compression flag. + __ LoadFromOffset(kLoadWord, TMP, srcObj, count_offset); + __ Dext(TMP, TMP, 0, 1); + + // If string is uncompressed, use memcpy() path. + __ Bnezc(TMP, &uncompressed_copy); + + // Copy loop for compressed src, copying 1 character (8-bit) to (16-bit) at a time. + __ Daddu(srcPtr, srcObj, srcBegin); + __ Bind(&compressed_loop); + __ LoadFromOffset(kLoadUnsignedByte, TMP, srcPtr, value_offset); + __ StoreToOffset(kStoreHalfword, TMP, dstPtr, 0); + __ Daddiu(numChrs, numChrs, -1); + __ Daddiu(srcPtr, srcPtr, 1); + __ Daddiu(dstPtr, dstPtr, 2); + __ Bnezc(numChrs, &compressed_loop); + + __ Bc(&done); + __ Bind(&uncompressed_copy); + } + // Calculate source address. __ Daddiu(srcPtr, srcObj, value_offset); __ Dlsa(srcPtr, srcBegin, srcPtr, char_shift); diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 727ca7d893..0375c66e42 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -306,7 +306,7 @@ class OptimizingCompiler FINAL : public Compiler { InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx, - jobject class_loader, + Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file, Handle<mirror::DexCache> dex_cache) const OVERRIDE; @@ -375,7 +375,7 @@ class OptimizingCompiler FINAL : public Compiler { InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx, - jobject class_loader, + Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file, Handle<mirror::DexCache> dex_cache, ArtMethod* method, @@ -875,7 +875,7 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx, - jobject class_loader, + Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file, Handle<mirror::DexCache> dex_cache, ArtMethod* method, @@ -946,11 +946,8 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, const uint8_t* interpreter_metadata = nullptr; if (method == nullptr) { ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<1> hs(soa.Self()); - Handle<mirror::ClassLoader> loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader>(class_loader))); method = compiler_driver->ResolveMethod( - soa, dex_cache, loader, &dex_compilation_unit, method_idx, invoke_type); + soa, dex_cache, class_loader, &dex_compilation_unit, method_idx, invoke_type); } // For AOT compilation, we may not get a method, for example if its class is erroneous. // JIT should always have a method. @@ -959,16 +956,6 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, graph->SetArtMethod(method); ScopedObjectAccess soa(Thread::Current()); interpreter_metadata = method->GetQuickenedInfo(class_linker->GetImagePointerSize()); - dex::TypeIndex type_index = method->GetDeclaringClass()->GetDexTypeIndex(); - - // Update the dex cache if the type is not in it yet. Note that under AOT, - // the verifier must have set it, but under JIT, there's no guarantee, as we - // don't necessarily run the verifier. - // The compiler and the compiler driver assume the compiling class is - // in the dex cache. - if (dex_cache->GetResolvedType(type_index) == nullptr) { - dex_cache->SetResolvedType(type_index, method->GetDeclaringClass()); - } } std::unique_ptr<CodeGenerator> codegen( @@ -1049,7 +1036,7 @@ CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item, InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx, - jobject jclass_loader, + Handle<mirror::ClassLoader> jclass_loader, const DexFile& dex_file, Handle<mirror::DexCache> dex_cache) const { CompilerDriver* compiler_driver = GetCompilerDriver(); @@ -1163,7 +1150,6 @@ bool OptimizingCompiler::JitCompile(Thread* self, Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache())); DCHECK(method->IsCompilable()); - jobject jclass_loader = class_loader.ToJObject(); const DexFile* dex_file = method->GetDexFile(); const uint16_t class_def_idx = method->GetClassDefIndex(); const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset()); @@ -1187,7 +1173,7 @@ bool OptimizingCompiler::JitCompile(Thread* self, invoke_type, class_def_idx, method_idx, - jclass_loader, + class_loader, *dex_file, dex_cache, method, diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index c55fccc7d3..6e332ca59b 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -65,11 +65,13 @@ ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetThrowabl class ReferenceTypePropagation::RTPVisitor : public HGraphDelegateVisitor { public: RTPVisitor(HGraph* graph, + Handle<mirror::ClassLoader> class_loader, Handle<mirror::DexCache> hint_dex_cache, HandleCache* handle_cache, ArenaVector<HInstruction*>* worklist, bool is_first_run) : HGraphDelegateVisitor(graph), + class_loader_(class_loader), hint_dex_cache_(hint_dex_cache), handle_cache_(handle_cache), worklist_(worklist), @@ -101,6 +103,7 @@ class ReferenceTypePropagation::RTPVisitor : public HGraphDelegateVisitor { bool is_exact); private: + Handle<mirror::ClassLoader> class_loader_; Handle<mirror::DexCache> hint_dex_cache_; HandleCache* handle_cache_; ArenaVector<HInstruction*>* worklist_; @@ -108,11 +111,13 @@ class ReferenceTypePropagation::RTPVisitor : public HGraphDelegateVisitor { }; ReferenceTypePropagation::ReferenceTypePropagation(HGraph* graph, + Handle<mirror::ClassLoader> class_loader, Handle<mirror::DexCache> hint_dex_cache, VariableSizedHandleScope* handles, bool is_first_run, const char* name) : HOptimization(graph, name), + class_loader_(class_loader), hint_dex_cache_(hint_dex_cache), handle_cache_(handles), worklist_(graph->GetArena()->Adapter(kArenaAllocReferenceTypePropagation)), @@ -147,7 +152,12 @@ void ReferenceTypePropagation::ValidateTypes() { } void ReferenceTypePropagation::Visit(HInstruction* instruction) { - RTPVisitor visitor(graph_, hint_dex_cache_, &handle_cache_, &worklist_, is_first_run_); + RTPVisitor visitor(graph_, + class_loader_, + hint_dex_cache_, + &handle_cache_, + &worklist_, + is_first_run_); instruction->Accept(&visitor); } @@ -321,7 +331,12 @@ void ReferenceTypePropagation::Run() { } void ReferenceTypePropagation::VisitBasicBlock(HBasicBlock* block) { - RTPVisitor visitor(graph_, hint_dex_cache_, &handle_cache_, &worklist_, is_first_run_); + RTPVisitor visitor(graph_, + class_loader_, + hint_dex_cache_, + &handle_cache_, + &worklist_, + is_first_run_); // Handle Phis first as there might be instructions in the same block who depend on them. for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { VisitPhi(it.Current()->AsPhi()); @@ -542,8 +557,9 @@ void ReferenceTypePropagation::RTPVisitor::UpdateReferenceTypeInfo(HInstruction* ScopedObjectAccess soa(Thread::Current()); ObjPtr<mirror::DexCache> dex_cache = FindDexCacheWithHint(soa.Self(), dex_file, hint_dex_cache_); - // Get type from dex cache assuming it was populated by the verifier. - SetClassAsTypeInfo(instr, dex_cache->GetResolvedType(type_idx), is_exact); + ObjPtr<mirror::Class> klass = + ClassLinker::LookupResolvedType(type_idx, dex_cache, class_loader_.Get()); + SetClassAsTypeInfo(instr, klass, is_exact); } void ReferenceTypePropagation::RTPVisitor::VisitNewInstance(HNewInstance* instr) { @@ -556,25 +572,13 @@ void ReferenceTypePropagation::RTPVisitor::VisitNewArray(HNewArray* instr) { SetClassAsTypeInfo(instr, instr->GetLoadClass()->GetClass().Get(), /* is_exact */ true); } -static mirror::Class* GetClassFromDexCache(Thread* self, - const DexFile& dex_file, - dex::TypeIndex type_idx, - Handle<mirror::DexCache> hint_dex_cache) - REQUIRES_SHARED(Locks::mutator_lock_) { - ObjPtr<mirror::DexCache> dex_cache = FindDexCacheWithHint(self, dex_file, hint_dex_cache); - // Get type from dex cache assuming it was populated by the verifier. - return dex_cache->GetResolvedType(type_idx); -} - void ReferenceTypePropagation::RTPVisitor::VisitParameterValue(HParameterValue* instr) { // We check if the existing type is valid: the inliner may have set it. if (instr->GetType() == Primitive::kPrimNot && !instr->GetReferenceTypeInfo().IsValid()) { - ScopedObjectAccess soa(Thread::Current()); - mirror::Class* resolved_class = GetClassFromDexCache(soa.Self(), - instr->GetDexFile(), - instr->GetTypeIndex(), - hint_dex_cache_); - SetClassAsTypeInfo(instr, resolved_class, /* is_exact */ false); + UpdateReferenceTypeInfo(instr, + instr->GetTypeIndex(), + instr->GetDexFile(), + /* is_exact */ false); } } diff --git a/compiler/optimizing/reference_type_propagation.h b/compiler/optimizing/reference_type_propagation.h index 4663471729..215e96786b 100644 --- a/compiler/optimizing/reference_type_propagation.h +++ b/compiler/optimizing/reference_type_propagation.h @@ -33,6 +33,7 @@ namespace art { class ReferenceTypePropagation : public HOptimization { public: ReferenceTypePropagation(HGraph* graph, + Handle<mirror::ClassLoader> class_loader, Handle<mirror::DexCache> hint_dex_cache, VariableSizedHandleScope* handles, bool is_first_run, @@ -105,6 +106,8 @@ class ReferenceTypePropagation : public HOptimization { void ValidateTypes(); + Handle<mirror::ClassLoader> class_loader_; + // Note: hint_dex_cache_ is usually, but not necessarily, the dex cache associated with // graph_->GetDexFile(). Since we may look up also in other dex files, it's used only // as a hint, to reduce the number of calls to the costly ClassLinker::FindDexCache(). diff --git a/compiler/optimizing/reference_type_propagation_test.cc b/compiler/optimizing/reference_type_propagation_test.cc index b061c871b0..84a4bab1a9 100644 --- a/compiler/optimizing/reference_type_propagation_test.cc +++ b/compiler/optimizing/reference_type_propagation_test.cc @@ -38,6 +38,7 @@ class ReferenceTypePropagationTest : public CommonCompilerTest { void SetupPropagation(VariableSizedHandleScope* handles) { graph_->InitializeInexactObjectRTI(handles); propagation_ = new (&allocator_) ReferenceTypePropagation(graph_, + Handle<mirror::ClassLoader>(), Handle<mirror::DexCache>(), handles, true, diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc index 487e4dd498..50ab11bc23 100644 --- a/compiler/optimizing/ssa_builder.cc +++ b/compiler/optimizing/ssa_builder.cc @@ -499,7 +499,11 @@ GraphAnalysisResult SsaBuilder::BuildSsa() { // 4) Compute type of reference type instructions. The pass assumes that // NullConstant has been fixed up. - ReferenceTypePropagation(graph_, dex_cache_, handles_, /* is_first_run */ true).Run(); + ReferenceTypePropagation(graph_, + class_loader_, + dex_cache_, + handles_, + /* is_first_run */ true).Run(); // 5) HInstructionBuilder duplicated ArrayGet instructions with ambiguous type // (int/float or long/double) and marked ArraySets with ambiguous input type. diff --git a/compiler/optimizing/ssa_builder.h b/compiler/optimizing/ssa_builder.h index 45dac54115..978f113ec4 100644 --- a/compiler/optimizing/ssa_builder.h +++ b/compiler/optimizing/ssa_builder.h @@ -48,9 +48,11 @@ namespace art { class SsaBuilder : public ValueObject { public: SsaBuilder(HGraph* graph, + Handle<mirror::ClassLoader> class_loader, Handle<mirror::DexCache> dex_cache, VariableSizedHandleScope* handles) : graph_(graph), + class_loader_(class_loader), dex_cache_(dex_cache), handles_(handles), agets_fixed_(false), @@ -115,6 +117,7 @@ class SsaBuilder : public ValueObject { void RemoveRedundantUninitializedStrings(); HGraph* graph_; + Handle<mirror::ClassLoader> class_loader_; Handle<mirror::DexCache> dex_cache_; VariableSizedHandleScope* const handles_; diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc index c2275aca95..90b49556b7 100644 --- a/dex2oat/dex2oat_test.cc +++ b/dex2oat/dex2oat_test.cc @@ -231,7 +231,7 @@ class Dex2oatSwapTest : public Dex2oatTest { } virtual std::string GetTestDexFileName() { - return GetDexSrc1(); + return Dex2oatEnvironmentTest::GetTestDexFileName("VerifierDeps"); } virtual void CheckResult(bool expect_use) { diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index ce63e18921..147be4afa7 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -2235,9 +2235,14 @@ class ImageDumper { ScopedIndentation indent2(&state->vios_); auto* resolved_types = dex_cache->GetResolvedTypes(); for (size_t i = 0; i < num_types; ++i) { - auto* elem = resolved_types[i].Read(); + auto pair = resolved_types[i].load(std::memory_order_relaxed); size_t run = 0; - for (size_t j = i + 1; j != num_types && elem == resolved_types[j].Read(); ++j) { + for (size_t j = i + 1; j != num_types; ++j) { + auto other_pair = resolved_types[j].load(std::memory_order_relaxed); + if (pair.index != other_pair.index || + pair.object.Read() != other_pair.object.Read()) { + break; + } ++run; } if (run == 0) { @@ -2247,12 +2252,13 @@ class ImageDumper { i = i + run; } std::string msg; + auto* elem = pair.object.Read(); if (elem == nullptr) { msg = "null"; } else { msg = elem->PrettyClass(); } - os << StringPrintf("%p %s\n", elem, msg.c_str()); + os << StringPrintf("%p %u %s\n", elem, pair.index, msg.c_str()); } } } diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc index 9a73830f99..2546822613 100644 --- a/patchoat/patchoat.cc +++ b/patchoat/patchoat.cc @@ -643,8 +643,8 @@ void PatchOat::PatchDexFileArrays(mirror::ObjectArray<mirror::Object>* img_roots if (orig_strings != nullptr) { orig_dex_cache->FixupStrings(RelocatedCopyOf(orig_strings), RelocatedPointerVisitor(this)); } - GcRoot<mirror::Class>* orig_types = orig_dex_cache->GetResolvedTypes(); - GcRoot<mirror::Class>* relocated_types = RelocatedAddressOfPointer(orig_types); + mirror::TypeDexCacheType* orig_types = orig_dex_cache->GetResolvedTypes(); + mirror::TypeDexCacheType* relocated_types = RelocatedAddressOfPointer(orig_types); copy_dex_cache->SetField64<false>( mirror::DexCache::ResolvedTypesOffset(), static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_types))); diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc index a6c3cf067b..d395c170bf 100644 --- a/profman/profile_assistant_test.cc +++ b/profman/profile_assistant_test.cc @@ -94,6 +94,54 @@ class ProfileAssistantTest : public CommonRuntimeTest { std::string error; return ExecAndReturnCode(argv_str, &error); } + + bool CreateProfile(std::string class_file_contents, const std::string& filename) { + ScratchFile class_names_file; + File* file = class_names_file.GetFile(); + EXPECT_TRUE(file->WriteFully(class_file_contents.c_str(), class_file_contents.length())); + EXPECT_EQ(0, file->Flush()); + EXPECT_TRUE(file->ResetOffset()); + std::string profman_cmd = GetProfmanCmd(); + std::vector<std::string> argv_str; + argv_str.push_back(profman_cmd); + argv_str.push_back("--create-profile-from=" + class_names_file.GetFilename()); + argv_str.push_back("--reference-profile-file=" + filename); + argv_str.push_back("--apk=" + GetLibCoreDexFileNames()[0]); + argv_str.push_back("--dex-location=classes.dex"); + std::string error; + EXPECT_EQ(ExecAndReturnCode(argv_str, &error), 0); + return true; + } + + bool DumpClasses(const std::string& filename, std::string* file_contents) { + ScratchFile class_names_file; + std::string profman_cmd = GetProfmanCmd(); + std::vector<std::string> argv_str; + argv_str.push_back(profman_cmd); + argv_str.push_back("--dump-classes"); + argv_str.push_back("--profile-file=" + filename); + argv_str.push_back("--apk=" + GetLibCoreDexFileNames()[0]); + argv_str.push_back("--dex-location=classes.dex"); + argv_str.push_back("--dump-output-to-fd=" + std::to_string(GetFd(class_names_file))); + std::string error; + EXPECT_EQ(ExecAndReturnCode(argv_str, &error), 0); + File* file = class_names_file.GetFile(); + EXPECT_EQ(0, file->Flush()); + EXPECT_TRUE(file->ResetOffset()); + int64_t length = file->GetLength(); + std::unique_ptr<char[]> buf(new char[length]); + EXPECT_EQ(file->Read(buf.get(), length, 0), length); + *file_contents = std::string(buf.get(), length); + return true; + } + + bool CreateAndDump(const std::string& input_file_contents, std::string* output_file_contents) { + ScratchFile profile_file; + EXPECT_TRUE(CreateProfile(input_file_contents, profile_file.GetFilename())); + profile_file.GetFile()->ResetOffset(); + EXPECT_TRUE(DumpClasses(profile_file.GetFilename(), output_file_contents)); + return true; + } }; TEST_F(ProfileAssistantTest, AdviseCompilationEmptyReferences) { @@ -307,4 +355,55 @@ TEST_F(ProfileAssistantTest, TestProfileGeneration) { ASSERT_TRUE(info.Load(GetFd(profile))); } +TEST_F(ProfileAssistantTest, TestProfileCreationAllMatch) { + // Class names put here need to be in sorted order. + std::vector<std::string> class_names = { + "java.lang.Comparable", + "java.lang.Math", + "java.lang.Object" + }; + std::string input_file_contents; + for (std::string& class_name : class_names) { + input_file_contents += class_name + std::string("\n"); + } + std::string output_file_contents; + ASSERT_TRUE(CreateAndDump(input_file_contents, &output_file_contents)); + ASSERT_EQ(output_file_contents, input_file_contents); +} + +TEST_F(ProfileAssistantTest, TestProfileCreationOneNotMatched) { + // Class names put here need to be in sorted order. + std::vector<std::string> class_names = { + "doesnt.match.this.one", + "java.lang.Comparable", + "java.lang.Object" + }; + std::string input_file_contents; + for (std::string& class_name : class_names) { + input_file_contents += class_name + std::string("\n"); + } + std::string output_file_contents; + ASSERT_TRUE(CreateAndDump(input_file_contents, &output_file_contents)); + std::string expected_contents = + class_names[1] + std::string("\n") + class_names[2] + std::string("\n"); + ASSERT_EQ(output_file_contents, expected_contents); +} + +TEST_F(ProfileAssistantTest, TestProfileCreationNoneMatched) { + // Class names put here need to be in sorted order. + std::vector<std::string> class_names = { + "doesnt.match.this.one", + "doesnt.match.this.one.either", + "nor.this.one" + }; + std::string input_file_contents; + for (std::string& class_name : class_names) { + input_file_contents += class_name + std::string("\n"); + } + std::string output_file_contents; + ASSERT_TRUE(CreateAndDump(input_file_contents, &output_file_contents)); + std::string expected_contents(""); + ASSERT_EQ(output_file_contents, expected_contents); +} + } // namespace art diff --git a/profman/profman.cc b/profman/profman.cc index b0cbed1ef9..f6b145aa76 100644 --- a/profman/profman.cc +++ b/profman/profman.cc @@ -21,8 +21,11 @@ #include <sys/stat.h> #include <unistd.h> +#include <fstream> #include <iostream> +#include <set> #include <string> +#include <unordered_set> #include <vector> #include "android-base/stringprintf.h" @@ -84,8 +87,10 @@ NO_RETURN static void Usage(const char *fmt, ...) { UsageError(" --dump-only: dumps the content of the specified profile files"); UsageError(" to standard output (default) in a human readable form."); UsageError(""); - UsageError(" --dump-output-to-fd=<number>: redirects --dump-info-for output to a file"); - UsageError(" descriptor."); + UsageError(" --dump-output-to-fd=<number>: redirects --dump-only output to a file descriptor."); + UsageError(""); + UsageError(" --dump-classes: dumps a sorted list of classes that are in the specified profile"); + UsageError(" file to standard output (default) in a human readable form."); UsageError(""); UsageError(" --profile-file=<filename>: specify profiler output file to use for compilation."); UsageError(" Can be specified multiple time, in which case the data from the different"); @@ -103,6 +108,7 @@ NO_RETURN static void Usage(const char *fmt, ...) { UsageError(" --reference-profile-file-fd=<number>: same as --reference-profile-file but"); UsageError(" accepts a file descriptor. Cannot be used together with"); UsageError(" --reference-profile-file."); + UsageError(""); UsageError(" --generate-test-profile=<filename>: generates a random profile file for testing."); UsageError(" --generate-test-profile-num-dex=<number>: number of dex files that should be"); UsageError(" included in the generated profile. Defaults to 20."); @@ -111,12 +117,15 @@ NO_RETURN static void Usage(const char *fmt, ...) { UsageError(" --generate-test-profile-class-ratio=<number>: the percentage from the maximum"); UsageError(" number of classes that should be generated. Defaults to 5."); UsageError(""); + UsageError(" --create-profile-from=<filename>: creates a profile from a list of classes."); + UsageError(""); UsageError(""); UsageError(" --dex-location=<string>: location string to use with corresponding"); UsageError(" apk-fd to find dex files"); UsageError(""); UsageError(" --apk-fd=<number>: file descriptor containing an open APK to"); UsageError(" search for dex files"); + UsageError(" --apk-=<filename>: an APK to search for dex files"); UsageError(""); exit(EXIT_FAILURE); @@ -132,6 +141,7 @@ class ProfMan FINAL { ProfMan() : reference_profile_file_fd_(kInvalidFd), dump_only_(false), + dump_classes_(false), dump_output_to_fd_(kInvalidFd), test_profile_num_dex_(kDefaultTestProfileNumDex), test_profile_method_ratio_(kDefaultTestProfileMethodRatio), @@ -164,6 +174,10 @@ class ProfMan FINAL { } if (option == "--dump-only") { dump_only_ = true; + } else if (option == "--dump-classes") { + dump_classes_ = true; + } else if (option.starts_with("--create-profile-from=")) { + create_profile_from_file_ = option.substr(strlen("--create-profile-from=")).ToString(); } else if (option.starts_with("--dump-output-to-fd=")) { ParseUintOption(option, "--dump-output-to-fd", &dump_output_to_fd_, Usage); } else if (option.starts_with("--profile-file=")) { @@ -178,6 +192,8 @@ class ProfMan FINAL { dex_locations_.push_back(option.substr(strlen("--dex-location=")).ToString()); } else if (option.starts_with("--apk-fd=")) { ParseFdForCollection(option, "--apk-fd", &apks_fd_); + } else if (option.starts_with("--apk=")) { + apk_files_.push_back(option.substr(strlen("--apk=")).ToString()); } else if (option.starts_with("--generate-test-profile=")) { test_profile_ = option.substr(strlen("--generate-test-profile=")).ToString(); } else if (option.starts_with("--generate-test-profile-num-dex=")) { @@ -213,14 +229,34 @@ class ProfMan FINAL { } return; } - // --dump-only may be specified with only --reference-profiles present. - if (!dump_only_ && !has_profiles) { + if (!apk_files_.empty() && !apks_fd_.empty()) { + Usage("APK files should not be specified with both --apk-fd and --apk"); + } + if (!create_profile_from_file_.empty()) { + if (apk_files_.empty() && apks_fd_.empty()) { + Usage("APK files must be specified"); + } + if (dex_locations_.empty()) { + Usage("DEX locations must be specified"); + } + if (reference_profile_file_.empty() && !FdIsValid(reference_profile_file_fd_)) { + Usage("Reference profile must be specified with --reference-profile-file or " + "--reference-profile-file-fd"); + } + if (has_profiles) { + Usage("Profile must be specified with --reference-profile-file or " + "--reference-profile-file-fd"); + } + return; + } + // --dump-only and --dump-classes may be specified with only --reference-profiles present. + if (!dump_only_ && !dump_classes_ && !has_profiles) { Usage("No profile files specified."); } if (!profile_files_.empty() && !profile_files_fd_.empty()) { Usage("Profile files should not be specified with both --profile-file-fd and --profile-file"); } - if (!dump_only_ && !has_reference_profile) { + if (!dump_only_ && !dump_classes_ && !has_reference_profile) { Usage("No reference profile file specified."); } if (!reference_profile_file_.empty() && FdIsValid(reference_profile_file_fd_)) { @@ -248,6 +284,46 @@ class ProfMan FINAL { return result; } + void OpenApkFilesFromLocations(std::vector<std::unique_ptr<const DexFile>>* dex_files) { + bool use_apk_fd_list = !apks_fd_.empty(); + if (use_apk_fd_list) { + CHECK(apk_files_.empty()); + CHECK_EQ(dex_locations_.size(), apks_fd_.size()); + } else { + CHECK_EQ(dex_locations_.size(), apk_files_.size()); + CHECK(!apk_files_.empty()); + } + static constexpr bool kVerifyChecksum = true; + for (size_t i = 0; i < dex_locations_.size(); ++i) { + std::string error_msg; + std::vector<std::unique_ptr<const DexFile>> dex_files_for_location; + if (use_apk_fd_list) { + if (DexFile::OpenZip(apks_fd_[i], + dex_locations_[i], + kVerifyChecksum, + &error_msg, + &dex_files_for_location)) { + } else { + LOG(WARNING) << "OpenZip failed for '" << dex_locations_[i] << "' " << error_msg; + continue; + } + } else { + if (DexFile::Open(apk_files_[i].c_str(), + dex_locations_[i], + kVerifyChecksum, + &error_msg, + &dex_files_for_location)) { + } else { + LOG(WARNING) << "Open failed for '" << dex_locations_[i] << "' " << error_msg; + continue; + } + } + for (std::unique_ptr<const DexFile>& dex_file : dex_files_for_location) { + dex_files->emplace_back(std::move(dex_file)); + } + } + } + int DumpOneProfile(const std::string& banner, const std::string& filename, int fd, @@ -256,13 +332,13 @@ class ProfMan FINAL { if (!filename.empty()) { fd = open(filename.c_str(), O_RDWR); if (fd < 0) { - std::cerr << "Cannot open " << filename << strerror(errno); + LOG(ERROR) << "Cannot open " << filename << strerror(errno); return -1; } } ProfileCompilationInfo info; if (!info.Load(fd)) { - std::cerr << "Cannot load profile info from fd=" << fd << "\n"; + LOG(ERROR) << "Cannot load profile info from fd=" << fd << "\n"; return -1; } std::string this_dump = banner + "\n" + info.DumpInfo(dex_files) + "\n"; @@ -281,25 +357,7 @@ class ProfMan FINAL { // Open apk/zip files and and read dex files. MemMap::Init(); // for ZipArchive::OpenFromFd std::vector<std::unique_ptr<const DexFile>> dex_files; - assert(dex_locations_.size() == apks_fd_.size()); - static constexpr bool kVerifyChecksum = true; - for (size_t i = 0; i < dex_locations_.size(); ++i) { - std::string error_msg; - std::vector<std::unique_ptr<const DexFile>> dex_files_for_location; - if (DexFile::OpenZip(apks_fd_[i], - dex_locations_[i], - kVerifyChecksum, - &error_msg, - &dex_files_for_location)) { - } else { - LOG(WARNING) << "OpenFromZip failed for '" << dex_locations_[i] << "' " << error_msg; - continue; - } - for (std::unique_ptr<const DexFile>& dex_file : dex_files_for_location) { - dex_files.emplace_back(std::move(dex_file)); - } - } - + OpenApkFilesFromLocations(&dex_files); std::string dump; // Dump individual profile files. if (!profile_files_fd_.empty()) { @@ -358,17 +416,207 @@ class ProfMan FINAL { return dump_only_; } + bool GetClassNames(int fd, + std::vector<std::unique_ptr<const DexFile>>* dex_files, + std::set<std::string>* class_names) { + ProfileCompilationInfo profile_info; + if (!profile_info.Load(fd)) { + LOG(ERROR) << "Cannot load profile info"; + return false; + } + profile_info.GetClassNames(dex_files, class_names); + return true; + } + + bool GetClassNames(std::string profile_file, + std::vector<std::unique_ptr<const DexFile>>* dex_files, + std::set<std::string>* class_names) { + int fd = open(profile_file.c_str(), O_RDONLY); + if (!FdIsValid(fd)) { + LOG(ERROR) << "Cannot open " << profile_file << strerror(errno); + return false; + } + if (!GetClassNames(fd, dex_files, class_names)) { + return false; + } + if (close(fd) < 0) { + PLOG(WARNING) << "Failed to close descriptor"; + } + return true; + } + + int DumpClasses() { + // Open apk/zip files and and read dex files. + MemMap::Init(); // for ZipArchive::OpenFromFd + // Open the dex files to get the names for classes. + std::vector<std::unique_ptr<const DexFile>> dex_files; + OpenApkFilesFromLocations(&dex_files); + // Build a vector of class names from individual profile files. + std::set<std::string> class_names; + if (!profile_files_fd_.empty()) { + for (int profile_file_fd : profile_files_fd_) { + if (!GetClassNames(profile_file_fd, &dex_files, &class_names)) { + return -1; + } + } + } + if (!profile_files_.empty()) { + for (const std::string& profile_file : profile_files_) { + if (!GetClassNames(profile_file, &dex_files, &class_names)) { + return -1; + } + } + } + // Concatenate class names from reference profile file. + if (FdIsValid(reference_profile_file_fd_)) { + if (!GetClassNames(reference_profile_file_fd_, &dex_files, &class_names)) { + return -1; + } + } + if (!reference_profile_file_.empty()) { + if (!GetClassNames(reference_profile_file_, &dex_files, &class_names)) { + return -1; + } + } + // Dump the class names. + std::string dump; + for (const std::string& class_name : class_names) { + dump += class_name + std::string("\n"); + } + if (!FdIsValid(dump_output_to_fd_)) { + std::cout << dump; + } else { + unix_file::FdFile out_fd(dump_output_to_fd_, false /*check_usage*/); + if (!out_fd.WriteFully(dump.c_str(), dump.length())) { + return -1; + } + } + return 0; + } + + bool ShouldOnlyDumpClasses() { + return dump_classes_; + } + + // Read lines from the given file, dropping comments and empty lines. Post-process each line with + // the given function. + template <typename T> + static T* ReadCommentedInputFromFile( + const char* input_filename, std::function<std::string(const char*)>* process) { + std::unique_ptr<std::ifstream> input_file(new std::ifstream(input_filename, std::ifstream::in)); + if (input_file.get() == nullptr) { + LOG(ERROR) << "Failed to open input file " << input_filename; + return nullptr; + } + std::unique_ptr<T> result( + ReadCommentedInputStream<T>(*input_file, process)); + input_file->close(); + return result.release(); + } + + // Read lines from the given stream, dropping comments and empty lines. Post-process each line + // with the given function. + template <typename T> + static T* ReadCommentedInputStream( + std::istream& in_stream, + std::function<std::string(const char*)>* process) { + std::unique_ptr<T> output(new T()); + while (in_stream.good()) { + std::string dot; + std::getline(in_stream, dot); + if (android::base::StartsWith(dot, "#") || dot.empty()) { + continue; + } + if (process != nullptr) { + std::string descriptor((*process)(dot.c_str())); + output->insert(output->end(), descriptor); + } else { + output->insert(output->end(), dot); + } + } + return output.release(); + } + + int CreateProfile() { + MemMap::Init(); // for ZipArchive::OpenFromFd + // Open the profile output file if needed. + int fd = reference_profile_file_fd_; + if (!FdIsValid(fd)) { + CHECK(!reference_profile_file_.empty()); + fd = open(reference_profile_file_.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644); + if (fd < 0) { + LOG(ERROR) << "Cannot open " << reference_profile_file_ << strerror(errno); + return -1; + } + } + // Read the user-specified list of classes (dot notation rather than descriptors). + std::unique_ptr<std::unordered_set<std::string>> + user_class_list(ReadCommentedInputFromFile<std::unordered_set<std::string>>( + create_profile_from_file_.c_str(), nullptr)); // No post-processing. + std::unordered_set<std::string> matched_user_classes; + // Open the dex files to look up class names. + std::vector<std::unique_ptr<const DexFile>> dex_files; + OpenApkFilesFromLocations(&dex_files); + // Iterate over the dex files looking for class names in the input stream. + std::set<DexCacheResolvedClasses> resolved_class_set; + for (auto& dex_file : dex_files) { + // Compute the set of classes to be added for this dex file first. This + // avoids creating an entry in the profile information for dex files that + // contribute no classes. + std::unordered_set<dex::TypeIndex> classes_to_be_added; + for (const auto& klass : *user_class_list) { + std::string descriptor = DotToDescriptor(klass.c_str()); + const DexFile::TypeId* type_id = dex_file->FindTypeId(descriptor.c_str()); + if (type_id == nullptr) { + continue; + } + classes_to_be_added.insert(dex_file->GetIndexForTypeId(*type_id)); + matched_user_classes.insert(klass); + } + if (classes_to_be_added.empty()) { + continue; + } + // Insert the DexCacheResolved Classes into the set expected for + // AddMethodsAndClasses. + std::set<DexCacheResolvedClasses>::iterator dex_resolved_classes = + resolved_class_set.emplace(dex_file->GetLocation(), + dex_file->GetBaseLocation(), + dex_file->GetLocationChecksum()).first; + dex_resolved_classes->AddClasses(classes_to_be_added.begin(), classes_to_be_added.end()); + } + // Warn the user if we didn't find matches for every class. + for (const auto& klass : *user_class_list) { + if (matched_user_classes.find(klass) == matched_user_classes.end()) { + LOG(WARNING) << "requested class '" << klass << "' was not matched in any dex file"; + } + } + // Generate the profile data structure. + ProfileCompilationInfo info; + std::vector<MethodReference> methods; // No methods for now. + info.AddMethodsAndClasses(methods, resolved_class_set); + // Write the profile file. + CHECK(info.Save(fd)); + if (close(fd) < 0) { + PLOG(WARNING) << "Failed to close descriptor"; + } + return 0; + } + + bool ShouldCreateProfile() { + return !create_profile_from_file_.empty(); + } + int GenerateTestProfile() { int profile_test_fd = open(test_profile_.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644); if (profile_test_fd < 0) { - std::cerr << "Cannot open " << test_profile_ << strerror(errno); + LOG(ERROR) << "Cannot open " << test_profile_ << strerror(errno); return -1; } bool result = ProfileCompilationInfo::GenerateTestProfile(profile_test_fd, - test_profile_num_dex_, - test_profile_method_ratio_, - test_profile_class_ratio_); + test_profile_num_dex_, + test_profile_method_ratio_, + test_profile_class_ratio_); close(profile_test_fd); // ignore close result. return result ? 0 : -1; } @@ -405,12 +653,15 @@ class ProfMan FINAL { std::vector<std::string> profile_files_; std::vector<int> profile_files_fd_; std::vector<std::string> dex_locations_; + std::vector<std::string> apk_files_; std::vector<int> apks_fd_; std::string reference_profile_file_; int reference_profile_file_fd_; bool dump_only_; + bool dump_classes_; int dump_output_to_fd_; std::string test_profile_; + std::string create_profile_from_file_; uint16_t test_profile_num_dex_; uint16_t test_profile_method_ratio_; uint16_t test_profile_class_ratio_; @@ -430,6 +681,12 @@ static int profman(int argc, char** argv) { if (profman.ShouldOnlyDumpProfile()) { return profman.DumpProfileInfo(); } + if (profman.ShouldOnlyDumpClasses()) { + return profman.DumpClasses(); + } + if (profman.ShouldCreateProfile()) { + return profman.CreateProfile(); + } // Process profile information and assess if we need to do a profile guided compilation. // This operation involves I/O. return profman.ProcessProfiles(); diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S index 10b690ac4a..ec8ae85722 100644 --- a/runtime/arch/mips/quick_entrypoints_mips.S +++ b/runtime/arch/mips/quick_entrypoints_mips.S @@ -2042,67 +2042,158 @@ ENTRY_NO_GP art_quick_indexof /* $a0 holds address of "this" */ /* $a1 holds "ch" */ /* $a2 holds "fromIndex" */ - lw $t0, MIRROR_STRING_COUNT_OFFSET($a0) # this.length() - slt $t1, $a2, $zero # if fromIndex < 0 +#if (STRING_COMPRESSION_FEATURE) + lw $a3, MIRROR_STRING_COUNT_OFFSET($a0) # 'count' field of this +#else + lw $t0, MIRROR_STRING_COUNT_OFFSET($a0) # this.length() +#endif + slt $t1, $a2, $zero # if fromIndex < 0 #if defined(_MIPS_ARCH_MIPS32R6) || defined(_MIPS_ARCH_MIPS64R6) - seleqz $a2, $a2, $t1 # fromIndex = 0; + seleqz $a2, $a2, $t1 # fromIndex = 0; #else - movn $a2, $zero, $t1 # fromIndex = 0; + movn $a2, $zero, $t1 # fromIndex = 0; #endif - subu $t0, $t0, $a2 # this.length() - fromIndex - blez $t0, 6f # if this.length()-fromIndex <= 0 - li $v0, -1 # return -1; - - sll $v0, $a2, 1 # $a0 += $a2 * 2 - addu $a0, $a0, $v0 # " ditto " - move $v0, $a2 # Set i to fromIndex. +#if (STRING_COMPRESSION_FEATURE) + srl $t0, $a3, 1 # $a3 holds count (with flag) and $t0 holds actual length +#endif + subu $t0, $t0, $a2 # this.length() - fromIndex + blez $t0, 6f # if this.length()-fromIndex <= 0 + li $v0, -1 # return -1; + +#if (STRING_COMPRESSION_FEATURE) + sll $a3, $a3, 31 # Extract compression flag. + beqz $a3, .Lstring_indexof_compressed + move $t2, $a0 # Save a copy in $t2 to later compute result (in branch delay slot). +#endif + sll $v0, $a2, 1 # $a0 += $a2 * 2 + addu $a0, $a0, $v0 # " ditto " + move $v0, $a2 # Set i to fromIndex. 1: - lhu $t3, MIRROR_STRING_VALUE_OFFSET($a0) # if this.charAt(i) == ch - beq $t3, $a1, 6f # return i; - addu $a0, $a0, 2 # i++ - subu $t0, $t0, 1 # this.length() - i - bnez $t0, 1b # while this.length() - i > 0 - addu $v0, $v0, 1 # i++ + lhu $t3, MIRROR_STRING_VALUE_OFFSET($a0) # if this.charAt(i) == ch + beq $t3, $a1, 6f # return i; + addu $a0, $a0, 2 # i++ + subu $t0, $t0, 1 # this.length() - i + bnez $t0, 1b # while this.length() - i > 0 + addu $v0, $v0, 1 # i++ - li $v0, -1 # if this.length() - i <= 0 - # return -1; + li $v0, -1 # if this.length() - i <= 0 + # return -1; 6: - j $ra - nop + j $ra + nop + +#if (STRING_COMPRESSION_FEATURE) +.Lstring_indexof_compressed: + addu $a0, $a0, $a2 # $a0 += $a2 + +.Lstring_indexof_compressed_loop: + lbu $t3, MIRROR_STRING_VALUE_OFFSET($a0) + beq $t3, $a1, .Lstring_indexof_compressed_matched + subu $t0, $t0, 1 + bgtz $t0, .Lstring_indexof_compressed_loop + addu $a0, $a0, 1 + +.Lstring_indexof_nomatch: + jalr $zero, $ra + li $v0, -1 # return -1; + +.Lstring_indexof_compressed_matched: + jalr $zero, $ra + subu $v0, $a0, $t2 # return (current - start); +#endif END art_quick_indexof /* java.lang.String.compareTo(String anotherString) */ ENTRY_NO_GP art_quick_string_compareto /* $a0 holds address of "this" */ /* $a1 holds address of "anotherString" */ - beq $a0, $a1, 9f # this and anotherString are the same object - move $v0, $zero + beq $a0, $a1, .Lstring_compareto_length_diff # this and anotherString are the same object + move $a3, $a2 # trick to return 0 (it returns a2 - a3) + +#if (STRING_COMPRESSION_FEATURE) + lw $t0, MIRROR_STRING_COUNT_OFFSET($a0) # 'count' field of this + lw $t1, MIRROR_STRING_COUNT_OFFSET($a1) # 'count' field of anotherString + sra $a2, $t0, 1 # this.length() + sra $a3, $t1, 1 # anotherString.length() +#else + lw $a2, MIRROR_STRING_COUNT_OFFSET($a0) # this.length() + lw $a3, MIRROR_STRING_COUNT_OFFSET($a1) # anotherString.length() +#endif - lw $a2, MIRROR_STRING_COUNT_OFFSET($a0) # this.length() - lw $a3, MIRROR_STRING_COUNT_OFFSET($a1) # anotherString.length() - MINu $t2, $a2, $a3 -# $t2 now holds min(this.length(),anotherString.length()) + MINu $t2, $a2, $a3 + # $t2 now holds min(this.length(),anotherString.length()) - beqz $t2, 9f # while min(this.length(),anotherString.length())-i != 0 - subu $v0, $a2, $a3 # if $t2==0 return - # (this.length() - anotherString.length()) -1: - lhu $t0, MIRROR_STRING_VALUE_OFFSET($a0) # while this.charAt(i) == anotherString.charAt(i) - lhu $t1, MIRROR_STRING_VALUE_OFFSET($a1) - bne $t0, $t1, 9f # if this.charAt(i) != anotherString.charAt(i) - subu $v0, $t0, $t1 # return (this.charAt(i) - anotherString.charAt(i)) - addiu $a0, $a0, 2 # point at this.charAt(i++) - subu $t2, $t2, 1 # new value of - # min(this.length(),anotherString.length())-i - bnez $t2, 1b - addiu $a1, $a1, 2 # point at anotherString.charAt(i++) - subu $v0, $a2, $a3 - -9: - j $ra - nop + # while min(this.length(),anotherString.length())-i != 0 + beqz $t2, .Lstring_compareto_length_diff # if $t2==0 + nop # return (this.length() - anotherString.length()) + +#if (STRING_COMPRESSION_FEATURE) + # Differ cases: + sll $t3, $t0, 31 + beqz $t3, .Lstring_compareto_this_is_compressed + sll $t3, $t1, 31 # In branch delay slot. + beqz $t3, .Lstring_compareto_that_is_compressed + nop + b .Lstring_compareto_both_not_compressed + nop + +.Lstring_compareto_this_is_compressed: + beqz $t3, .Lstring_compareto_both_compressed + nop + /* If (this->IsCompressed() && that->IsCompressed() == false) */ +.Lstring_compareto_loop_comparison_this_compressed: + lbu $t0, MIRROR_STRING_VALUE_OFFSET($a0) + lhu $t1, MIRROR_STRING_VALUE_OFFSET($a1) + bne $t0, $t1, .Lstring_compareto_char_diff + addiu $a0, $a0, 1 # point at this.charAt(i++) - compressed + subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i + bnez $t2, .Lstring_compareto_loop_comparison_this_compressed + addiu $a1, $a1, 2 # point at anotherString.charAt(i++) - uncompressed + jalr $zero, $ra + subu $v0, $a2, $a3 # return (this.length() - anotherString.length()) + +.Lstring_compareto_that_is_compressed: + lhu $t0, MIRROR_STRING_VALUE_OFFSET($a0) + lbu $t1, MIRROR_STRING_VALUE_OFFSET($a1) + bne $t0, $t1, .Lstring_compareto_char_diff + addiu $a0, $a0, 2 # point at this.charAt(i++) - uncompressed + subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i + bnez $t2, .Lstring_compareto_that_is_compressed + addiu $a1, $a1, 1 # point at anotherString.charAt(i++) - compressed + jalr $zero, $ra + subu $v0, $a2, $a3 # return (this.length() - anotherString.length()) + +.Lstring_compareto_both_compressed: + lbu $t0, MIRROR_STRING_VALUE_OFFSET($a0) + lbu $t1, MIRROR_STRING_VALUE_OFFSET($a1) + bne $t0, $t1, .Lstring_compareto_char_diff + addiu $a0, $a0, 1 # point at this.charAt(i++) - compressed + subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i + bnez $t2, .Lstring_compareto_both_compressed + addiu $a1, $a1, 1 # point at anotherString.charAt(i++) - compressed + jalr $zero, $ra + subu $v0, $a2, $a3 # return (this.length() - anotherString.length()) +#endif + +.Lstring_compareto_both_not_compressed: + lhu $t0, MIRROR_STRING_VALUE_OFFSET($a0) # while this.charAt(i) == anotherString.charAt(i) + lhu $t1, MIRROR_STRING_VALUE_OFFSET($a1) + bne $t0, $t1, .Lstring_compareto_char_diff # if this.charAt(i) != anotherString.charAt(i) + # return (this.charAt(i) - anotherString.charAt(i)) + addiu $a0, $a0, 2 # point at this.charAt(i++) + subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i + bnez $t2, .Lstring_compareto_both_not_compressed + addiu $a1, $a1, 2 # point at anotherString.charAt(i++) + +.Lstring_compareto_length_diff: + jalr $zero, $ra + subu $v0, $a2, $a3 # return (this.length() - anotherString.length()) + +.Lstring_compareto_char_diff: + jalr $zero, $ra + subu $v0, $t0, $t1 # return (this.charAt(i) - anotherString.charAt(i)) END art_quick_string_compareto .extern artInvokePolymorphic diff --git a/runtime/arch/mips64/quick_entrypoints_mips64.S b/runtime/arch/mips64/quick_entrypoints_mips64.S index fff6d256b1..28d7c77938 100644 --- a/runtime/arch/mips64/quick_entrypoints_mips64.S +++ b/runtime/arch/mips64/quick_entrypoints_mips64.S @@ -1900,32 +1900,91 @@ END art_quick_deoptimize_from_compiled_code ENTRY_NO_GP art_quick_string_compareto /* $a0 holds address of "this" */ /* $a1 holds address of "anotherString" */ - beq $a0,$a1,9f # this and anotherString are the same object - move $v0,$zero + move $a2, $zero + beq $a0, $a1, .Lstring_compareto_length_diff # this and anotherString are the same object + move $a3, $zero # return 0 (it returns a2 - a3) + +#if (STRING_COMPRESSION_FEATURE) + lw $a4, MIRROR_STRING_COUNT_OFFSET($a0) # 'count' field of this + lw $a5, MIRROR_STRING_COUNT_OFFSET($a1) # 'count' field of anotherString + sra $a2, $a4, 1 # this.length() + sra $a3, $a5, 1 # anotherString.length() +#else + lw $a2, MIRROR_STRING_COUNT_OFFSET($a0) # this.length() + lw $a3, MIRROR_STRING_COUNT_OFFSET($a1) # anotherString.length() +#endif - lw $a2,MIRROR_STRING_COUNT_OFFSET($a0) # this.length() - lw $a3,MIRROR_STRING_COUNT_OFFSET($a1) # anotherString.length() - MINu $t2, $a2, $a3 -# $t2 now holds min(this.length(),anotherString.length()) + MINu $t2, $a2, $a3 + # $t2 now holds min(this.length(),anotherString.length()) - beqz $t2,9f # while min(this.length(),anotherString.length())-i != 0 - subu $v0,$a2,$a3 # if $t2==0 return - # (this.length() - anotherString.length()) -1: - lhu $t0,MIRROR_STRING_VALUE_OFFSET($a0) # while this.charAt(i) == anotherString.charAt(i) - lhu $t1,MIRROR_STRING_VALUE_OFFSET($a1) - bne $t0,$t1,9f # if this.charAt(i) != anotherString.charAt(i) - subu $v0,$t0,$t1 # return (this.charAt(i) - anotherString.charAt(i)) - daddiu $a0,$a0,2 # point at this.charAt(i++) - subu $t2,$t2,1 # new value of - # min(this.length(),anotherString.length())-i - bnez $t2,1b - daddiu $a1,$a1,2 # point at anotherString.charAt(i++) - subu $v0,$a2,$a3 - -9: - j $ra - nop + # while min(this.length(),anotherString.length())-i != 0 + beqzc $t2, .Lstring_compareto_length_diff # if $t2==0 + # return (this.length() - anotherString.length()) + +#if (STRING_COMPRESSION_FEATURE) + # Differ cases: + dext $a6, $a4, 0, 1 + beqz $a6, .Lstring_compareto_this_is_compressed + dext $a6, $a5, 0, 1 # In branch delay slot. + beqz $a6, .Lstring_compareto_that_is_compressed + nop + b .Lstring_compareto_both_not_compressed + nop + +.Lstring_compareto_this_is_compressed: + beqzc $a6, .Lstring_compareto_both_compressed + /* If (this->IsCompressed() && that->IsCompressed() == false) */ +.Lstring_compareto_loop_comparison_this_compressed: + lbu $t0, MIRROR_STRING_VALUE_OFFSET($a0) + lhu $t1, MIRROR_STRING_VALUE_OFFSET($a1) + bnec $t0, $t1, .Lstring_compareto_char_diff + daddiu $a0, $a0, 1 # point at this.charAt(i++) - compressed + subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i + bnez $t2, .Lstring_compareto_loop_comparison_this_compressed + daddiu $a1, $a1, 2 # point at anotherString.charAt(i++) - uncompressed + jalr $zero, $ra + subu $v0, $a2, $a3 # return (this.length() - anotherString.length()) + +.Lstring_compareto_that_is_compressed: + lhu $t0, MIRROR_STRING_VALUE_OFFSET($a0) + lbu $t1, MIRROR_STRING_VALUE_OFFSET($a1) + bnec $t0, $t1, .Lstring_compareto_char_diff + daddiu $a0, $a0, 2 # point at this.charAt(i++) - uncompressed + subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i + bnez $t2, .Lstring_compareto_that_is_compressed + daddiu $a1, $a1, 1 # point at anotherString.charAt(i++) - compressed + jalr $zero, $ra + subu $v0, $a2, $a3 # return (this.length() - anotherString.length()) + +.Lstring_compareto_both_compressed: + lbu $t0, MIRROR_STRING_VALUE_OFFSET($a0) + lbu $t1, MIRROR_STRING_VALUE_OFFSET($a1) + bnec $t0, $t1, .Lstring_compareto_char_diff + daddiu $a0, $a0, 1 # point at this.charAt(i++) - compressed + subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i + bnez $t2, .Lstring_compareto_both_compressed + daddiu $a1, $a1, 1 # point at anotherString.charAt(i++) - compressed + jalr $zero, $ra + subu $v0, $a2, $a3 # return (this.length() - anotherString.length()) +#endif + +.Lstring_compareto_both_not_compressed: + lhu $t0, MIRROR_STRING_VALUE_OFFSET($a0) # while this.charAt(i) == anotherString.charAt(i) + lhu $t1, MIRROR_STRING_VALUE_OFFSET($a1) + bnec $t0, $t1, .Lstring_compareto_char_diff # if this.charAt(i) != anotherString.charAt(i) + # return (this.charAt(i) - anotherString.charAt(i)) + daddiu $a0, $a0, 2 # point at this.charAt(i++) + subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i + bnez $t2, .Lstring_compareto_both_not_compressed + daddiu $a1, $a1, 2 # point at anotherString.charAt(i++) + +.Lstring_compareto_length_diff: + jalr $zero, $ra + subu $v0, $a2, $a3 # return (this.length() - anotherString.length()) + +.Lstring_compareto_char_diff: + jalr $zero, $ra + subu $v0, $t0, $t1 # return (this.charAt(i) - anotherString.charAt(i)) END art_quick_string_compareto /* java.lang.String.indexOf(int ch, int fromIndex=0) */ @@ -1933,31 +1992,64 @@ ENTRY_NO_GP art_quick_indexof /* $a0 holds address of "this" */ /* $a1 holds "ch" */ /* $a2 holds "fromIndex" */ - lw $t0,MIRROR_STRING_COUNT_OFFSET($a0) # this.length() - slt $at, $a2, $zero # if fromIndex < 0 - seleqz $a2, $a2, $at # fromIndex = 0; - subu $t0,$t0,$a2 # this.length() - fromIndex - blez $t0,6f # if this.length()-fromIndex <= 0 - li $v0,-1 # return -1; +#if (STRING_COMPRESSION_FEATURE) + lw $a3, MIRROR_STRING_COUNT_OFFSET($a0) # 'count' field of this +#else + lw $t0, MIRROR_STRING_COUNT_OFFSET($a0) # this.length() +#endif + slt $at, $a2, $zero # if fromIndex < 0 + seleqz $a2, $a2, $at # fromIndex = 0; +#if (STRING_COMPRESSION_FEATURE) + srl $t0, $a3, 1 # $a3 holds count (with flag) and $t0 holds actual length +#endif + subu $t0, $t0, $a2 # this.length() - fromIndex + blez $t0, 6f # if this.length()-fromIndex <= 0 + li $v0, -1 # return -1; - sll $v0,$a2,1 # $a0 += $a2 * 2 - daddu $a0,$a0,$v0 # " ditto " - move $v0,$a2 # Set i to fromIndex. +#if (STRING_COMPRESSION_FEATURE) + dext $a3, $a3, 0, 1 # Extract compression flag. + beqzc $a3, .Lstring_indexof_compressed +#endif + + sll $v0, $a2, 1 # $a0 += $a2 * 2 + daddu $a0, $a0, $v0 # " ditto " + move $v0, $a2 # Set i to fromIndex. 1: - lhu $t3,MIRROR_STRING_VALUE_OFFSET($a0) # if this.charAt(i) == ch - beq $t3,$a1,6f # return i; - daddu $a0,$a0,2 # i++ - subu $t0,$t0,1 # this.length() - i - bnez $t0,1b # while this.length() - i > 0 - addu $v0,$v0,1 # i++ + lhu $t3, MIRROR_STRING_VALUE_OFFSET($a0) # if this.charAt(i) == ch + beq $t3, $a1, 6f # return i; + daddu $a0, $a0, 2 # i++ + subu $t0, $t0, 1 # this.length() - i + bnez $t0, 1b # while this.length() - i > 0 + addu $v0, $v0, 1 # i++ - li $v0,-1 # if this.length() - i <= 0 - # return -1; + li $v0, -1 # if this.length() - i <= 0 + # return -1; 6: - j $ra - nop + j $ra + nop + +#if (STRING_COMPRESSION_FEATURE) +.Lstring_indexof_compressed: + move $a4, $a0 # Save a copy in $a4 to later compute result. + daddu $a0, $a0, $a2 # $a0 += $a2 + +.Lstring_indexof_compressed_loop: + lbu $t3, MIRROR_STRING_VALUE_OFFSET($a0) + beq $t3, $a1, .Lstring_indexof_compressed_matched + subu $t0, $t0, 1 + bgtz $t0, .Lstring_indexof_compressed_loop + daddu $a0, $a0, 1 + +.Lstring_indexof_nomatch: + jalr $zero, $ra + li $v0, -1 # return -1; + +.Lstring_indexof_compressed_matched: + jalr $zero, $ra + dsubu $v0, $a0, $a4 # return (current - start); +#endif END art_quick_indexof .extern artInvokePolymorphic diff --git a/runtime/art_field-inl.h b/runtime/art_field-inl.h index 80af8e7bde..16b73c681f 100644 --- a/runtime/art_field-inl.h +++ b/runtime/art_field-inl.h @@ -311,6 +311,8 @@ inline bool ArtField::IsPrimitiveType() REQUIRES_SHARED(Locks::mutator_lock_) { template <bool kResolve> inline ObjPtr<mirror::Class> ArtField::GetType() { + // TODO: Refactor this function into two functions, ResolveType() and LookupType() + // so that we can properly annotate it with no-suspension possible / suspension possible. const uint32_t field_index = GetDexFieldIndex(); ObjPtr<mirror::Class> declaring_class = GetDeclaringClass(); if (UNLIKELY(declaring_class->IsProxyClass())) { @@ -320,9 +322,16 @@ inline ObjPtr<mirror::Class> ArtField::GetType() { const DexFile* const dex_file = dex_cache->GetDexFile(); const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index); ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(field_id.type_idx_); - if (kResolve && UNLIKELY(type == nullptr)) { - type = ResolveGetType(field_id.type_idx_); - CHECK(type != nullptr || Thread::Current()->IsExceptionPending()); + if (UNLIKELY(type == nullptr)) { + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + if (kResolve) { + type = class_linker->ResolveType(*dex_file, field_id.type_idx_, declaring_class); + CHECK(type != nullptr || Thread::Current()->IsExceptionPending()); + } else { + type = class_linker->LookupResolvedType( + *dex_file, field_id.type_idx_, dex_cache, declaring_class->GetClassLoader()); + DCHECK(!Thread::Current()->IsExceptionPending()); + } } return type; } diff --git a/runtime/art_field.cc b/runtime/art_field.cc index a4a6e5a4fb..7e131040be 100644 --- a/runtime/art_field.cc +++ b/runtime/art_field.cc @@ -48,10 +48,6 @@ ObjPtr<mirror::Class> ArtField::ProxyFindSystemClass(const char* descriptor) { return Runtime::Current()->GetClassLinker()->FindSystemClass(Thread::Current(), descriptor); } -ObjPtr<mirror::Class> ArtField::ResolveGetType(dex::TypeIndex type_idx) { - return Runtime::Current()->GetClassLinker()->ResolveType(type_idx, this); -} - ObjPtr<mirror::String> ArtField::ResolveGetStringName(Thread* self, const DexFile& dex_file, dex::StringIndex string_idx, diff --git a/runtime/art_field.h b/runtime/art_field.h index 427e103749..75dd981136 100644 --- a/runtime/art_field.h +++ b/runtime/art_field.h @@ -217,8 +217,6 @@ class ArtField FINAL { private: ObjPtr<mirror::Class> ProxyFindSystemClass(const char* descriptor) REQUIRES_SHARED(Locks::mutator_lock_); - ObjPtr<mirror::Class> ResolveGetType(dex::TypeIndex type_idx) - REQUIRES_SHARED(Locks::mutator_lock_); ObjPtr<mirror::String> ResolveGetStringName(Thread* self, const DexFile& dex_file, dex::StringIndex string_idx, diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h index 950f1aa9f4..473d9cf74e 100644 --- a/runtime/art_method-inl.h +++ b/runtime/art_method-inl.h @@ -175,12 +175,19 @@ inline bool ArtMethod::HasSameDexCacheResolvedMethods(ArtMethod* other, PointerS } inline mirror::Class* ArtMethod::GetClassFromTypeIndex(dex::TypeIndex type_idx, bool resolve) { + // TODO: Refactor this function into two functions, Resolve...() and Lookup...() + // so that we can properly annotate it with no-suspension possible / suspension possible. ObjPtr<mirror::DexCache> dex_cache = GetDexCache(); ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(type_idx); - if (UNLIKELY(type == nullptr) && resolve) { + if (UNLIKELY(type == nullptr)) { ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - type = class_linker->ResolveType(type_idx, this); - CHECK(type != nullptr || Thread::Current()->IsExceptionPending()); + if (resolve) { + type = class_linker->ResolveType(type_idx, this); + CHECK(type != nullptr || Thread::Current()->IsExceptionPending()); + } else { + type = class_linker->LookupResolvedType( + *dex_cache->GetDexFile(), type_idx, dex_cache, GetClassLoader()); + } } return type.Ptr(); } diff --git a/runtime/art_method.cc b/runtime/art_method.cc index 5a93e29663..6cb8544617 100644 --- a/runtime/art_method.cc +++ b/runtime/art_method.cc @@ -442,51 +442,12 @@ static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file, UNREACHABLE(); } -// We use the method's DexFile and declaring class name to find the OatMethod for an obsolete -// method. This is extremely slow but we need it if we want to be able to have obsolete native -// methods since we need this to find the size of it's stack frames. -static const OatFile::OatMethod FindOatMethodFromDexFileFor(ArtMethod* method, bool* found) - REQUIRES_SHARED(Locks::mutator_lock_) { - DCHECK(method->IsObsolete() && method->IsNative()); - const DexFile* dex_file = method->GetDexFile(); - - // recreate the class_def_index from the descriptor. - std::string descriptor_storage; - const DexFile::TypeId* declaring_class_type_id = - dex_file->FindTypeId(method->GetDeclaringClass()->GetDescriptor(&descriptor_storage)); - CHECK(declaring_class_type_id != nullptr); - dex::TypeIndex declaring_class_type_index = dex_file->GetIndexForTypeId(*declaring_class_type_id); - const DexFile::ClassDef* declaring_class_type_def = - dex_file->FindClassDef(declaring_class_type_index); - CHECK(declaring_class_type_def != nullptr); - uint16_t declaring_class_def_index = dex_file->GetIndexForClassDef(*declaring_class_type_def); - - size_t oat_method_index = GetOatMethodIndexFromMethodIndex(*dex_file, - declaring_class_def_index, - method->GetDexMethodIndex()); - - OatFile::OatClass oat_class = OatFile::FindOatClass(*dex_file, - declaring_class_def_index, - found); - if (!(*found)) { - return OatFile::OatMethod::Invalid(); - } - return oat_class.GetOatMethod(oat_method_index); -} - static const OatFile::OatMethod FindOatMethodFor(ArtMethod* method, PointerSize pointer_size, bool* found) REQUIRES_SHARED(Locks::mutator_lock_) { - if (UNLIKELY(method->IsObsolete())) { - // We shouldn't be calling this with obsolete methods except for native obsolete methods for - // which we need to use the oat method to figure out how large the quick frame is. - DCHECK(method->IsNative()) << "We should only be finding the OatMethod of obsolete methods in " - << "order to allow stack walking. Other obsolete methods should " - << "never need to access this information."; - DCHECK_EQ(pointer_size, kRuntimePointerSize) << "Obsolete method in compiler!"; - return FindOatMethodFromDexFileFor(method, found); - } + // We shouldn't be calling this with obsolete methods. + DCHECK(!method->IsObsolete()); // Although we overwrite the trampoline of non-static methods, we may get here via the resolution // method for direct methods (or virtual methods made direct). mirror::Class* declaring_class = method->GetDeclaringClass(); diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h index 3438810069..bd510ca0e1 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -78,6 +78,18 @@ inline mirror::String* ClassLinker::ResolveString(dex::StringIndex string_idx, return string.Ptr(); } +inline ObjPtr<mirror::Class> ClassLinker::LookupResolvedType( + dex::TypeIndex type_idx, + ObjPtr<mirror::DexCache> dex_cache, + ObjPtr<mirror::ClassLoader> class_loader) { + ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(type_idx); + if (type == nullptr) { + type = Runtime::Current()->GetClassLinker()->LookupResolvedType( + *dex_cache->GetDexFile(), type_idx, dex_cache, class_loader); + } + return type; +} + inline mirror::Class* ClassLinker::ResolveType(dex::TypeIndex type_idx, ArtMethod* referrer) { Thread::PoisonObjectPointersIfDebug(); if (kIsDebugBuild) { @@ -91,25 +103,6 @@ inline mirror::Class* ClassLinker::ResolveType(dex::TypeIndex type_idx, ArtMetho Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader())); const DexFile& dex_file = *dex_cache->GetDexFile(); resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader); - // Note: We cannot check here to see whether we added the type to the cache. The type - // might be an erroneous class, which results in it being hidden from us. - } - return resolved_type.Ptr(); -} - -inline mirror::Class* ClassLinker::ResolveType(dex::TypeIndex type_idx, ArtField* referrer) { - Thread::PoisonObjectPointersIfDebug(); - ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass(); - ObjPtr<mirror::DexCache> dex_cache_ptr = declaring_class->GetDexCache(); - ObjPtr<mirror::Class> resolved_type = dex_cache_ptr->GetResolvedType(type_idx); - if (UNLIKELY(resolved_type == nullptr)) { - StackHandleScope<2> hs(Thread::Current()); - Handle<mirror::DexCache> dex_cache(hs.NewHandle(dex_cache_ptr)); - Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader())); - const DexFile& dex_file = *dex_cache->GetDexFile(); - resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader); - // Note: We cannot check here to see whether we added the type to the cache. The type - // might be an erroneous class, which results in it being hidden from us. } return resolved_type.Ptr(); } diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 7db83688e2..9380588576 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1171,6 +1171,23 @@ static void CopyNonNull(const T* src, size_t count, T* dst, const NullPred& pred } } +template <typename T> +static void CopyDexCachePairs(const std::atomic<mirror::DexCachePair<T>>* src, + size_t count, + std::atomic<mirror::DexCachePair<T>>* dst) { + DCHECK_NE(count, 0u); + DCHECK(!src[0].load(std::memory_order_relaxed).object.IsNull() || + src[0].load(std::memory_order_relaxed).index != 0u); + for (size_t i = 0; i < count; ++i) { + DCHECK_EQ(dst[i].load(std::memory_order_relaxed).index, 0u); + DCHECK(dst[i].load(std::memory_order_relaxed).object.IsNull()); + mirror::DexCachePair<T> source = src[i].load(std::memory_order_relaxed); + if (source.index != 0u || !source.object.IsNull()) { + dst[i].store(source, std::memory_order_relaxed); + } + } +} + bool ClassLinker::UpdateAppImageClassLoadersAndDexCaches( gc::space::ImageSpace* space, Handle<mirror::ClassLoader> class_loader, @@ -1224,7 +1241,10 @@ bool ClassLinker::UpdateAppImageClassLoadersAndDexCaches( if (dex_file->NumStringIds() < num_strings) { num_strings = dex_file->NumStringIds(); } - const size_t num_types = dex_file->NumTypeIds(); + size_t num_types = mirror::DexCache::kDexCacheTypeCacheSize; + if (dex_file->NumTypeIds() < num_types) { + num_types = dex_file->NumTypeIds(); + } const size_t num_methods = dex_file->NumMethodIds(); const size_t num_fields = dex_file->NumFieldIds(); size_t num_method_types = mirror::DexCache::kDexCacheMethodTypeCacheSize; @@ -1243,28 +1263,14 @@ bool ClassLinker::UpdateAppImageClassLoadersAndDexCaches( mirror::StringDexCacheType* const image_resolved_strings = dex_cache->GetStrings(); mirror::StringDexCacheType* const strings = reinterpret_cast<mirror::StringDexCacheType*>(raw_arrays + layout.StringsOffset()); - for (size_t j = 0; j < num_strings; ++j) { - DCHECK_EQ(strings[j].load(std::memory_order_relaxed).index, 0u); - DCHECK(strings[j].load(std::memory_order_relaxed).object.IsNull()); - strings[j].store(image_resolved_strings[j].load(std::memory_order_relaxed), - std::memory_order_relaxed); - } - mirror::StringDexCachePair::Initialize(strings); + CopyDexCachePairs(image_resolved_strings, num_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 = - reinterpret_cast<GcRoot<mirror::Class>*>(raw_arrays + layout.TypesOffset()); - for (size_t j = 0; kIsDebugBuild && j < num_types; ++j) { - DCHECK(types[j].IsNull()); - } - CopyNonNull(image_resolved_types, - num_types, - types, - [](const GcRoot<mirror::Class>& elem) { - return elem.IsNull(); - }); + mirror::TypeDexCacheType* const image_resolved_types = dex_cache->GetResolvedTypes(); + mirror::TypeDexCacheType* const types = + reinterpret_cast<mirror::TypeDexCacheType*>(raw_arrays + layout.TypesOffset()); + CopyDexCachePairs(image_resolved_types, num_types, types); dex_cache->SetResolvedTypes(types); } if (num_methods != 0u) { @@ -1305,15 +1311,7 @@ bool ClassLinker::UpdateAppImageClassLoadersAndDexCaches( mirror::MethodTypeDexCacheType* const method_types = reinterpret_cast<mirror::MethodTypeDexCacheType*>( raw_arrays + layout.MethodTypesOffset()); - for (size_t j = 0; j < num_method_types; ++j) { - DCHECK_EQ(method_types[j].load(std::memory_order_relaxed).index, 0u); - DCHECK(method_types[j].load(std::memory_order_relaxed).object.IsNull()); - method_types[j].store( - image_resolved_method_types[j].load(std::memory_order_relaxed), - std::memory_order_relaxed); - } - - mirror::MethodTypeDexCachePair::Initialize(method_types); + CopyDexCachePairs(image_resolved_method_types, num_method_types, method_types); dex_cache->SetResolvedMethodTypes(method_types); } } @@ -1327,11 +1325,11 @@ bool ClassLinker::UpdateAppImageClassLoadersAndDexCaches( } if (kIsDebugBuild) { CHECK(new_class_set != nullptr); - GcRoot<mirror::Class>* const types = dex_cache->GetResolvedTypes(); + mirror::TypeDexCacheType* const types = dex_cache->GetResolvedTypes(); const size_t num_types = dex_cache->NumResolvedTypes(); - for (int32_t j = 0; j < static_cast<int32_t>(num_types); j++) { + for (size_t j = 0; j != num_types; ++j) { // The image space is not yet added to the heap, avoid read barriers. - ObjPtr<mirror::Class> klass = types[j].Read(); + ObjPtr<mirror::Class> klass = types[j].load(std::memory_order_relaxed).object.Read(); if (space->HasAddress(klass.Ptr())) { DCHECK(!klass->IsErroneous()) << klass->GetStatus(); auto it = new_class_set->Find(ClassTable::TableSlot(klass)); @@ -1690,9 +1688,9 @@ bool ClassLinker::AddImageSpace( // The current dex file field is bogus, overwrite it so that we can get the dex file in the // loop below. dex_cache->SetDexFile(dex_file.get()); - GcRoot<mirror::Class>* const types = dex_cache->GetResolvedTypes(); + mirror::TypeDexCacheType* const types = dex_cache->GetResolvedTypes(); for (int32_t j = 0, num_types = dex_cache->NumResolvedTypes(); j < num_types; j++) { - ObjPtr<mirror::Class> klass = types[j].Read(); + ObjPtr<mirror::Class> klass = types[j].load(std::memory_order_relaxed).object.Read(); if (klass != nullptr) { DCHECK(!klass->IsErroneous()) << klass->GetStatus(); } @@ -7722,7 +7720,9 @@ mirror::String* ClassLinker::ResolveString(const DexFile& dex_file, uint32_t utf16_length; const char* utf8_data = dex_file.StringDataAndUtf16LengthByIdx(string_idx, &utf16_length); ObjPtr<mirror::String> string = intern_table_->InternStrong(utf16_length, utf8_data); - dex_cache->SetResolvedString(string_idx, string); + if (string != nullptr) { + dex_cache->SetResolvedString(string_idx, string); + } return string.Ptr(); } @@ -7763,11 +7763,16 @@ ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(const DexFile& dex_file, // Find the class in the loaded classes table. type = LookupClass(self, descriptor, hash, class_loader.Ptr()); } + if (type != nullptr) { + if (type->IsResolved()) { + dex_cache->SetResolvedType(type_idx, type); + } else { + type = nullptr; + } + } } - if (type != nullptr && type->IsResolved()) { - return type.Ptr(); - } - return nullptr; + DCHECK(type == nullptr || type->IsResolved()); + return type; } mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, @@ -7787,6 +7792,12 @@ mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, Thread::PoisonObjectPointersIfDebug(); ObjPtr<mirror::Class> resolved = dex_cache->GetResolvedType(type_idx); if (resolved == nullptr) { + // TODO: Avoid this lookup as it duplicates work done in FindClass(). It is here + // as a workaround for FastNative JNI to avoid AssertNoPendingException() when + // trying to resolve annotations while an exception may be pending. Bug: 34659969 + resolved = LookupResolvedType(dex_file, type_idx, dex_cache.Get(), class_loader.Get()); + } + if (resolved == nullptr) { Thread* self = Thread::Current(); const char* descriptor = dex_file.StringByTypeIdx(type_idx); resolved = FindClass(self, descriptor, class_loader); diff --git a/runtime/class_linker.h b/runtime/class_linker.h index 62d3c29a19..a880a10eb8 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -262,10 +262,6 @@ class ClassLinker { REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_); - mirror::Class* ResolveType(dex::TypeIndex type_idx, ArtField* referrer) - REQUIRES_SHARED(Locks::mutator_lock_) - REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_); - // Look up a resolved type with the given ID from the DexFile. The ClassLoader is used to search // for the type, since it may be referenced from but not contained within the given DexFile. ObjPtr<mirror::Class> LookupResolvedType(const DexFile& dex_file, @@ -273,6 +269,10 @@ class ClassLinker { ObjPtr<mirror::DexCache> dex_cache, ObjPtr<mirror::ClassLoader> class_loader) REQUIRES_SHARED(Locks::mutator_lock_); + static ObjPtr<mirror::Class> LookupResolvedType(dex::TypeIndex type_idx, + ObjPtr<mirror::DexCache> dex_cache, + ObjPtr<mirror::ClassLoader> class_loader) + REQUIRES_SHARED(Locks::mutator_lock_); // Resolve a type with the given ID from the DexFile, storing the // result in DexCache. The ClassLoader is used to search for the diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index 03105cb6fb..de1cd6d807 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -914,7 +914,7 @@ TEST_F(ClassLinkerTest, LookupResolvedType) { class_linker_->LookupResolvedType(dex_file, type_idx, dex_cache, class_loader.Get()), klass); // Zero out the resolved type and make sure LookupResolvedType still finds it. - dex_cache->SetResolvedType(type_idx, nullptr); + dex_cache->ClearResolvedType(type_idx); EXPECT_TRUE(dex_cache->GetResolvedType(type_idx) == nullptr); EXPECT_OBJ_PTR_EQ( class_linker_->LookupResolvedType(dex_file, type_idx, dex_cache, class_loader.Get()), @@ -949,7 +949,7 @@ TEST_F(ClassLinkerTest, LookupResolvedTypeArray) { class_linker_->LookupResolvedType(dex_file, array_idx, dex_cache.Get(), class_loader.Get()), array_klass); // Zero out the resolved type and make sure LookupResolvedType() still finds it. - dex_cache->SetResolvedType(array_idx, nullptr); + dex_cache->ClearResolvedType(array_idx); EXPECT_TRUE(dex_cache->GetResolvedType(array_idx) == nullptr); EXPECT_OBJ_PTR_EQ( class_linker_->LookupResolvedType(dex_file, array_idx, dex_cache.Get(), class_loader.Get()), @@ -972,7 +972,7 @@ TEST_F(ClassLinkerTest, LookupResolvedTypeErroneousInit) { class_linker_->LookupResolvedType(dex_file, type_idx, dex_cache.Get(), class_loader.Get()), klass.Get()); // Zero out the resolved type and make sure LookupResolvedType still finds it. - dex_cache->SetResolvedType(type_idx, nullptr); + dex_cache->ClearResolvedType(type_idx); EXPECT_TRUE(dex_cache->GetResolvedType(type_idx) == nullptr); EXPECT_OBJ_PTR_EQ( class_linker_->LookupResolvedType(dex_file, type_idx, dex_cache.Get(), class_loader.Get()), @@ -990,7 +990,7 @@ TEST_F(ClassLinkerTest, LookupResolvedTypeErroneousInit) { class_linker_->LookupResolvedType(dex_file, type_idx, dex_cache.Get(), class_loader.Get()), klass.Get()); // Zero out the resolved type and make sure LookupResolvedType() still finds it. - dex_cache->SetResolvedType(type_idx, nullptr); + dex_cache->ClearResolvedType(type_idx); EXPECT_TRUE(dex_cache->GetResolvedType(type_idx) == nullptr); EXPECT_OBJ_PTR_EQ( class_linker_->LookupResolvedType(dex_file, type_idx, dex_cache.Get(), class_loader.Get()), diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc index 187af4bf97..f59420d332 100644 --- a/runtime/dex_file.cc +++ b/runtime/dex_file.cc @@ -333,32 +333,7 @@ std::unique_ptr<const DexFile> DexFile::OpenOneDexFileFromZip(const ZipArchive& *error_code = ZipOpenErrorCode::kDexFileError; return nullptr; } - - std::unique_ptr<MemMap> map; - if (zip_entry->IsUncompressed()) { - if (!zip_entry->IsAlignedTo(alignof(Header))) { - // Do not mmap unaligned ZIP entries because - // doing so would fail dex verification which requires 4 byte alignment. - LOG(WARNING) << "Can't mmap dex file " << location << "!" << entry_name << " directly; " - << "please zipalign to " << alignof(Header) << " bytes. " - << "Falling back to extracting file."; - } else { - // Map uncompressed files within zip as file-backed to avoid a dirty copy. - map.reset(zip_entry->MapDirectlyFromFile(location.c_str(), /*out*/error_msg)); - if (map == nullptr) { - LOG(WARNING) << "Can't mmap dex file " << location << "!" << entry_name << " directly; " - << "is your ZIP file corrupted? Falling back to extraction."; - // Try again with Extraction which still has a chance of recovery. - } - } - } - - if (map == nullptr) { - // Default path for compressed ZIP entries, - // and fallback for stored ZIP entries. - map.reset(zip_entry->ExtractToMemMap(location.c_str(), entry_name, error_msg)); - } - + std::unique_ptr<MemMap> map(zip_entry->ExtractToMemMap(location.c_str(), entry_name, error_msg)); if (map == nullptr) { *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", entry_name, location.c_str(), error_msg->c_str()); @@ -525,11 +500,6 @@ DexFile::DexFile(const uint8_t* base, oat_dex_file_(oat_dex_file) { CHECK(begin_ != nullptr) << GetLocation(); CHECK_GT(size_, 0U) << GetLocation(); - - // Check base (=header) alignment. - // Must be 4-byte aligned to avoid undefined behavior when accessing - // any of the sections via a pointer. - CHECK_ALIGNED(begin_, alignof(Header)); } DexFile::~DexFile() { diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index 28aca6c905..3bc49b8506 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -709,10 +709,10 @@ inline ArtMethod* FindMethodFast(uint32_t method_idx, return resolved_method; } else if (type == kSuper) { // TODO This lookup is rather slow. - dex::TypeIndex method_type_idx = - referrer->GetDexFile()->GetMethodId(method_idx).class_idx_; - mirror::Class* method_reference_class = - referrer->GetDexCache()->GetResolvedType(method_type_idx); + ObjPtr<mirror::DexCache> dex_cache = referrer->GetDexCache(); + dex::TypeIndex method_type_idx = dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_; + ObjPtr<mirror::Class> method_reference_class = ClassLinker::LookupResolvedType( + method_type_idx, dex_cache, referrer->GetClassLoader()); if (method_reference_class == nullptr) { // Need to do full type resolution... return nullptr; diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index ffbca525d9..4be4ef05b4 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -587,15 +587,18 @@ class ImageSpaceLoader { } std::unique_ptr<MemMap> map; + // GetImageBegin is the preferred address to map the image. If we manage to map the // image at the image begin, the amount of fixup work required is minimized. + // If it is pic we will retry with error_msg for the failure case. Pass a null error_msg to + // avoid reading proc maps for a mapping failure and slowing everything down. map.reset(LoadImageFile(image_filename, image_location, *image_header, image_header->GetImageBegin(), file->Fd(), logger, - error_msg)); + image_header->IsPic() ? nullptr : error_msg)); // If the header specifies PIC mode, we can also map at a random low_4gb address since we can // relocate in-place. if (map == nullptr && image_header->IsPic()) { @@ -765,8 +768,10 @@ class ImageSpaceLoader { if (storage_mode != ImageHeader::kStorageModeLZ4 && storage_mode != ImageHeader::kStorageModeLZ4HC) { - *error_msg = StringPrintf("Invalid storage mode in image header %d", - static_cast<int>(storage_mode)); + if (error_msg != nullptr) { + *error_msg = StringPrintf("Invalid storage mode in image header %d", + static_cast<int>(storage_mode)); + } return nullptr; } @@ -790,7 +795,7 @@ class ImageSpaceLoader { image_filename, error_msg)); if (temp_map == nullptr) { - DCHECK(!error_msg->empty()); + DCHECK(error_msg == nullptr || !error_msg->empty()); return nullptr; } memcpy(map->Begin(), &image_header, sizeof(ImageHeader)); @@ -802,12 +807,18 @@ class ImageSpaceLoader { reinterpret_cast<char*>(map->Begin()) + decompress_offset, stored_size, map->Size() - decompress_offset); - VLOG(image) << "Decompressing image took " << PrettyDuration(NanoTime() - start); + const uint64_t time = NanoTime() - start; + // Add one 1 ns to prevent possible divide by 0. + VLOG(image) << "Decompressing image took " << PrettyDuration(time) << " (" + << PrettySize(static_cast<uint64_t>(map->Size()) * MsToNs(1000) / (time + 1)) + << "/s)"; if (decompressed_size + sizeof(ImageHeader) != image_header.GetImageSize()) { - *error_msg = StringPrintf( - "Decompressed size does not match expected image size %zu vs %zu", - decompressed_size + sizeof(ImageHeader), - image_header.GetImageSize()); + if (error_msg != nullptr) { + *error_msg = StringPrintf( + "Decompressed size does not match expected image size %zu vs %zu", + decompressed_size + sizeof(ImageHeader), + image_header.GetImageSize()); + } return nullptr; } } @@ -1226,9 +1237,9 @@ class ImageSpaceLoader { } dex_cache->FixupStrings<kWithoutReadBarrier>(new_strings, fixup_adapter); } - GcRoot<mirror::Class>* types = dex_cache->GetResolvedTypes(); + mirror::TypeDexCacheType* types = dex_cache->GetResolvedTypes(); if (types != nullptr) { - GcRoot<mirror::Class>* new_types = fixup_adapter.ForwardObject(types); + mirror::TypeDexCacheType* new_types = fixup_adapter.ForwardObject(types); if (types != new_types) { dex_cache->SetResolvedTypes(new_types); } diff --git a/runtime/image.cc b/runtime/image.cc index 54b099eb14..87f429568d 100644 --- a/runtime/image.cc +++ b/runtime/image.cc @@ -25,7 +25,7 @@ namespace art { const uint8_t ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' }; -const uint8_t ImageHeader::kImageVersion[] = { '0', '3', '6', '\0' }; // Erroneous resolved class. +const uint8_t ImageHeader::kImageVersion[] = { '0', '3', '7', '\0' }; // hash-based DexCache types ImageHeader::ImageHeader(uint32_t image_begin, uint32_t image_size, diff --git a/runtime/jit/profile_compilation_info.cc b/runtime/jit/profile_compilation_info.cc index 9ba2d1a355..54fc0386e1 100644 --- a/runtime/jit/profile_compilation_info.cc +++ b/runtime/jit/profile_compilation_info.cc @@ -664,6 +664,38 @@ std::string ProfileCompilationInfo::DumpInfo(const std::vector<const DexFile*>* return os.str(); } +void ProfileCompilationInfo::GetClassNames( + const std::vector<std::unique_ptr<const DexFile>>* dex_files, + std::set<std::string>* class_names) const { + std::unique_ptr<const std::vector<const DexFile*>> non_owning_dex_files( + MakeNonOwningVector(dex_files)); + GetClassNames(non_owning_dex_files.get(), class_names); +} + +void ProfileCompilationInfo::GetClassNames(const std::vector<const DexFile*>* dex_files, + std::set<std::string>* class_names) const { + if (info_.empty()) { + return; + } + for (const auto& it : info_) { + const std::string& location = it.first; + const DexFileData& dex_data = it.second; + const DexFile* dex_file = nullptr; + if (dex_files != nullptr) { + for (size_t i = 0; i < dex_files->size(); i++) { + if (location == (*dex_files)[i]->GetLocation()) { + dex_file = (*dex_files)[i]; + } + } + } + for (const auto class_it : dex_data.class_set) { + if (dex_file != nullptr) { + class_names->insert(std::string(dex_file->PrettyType(class_it))); + } + } + } +} + bool ProfileCompilationInfo::Equals(const ProfileCompilationInfo& other) { return info_.Equals(other.info_); } diff --git a/runtime/jit/profile_compilation_info.h b/runtime/jit/profile_compilation_info.h index b1587c0070..758b46d74a 100644 --- a/runtime/jit/profile_compilation_info.h +++ b/runtime/jit/profile_compilation_info.h @@ -78,6 +78,11 @@ class ProfileCompilationInfo { std::string DumpInfo(const std::vector<const DexFile*>* dex_files, bool print_full_dex_location = true) const; + void GetClassNames(const std::vector<std::unique_ptr<const DexFile>>* dex_files, + std::set<std::string>* class_names) const; + void GetClassNames(const std::vector<const DexFile*>* dex_files, + std::set<std::string>* class_names) const; + bool Equals(const ProfileCompilationInfo& other); static std::string GetProfileDexFileKey(const std::string& dex_location); diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc index dce56b3c58..93c212bafb 100644 --- a/runtime/mem_map.cc +++ b/runtime/mem_map.cc @@ -400,7 +400,7 @@ MemMap* MemMap::MapFileAtAddress(uint8_t* expected_ptr, // reuse means it is okay that it overlaps an existing page mapping. // Only use this if you actually made the page reservation yourself. CHECK(expected_ptr != nullptr); - + DCHECK(error_msg != nullptr); DCHECK(ContainedWithinExistingMap(expected_ptr, byte_count, error_msg)) << ((error_msg != nullptr) ? *error_msg : std::string()); flags |= MAP_FIXED; diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index 1b8f3f83e7..f7ff735fcc 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -951,7 +951,8 @@ ObjPtr<Class> Class::GetDirectInterface(Thread* self, ObjPtr<Class> klass, uint3 return interfaces->Get(idx); } else { dex::TypeIndex type_idx = klass->GetDirectInterfaceTypeIdx(idx); - ObjPtr<Class> interface = klass->GetDexCache()->GetResolvedType(type_idx); + ObjPtr<Class> interface = ClassLinker::LookupResolvedType( + type_idx, klass->GetDexCache(), klass->GetClassLoader()); return interface; } } diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h index a59bb7b880..bef3ad29a3 100644 --- a/runtime/mirror/dex_cache-inl.h +++ b/runtime/mirror/dex_cache-inl.h @@ -40,14 +40,22 @@ inline uint32_t DexCache::ClassSize(PointerSize pointer_size) { return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0, pointer_size); } -inline mirror::String* DexCache::GetResolvedString(dex::StringIndex string_idx) { +inline uint32_t DexCache::StringSlotIndex(dex::StringIndex string_idx) { DCHECK_LT(string_idx.index_, GetDexFile()->NumStringIds()); - return StringDexCachePair::Lookup(GetStrings(), string_idx.index_, NumStrings()).Read(); + const uint32_t slot_idx = string_idx.index_ % kDexCacheStringCacheSize; + DCHECK_LT(slot_idx, NumStrings()); + return slot_idx; } -inline void DexCache::SetResolvedString(dex::StringIndex string_idx, - ObjPtr<mirror::String> resolved) { - StringDexCachePair::Assign(GetStrings(), string_idx.index_, resolved.Ptr(), NumStrings()); +inline String* DexCache::GetResolvedString(dex::StringIndex string_idx) { + return GetStrings()[StringSlotIndex(string_idx)].load( + std::memory_order_relaxed).GetObjectForIndex(string_idx.index_); +} + +inline void DexCache::SetResolvedString(dex::StringIndex string_idx, ObjPtr<String> resolved) { + DCHECK(resolved != nullptr); + GetStrings()[StringSlotIndex(string_idx)].store( + StringDexCachePair(resolved, string_idx.index_), std::memory_order_relaxed); Runtime* const runtime = Runtime::Current(); if (UNLIKELY(runtime->IsActiveTransaction())) { DCHECK(runtime->IsAotCompiler()); @@ -58,50 +66,70 @@ inline void DexCache::SetResolvedString(dex::StringIndex string_idx, } inline void DexCache::ClearString(dex::StringIndex string_idx) { - const uint32_t slot_idx = string_idx.index_ % NumStrings(); DCHECK(Runtime::Current()->IsAotCompiler()); + uint32_t slot_idx = StringSlotIndex(string_idx); StringDexCacheType* slot = &GetStrings()[slot_idx]; // This is racy but should only be called from the transactional interpreter. if (slot->load(std::memory_order_relaxed).index == string_idx.index_) { - StringDexCachePair cleared( - nullptr, - StringDexCachePair::InvalidIndexForSlot(slot_idx)); + StringDexCachePair cleared(nullptr, StringDexCachePair::InvalidIndexForSlot(slot_idx)); slot->store(cleared, std::memory_order_relaxed); } } +inline uint32_t DexCache::TypeSlotIndex(dex::TypeIndex type_idx) { + DCHECK_LT(type_idx.index_, GetDexFile()->NumTypeIds()); + const uint32_t slot_idx = type_idx.index_ % kDexCacheTypeCacheSize; + DCHECK_LT(slot_idx, NumResolvedTypes()); + return slot_idx; +} + inline Class* DexCache::GetResolvedType(dex::TypeIndex type_idx) { // It is theorized that a load acquire is not required since obtaining the resolved class will // always have an address dependency or a lock. - DCHECK_LT(type_idx.index_, NumResolvedTypes()); - return GetResolvedTypes()[type_idx.index_].Read(); + return GetResolvedTypes()[TypeSlotIndex(type_idx)].load( + std::memory_order_relaxed).GetObjectForIndex(type_idx.index_); } inline void DexCache::SetResolvedType(dex::TypeIndex type_idx, ObjPtr<Class> resolved) { - DCHECK_LT(type_idx.index_, NumResolvedTypes()); // NOTE: Unchecked, i.e. not throwing AIOOB. + DCHECK(resolved != nullptr); // TODO default transaction support. // Use a release store for SetResolvedType. This is done to prevent other threads from seeing a // class but not necessarily seeing the loaded members like the static fields array. // See b/32075261. - reinterpret_cast<Atomic<GcRoot<mirror::Class>>&>(GetResolvedTypes()[type_idx.index_]). - StoreRelease(GcRoot<Class>(resolved)); + GetResolvedTypes()[TypeSlotIndex(type_idx)].store( + TypeDexCachePair(resolved, type_idx.index_), std::memory_order_release); // TODO: Fine-grained marking, so that we don't need to go through all arrays in full. Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(this); } -inline MethodType* DexCache::GetResolvedMethodType(uint32_t proto_idx) { - DCHECK(Runtime::Current()->IsMethodHandlesEnabled()); - DCHECK_LT(proto_idx, GetDexFile()->NumProtoIds()); - return MethodTypeDexCachePair::Lookup( - GetResolvedMethodTypes(), proto_idx, NumResolvedMethodTypes()).Read(); +inline void DexCache::ClearResolvedType(dex::TypeIndex type_idx) { + DCHECK(Runtime::Current()->IsAotCompiler()); + uint32_t slot_idx = TypeSlotIndex(type_idx); + TypeDexCacheType* slot = &GetResolvedTypes()[slot_idx]; + // This is racy but should only be called from the single-threaded ImageWriter and tests. + if (slot->load(std::memory_order_relaxed).index == type_idx.index_) { + TypeDexCachePair cleared(nullptr, TypeDexCachePair::InvalidIndexForSlot(slot_idx)); + slot->store(cleared, std::memory_order_relaxed); + } } -inline void DexCache::SetResolvedMethodType(uint32_t proto_idx, MethodType* resolved) { +inline uint32_t DexCache::MethodTypeSlotIndex(uint32_t proto_idx) { DCHECK(Runtime::Current()->IsMethodHandlesEnabled()); DCHECK_LT(proto_idx, GetDexFile()->NumProtoIds()); + const uint32_t slot_idx = proto_idx % kDexCacheMethodTypeCacheSize; + DCHECK_LT(slot_idx, NumResolvedMethodTypes()); + return slot_idx; +} - MethodTypeDexCachePair::Assign(GetResolvedMethodTypes(), proto_idx, resolved, - NumResolvedMethodTypes()); +inline MethodType* DexCache::GetResolvedMethodType(uint32_t proto_idx) { + return GetResolvedMethodTypes()[MethodTypeSlotIndex(proto_idx)].load( + std::memory_order_relaxed).GetObjectForIndex(proto_idx); +} + +inline void DexCache::SetResolvedMethodType(uint32_t proto_idx, MethodType* resolved) { + DCHECK(resolved != nullptr); + GetResolvedMethodTypes()[MethodTypeSlotIndex(proto_idx)].store( + MethodTypeDexCachePair(resolved, proto_idx), std::memory_order_relaxed); // TODO: Fine-grained marking, so that we don't need to go through all arrays in full. Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(this); } @@ -198,49 +226,49 @@ inline void DexCache::VisitReferences(ObjPtr<Class> klass, const Visitor& visito VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass, visitor); // Visit arrays after. if (kVisitNativeRoots) { - VisitDexCachePairs<mirror::String, kReadBarrierOption, Visitor>( + VisitDexCachePairs<String, kReadBarrierOption, Visitor>( GetStrings(), NumStrings(), visitor); - GcRoot<mirror::Class>* resolved_types = GetResolvedTypes(); - for (size_t i = 0, num_types = NumResolvedTypes(); i != num_types; ++i) { - visitor.VisitRootIfNonNull(resolved_types[i].AddressWithoutBarrier()); - } + VisitDexCachePairs<Class, kReadBarrierOption, Visitor>( + GetResolvedTypes(), NumResolvedTypes(), visitor); - VisitDexCachePairs<mirror::MethodType, kReadBarrierOption, Visitor>( + VisitDexCachePairs<MethodType, kReadBarrierOption, Visitor>( GetResolvedMethodTypes(), NumResolvedMethodTypes(), visitor); } } template <ReadBarrierOption kReadBarrierOption, typename Visitor> -inline void DexCache::FixupStrings(mirror::StringDexCacheType* dest, const Visitor& visitor) { - mirror::StringDexCacheType* src = GetStrings(); +inline void DexCache::FixupStrings(StringDexCacheType* dest, const Visitor& visitor) { + StringDexCacheType* src = GetStrings(); for (size_t i = 0, count = NumStrings(); i < count; ++i) { StringDexCachePair source = src[i].load(std::memory_order_relaxed); - mirror::String* ptr = source.object.Read<kReadBarrierOption>(); - mirror::String* new_source = visitor(ptr); + String* ptr = source.object.Read<kReadBarrierOption>(); + String* new_source = visitor(ptr); source.object = GcRoot<String>(new_source); dest[i].store(source, std::memory_order_relaxed); } } template <ReadBarrierOption kReadBarrierOption, typename Visitor> -inline void DexCache::FixupResolvedTypes(GcRoot<mirror::Class>* dest, const Visitor& visitor) { - GcRoot<mirror::Class>* src = GetResolvedTypes(); +inline void DexCache::FixupResolvedTypes(TypeDexCacheType* dest, const Visitor& visitor) { + TypeDexCacheType* src = GetResolvedTypes(); for (size_t i = 0, count = NumResolvedTypes(); i < count; ++i) { - mirror::Class* source = src[i].Read<kReadBarrierOption>(); - mirror::Class* new_source = visitor(source); - dest[i] = GcRoot<mirror::Class>(new_source); + TypeDexCachePair source = src[i].load(std::memory_order_relaxed); + Class* ptr = source.object.Read<kReadBarrierOption>(); + Class* new_source = visitor(ptr); + source.object = GcRoot<Class>(new_source); + dest[i].store(source, std::memory_order_relaxed); } } template <ReadBarrierOption kReadBarrierOption, typename Visitor> -inline void DexCache::FixupResolvedMethodTypes(mirror::MethodTypeDexCacheType* dest, +inline void DexCache::FixupResolvedMethodTypes(MethodTypeDexCacheType* dest, const Visitor& visitor) { - mirror::MethodTypeDexCacheType* src = GetResolvedMethodTypes(); + MethodTypeDexCacheType* src = GetResolvedMethodTypes(); for (size_t i = 0, count = NumResolvedMethodTypes(); i < count; ++i) { MethodTypeDexCachePair source = src[i].load(std::memory_order_relaxed); - mirror::MethodType* ptr = source.object.Read<kReadBarrierOption>(); - mirror::MethodType* new_source = visitor(ptr); + MethodType* ptr = source.object.Read<kReadBarrierOption>(); + MethodType* new_source = visitor(ptr); source.object = GcRoot<MethodType>(new_source); dest[i].store(source, std::memory_order_relaxed); } diff --git a/runtime/mirror/dex_cache.cc b/runtime/mirror/dex_cache.cc index 741cf3bb47..3103a92c83 100644 --- a/runtime/mirror/dex_cache.cc +++ b/runtime/mirror/dex_cache.cc @@ -58,8 +58,8 @@ void DexCache::InitializeDexCache(Thread* self, mirror::StringDexCacheType* strings = (dex_file->NumStringIds() == 0u) ? nullptr : reinterpret_cast<mirror::StringDexCacheType*>(raw_arrays + layout.StringsOffset()); - GcRoot<mirror::Class>* types = (dex_file->NumTypeIds() == 0u) ? nullptr : - reinterpret_cast<GcRoot<mirror::Class>*>(raw_arrays + layout.TypesOffset()); + mirror::TypeDexCacheType* types = (dex_file->NumTypeIds() == 0u) ? nullptr : + reinterpret_cast<mirror::TypeDexCacheType*>(raw_arrays + layout.TypesOffset()); ArtMethod** methods = (dex_file->NumMethodIds() == 0u) ? nullptr : reinterpret_cast<ArtMethod**>(raw_arrays + layout.MethodsOffset()); ArtField** fields = (dex_file->NumFieldIds() == 0u) ? nullptr : @@ -69,6 +69,10 @@ void DexCache::InitializeDexCache(Thread* self, if (dex_file->NumStringIds() < num_strings) { num_strings = dex_file->NumStringIds(); } + size_t num_types = mirror::DexCache::kDexCacheTypeCacheSize; + if (dex_file->NumTypeIds() < num_types) { + num_types = dex_file->NumTypeIds(); + } // Note that we allocate the method type dex caches regardless of this flag, // and we make sure here that they're not used by the runtime. This is in the @@ -104,8 +108,9 @@ void DexCache::InitializeDexCache(Thread* self, CHECK_EQ(strings[i].load(std::memory_order_relaxed).index, 0u); CHECK(strings[i].load(std::memory_order_relaxed).object.IsNull()); } - for (size_t i = 0; i < dex_file->NumTypeIds(); ++i) { - CHECK(types[i].IsNull()); + for (size_t i = 0; i < num_types; ++i) { + CHECK_EQ(types[i].load(std::memory_order_relaxed).index, 0u); + CHECK(types[i].load(std::memory_order_relaxed).object.IsNull()); } for (size_t i = 0; i < dex_file->NumMethodIds(); ++i) { CHECK(mirror::DexCache::GetElementPtrSize(methods, i, image_pointer_size) == nullptr); @@ -121,6 +126,9 @@ void DexCache::InitializeDexCache(Thread* self, if (strings != nullptr) { mirror::StringDexCachePair::Initialize(strings); } + if (types != nullptr) { + mirror::TypeDexCachePair::Initialize(types); + } if (method_types != nullptr) { mirror::MethodTypeDexCachePair::Initialize(method_types); } @@ -129,7 +137,7 @@ void DexCache::InitializeDexCache(Thread* self, strings, num_strings, types, - dex_file->NumTypeIds(), + num_types, methods, dex_file->NumMethodIds(), fields, @@ -143,7 +151,7 @@ void DexCache::Init(const DexFile* dex_file, ObjPtr<String> location, StringDexCacheType* strings, uint32_t num_strings, - GcRoot<Class>* resolved_types, + TypeDexCacheType* resolved_types, uint32_t num_resolved_types, ArtMethod** resolved_methods, uint32_t num_resolved_methods, diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h index 6f88cc5df4..e68b0c7219 100644 --- a/runtime/mirror/dex_cache.h +++ b/runtime/mirror/dex_cache.h @@ -18,14 +18,14 @@ #define ART_RUNTIME_MIRROR_DEX_CACHE_H_ #include "array.h" -#include "art_field.h" -#include "class.h" +#include "base/bit_utils.h" #include "dex_file_types.h" #include "object.h" #include "object_array.h" namespace art { +class ArtField; class ArtMethod; struct DexCacheOffsets; class DexFile; @@ -36,6 +36,7 @@ class Thread; namespace mirror { +class Class; class MethodType; class String; @@ -60,7 +61,7 @@ template <typename T> struct PACKED(8) DexCachePair { // it's always non-null if the id branch succeeds (except for the 0th id). // Set the initial state for the 0th entry to be {0,1} which is guaranteed to fail // the lookup id == stored id branch. - DexCachePair(T* object, uint32_t index) + DexCachePair(ObjPtr<T> object, uint32_t index) : object(object), index(index) {} DexCachePair() = default; @@ -74,39 +75,28 @@ template <typename T> struct PACKED(8) DexCachePair { dex_cache[0].store(first_elem, std::memory_order_relaxed); } - static GcRoot<T> Lookup(std::atomic<DexCachePair<T>>* dex_cache, - uint32_t idx, - uint32_t cache_size) { - DCHECK_NE(cache_size, 0u); - DexCachePair<T> element = dex_cache[idx % cache_size].load(std::memory_order_relaxed); - if (idx != element.index) { - return GcRoot<T>(nullptr); - } - - DCHECK(!element.object.IsNull()); - return element.object; - } - - static void Assign(std::atomic<DexCachePair<T>>* dex_cache, - uint32_t idx, - T* object, - uint32_t cache_size) { - DCHECK_LT(idx % cache_size, cache_size); - dex_cache[idx % cache_size].store( - DexCachePair<T>(object, idx), std::memory_order_relaxed); - } - static uint32_t InvalidIndexForSlot(uint32_t slot) { // Since the cache size is a power of two, 0 will always map to slot 0. // Use 1 for slot 0 and 0 for all other slots. return (slot == 0) ? 1u : 0u; } + + T* GetObjectForIndex(uint32_t idx) REQUIRES_SHARED(Locks::mutator_lock_) { + if (idx != index) { + return nullptr; + } + DCHECK(!object.IsNull()); + return object.Read(); + } }; -using StringDexCachePair = DexCachePair<mirror::String>; +using TypeDexCachePair = DexCachePair<Class>; +using TypeDexCacheType = std::atomic<TypeDexCachePair>; + +using StringDexCachePair = DexCachePair<String>; using StringDexCacheType = std::atomic<StringDexCachePair>; -using MethodTypeDexCachePair = DexCachePair<mirror::MethodType>; +using MethodTypeDexCachePair = DexCachePair<MethodType>; using MethodTypeDexCacheType = std::atomic<MethodTypeDexCachePair>; // C++ mirror of java.lang.DexCache. @@ -115,6 +105,11 @@ class MANAGED DexCache FINAL : public Object { // Size of java.lang.DexCache.class. static uint32_t ClassSize(PointerSize pointer_size); + // Size of type dex cache. Needs to be a power of 2 for entrypoint assumptions to hold. + static constexpr size_t kDexCacheTypeCacheSize = 1024; + static_assert(IsPowerOfTwo(kDexCacheTypeCacheSize), + "Type dex cache size is not a power of 2."); + // Size of string dex cache. Needs to be a power of 2 for entrypoint assumptions to hold. static constexpr size_t kDexCacheStringCacheSize = 1024; static_assert(IsPowerOfTwo(kDexCacheStringCacheSize), @@ -126,6 +121,10 @@ class MANAGED DexCache FINAL : public Object { static_assert(IsPowerOfTwo(kDexCacheMethodTypeCacheSize), "MethodType dex cache size is not a power of 2."); + static constexpr size_t StaticTypeSize() { + return kDexCacheTypeCacheSize; + } + static constexpr size_t StaticStringSize() { return kDexCacheStringCacheSize; } @@ -156,7 +155,7 @@ class MANAGED DexCache FINAL : public Object { REQUIRES_SHARED(Locks::mutator_lock_); template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor> - void FixupResolvedTypes(GcRoot<mirror::Class>* dest, const Visitor& visitor) + void FixupResolvedTypes(TypeDexCacheType* dest, const Visitor& visitor) REQUIRES_SHARED(Locks::mutator_lock_); template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor> @@ -211,7 +210,7 @@ class MANAGED DexCache FINAL : public Object { return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_method_types_); } - mirror::String* GetResolvedString(dex::StringIndex string_idx) ALWAYS_INLINE + String* GetResolvedString(dex::StringIndex string_idx) ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_); void SetResolvedString(dex::StringIndex string_idx, ObjPtr<mirror::String> resolved) ALWAYS_INLINE @@ -226,6 +225,8 @@ class MANAGED DexCache FINAL : public Object { void SetResolvedType(dex::TypeIndex type_idx, ObjPtr<Class> resolved) REQUIRES_SHARED(Locks::mutator_lock_); + void ClearResolvedType(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_); + ALWAYS_INLINE ArtMethod* GetResolvedMethod(uint32_t method_idx, PointerSize ptr_size) REQUIRES_SHARED(Locks::mutator_lock_); @@ -254,11 +255,11 @@ class MANAGED DexCache FINAL : public Object { SetFieldPtr<false>(StringsOffset(), strings); } - GcRoot<Class>* GetResolvedTypes() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) { - return GetFieldPtr<GcRoot<Class>*>(ResolvedTypesOffset()); + TypeDexCacheType* GetResolvedTypes() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) { + return GetFieldPtr<TypeDexCacheType*>(ResolvedTypesOffset()); } - void SetResolvedTypes(GcRoot<Class>* resolved_types) + void SetResolvedTypes(TypeDexCacheType* resolved_types) ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) { SetFieldPtr<false>(ResolvedTypesOffset(), resolved_types); @@ -323,7 +324,7 @@ class MANAGED DexCache FINAL : public Object { SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), dex_file); } - void SetLocation(ObjPtr<mirror::String> location) REQUIRES_SHARED(Locks::mutator_lock_); + void SetLocation(ObjPtr<String> location) REQUIRES_SHARED(Locks::mutator_lock_); // NOTE: Get/SetElementPtrSize() are intended for working with ArtMethod** and ArtField** // provided by GetResolvedMethods/Fields() and ArtMethod::GetDexCacheResolvedMethods(), @@ -340,7 +341,7 @@ class MANAGED DexCache FINAL : public Object { ObjPtr<String> location, StringDexCacheType* strings, uint32_t num_strings, - GcRoot<Class>* resolved_types, + TypeDexCacheType* resolved_types, uint32_t num_resolved_types, ArtMethod** resolved_methods, uint32_t num_resolved_methods, @@ -351,12 +352,16 @@ class MANAGED DexCache FINAL : public Object { PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_); + uint32_t StringSlotIndex(dex::StringIndex string_idx) REQUIRES_SHARED(Locks::mutator_lock_); + uint32_t TypeSlotIndex(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_); + uint32_t MethodTypeSlotIndex(uint32_t proto_idx) REQUIRES_SHARED(Locks::mutator_lock_); + // Visit instance fields of the dex cache as well as its associated arrays. template <bool kVisitNativeRoots, VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor> - void VisitReferences(ObjPtr<mirror::Class> klass, const Visitor& visitor) + void VisitReferences(ObjPtr<Class> klass, const Visitor& visitor) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_); HeapReference<Object> dex_; @@ -366,7 +371,7 @@ class MANAGED DexCache FINAL : public Object { uint64_t resolved_method_types_; // std::atomic<MethodTypeDexCachePair>* array with // num_resolved_method_types_ elements. uint64_t resolved_methods_; // ArtMethod*, array with num_resolved_methods_ elements. - uint64_t resolved_types_; // GcRoot<Class>*, array with num_resolved_types_ elements. + uint64_t resolved_types_; // TypeDexCacheType*, array with num_resolved_types_ elements. uint64_t strings_; // std::atomic<StringDexCachePair>*, array with num_strings_ // elements. diff --git a/runtime/mirror/dex_cache_test.cc b/runtime/mirror/dex_cache_test.cc index 8f978e122c..5693f67646 100644 --- a/runtime/mirror/dex_cache_test.cc +++ b/runtime/mirror/dex_cache_test.cc @@ -51,7 +51,8 @@ TEST_F(DexCacheTest, Open) { EXPECT_TRUE(dex_cache->StaticStringSize() == dex_cache->NumStrings() || java_lang_dex_file_->NumStringIds() == dex_cache->NumStrings()); - EXPECT_EQ(java_lang_dex_file_->NumTypeIds(), dex_cache->NumResolvedTypes()); + EXPECT_TRUE(dex_cache->StaticTypeSize() == dex_cache->NumResolvedTypes() + || java_lang_dex_file_->NumTypeIds() == dex_cache->NumResolvedTypes()); EXPECT_EQ(java_lang_dex_file_->NumMethodIds(), dex_cache->NumResolvedMethods()); EXPECT_EQ(java_lang_dex_file_->NumFieldIds(), dex_cache->NumResolvedFields()); EXPECT_TRUE(dex_cache->StaticMethodTypeSize() == dex_cache->NumResolvedMethodTypes() diff --git a/runtime/native/java_lang_DexCache.cc b/runtime/native/java_lang_DexCache.cc index b1ed74a6de..ee6dda56a5 100644 --- a/runtime/native/java_lang_DexCache.cc +++ b/runtime/native/java_lang_DexCache.cc @@ -53,7 +53,7 @@ static jobject DexCache_getDexNative(JNIEnv* env, jobject javaDexCache) { static jobject DexCache_getResolvedType(JNIEnv* env, jobject javaDexCache, jint type_index) { ScopedFastNativeObjectAccess soa(env); ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache); - CHECK_LT(static_cast<size_t>(type_index), dex_cache->NumResolvedTypes()); + CHECK_LT(static_cast<size_t>(type_index), dex_cache->GetDexFile()->NumTypeIds()); return soa.AddLocalReference<jobject>(dex_cache->GetResolvedType(dex::TypeIndex(type_index))); } diff --git a/runtime/oat.h b/runtime/oat.h index e7e8328796..e454c64d52 100644 --- a/runtime/oat.h +++ b/runtime/oat.h @@ -32,7 +32,7 @@ class InstructionSetFeatures; class PACKED(4) OatHeader { public: static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' }; - static constexpr uint8_t kOatVersion[] = { '1', '1', '0', '\0' }; // Clean up code info change. + static constexpr uint8_t kOatVersion[] = { '1', '1', '1', '\0' }; // hash-based DexCache types. static constexpr const char* kImageLocationKey = "image-location"; static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline"; diff --git a/runtime/openjdkjvmti/ti_redefine.cc b/runtime/openjdkjvmti/ti_redefine.cc index 5e6a23f82a..843fd8c8e4 100644 --- a/runtime/openjdkjvmti/ti_redefine.cc +++ b/runtime/openjdkjvmti/ti_redefine.cc @@ -457,11 +457,6 @@ void Redefiner::ClassRedefinition::FindAndAllocateObsoleteMethods(art::mirror::C CallbackCtx ctx(linker->GetAllocatorForClassLoader(art_klass->GetClassLoader())); // Add all the declared methods to the map for (auto& m : art_klass->GetDeclaredMethods(art::kRuntimePointerSize)) { - // TODO It should be possible to simply filter out some methods where they cannot really become - // obsolete, such as native methods and keep their original (possibly optimized) - // implementations. We don't do this, however, since we would need to mark these functions - // (still in the classes declared_methods array) as obsolete so we will find the correct dex - // file to get meta-data from (for example about stack-frame size). ctx.obsolete_methods.insert(&m); // TODO Allow this or check in IsModifiableClass. DCHECK(!m.IsIntrinsic()); diff --git a/runtime/stack.cc b/runtime/stack.cc index 96fc664584..d7ba1d75d8 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -874,11 +874,9 @@ void StackVisitor::WalkStack(bool include_transitions) { CHECK_EQ(GetMethod(), callee) << "Expected: " << ArtMethod::PrettyMethod(callee) << " Found: " << ArtMethod::PrettyMethod(GetMethod()); } else { - // Instrumentation generally doesn't distinguish between a method's obsolete and - // non-obsolete version. - CHECK_EQ(instrumentation_frame.method_, GetMethod()->GetNonObsoleteMethod()) + CHECK_EQ(instrumentation_frame.method_, GetMethod()) << "Expected: " << ArtMethod::PrettyMethod(instrumentation_frame.method_) - << " Found: " << ArtMethod::PrettyMethod(GetMethod()->GetNonObsoleteMethod()); + << " Found: " << ArtMethod::PrettyMethod(GetMethod()); } if (num_frames_ != 0) { // Check agreement of frame Ids only if num_frames_ is computed to avoid infinite @@ -905,7 +903,7 @@ void StackVisitor::WalkStack(bool include_transitions) { << " native=" << method->IsNative() << std::noboolalpha << " entrypoints=" << method->GetEntryPointFromQuickCompiledCode() - << "," << (method->IsNative() ? method->GetEntryPointFromJni() : nullptr) + << "," << method->GetEntryPointFromJni() << " next=" << *cur_quick_frame_; } diff --git a/runtime/utils/dex_cache_arrays_layout-inl.h b/runtime/utils/dex_cache_arrays_layout-inl.h index bd1b044dae..2812c21004 100644 --- a/runtime/utils/dex_cache_arrays_layout-inl.h +++ b/runtime/utils/dex_cache_arrays_layout-inl.h @@ -48,9 +48,11 @@ inline DexCacheArraysLayout::DexCacheArraysLayout(PointerSize pointer_size, cons : DexCacheArraysLayout(pointer_size, dex_file->GetHeader()) { } -inline constexpr size_t DexCacheArraysLayout::Alignment() { - // GcRoot<> alignment is 4, i.e. lower than or equal to the pointer alignment. - static_assert(alignof(GcRoot<mirror::Class>) == 4, "Expecting alignof(GcRoot<>) == 4"); +constexpr size_t DexCacheArraysLayout::Alignment() { + // mirror::Type/String/MethodTypeDexCacheType alignment is 8, + // i.e. higher than or equal to the pointer alignment. + static_assert(alignof(mirror::TypeDexCacheType) == 8, + "Expecting alignof(ClassDexCacheType) == 8"); static_assert(alignof(mirror::StringDexCacheType) == 8, "Expecting alignof(StringDexCacheType) == 8"); static_assert(alignof(mirror::MethodTypeDexCacheType) == 8, @@ -60,17 +62,22 @@ inline constexpr size_t DexCacheArraysLayout::Alignment() { } template <typename T> -static constexpr PointerSize GcRootAsPointerSize() { +constexpr PointerSize GcRootAsPointerSize() { static_assert(sizeof(GcRoot<T>) == 4U, "Unexpected GcRoot size"); return PointerSize::k32; } inline size_t DexCacheArraysLayout::TypeOffset(dex::TypeIndex type_idx) const { - return types_offset_ + ElementOffset(GcRootAsPointerSize<mirror::Class>(), type_idx.index_); + return types_offset_ + ElementOffset(PointerSize::k64, + type_idx.index_ % mirror::DexCache::kDexCacheTypeCacheSize); } inline size_t DexCacheArraysLayout::TypesSize(size_t num_elements) const { - return ArraySize(GcRootAsPointerSize<mirror::Class>(), num_elements); + size_t cache_size = mirror::DexCache::kDexCacheTypeCacheSize; + if (num_elements < cache_size) { + cache_size = num_elements; + } + return ArraySize(PointerSize::k64, cache_size); } inline size_t DexCacheArraysLayout::TypesAlignment() const { diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 5f55f3fd29..9598870dcf 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -2399,7 +2399,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { const RegType& res_type = ResolveClassAndCheckAccess(type_idx); if (res_type.IsConflict()) { // If this is a primitive type, fail HARD. - mirror::Class* klass = dex_cache_->GetResolvedType(type_idx); + ObjPtr<mirror::Class> klass = + ClassLinker::LookupResolvedType(type_idx, dex_cache_.Get(), class_loader_.Get()); if (klass != nullptr && klass->IsPrimitive()) { Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "using primitive type " << dex_file_->StringByTypeIdx(type_idx) << " in instanceof in " @@ -3684,9 +3685,16 @@ inline bool MethodVerifier::IsInstantiableOrPrimitive(mirror::Class* klass) { } const RegType& MethodVerifier::ResolveClassAndCheckAccess(dex::TypeIndex class_idx) { - mirror::Class* klass = dex_cache_->GetResolvedType(class_idx); + mirror::Class* klass = can_load_classes_ + ? Runtime::Current()->GetClassLinker()->ResolveType( + *dex_file_, class_idx, dex_cache_, class_loader_) + : ClassLinker::LookupResolvedType(class_idx, dex_cache_.Get(), class_loader_.Get()).Ptr(); + if (can_load_classes_ && klass == nullptr) { + DCHECK(self_->IsExceptionPending()); + self_->ClearException(); + } const RegType* result = nullptr; - if (klass != nullptr) { + if (klass != nullptr && !klass->IsErroneous()) { bool precise = klass->CannotBeAssignedFromOtherTypes(); if (precise && !IsInstantiableOrPrimitive(klass)) { const char* descriptor = dex_file_->StringByTypeIdx(class_idx); @@ -3709,10 +3717,6 @@ const RegType& MethodVerifier::ResolveClassAndCheckAccess(dex::TypeIndex class_i << "' in " << GetDeclaringClass(); return *result; } - if (klass == nullptr && !result->IsUnresolvedTypes()) { - klass = result->GetClass(); - dex_cache_->SetResolvedType(class_idx, klass); - } // Record result of class resolution attempt. VerifierDeps::MaybeRecordClassResolution(*dex_file_, class_idx, klass); diff --git a/runtime/zip_archive.cc b/runtime/zip_archive.cc index 416873f4c3..cd79bb61f3 100644 --- a/runtime/zip_archive.cc +++ b/runtime/zip_archive.cc @@ -23,16 +23,10 @@ #include <unistd.h> #include <vector> -#include "android-base/stringprintf.h" #include "base/unix_file/fd_file.h" namespace art { -// Log file contents and mmap info when mapping entries directly. -static constexpr const bool kDebugZipMapDirectly = false; - -using android::base::StringPrintf; - uint32_t ZipEntry::GetUncompressedLength() { return zip_entry_->uncompressed_length; } @@ -41,15 +35,6 @@ uint32_t ZipEntry::GetCrc32() { return zip_entry_->crc32; } -bool ZipEntry::IsUncompressed() { - return zip_entry_->method == kCompressStored; -} - -bool ZipEntry::IsAlignedTo(size_t alignment) { - DCHECK(IsPowerOfTwo(alignment)) << alignment; - return IsAlignedParam(zip_entry_->offset, static_cast<int>(alignment)); -} - ZipEntry::~ZipEntry() { delete zip_entry_; } @@ -88,102 +73,6 @@ MemMap* ZipEntry::ExtractToMemMap(const char* zip_filename, const char* entry_fi return map.release(); } -MemMap* ZipEntry::MapDirectlyFromFile(const char* zip_filename, std::string* error_msg) { - const int zip_fd = GetFileDescriptor(handle_); - const char* entry_filename = entry_name_.c_str(); - - // Should not happen since we don't have a memory ZipArchive constructor. - // However the underlying ZipArchive isn't required to have an FD, - // so check to be sure. - CHECK_GE(zip_fd, 0) << - StringPrintf("Cannot map '%s' (in zip '%s') directly because the zip archive " - "is not file backed.", - entry_filename, - zip_filename); - - if (!IsUncompressed()) { - *error_msg = StringPrintf("Cannot map '%s' (in zip '%s') directly because it is compressed.", - entry_filename, - zip_filename); - return nullptr; - } else if (zip_entry_->uncompressed_length != zip_entry_->compressed_length) { - *error_msg = StringPrintf("Cannot map '%s' (in zip '%s') directly because " - "entry has bad size (%u != %u).", - entry_filename, - zip_filename, - zip_entry_->uncompressed_length, - zip_entry_->compressed_length); - return nullptr; - } - - std::string name(entry_filename); - name += " mapped directly in memory from "; - name += zip_filename; - - const off_t offset = zip_entry_->offset; - - if (kDebugZipMapDirectly) { - LOG(INFO) << "zip_archive: " << "make mmap of " << name << " @ offset = " << offset; - } - - std::unique_ptr<MemMap> map( - MemMap::MapFileAtAddress(nullptr, // Expected pointer address - GetUncompressedLength(), // Byte count - PROT_READ | PROT_WRITE, - MAP_PRIVATE, - zip_fd, - offset, - false, // Don't restrict allocation to lower4GB - false, // Doesn't overlap existing map (reuse=false) - name.c_str(), - /*out*/error_msg)); - - if (map == nullptr) { - DCHECK(!error_msg->empty()); - } - - if (kDebugZipMapDirectly) { - // Dump contents of file, same format as using this shell command: - // $> od -j <offset> -t x1 <zip_filename> - static constexpr const int kMaxDumpChars = 15; - lseek(zip_fd, 0, SEEK_SET); - - int count = offset + kMaxDumpChars; - - std::string tmp; - char buf; - - // Dump file contents. - int i = 0; - while (read(zip_fd, &buf, 1) > 0 && i < count) { - tmp += StringPrintf("%3d ", (unsigned int)buf); - ++i; - } - - LOG(INFO) << "map_fd raw bytes starting at 0"; - LOG(INFO) << "" << tmp; - LOG(INFO) << "---------------------------"; - - // Dump map contents. - if (map != nullptr) { - tmp = ""; - - count = kMaxDumpChars; - - uint8_t* begin = map->Begin(); - for (i = 0; i < count; ++i) { - tmp += StringPrintf("%3d ", (unsigned int)begin[i]); - } - - LOG(INFO) << "map address " << StringPrintf("%p", begin); - LOG(INFO) << "map first " << kMaxDumpChars << " chars:"; - LOG(INFO) << tmp; - } - } - - return map.release(); -} - static void SetCloseOnExec(int fd) { // This dance is more portable than Linux's O_CLOEXEC open(2) flag. int flags = fcntl(fd, F_GETFD); @@ -240,7 +129,7 @@ ZipEntry* ZipArchive::Find(const char* name, std::string* error_msg) const { return nullptr; } - return new ZipEntry(handle_, zip_entry.release(), name); + return new ZipEntry(handle_, zip_entry.release()); } ZipArchive::~ZipArchive() { diff --git a/runtime/zip_archive.h b/runtime/zip_archive.h index 18584447e8..42bf55cb3f 100644 --- a/runtime/zip_archive.h +++ b/runtime/zip_archive.h @@ -37,35 +37,19 @@ class MemMap; class ZipEntry { public: bool ExtractToFile(File& file, std::string* error_msg); - // Extract this entry to anonymous memory (R/W). - // Returns null on failure and sets error_msg. MemMap* ExtractToMemMap(const char* zip_filename, const char* entry_filename, std::string* error_msg); - // Create a file-backed private (clean, R/W) memory mapping to this entry. - // 'zip_filename' is used for diagnostics only, - // the original file that the ZipArchive was open with is used - // for the mapping. - // - // Will only succeed if the entry is stored uncompressed. - // Returns null on failure and sets error_msg. - MemMap* MapDirectlyFromFile(const char* zip_filename, /*out*/std::string* error_msg); virtual ~ZipEntry(); uint32_t GetUncompressedLength(); uint32_t GetCrc32(); - bool IsUncompressed(); - bool IsAlignedTo(size_t alignment); - private: ZipEntry(ZipArchiveHandle handle, - ::ZipEntry* zip_entry, - const std::string& entry_name) - : handle_(handle), zip_entry_(zip_entry), entry_name_(entry_name) {} + ::ZipEntry* zip_entry) : handle_(handle), zip_entry_(zip_entry) {} ZipArchiveHandle handle_; ::ZipEntry* const zip_entry_; - std::string const entry_name_; friend class ZipArchive; DISALLOW_COPY_AND_ASSIGN(ZipEntry); diff --git a/test/071-dexfile-map-clean/build b/test/071-dexfile-map-clean/build deleted file mode 100755 index a171fc3b3b..0000000000 --- a/test/071-dexfile-map-clean/build +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -# -# Copyright 2017 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Any JAR files used by this test shall have their classes.dex be stored, NOT compressed. -# This is needed for our test correctness which validates classes.dex are mapped file-backed. -# -# In addition, align to at least 4 bytes since that's the dex alignment requirement. -./default-build "$@" --zip-compression-method store --zip-align 4 diff --git a/test/071-dexfile-map-clean/expected.txt b/test/071-dexfile-map-clean/expected.txt deleted file mode 100644 index af7fb2806b..0000000000 --- a/test/071-dexfile-map-clean/expected.txt +++ /dev/null @@ -1,3 +0,0 @@ -Another -Secondary dexfile mmap is clean -Another Instance diff --git a/test/071-dexfile-map-clean/info.txt b/test/071-dexfile-map-clean/info.txt deleted file mode 100644 index 7e45808603..0000000000 --- a/test/071-dexfile-map-clean/info.txt +++ /dev/null @@ -1,11 +0,0 @@ -Exercise Dalvik-specific DEX file feature. Will not work on RI. - -If these conditions are met: -* When we are loading in a secondary dex file -* and when dex2oat is not used -* and the dex file is stored uncompressed in a ZIP file - -Then check: -* The dex file is memory-mapped file-backed as clean memory -(i.e. there is no extraction step) - diff --git a/test/071-dexfile-map-clean/run b/test/071-dexfile-map-clean/run deleted file mode 100755 index b045109739..0000000000 --- a/test/071-dexfile-map-clean/run +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# -# Copyright 2017 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Run without dex2oat so that we don't create oat/vdex files -# when trying to load the secondary dex file. - -# In this way, the secondary dex file will be forced to be -# loaded directly. -./default-run "$@" --no-dex2oat diff --git a/test/071-dexfile-map-clean/src-ex/Another.java b/test/071-dexfile-map-clean/src-ex/Another.java deleted file mode 100644 index 58464a65ab..0000000000 --- a/test/071-dexfile-map-clean/src-ex/Another.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -public class Another { - public Another() { - System.out.println("Another Instance"); - } -} diff --git a/test/071-dexfile-map-clean/src/Main.java b/test/071-dexfile-map-clean/src/Main.java deleted file mode 100644 index 8a196dd52e..0000000000 --- a/test/071-dexfile-map-clean/src/Main.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.lang.reflect.Method; -import java.util.Enumeration; - -import java.nio.file.Files; -import java.nio.file.Paths; - -/** - * DexFile tests (Dalvik-specific). - */ -public class Main { - private static final String CLASS_PATH = - System.getenv("DEX_LOCATION") + "/071-dexfile-map-clean-ex.jar"; - - /** - * Prep the environment then run the test. - */ - public static void main(String[] args) throws Exception { - // Load the dex file, this is a pre-requisite to mmap-ing it in. - Class<?> AnotherClass = testDexFile(); - // Check that the memory maps are clean. - testDexMemoryMaps(); - - // Prevent garbage collector from collecting our DexFile - // (and unmapping too early) by using it after we finish - // our verification. - AnotherClass.newInstance(); - } - - private static boolean checkSmapsEntry(String[] smapsLines, int offset) { - String nameDescription = smapsLines[offset]; - String[] split = nameDescription.split(" "); - - String permissions = split[1]; - // Mapped as read-only + anonymous. - if (!permissions.startsWith("r--p")) { - return false; - } - - boolean validated = false; - - // We have the right entry, now make sure it's valid. - for (int i = offset; i < smapsLines.length; ++i) { - String line = smapsLines[i]; - - if (line.startsWith("Shared_Dirty") || line.startsWith("Private_Dirty")) { - String lineTrimmed = line.trim(); - String[] lineSplit = lineTrimmed.split(" +"); - - String sizeUsuallyInKb = lineSplit[lineSplit.length - 2]; - - sizeUsuallyInKb = sizeUsuallyInKb.trim(); - - if (!sizeUsuallyInKb.equals("0")) { - System.out.println( - "ERROR: Memory mapping for " + CLASS_PATH + " is unexpectedly dirty"); - System.out.println(line); - } else { - validated = true; - } - } - - // VmFlags marks the "end" of an smaps entry. - if (line.startsWith("VmFlags")) { - break; - } - } - - if (validated) { - System.out.println("Secondary dexfile mmap is clean"); - } else { - System.out.println("ERROR: Memory mapping is missing Shared_Dirty/Private_Dirty entries"); - } - - return true; - } - - // This test takes relies on dex2oat being skipped. - // (enforced in 'run' file by using '--no-dex2oat' - // - // This could happen in a non-test situation - // if a secondary dex file is loaded (but not yet maintenance-mode compiled) - // with JIT. - // - // Or it could also happen if a secondary dex file is loaded and forced - // into running into the interpreter (e.g. duplicate classes). - // - // Rather than relying on those weird fallbacks, - // we force the runtime not to dex2oat the dex file to ensure - // this test is repeatable and less brittle. - private static void testDexMemoryMaps() throws Exception { - // Ensure that the secondary dex file is mapped clean (directly from JAR file). - String smaps = new String(Files.readAllBytes(Paths.get("/proc/self/smaps"))); - - String[] smapsLines = smaps.split("\n"); - boolean found = true; - for (int i = 0; i < smapsLines.length; ++i) { - if (smapsLines[i].contains(CLASS_PATH)) { - if (checkSmapsEntry(smapsLines, i)) { - return; - } // else we found the wrong one, keep going. - } - } - - // Error case: - System.out.println("Could not find " + CLASS_PATH + " RO-anonymous smaps entry"); - System.out.println(smaps); - } - - private static Class<?> testDexFile() throws Exception { - ClassLoader classLoader = Main.class.getClassLoader(); - Class<?> DexFile = classLoader.loadClass("dalvik.system.DexFile"); - Method DexFile_loadDex = DexFile.getMethod("loadDex", - String.class, - String.class, - Integer.TYPE); - Method DexFile_entries = DexFile.getMethod("entries"); - Object dexFile = DexFile_loadDex.invoke(null, CLASS_PATH, null, 0); - Enumeration<String> e = (Enumeration<String>) DexFile_entries.invoke(dexFile); - while (e.hasMoreElements()) { - String className = e.nextElement(); - System.out.println(className); - } - - Method DexFile_loadClass = DexFile.getMethod("loadClass", - String.class, - ClassLoader.class); - Class<?> AnotherClass = (Class<?>)DexFile_loadClass.invoke(dexFile, - "Another", Main.class.getClassLoader()); - return AnotherClass; - } -} diff --git a/test/155-java-set-resolved-type/src/Main.java b/test/155-java-set-resolved-type/src/Main.java index f92363e915..56b8c3ece9 100644 --- a/test/155-java-set-resolved-type/src/Main.java +++ b/test/155-java-set-resolved-type/src/Main.java @@ -55,11 +55,7 @@ public class Main { Class<?> timpl = Class.forName("TestImplementation", false, mainLoader); // Clear the dex cache resolved types to force a proper lookup the next time // we need to find TestInterface. - // TODO: Enable clearing the dex cache when we switch to the hash-based type array - // and do a proper lookup. Currently, ClassLinker fully relies on the DexCache. - if (false) { - clearResolvedTypes(timpl); - } + clearResolvedTypes(timpl); // Force intialization of TestClass2. This expects the interface type to be // resolved and found through simple lookup. diff --git a/test/626-const-class-linking/clear_dex_cache_types.cc b/test/626-const-class-linking/clear_dex_cache_types.cc index c0aedc199f..ff5ae6bd0d 100644 --- a/test/626-const-class-linking/clear_dex_cache_types.cc +++ b/test/626-const-class-linking/clear_dex_cache_types.cc @@ -27,7 +27,8 @@ extern "C" JNIEXPORT void JNICALL Java_Main_nativeClearResolvedTypes(JNIEnv*, jc ScopedObjectAccess soa(Thread::Current()); mirror::DexCache* dex_cache = soa.Decode<mirror::Class>(cls)->GetDexCache(); for (size_t i = 0, num_types = dex_cache->NumResolvedTypes(); i != num_types; ++i) { - dex_cache->SetResolvedType(dex::TypeIndex(i), ObjPtr<mirror::Class>(nullptr)); + mirror::TypeDexCachePair cleared(nullptr, mirror::TypeDexCachePair::InvalidIndexForSlot(i)); + dex_cache->GetResolvedTypes()[i].store(cleared, std::memory_order_relaxed); } } diff --git a/test/945-obsolete-native/build b/test/636-arm64-veneer-pool/build index 898e2e54a2..27cc4d6d98 100755 --- a/test/945-obsolete-native/build +++ b/test/636-arm64-veneer-pool/build @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2016 The Android Open Source Project +# Copyright 2017 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,5 +13,10 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +# Make us exit on a failure. -./default-build "$@" --experimental agents +set -e + +# Use javac+dx instead of jack. +export USE_JACK=false +./default-build "$@" diff --git a/test/636-arm64-veneer-pool/expected.txt b/test/636-arm64-veneer-pool/expected.txt new file mode 100644 index 0000000000..b0aad4deb5 --- /dev/null +++ b/test/636-arm64-veneer-pool/expected.txt @@ -0,0 +1 @@ +passed diff --git a/test/636-arm64-veneer-pool/info.txt b/test/636-arm64-veneer-pool/info.txt new file mode 100644 index 0000000000..2393be0538 --- /dev/null +++ b/test/636-arm64-veneer-pool/info.txt @@ -0,0 +1 @@ +Regression test for an issue with VIXL ARM64 veneer pools (b/34850123). diff --git a/test/636-arm64-veneer-pool/src/Main.java b/test/636-arm64-veneer-pool/src/Main.java new file mode 100644 index 0000000000..8229fee378 --- /dev/null +++ b/test/636-arm64-veneer-pool/src/Main.java @@ -0,0 +1,4223 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class C0 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C2 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C3 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C4 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C5 { + public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } + public static void mImpl(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } +} +class C6 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C7 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C8 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C9 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C10 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C11 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C12 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C13 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C14 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C15 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C16 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C17 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C18 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C19 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C20 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C21 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C22 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C23 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C24 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C25 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C26 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C27 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C28 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C29 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C30 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C31 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C32 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C33 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C34 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C35 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C36 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C37 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C38 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C39 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C40 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C41 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C42 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C43 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C44 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C45 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C46 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C47 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C48 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C49 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C50 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C51 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C52 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C53 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C54 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C55 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C56 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C57 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C58 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C59 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C60 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C61 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C62 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C63 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C64 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C65 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C66 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C67 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C68 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C69 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C70 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C71 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C72 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C73 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C74 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C75 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C76 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C77 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C78 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C79 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C80 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C81 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C82 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C83 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C84 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C85 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C86 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C87 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C88 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C89 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C90 { + public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } + public static void mReport_Factory(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } + public static void mApi(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } +} +class C91 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C92 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C93 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C94 { + public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } + public static void mImpl(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } +} +class C95 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C96 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C97 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C98 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C99 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C100 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C101 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C102 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C103 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C104 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C105 { + public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } + public static void m_InMemoryScanner(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } + public static void m_Scanner(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } +} +class C106 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C107 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C108 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C109 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C110 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C111 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C112 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C113 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C114 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C115 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C116 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C117 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C118 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C119 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C120 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C121 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C122 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C123 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C124 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C125 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C126 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C127 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C128 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C129 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C130 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C131 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C132 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C133 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C134 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C135 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C136 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C137 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C138 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C139 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C140 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C141 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C142 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C143 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C144 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C145 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C146 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C147 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C148 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C149 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C150 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C151 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C152 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C153 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C154 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C155 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C156 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C157 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C158 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C159 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C160 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C161 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C162 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C163 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C164 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C165 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C166 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C167 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C168 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C169 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C170 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C171 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C172 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C173 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C174 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C175 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C176 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C177 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C178 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C179 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C180 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C181 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C182 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C183 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C184 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C185 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C186 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C187 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C188 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C189 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C190 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C191 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C192 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C193 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C194 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C195 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C196 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C197 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C198 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C199 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C200 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C201 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C202 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C203 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C204 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C205 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C206 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C207 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C208 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C209 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C210 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C211 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C212 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C213 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C214 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C215 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C216 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C217 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C218 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C219 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C220 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C221 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C222 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C223 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C224 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C225 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C226 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C227 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C228 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C229 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C230 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C231 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C232 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C233 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C234 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C235 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C236 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C237 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C238 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C239 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C240 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C241 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C242 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C243 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C244 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C245 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C246 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C247 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C248 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C249 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C250 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C251 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C252 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C253 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C254 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C255 { + public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } + public static void mFactory(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } +} +class C256 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C257 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C258 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C259 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C260 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C261 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C262 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C263 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C264 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C265 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C266 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C267 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C268 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C269 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C270 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C271 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C272 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C273 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C274 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C275 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C276 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C277 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C278 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C279 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C280 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C281 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C282 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C283 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C284 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C285 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C286 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C287 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C288 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C289 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C290 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C291 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C292 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C293 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C294 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C295 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C296 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C297 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C298 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C299 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C300 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C301 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C302 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C303 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C304 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C305 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C306 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C307 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C308 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C309 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C310 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C311 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C312 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C313 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C314 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C315 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C316 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C317 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C318 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C319 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C320 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C321 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C322 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C323 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C324 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C325 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C326 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C327 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C328 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C329 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C330 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C331 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C332 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C333 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C334 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C335 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C336 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C337 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C338 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C339 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C340 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C341 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C342 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C343 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C344 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C345 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C346 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C347 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C348 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C349 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C350 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C351 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C352 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C353 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C354 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C355 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C356 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C357 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C358 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C359 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C360 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C361 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C362 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C363 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C364 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C365 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C366 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C367 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C368 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C369 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C370 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C371 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C372 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C373 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C374 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C375 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C376 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C377 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C378 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C379 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C380 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C381 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C382 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C383 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C384 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C385 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C386 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C387 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C388 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C389 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C390 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C391 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C392 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C393 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C394 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C395 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C396 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C397 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C398 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C399 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C400 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C401 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C402 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C403 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C404 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C405 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C406 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C407 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C408 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C409 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C410 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C411 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C412 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C413 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C414 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C415 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C416 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C417 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C418 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C419 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C420 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C421 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C422 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C423 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C424 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C425 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C426 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C427 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C428 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C429 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C430 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C431 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C432 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C433 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C434 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C435 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C436 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C437 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C438 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C439 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C440 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C441 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C442 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C443 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C444 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C445 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C446 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C447 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C448 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C449 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C450 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C451 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C452 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C453 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C454 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C455 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C456 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C457 { + public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } + public static void mMap(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } +} +class C458 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C459 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C460 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C461 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C462 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C463 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C464 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C465 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C466 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C467 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C468 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C469 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C470 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C471 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C472 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C473 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C474 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C475 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C476 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C477 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C478 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C479 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C480 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C481 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C482 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C483 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C484 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C485 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C486 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C487 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C488 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C489 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C490 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C491 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C492 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C493 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C494 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C495 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C496 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C497 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C498 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C499 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C500 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C501 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C502 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C503 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C504 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C505 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C506 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C507 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C508 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C509 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C510 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C511 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C512 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C513 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C514 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C515 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C516 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C517 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C518 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C519 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C520 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C521 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C522 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C523 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C524 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C525 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C526 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C527 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C528 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C529 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C530 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C531 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C532 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C533 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C534 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C535 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C536 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C537 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C538 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C539 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C540 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C541 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C542 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C543 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C544 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C545 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C546 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C547 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C548 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C549 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C550 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C551 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C552 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C553 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C554 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C555 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C556 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C557 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C558 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C559 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C560 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C561 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C562 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C563 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C564 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C565 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C566 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C567 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C568 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C569 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C570 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C571 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C572 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C573 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C574 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C575 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C576 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C577 { + public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } + public static void mDebug(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } +} +class C578 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C579 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C580 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C581 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C582 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C583 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C584 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C585 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C586 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C587 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C588 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C589 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C590 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C591 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C592 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C593 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C594 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C595 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C596 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C597 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C598 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C599 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C600 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C601 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C602 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C603 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C604 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C605 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C606 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C607 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C608 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C609 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C610 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C611 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C612 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C613 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C614 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C615 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C616 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C617 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C618 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C619 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C620 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C621 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C622 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C623 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C624 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C625 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C626 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C627 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C628 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C629 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C630 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C631 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C632 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C633 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C634 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C635 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C636 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C637 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C638 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C639 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C640 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C641 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C642 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C643 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C644 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C645 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C646 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C647 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C648 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C649 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C650 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C651 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C652 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C653 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C654 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C655 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C656 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C657 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C658 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C659 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C660 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C661 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C662 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C663 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C664 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C665 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C666 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C667 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C668 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C669 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C670 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C671 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C672 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C673 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C674 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C675 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C676 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C677 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C678 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C679 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C680 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C681 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C682 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C683 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C684 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C685 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C686 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C687 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C688 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C689 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C690 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C691 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C692 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C693 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C694 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C695 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C696 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C697 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C698 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C699 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C700 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C701 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C702 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C703 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C704 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C705 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C706 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C707 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C708 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C709 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C710 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C711 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C712 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C713 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C714 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C715 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C716 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C717 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C718 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C719 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C720 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C721 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C722 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C723 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C724 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C725 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C726 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C727 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C728 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C729 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C730 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C731 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C732 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C733 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C734 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C735 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C736 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C737 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C738 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C739 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C740 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C741 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C742 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C743 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C744 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C745 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C746 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C747 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C748 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C749 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C750 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C751 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C752 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C753 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C754 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C755 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C756 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C757 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C758 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C759 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C760 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C761 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C762 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C763 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C764 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C765 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C766 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C767 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C768 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C769 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C770 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C771 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C772 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C773 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C774 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C775 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C776 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C777 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C778 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C779 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C780 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C781 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C782 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C783 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C784 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C785 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C786 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C787 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C788 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C789 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C790 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C791 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C792 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C793 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C794 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C795 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C796 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C797 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C798 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C799 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C800 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C801 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C802 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C803 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C804 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C805 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C806 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C807 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C808 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C809 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C810 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C811 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C812 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C813 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C814 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C815 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C816 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C817 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C818 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C819 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C820 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C821 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C822 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C823 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C824 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C825 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C826 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C827 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C828 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C829 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C830 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C831 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C832 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C833 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C834 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C835 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C836 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C837 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C838 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C839 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C840 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C841 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C842 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C843 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C844 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C845 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C846 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C847 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C848 { + public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } + public static void mMap(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } +} +class C849 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C850 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C851 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C852 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C853 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C854 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C855 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C856 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C857 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C858 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C859 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C860 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C861 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C862 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C863 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C864 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C865 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C866 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C867 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C868 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C869 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C870 { + public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } + public static void mImpl(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } +} +class C871 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C872 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C873 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C874 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C875 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C876 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C877 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C878 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C879 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C880 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C881 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C882 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C883 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C884 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C885 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C886 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C887 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C888 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C889 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C890 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C891 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C892 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C893 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C894 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C895 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C896 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C897 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C898 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C899 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C900 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C901 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C902 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C903 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C904 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C905 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C906 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C907 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C908 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C909 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C910 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C911 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C912 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C913 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C914 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C915 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C916 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C917 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C918 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C919 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C920 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C921 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C922 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C923 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C924 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C925 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C926 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C927 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C928 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C929 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C930 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C931 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C932 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C933 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C934 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C935 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C936 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C937 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C938 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C939 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C940 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C941 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C942 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C943 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C944 { + public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } + public static void mManager(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } +} +class C945 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C946 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C947 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C948 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C949 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C950 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C951 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C952 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C953 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C954 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C955 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C956 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C957 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C958 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C959 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C960 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C961 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C962 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C963 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C964 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C965 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C966 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C967 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C968 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C969 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C970 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C971 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C972 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C973 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C974 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C975 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C976 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C977 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C978 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C979 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C980 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C981 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C982 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C983 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C984 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C985 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C986 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C987 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C988 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C989 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C990 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C991 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C992 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C993 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C994 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C995 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C996 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C997 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C998 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C999 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1000 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1001 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1002 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1003 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1004 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1005 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1006 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1007 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1008 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1009 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1010 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1011 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1012 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1013 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1014 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1015 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1016 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1017 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1018 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1019 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1020 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1021 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1022 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1023 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1024 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1025 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1026 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1027 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1028 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1029 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1030 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1031 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1032 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1033 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1034 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1035 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1036 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1037 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1038 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1039 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1040 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1041 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1042 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1043 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1044 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1045 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1046 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1047 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1048 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1049 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1050 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1051 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1052 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1053 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1054 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1055 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1056 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1057 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1058 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1059 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1060 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1061 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1062 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1063 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1064 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1065 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1066 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1067 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1068 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1069 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1070 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1071 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1072 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1073 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1074 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1075 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1076 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1077 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1078 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1079 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1080 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1081 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1082 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1083 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1084 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1085 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1086 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1087 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1088 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1089 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1090 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1091 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1092 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1093 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1094 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1095 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1096 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1097 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1098 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1099 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1100 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1101 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1102 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1103 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1104 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1105 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1106 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1107 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1108 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1109 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1110 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1111 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1112 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1113 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1114 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1115 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1116 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1117 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1118 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1119 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1120 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1121 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1122 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1123 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1124 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1125 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1126 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1127 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1128 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1129 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1130 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1131 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1132 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1133 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1134 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1135 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1136 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1137 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1138 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1139 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1140 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1141 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1142 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1143 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1144 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1145 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1146 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1147 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1148 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1149 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1150 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1151 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1152 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1153 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1154 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1155 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1156 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1157 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1158 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1159 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1160 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1161 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1162 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1163 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1164 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1165 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1166 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1167 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1168 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1169 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1170 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1171 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1172 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1173 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1174 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1175 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1176 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1177 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1178 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1179 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1180 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1181 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1181a { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1181b { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1182 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1183 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1184 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1185 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1186 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1187 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1188 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1189 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1190 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1191 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1192 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1193 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1194 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1195 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1196 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1197 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1198 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1199 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1200 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1201 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1202 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1203 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1204 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1205 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1206 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1207 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1208 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1209 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1210 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1211 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } +class C1212 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } } + +class Context {} +class Binder {} + +public class Main { + + java.util.HashMap<String, Integer> typeMap; + private void buildTypeMap() {} + + // TODO: Add Checker assertions? + public void configure(Context context, Class<?> cls, Binder binder) { + if (this.typeMap == null) { + buildTypeMap(); + } + Integer num = (Integer) this.typeMap.get(cls.getName()); + if (num != null) { + switch (num.intValue()) { + case 0: + C0.m(context, binder); + return; + case 1: + C1.m(context, binder); + return; + case 2: + C2.m(context, binder); + return; + case 3: + C3.m(context, binder); + return; + case 4: + C4.m(context, binder); + return; + case 5: + C5.m(context, binder); + return; + case 6: + C6.m(context, binder); + C7.m(context, binder); + C8.m(context, binder); + return; + case 7: + C9.m(context, binder); + return; + case 8: + C10.m(context, binder); + return; + case 9: + C11.m(context, binder); + return; + case 10: + C12.m(context, binder); + return; + case 11: + C13.m(context, binder); + return; + case 12: + C14.m(context, binder); + return; + case 13: + C15.m(context, binder); + return; + case 14: + C16.m(context, binder); + return; + case 15: + C17.m(context, binder); + return; + case 16: + C18.m(context, binder); + C19.m(context, binder); + return; + case 17: + C20.m(context, binder); + return; + case 18: + C21.m(context, binder); + return; + case 19: + C22.m(context, binder); + return; + case 20: + C23.m(context, binder); + C24.m(context, binder); + C25.m(context, binder); + C26.m(context, binder); + C27.m(context, binder); + C28.m(context, binder); + C29.m(context, binder); + C30.m(context, binder); + C31.m(context, binder); + C32.m(context, binder); + C33.m(context, binder); + C34.m(context, binder); + C35.m(context, binder); + C36.m(context, binder); + C37.m(context, binder); + C38.m(context, binder); + C39.m(context, binder); + C40.m(context, binder); + C41.m(context, binder); + C42.m(context, binder); + C43.m(context, binder); + C44.m(context, binder); + C45.m(context, binder); + C46.m(context, binder); + C47.m(context, binder); + C48.m(context, binder); + C49.m(context, binder); + C50.m(context, binder); + C51.m(context, binder); + C52.m(context, binder); + C53.m(context, binder); + C54.m(context, binder); + C55.m(context, binder); + C56.m(context, binder); + C57.m(context, binder); + C58.m(context, binder); + C59.m(context, binder); + C60.m(context, binder); + C61.m(context, binder); + C62.m(context, binder); + C63.m(context, binder); + C64.m(context, binder); + C65.m(context, binder); + C66.m(context, binder); + C67.m(context, binder); + C68.m(context, binder); + C69.m(context, binder); + C70.m(context, binder); + C71.m(context, binder); + C72.m(context, binder); + C73.m(context, binder); + C74.m(context, binder); + C75.m(context, binder); + C76.m(context, binder); + C77.m(context, binder); + C78.m(context, binder); + C79.m(context, binder); + C80.m(context, binder); + C81.m(context, binder); + C82.m(context, binder); + C83.m(context, binder); + C84.m(context, binder); + C85.m(context, binder); + return; + case 21: + C86.m(context, binder); + return; + case 22: + C87.m(context, binder); + return; + case 23: + C88.m(context, binder); + C89.m(context, binder); + return; + case 24: + C90.m(context, binder); + return; + case 25: + C91.m(context, binder); + return; + case 26: + C92.m(context, binder); + return; + case 27: + C93.m(context, binder); + return; + case 28: + C94.m(context, binder); + return; + case 29: + C95.m(context, binder); + return; + case 30: + C96.m(context, binder); + return; + case 31: + C97.m(context, binder); + return; + case 32: + C98.m(context, binder); + C99.m(context, binder); + return; + case 33: + C100.m(context, binder); + return; + case 34: + C101.m(context, binder); + return; + case 35: + C102.m(context, binder); + return; + case 36: + C103.m(context, binder); + return; + case 37: + C104.m(context, binder); + return; + case 38: + C105.m(context, binder); + return; + case 39: + C106.m(context, binder); + return; + case 40: + C107.m(context, binder); + return; + case 41: + C108.m(context, binder); + return; + case 42: + C109.m(context, binder); + return; + case 43: + C110.m(context, binder); + return; + case 44: + C111.m(context, binder); + return; + case 45: + C112.m(context, binder); + return; + case 46: + C113.m(context, binder); + return; + case 47: + C114.m(context, binder); + return; + case 48: + C115.m(context, binder); + return; + case 49: + C116.m(context, binder); + return; + case 50: + C117.m(context, binder); + C118.m(context, binder); + return; + case 51: + C119.m(context, binder); + return; + case 52: + C120.m(context, binder); + return; + case 53: + C121.m(context, binder); + return; + case 54: + C122.m(context, binder); + return; + case 55: + C123.m(context, binder); + return; + case 56: + C124.m(context, binder); + return; + case 57: + C125.m(context, binder); + return; + case 58: + C126.m(context, binder); + return; + case 59: + C127.m(context, binder); + return; + case 60: + C128.m(context, binder); + return; + case 61: + C129.m(context, binder); + return; + case 62: + C130.m(context, binder); + C131.m(context, binder); + C132.m(context, binder); + C133.m(context, binder); + C134.m(context, binder); + C135.m(context, binder); + C136.m(context, binder); + C137.m(context, binder); + return; + case 63: + C138.m(context, binder); + return; + case 64: + C139.m(context, binder); + return; + case 65: + C140.m(context, binder); + return; + case 66: + C141.m(context, binder); + return; + case 67: + C142.m(context, binder); + return; + case 68: + C143.m(context, binder); + C144.m(context, binder); + C145.m(context, binder); + return; + case 69: + C146.m(context, binder); + return; + case 70: + C147.m(context, binder); + return; + case 71: + C148.m(context, binder); + return; + case 72: + C149.m(context, binder); + return; + case 73: + C150.m(context, binder); + return; + case 74: + C151.m(context, binder); + return; + case 75: + C152.m(context, binder); + return; + case 76: + C153.m(context, binder); + return; + case 77: + C154.m(context, binder); + return; + case 78: + C155.m(context, binder); + return; + case 79: + C156.m(context, binder); + return; + case 80: + C157.m(context, binder); + C158.m(context, binder); + C159.m(context, binder); + return; + case 81: + C160.m(context, binder); + return; + case 82: + C161.m(context, binder); + return; + case 83: + C162.m(context, binder); + return; + case 84: + C163.m(context, binder); + return; + case 85: + C164.m(context, binder); + C165.m(context, binder); + C166.m(context, binder); + C167.m(context, binder); + C168.m(context, binder); + C169.m(context, binder); + C170.m(context, binder); + C171.m(context, binder); + C172.m(context, binder); + C173.m(context, binder); + C174.m(context, binder); + C175.m(context, binder); + C176.m(context, binder); + C177.m(context, binder); + C178.m(context, binder); + C179.m(context, binder); + C180.m(context, binder); + C181.m(context, binder); + C182.m(context, binder); + C183.m(context, binder); + C184.m(context, binder); + return; + case 86: + C185.m(context, binder); + return; + case 87: + C186.m(context, binder); + return; + case 88: + C187.m(context, binder); + return; + case 89: + C188.m(context, binder); + return; + case 90: + C189.m(context, binder); + return; + case 91: + C190.m(context, binder); + return; + case 92: + C191.m(context, binder); + return; + case 93: + C192.m(context, binder); + return; + case 94: + C193.m(context, binder); + return; + case 95: + C194.m(context, binder); + return; + case 96: + C195.m(context, binder); + return; + case 97: + C196.m(context, binder); + return; + case 98: + C197.m(context, binder); + return; + case 99: + C198.m(context, binder); + return; + case 100: + C199.m(context, binder); + return; + case 101: + C200.m(context, binder); + return; + case 102: + C201.m(context, binder); + return; + case 103: + C202.m(context, binder); + C203.m(context, binder); + C204.m(context, binder); + C205.m(context, binder); + C206.m(context, binder); + return; + case 104: + C207.m(context, binder); + return; + case 105: + C208.m(context, binder); + return; + case 106: + C209.m(context, binder); + return; + case 107: + C210.m(context, binder); + return; + case 108: + C211.m(context, binder); + return; + case 109: + C212.m(context, binder); + return; + case 110: + C213.m(context, binder); + return; + case 111: + C214.m(context, binder); + return; + case 112: + C215.m(context, binder); + C216.m(context, binder); + C217.m(context, binder); + C218.m(context, binder); + C219.m(context, binder); + C220.m(context, binder); + C221.m(context, binder); + C222.m(context, binder); + C223.m(context, binder); + C224.m(context, binder); + C225.m(context, binder); + C226.m(context, binder); + return; + case 113: + C227.m(context, binder); + return; + case 114: + C228.m(context, binder); + return; + case 115: + C229.m(context, binder); + return; + case 116: + C230.m(context, binder); + return; + case 117: + C231.m(context, binder); + return; + case 118: + C232.m(context, binder); + return; + case 119: + C233.m(context, binder); + return; + case 120: + C234.m(context, binder); + return; + case 121: + C235.m(context, binder); + return; + case 122: + C236.m(context, binder); + return; + case 123: + C237.m(context, binder); + return; + case 124: + C238.m(context, binder); + return; + case 125: + C239.m(context, binder); + return; + case 126: + C240.m(context, binder); + return; + case 127: + C241.m(context, binder); + return; + case 128: + C242.m(context, binder); + return; + case 129: + C243.m(context, binder); + C244.m(context, binder); + C245.m(context, binder); + C246.m(context, binder); + C247.m(context, binder); + C248.m(context, binder); + C249.m(context, binder); + C250.m(context, binder); + C251.m(context, binder); + return; + case 130: + C252.m(context, binder); + return; + case 131: + C253.m(context, binder); + return; + case 132: + C254.m(context, binder); + return; + case 133: + C255.m(context, binder); + return; + case 134: + C256.m(context, binder); + return; + case 135: + C257.m(context, binder); + return; + case 136: + C258.m(context, binder); + return; + case 137: + C259.m(context, binder); + return; + case 138: + C260.m(context, binder); + return; + case 139: + C261.m(context, binder); + return; + case 140: + C262.m(context, binder); + return; + case 141: + C263.m(context, binder); + return; + case 142: + C264.m(context, binder); + return; + case 143: + C265.m(context, binder); + return; + case 144: + C266.m(context, binder); + C267.m(context, binder); + return; + case 145: + C268.m(context, binder); + return; + case 146: + C269.m(context, binder); + return; + case 147: + C270.m(context, binder); + return; + case 148: + C271.m(context, binder); + return; + case 149: + C272.m(context, binder); + return; + case 150: + C273.m(context, binder); + return; + case 151: + C274.m(context, binder); + return; + case 152: + C275.m(context, binder); + return; + case 153: + C276.m(context, binder); + return; + case 154: + C277.m(context, binder); + return; + case 155: + C278.m(context, binder); + return; + case 156: + C279.m(context, binder); + return; + case 157: + C280.m(context, binder); + return; + case 158: + C281.m(context, binder); + return; + case 159: + C282.m(context, binder); + return; + case 160: + C283.m(context, binder); + return; + case 161: + C284.m(context, binder); + return; + case 162: + C285.m(context, binder); + return; + case 163: + C286.m(context, binder); + return; + case 164: + C287.m(context, binder); + return; + case 165: + C288.m(context, binder); + return; + case 166: + C289.m(context, binder); + return; + case 167: + C290.m(context, binder); + return; + case 168: + C291.m(context, binder); + C292.m(context, binder); + C293.m(context, binder); + C294.m(context, binder); + C295.m(context, binder); + C296.m(context, binder); + C297.m(context, binder); + return; + case 169: + C298.m(context, binder); + return; + case 170: + C299.m(context, binder); + return; + case 171: + C300.m(context, binder); + return; + case 172: + C301.m(context, binder); + return; + case 173: + C302.m(context, binder); + return; + case 174: + C303.m(context, binder); + return; + case 175: + C304.m(context, binder); + return; + case 176: + C305.m(context, binder); + return; + case 177: + C306.m(context, binder); + return; + case 178: + C307.m(context, binder); + return; + case 179: + C308.m(context, binder); + return; + case 180: + C309.m(context, binder); + return; + case 181: + C310.m(context, binder); + return; + case 182: + C311.m(context, binder); + return; + case 183: + C312.m(context, binder); + return; + case 184: + C313.m(context, binder); + return; + case 185: + C314.m(context, binder); + return; + case 186: + C315.m(context, binder); + return; + case 187: + C316.m(context, binder); + return; + case 188: + C317.m(context, binder); + return; + case 189: + C318.m(context, binder); + return; + case 190: + C319.m(context, binder); + return; + case 191: + C320.m(context, binder); + return; + case 192: + C321.m(context, binder); + return; + case 193: + C322.m(context, binder); + return; + case 194: + C323.m(context, binder); + C324.m(context, binder); + C325.m(context, binder); + return; + case 195: + C326.m(context, binder); + return; + case 196: + C327.m(context, binder); + return; + case 197: + C328.m(context, binder); + return; + case 198: + C329.m(context, binder); + return; + case 199: + C330.m(context, binder); + return; + case 200: + C331.m(context, binder); + return; + case 201: + C332.m(context, binder); + return; + case 202: + C333.m(context, binder); + return; + case 203: + C334.m(context, binder); + C335.m(context, binder); + C336.m(context, binder); + C337.m(context, binder); + C338.m(context, binder); + C339.m(context, binder); + C340.m(context, binder); + C341.m(context, binder); + C342.m(context, binder); + C343.m(context, binder); + C344.m(context, binder); + C345.m(context, binder); + return; + case 204: + C346.m(context, binder); + return; + case 205: + C347.m(context, binder); + return; + case 206: + C348.m(context, binder); + return; + case 207: + C349.m(context, binder); + return; + case 208: + C350.m(context, binder); + return; + case 209: + C351.m(context, binder); + return; + case 210: + C352.m(context, binder); + C353.m(context, binder); + return; + case 211: + C354.m(context, binder); + return; + case 212: + C355.m(context, binder); + C356.m(context, binder); + C357.m(context, binder); + C358.m(context, binder); + C359.m(context, binder); + C360.m(context, binder); + C361.m(context, binder); + C362.m(context, binder); + C363.m(context, binder); + C364.m(context, binder); + C365.m(context, binder); + C366.m(context, binder); + C367.m(context, binder); + C368.m(context, binder); + C369.m(context, binder); + C370.m(context, binder); + C371.m(context, binder); + return; + case 213: + C372.m(context, binder); + return; + case 214: + C373.m(context, binder); + return; + case 215: + C374.m(context, binder); + return; + case 216: + C375.m(context, binder); + C376.m(context, binder); + C377.m(context, binder); + C378.m(context, binder); + C379.m(context, binder); + C380.m(context, binder); + C381.m(context, binder); + C382.m(context, binder); + return; + case 217: + C383.m(context, binder); + return; + case 218: + C384.m(context, binder); + return; + case 219: + C385.m(context, binder); + return; + case 220: + C386.m(context, binder); + return; + case 221: + C387.m(context, binder); + return; + case 222: + C388.m(context, binder); + return; + case 223: + C389.m(context, binder); + return; + case 224: + C390.m(context, binder); + return; + case 225: + C391.m(context, binder); + return; + case 226: + C392.m(context, binder); + return; + case 227: + C393.m(context, binder); + C394.m(context, binder); + return; + case 228: + C395.m(context, binder); + return; + case 229: + C396.m(context, binder); + return; + case 230: + C397.m(context, binder); + return; + case 231: + C398.m(context, binder); + return; + case 232: + C399.m(context, binder); + return; + case 233: + C400.m(context, binder); + return; + case 234: + C401.m(context, binder); + return; + case 235: + C402.m(context, binder); + return; + case 236: + C403.m(context, binder); + return; + case 237: + C404.m(context, binder); + return; + case 238: + C405.m(context, binder); + return; + case 239: + C406.m(context, binder); + return; + case 240: + C407.m(context, binder); + return; + case 241: + C408.m(context, binder); + return; + case 242: + C409.m(context, binder); + return; + case 243: + C410.m(context, binder); + return; + case 244: + C411.m(context, binder); + return; + case 245: + C412.m(context, binder); + return; + case 246: + C413.m(context, binder); + return; + case 247: + C414.m(context, binder); + return; + case 248: + C415.m(context, binder); + return; + case 249: + C416.m(context, binder); + return; + case 250: + C417.m(context, binder); + return; + case 251: + C418.m(context, binder); + return; + case 252: + C419.m(context, binder); + return; + case 253: + C420.m(context, binder); + return; + case 254: + C421.m(context, binder); + return; + case 255: + C422.m(context, binder); + return; + case 256: + C423.m(context, binder); + return; + case 257: + C424.m(context, binder); + return; + case 258: + C425.m(context, binder); + return; + case 259: + C426.m(context, binder); + return; + case 260: + C427.m(context, binder); + return; + case 261: + C428.m(context, binder); + return; + case 262: + C429.m(context, binder); + return; + case 263: + C430.m(context, binder); + return; + case 264: + C431.m(context, binder); + return; + case 265: + C432.m(context, binder); + return; + case 266: + C433.m(context, binder); + return; + case 267: + C434.m(context, binder); + C435.m(context, binder); + C436.m(context, binder); + C437.m(context, binder); + return; + case 268: + C438.m(context, binder); + return; + case 269: + C439.m(context, binder); + return; + case 270: + C440.m(context, binder); + return; + case 271: + C441.m(context, binder); + return; + case 272: + C442.m(context, binder); + return; + case 273: + C443.m(context, binder); + return; + case 274: + C444.m(context, binder); + return; + case 275: + C445.m(context, binder); + return; + case 276: + C446.m(context, binder); + return; + case 277: + C447.m(context, binder); + return; + case 278: + C448.m(context, binder); + return; + case 279: + C449.m(context, binder); + return; + case 280: + C450.m(context, binder); + return; + case 281: + C451.m(context, binder); + return; + case 282: + C452.m(context, binder); + return; + case 283: + C453.m(context, binder); + return; + case 284: + C454.m(context, binder); + return; + case 285: + C455.m(context, binder); + return; + case 286: + C456.m(context, binder); + return; + case 287: + C457.m(context, binder); + return; + case 288: + C458.m(context, binder); + return; + case 289: + C459.m(context, binder); + return; + case 290: + C460.m(context, binder); + return; + case 291: + C461.m(context, binder); + return; + case 292: + C462.m(context, binder); + return; + case 293: + C463.m(context, binder); + return; + case 294: + C464.m(context, binder); + return; + case 295: + C465.m(context, binder); + return; + case 296: + C466.m(context, binder); + return; + case 297: + C467.m(context, binder); + return; + case 298: + C468.m(context, binder); + return; + case 299: + C469.m(context, binder); + return; + case 300: + C470.m(context, binder); + return; + case 301: + C471.m(context, binder); + return; + case 302: + C472.m(context, binder); + return; + case 303: + C473.m(context, binder); + return; + case 304: + C474.m(context, binder); + return; + case 305: + C475.m(context, binder); + return; + case 306: + C476.m(context, binder); + return; + case 307: + C477.m(context, binder); + return; + case 308: + C478.m(context, binder); + return; + case 309: + C479.m(context, binder); + return; + case 310: + C480.m(context, binder); + return; + case 311: + C481.m(context, binder); + return; + case 312: + C482.m(context, binder); + return; + case 313: + C483.m(context, binder); + return; + case 314: + C484.m(context, binder); + return; + case 315: + C485.m(context, binder); + return; + case 316: + C486.m(context, binder); + return; + case 317: + C487.m(context, binder); + return; + case 318: + C488.m(context, binder); + return; + case 319: + C489.m(context, binder); + return; + case 320: + C490.m(context, binder); + return; + case 321: + C491.m(context, binder); + C492.m(context, binder); + C493.m(context, binder); + C494.m(context, binder); + C495.m(context, binder); + C496.m(context, binder); + C497.m(context, binder); + C498.m(context, binder); + return; + case 322: + C499.m(context, binder); + return; + case 323: + C500.m(context, binder); + return; + case 324: + C501.m(context, binder); + return; + case 325: + C502.m(context, binder); + return; + case 326: + C503.m(context, binder); + return; + case 327: + C504.m(context, binder); + return; + case 328: + C505.m(context, binder); + return; + case 329: + C506.m(context, binder); + return; + case 330: + C507.m(context, binder); + return; + case 331: + C508.m(context, binder); + return; + case 332: + C509.m(context, binder); + return; + case 333: + C510.m(context, binder); + return; + case 334: + C511.m(context, binder); + return; + case 335: + C512.m(context, binder); + return; + case 336: + C513.m(context, binder); + return; + case 337: + C514.m(context, binder); + return; + case 338: + C515.m(context, binder); + return; + case 339: + C516.m(context, binder); + return; + case 340: + C517.m(context, binder); + return; + case 341: + C518.m(context, binder); + return; + case 342: + C519.m(context, binder); + return; + case 343: + C520.m(context, binder); + return; + case 344: + C255.mFactory(context, binder); + return; + case 345: + C522.m(context, binder); + return; + case 346: + C523.m(context, binder); + return; + case 347: + C524.m(context, binder); + return; + case 348: + C525.m(context, binder); + return; + case 349: + C526.m(context, binder); + return; + case 350: + C527.m(context, binder); + return; + case 351: + C528.m(context, binder); + return; + case 352: + C529.m(context, binder); + return; + case 353: + C530.m(context, binder); + return; + case 354: + C531.m(context, binder); + return; + case 355: + C532.m(context, binder); + return; + case 356: + C533.m(context, binder); + return; + case 357: + C534.m(context, binder); + return; + case 358: + C535.m(context, binder); + return; + case 359: + C536.m(context, binder); + return; + case 360: + C537.m(context, binder); + return; + case 361: + C538.m(context, binder); + return; + case 362: + C539.m(context, binder); + return; + case 363: + C540.m(context, binder); + return; + case 364: + C541.m(context, binder); + return; + case 365: + C542.m(context, binder); + return; + case 366: + C543.m(context, binder); + return; + case 367: + C544.m(context, binder); + C545.m(context, binder); + return; + case 368: + C546.m(context, binder); + return; + case 369: + C547.m(context, binder); + return; + case 370: + C548.m(context, binder); + return; + case 371: + C549.m(context, binder); + return; + case 372: + C550.m(context, binder); + return; + case 373: + C551.m(context, binder); + return; + case 374: + C552.m(context, binder); + return; + case 375: + C553.m(context, binder); + return; + case 376: + C554.m(context, binder); + return; + case 377: + C555.m(context, binder); + return; + case 378: + C556.m(context, binder); + return; + case 379: + C557.m(context, binder); + return; + case 380: + C5.mImpl(context, binder); + return; + case 381: + C559.m(context, binder); + return; + case 382: + C560.m(context, binder); + return; + case 383: + C561.m(context, binder); + return; + case 384: + C562.m(context, binder); + return; + case 385: + C563.m(context, binder); + return; + case 386: + C564.m(context, binder); + return; + case 387: + C565.m(context, binder); + return; + case 388: + C566.m(context, binder); + return; + case 389: + C567.m(context, binder); + return; + case 390: + C568.m(context, binder); + return; + case 391: + C569.m(context, binder); + return; + case 392: + C570.m(context, binder); + return; + case 393: + C571.m(context, binder); + return; + case 394: + C572.m(context, binder); + return; + case 395: + C573.m(context, binder); + return; + case 396: + C574.m(context, binder); + return; + case 397: + C575.m(context, binder); + return; + case 398: + C576.m(context, binder); + return; + case 399: + C577.m(context, binder); + return; + case 400: + C578.m(context, binder); + return; + case 401: + C579.m(context, binder); + return; + case 402: + C580.m(context, binder); + return; + case 403: + C581.m(context, binder); + return; + case 404: + C582.m(context, binder); + return; + case 405: + C583.m(context, binder); + return; + case 406: + C584.m(context, binder); + C585.m(context, binder); + C586.m(context, binder); + C587.m(context, binder); + C588.m(context, binder); + C589.m(context, binder); + C590.m(context, binder); + C591.m(context, binder); + C592.m(context, binder); + C593.m(context, binder); + C594.m(context, binder); + return; + case 407: + C595.m(context, binder); + return; + case 408: + C596.m(context, binder); + return; + case 409: + C597.m(context, binder); + C598.m(context, binder); + return; + case 410: + C599.m(context, binder); + return; + case 411: + C600.m(context, binder); + return; + case 412: + C601.m(context, binder); + return; + case 413: + C602.m(context, binder); + return; + case 414: + C603.m(context, binder); + return; + case 415: + C604.m(context, binder); + return; + case 416: + C605.m(context, binder); + return; + case 417: + C606.m(context, binder); + return; + case 418: + C607.m(context, binder); + return; + case 419: + C608.m(context, binder); + return; + case 420: + C609.m(context, binder); + return; + case 421: + C610.m(context, binder); + return; + case 422: + C611.m(context, binder); + return; + case 423: + C612.m(context, binder); + return; + case 424: + C613.m(context, binder); + return; + case 425: + C614.m(context, binder); + C615.m(context, binder); + C616.m(context, binder); + return; + case 426: + C617.m(context, binder); + return; + case 427: + C618.m(context, binder); + return; + case 428: + C619.m(context, binder); + return; + case 429: + C620.m(context, binder); + return; + case 430: + C621.m(context, binder); + return; + case 431: + C622.m(context, binder); + return; + case 432: + C623.m(context, binder); + return; + case 433: + C624.m(context, binder); + return; + case 434: + C625.m(context, binder); + return; + case 435: + C626.m(context, binder); + return; + case 436: + C627.m(context, binder); + return; + case 437: + C628.m(context, binder); + return; + case 438: + C629.m(context, binder); + return; + case 439: + C630.m(context, binder); + return; + case 440: + C631.m(context, binder); + return; + case 441: + C632.m(context, binder); + return; + case 442: + C633.m(context, binder); + return; + case 443: + C634.m(context, binder); + return; + case 444: + C635.m(context, binder); + return; + case 445: + C636.m(context, binder); + return; + case 446: + C637.m(context, binder); + return; + case 447: + C638.m(context, binder); + return; + case 448: + C639.m(context, binder); + return; + case 449: + C640.m(context, binder); + return; + case 450: + C641.m(context, binder); + return; + case 451: + C642.m(context, binder); + return; + case 452: + C643.m(context, binder); + return; + case 453: + C644.m(context, binder); + return; + case 454: + C645.m(context, binder); + return; + case 455: + C646.m(context, binder); + return; + case 456: + C647.m(context, binder); + return; + case 457: + C648.m(context, binder); + return; + case 458: + C649.m(context, binder); + return; + case 459: + C650.m(context, binder); + return; + case 460: + C651.m(context, binder); + return; + case 461: + C652.m(context, binder); + return; + case 462: + C653.m(context, binder); + return; + case 463: + C654.m(context, binder); + return; + case 464: + C655.m(context, binder); + return; + case 465: + C656.m(context, binder); + return; + case 466: + C657.m(context, binder); + return; + case 467: + C658.m(context, binder); + return; + case 468: + C659.m(context, binder); + return; + case 469: + C660.m(context, binder); + return; + case 470: + C661.m(context, binder); + return; + case 471: + C90.mReport_Factory(context, binder); + return; + case 472: + C663.m(context, binder); + return; + case 473: + C664.m(context, binder); + return; + case 474: + C665.m(context, binder); + return; + case 475: + C666.m(context, binder); + return; + case 476: + C667.m(context, binder); + return; + case 477: + C668.m(context, binder); + return; + case 478: + C105.m_InMemoryScanner(context, binder); + return; + case 479: + C670.m(context, binder); + C671.m(context, binder); + return; + case 480: + C672.m(context, binder); + return; + case 481: + C673.m(context, binder); + return; + case 482: + C674.m(context, binder); + return; + case 483: + C675.m(context, binder); + return; + case 484: + C676.m(context, binder); + return; + case 485: + C677.m(context, binder); + return; + case 486: + C678.m(context, binder); + return; + case 487: + C679.m(context, binder); + C680.m(context, binder); + C681.m(context, binder); + C682.m(context, binder); + C683.m(context, binder); + C684.m(context, binder); + C685.m(context, binder); + return; + case 488: + C686.m(context, binder); + return; + case 489: + C687.m(context, binder); + return; + case 490: + C688.m(context, binder); + return; + case 491: + C689.m(context, binder); + return; + case 492: + C690.m(context, binder); + return; + case 493: + C691.m(context, binder); + C692.m(context, binder); + C693.m(context, binder); + C694.m(context, binder); + C695.m(context, binder); + C696.m(context, binder); + C697.m(context, binder); + C698.m(context, binder); + C699.m(context, binder); + C700.m(context, binder); + C701.m(context, binder); + C702.m(context, binder); + C703.m(context, binder); + C704.m(context, binder); + C705.m(context, binder); + C706.m(context, binder); + C707.m(context, binder); + C708.m(context, binder); + C709.m(context, binder); + C710.m(context, binder); + C711.m(context, binder); + C712.m(context, binder); + C713.m(context, binder); + C714.m(context, binder); + C715.m(context, binder); + C716.m(context, binder); + C717.m(context, binder); + C718.m(context, binder); + C719.m(context, binder); + C720.m(context, binder); + return; + case 494: + C721.m(context, binder); + C722.m(context, binder); + C723.m(context, binder); + return; + case 495: + C724.m(context, binder); + return; + case 496: + C725.m(context, binder); + return; + case 497: + C726.m(context, binder); + return; + case 498: + C727.m(context, binder); + return; + case 499: + C728.m(context, binder); + return; + case 500: + C729.m(context, binder); + return; + case 501: + C730.m(context, binder); + return; + case 502: + C731.m(context, binder); + return; + case 503: + C732.m(context, binder); + return; + case 504: + C733.m(context, binder); + return; + case 505: + C734.m(context, binder); + return; + case 506: + C735.m(context, binder); + return; + case 507: + C736.m(context, binder); + return; + case 508: + C737.m(context, binder); + return; + case 509: + C738.m(context, binder); + return; + case 510: + C739.m(context, binder); + return; + case 511: + C740.m(context, binder); + return; + case 512: + C741.m(context, binder); + return; + case 513: + C742.m(context, binder); + return; + case 514: + C743.m(context, binder); + return; + case 515: + C744.m(context, binder); + return; + case 516: + C745.m(context, binder); + return; + case 517: + C746.m(context, binder); + return; + case 518: + C747.m(context, binder); + return; + case 519: + C748.m(context, binder); + return; + case 520: + C749.m(context, binder); + return; + case 521: + C750.m(context, binder); + C751.m(context, binder); + C752.m(context, binder); + C753.m(context, binder); + C754.m(context, binder); + C755.m(context, binder); + C756.m(context, binder); + C757.m(context, binder); + C758.m(context, binder); + C759.m(context, binder); + C760.m(context, binder); + C761.m(context, binder); + return; + case 522: + C762.m(context, binder); + return; + case 523: + C763.m(context, binder); + return; + case 524: + C764.m(context, binder); + return; + case 525: + C765.m(context, binder); + return; + case 526: + C766.m(context, binder); + return; + case 527: + C767.m(context, binder); + return; + case 528: + C768.m(context, binder); + return; + case 529: + C769.m(context, binder); + return; + case 530: + C770.m(context, binder); + return; + case 531: + C771.m(context, binder); + return; + case 532: + C772.m(context, binder); + return; + case 533: + C773.m(context, binder); + return; + case 534: + C774.m(context, binder); + return; + case 535: + C775.m(context, binder); + return; + case 536: + C776.m(context, binder); + return; + case 537: + C777.m(context, binder); + return; + case 538: + C778.m(context, binder); + return; + case 539: + C779.m(context, binder); + return; + case 540: + C780.m(context, binder); + return; + case 541: + C781.m(context, binder); + return; + case 542: + C90.mApi(context, binder); + return; + case 543: + C783.m(context, binder); + return; + case 544: + C784.m(context, binder); + return; + case 545: + C785.m(context, binder); + return; + case 546: + C786.m(context, binder); + return; + case 547: + C787.m(context, binder); + return; + case 548: + C788.m(context, binder); + return; + case 549: + C789.m(context, binder); + return; + case 550: + C790.m(context, binder); + return; + case 551: + C791.m(context, binder); + return; + case 552: + C792.m(context, binder); + return; + case 553: + C793.m(context, binder); + return; + case 554: + C794.m(context, binder); + return; + case 555: + C795.m(context, binder); + C796.m(context, binder); + return; + case 556: + C797.m(context, binder); + return; + case 557: + C798.m(context, binder); + return; + case 558: + C799.m(context, binder); + return; + case 559: + C800.m(context, binder); + return; + case 560: + C801.m(context, binder); + return; + case 561: + C802.m(context, binder); + return; + case 562: + C803.m(context, binder); + C804.m(context, binder); + C805.m(context, binder); + C806.m(context, binder); + return; + case 563: + C807.m(context, binder); + return; + case 564: + C808.m(context, binder); + return; + case 565: + C809.m(context, binder); + return; + case 566: + C810.m(context, binder); + return; + case 567: + C811.m(context, binder); + return; + case 568: + C812.m(context, binder); + return; + case 569: + C813.m(context, binder); + C814.m(context, binder); + C815.m(context, binder); + C816.m(context, binder); + C817.m(context, binder); + C818.m(context, binder); + C819.m(context, binder); + C820.m(context, binder); + C821.m(context, binder); + return; + case 570: + C822.m(context, binder); + C823.m(context, binder); + return; + case 571: + C824.m(context, binder); + return; + case 572: + C825.m(context, binder); + return; + case 573: + C826.m(context, binder); + return; + case 574: + C827.m(context, binder); + return; + case 575: + C828.m(context, binder); + return; + case 576: + C829.m(context, binder); + return; + case 577: + C830.m(context, binder); + return; + case 578: + C831.m(context, binder); + return; + case 579: + C832.m(context, binder); + return; + case 580: + C833.m(context, binder); + return; + case 581: + C834.m(context, binder); + return; + case 582: + C835.m(context, binder); + return; + case 583: + C836.m(context, binder); + return; + case 584: + C837.m(context, binder); + return; + case 585: + C838.m(context, binder); + return; + case 586: + C105.m_Scanner(context, binder); + C840.m(context, binder); + return; + case 587: + C94.mImpl(context, binder); + return; + case 588: + C842.m(context, binder); + C843.m(context, binder); + C844.m(context, binder); + C845.m(context, binder); + return; + case 589: + C846.m(context, binder); + return; + case 590: + C847.m(context, binder); + return; + case 591: + C848.m(context, binder); + return; + case 592: + C849.m(context, binder); + return; + case 593: + C850.m(context, binder); + return; + case 594: + C851.m(context, binder); + return; + case 595: + C852.m(context, binder); + return; + case 596: + C853.m(context, binder); + return; + case 597: + C854.m(context, binder); + return; + case 598: + C855.m(context, binder); + return; + case 599: + C856.m(context, binder); + return; + case 600: + C857.m(context, binder); + return; + case 601: + C858.m(context, binder); + return; + case 602: + C859.m(context, binder); + return; + case 603: + C860.m(context, binder); + return; + case 604: + C861.m(context, binder); + return; + case 605: + C862.m(context, binder); + return; + case 606: + C863.m(context, binder); + return; + case 607: + C864.m(context, binder); + return; + case 608: + C865.m(context, binder); + return; + case 609: + C866.m(context, binder); + return; + case 610: + C867.m(context, binder); + return; + case 611: + C868.m(context, binder); + return; + case 612: + C869.m(context, binder); + return; + case 613: + C870.m(context, binder); + return; + case 614: + C871.m(context, binder); + return; + case 615: + C872.m(context, binder); + return; + case 616: + C873.m(context, binder); + return; + case 617: + C874.m(context, binder); + return; + case 618: + C875.m(context, binder); + return; + case 619: + C876.m(context, binder); + return; + case 620: + C877.m(context, binder); + return; + case 621: + C878.m(context, binder); + return; + case 622: + C879.m(context, binder); + C880.m(context, binder); + return; + case 623: + C881.m(context, binder); + return; + case 624: + C882.m(context, binder); + return; + case 625: + C883.m(context, binder); + return; + case 626: + C884.m(context, binder); + C885.m(context, binder); + C886.m(context, binder); + C887.m(context, binder); + C888.m(context, binder); + return; + case 627: + C889.m(context, binder); + return; + case 628: + C890.m(context, binder); + return; + case 629: + C891.m(context, binder); + return; + case 630: + C892.m(context, binder); + return; + case 631: + C893.m(context, binder); + return; + case 632: + C894.m(context, binder); + return; + case 633: + C895.m(context, binder); + return; + case 634: + C896.m(context, binder); + return; + case 635: + C897.m(context, binder); + return; + case 636: + C898.m(context, binder); + return; + case 637: + C899.m(context, binder); + return; + case 638: + C900.m(context, binder); + return; + case 639: + C901.m(context, binder); + return; + case 640: + C870.mImpl(context, binder); + return; + case 641: + C903.m(context, binder); + return; + case 642: + C904.m(context, binder); + return; + case 643: + C905.m(context, binder); + return; + case 644: + C906.m(context, binder); + C907.m(context, binder); + C908.m(context, binder); + C909.m(context, binder); + C910.m(context, binder); + return; + case 645: + C911.m(context, binder); + return; + case 646: + C912.m(context, binder); + C913.m(context, binder); + return; + case 647: + C914.m(context, binder); + return; + case 648: + C915.m(context, binder); + return; + case 649: + C916.m(context, binder); + return; + case 650: + C917.m(context, binder); + C918.m(context, binder); + return; + case 651: + C919.m(context, binder); + return; + case 652: + C920.m(context, binder); + return; + case 653: + C921.m(context, binder); + return; + case 654: + C922.m(context, binder); + return; + case 655: + C923.m(context, binder); + C924.m(context, binder); + C925.m(context, binder); + C926.m(context, binder); + C927.m(context, binder); + C928.m(context, binder); + C929.m(context, binder); + C930.m(context, binder); + C931.m(context, binder); + C932.m(context, binder); + C933.m(context, binder); + C934.m(context, binder); + C935.m(context, binder); + return; + case 656: + C936.m(context, binder); + return; + case 657: + C937.m(context, binder); + return; + case 658: + C938.m(context, binder); + return; + case 659: + C939.m(context, binder); + return; + case 660: + C940.m(context, binder); + return; + case 661: + C941.m(context, binder); + return; + case 662: + C942.m(context, binder); + return; + case 663: + C943.m(context, binder); + return; + case 664: + C944.m(context, binder); + return; + case 665: + C945.m(context, binder); + return; + case 666: + C946.m(context, binder); + return; + case 667: + C947.m(context, binder); + return; + case 668: + C948.m(context, binder); + return; + case 669: + C949.m(context, binder); + return; + case 670: + C950.m(context, binder); + return; + case 671: + C951.m(context, binder); + return; + case 672: + C952.m(context, binder); + C953.m(context, binder); + C954.m(context, binder); + C955.m(context, binder); + return; + case 673: + C956.m(context, binder); + return; + case 674: + C957.m(context, binder); + C958.m(context, binder); + return; + case 675: + C959.m(context, binder); + return; + case 676: + C960.m(context, binder); + C961.m(context, binder); + return; + case 677: + C962.m(context, binder); + return; + case 678: + C963.m(context, binder); + return; + case 679: + C964.m(context, binder); + return; + case 680: + C965.m(context, binder); + return; + case 681: + C966.m(context, binder); + return; + case 682: + C967.m(context, binder); + return; + case 683: + C968.m(context, binder); + return; + case 684: + C969.m(context, binder); + return; + case 685: + C970.m(context, binder); + return; + case 686: + C971.m(context, binder); + C972.m(context, binder); + return; + case 687: + C973.m(context, binder); + return; + case 688: + C974.m(context, binder); + return; + case 689: + C975.m(context, binder); + return; + case 690: + C976.m(context, binder); + return; + case 691: + C977.m(context, binder); + return; + case 692: + C978.m(context, binder); + return; + case 693: + C979.m(context, binder); + return; + case 694: + C980.m(context, binder); + return; + case 695: + C981.m(context, binder); + return; + case 696: + C982.m(context, binder); + return; + case 697: + C983.m(context, binder); + C984.m(context, binder); + C985.m(context, binder); + return; + case 698: + C986.m(context, binder); + return; + case 699: + C987.m(context, binder); + return; + case 700: + C988.m(context, binder); + return; + case 701: + C989.m(context, binder); + return; + case 702: + C990.m(context, binder); + return; + case 703: + C991.m(context, binder); + return; + case 704: + C992.m(context, binder); + return; + case 705: + C993.m(context, binder); + return; + case 706: + C994.m(context, binder); + return; + case 707: + C995.m(context, binder); + return; + case 708: + C996.m(context, binder); + return; + case 709: + C997.m(context, binder); + return; + case 710: + C998.m(context, binder); + return; + case 711: + C999.m(context, binder); + return; + case 712: + C1000.m(context, binder); + return; + case 713: + C1001.m(context, binder); + return; + case 714: + C1002.m(context, binder); + return; + case 715: + C1003.m(context, binder); + return; + case 716: + C1004.m(context, binder); + return; + case 717: + C1005.m(context, binder); + return; + case 718: + C1006.m(context, binder); + return; + case 719: + C1007.m(context, binder); + return; + case 720: + C1008.m(context, binder); + return; + case 721: + C1009.m(context, binder); + return; + case 722: + C1010.m(context, binder); + return; + case 723: + C1011.m(context, binder); + return; + case 724: + C1012.m(context, binder); + return; + case 725: + C1013.m(context, binder); + return; + case 726: + C1014.m(context, binder); + return; + case 727: + C1015.m(context, binder); + return; + case 728: + C577.mDebug(context, binder); + return; + case 729: + C1017.m(context, binder); + return; + case 730: + C1018.m(context, binder); + return; + case 731: + C1019.m(context, binder); + return; + case 732: + C1020.m(context, binder); + return; + case 733: + C1021.m(context, binder); + return; + case 734: + C1022.m(context, binder); + return; + case 735: + C1023.m(context, binder); + return; + case 736: + C1024.m(context, binder); + return; + case 737: + C1025.m(context, binder); + return; + case 738: + C1026.m(context, binder); + return; + case 739: + C1027.m(context, binder); + return; + case 740: + C1028.m(context, binder); + return; + case 741: + C1029.m(context, binder); + return; + case 742: + C1030.m(context, binder); + return; + case 743: + C1031.m(context, binder); + return; + case 744: + C1032.m(context, binder); + return; + case 745: + C1033.m(context, binder); + return; + case 746: + C1034.m(context, binder); + return; + case 747: + C1035.m(context, binder); + return; + case 748: + C1036.m(context, binder); + C1037.m(context, binder); + return; + case 749: + C1038.m(context, binder); + C1039.m(context, binder); + C1040.m(context, binder); + C1041.m(context, binder); + return; + case 750: + C1042.m(context, binder); + return; + case 751: + C1043.m(context, binder); + return; + case 752: + C1044.m(context, binder); + return; + case 753: + C1045.m(context, binder); + return; + case 754: + C1046.m(context, binder); + return; + case 755: + C1047.m(context, binder); + return; + case 756: + C848.mMap(context, binder); + return; + case 757: + C1049.m(context, binder); + return; + case 758: + C1050.m(context, binder); + return; + case 759: + C1051.m(context, binder); + return; + case 760: + C1052.m(context, binder); + return; + case 761: + C1053.m(context, binder); + return; + case 762: + C1054.m(context, binder); + return; + case 763: + C1055.m(context, binder); + return; + case 764: + C1056.m(context, binder); + return; + case 765: + C1057.m(context, binder); + return; + case 766: + C1058.m(context, binder); + return; + case 767: + C1059.m(context, binder); + return; + case 768: + C1060.m(context, binder); + return; + case 769: + C1061.m(context, binder); + return; + case 770: + C1062.m(context, binder); + return; + case 771: + C1063.m(context, binder); + return; + case 772: + C1064.m(context, binder); + return; + case 773: + C1065.m(context, binder); + return; + case 774: + C1066.m(context, binder); + return; + case 775: + C1067.m(context, binder); + return; + case 776: + C1068.m(context, binder); + return; + case 777: + C1069.m(context, binder); + return; + case 778: + C1070.m(context, binder); + return; + case 779: + C1071.m(context, binder); + return; + case 780: + C1072.m(context, binder); + return; + case 781: + C1073.m(context, binder); + C1074.m(context, binder); + C1075.m(context, binder); + C1076.m(context, binder); + C1077.m(context, binder); + C1078.m(context, binder); + C1079.m(context, binder); + C1080.m(context, binder); + return; + case 782: + C1081.m(context, binder); + return; + case 783: + C1082.m(context, binder); + return; + case 784: + C1083.m(context, binder); + return; + case 785: + C1084.m(context, binder); + return; + case 786: + C1085.m(context, binder); + return; + case 787: + C1086.m(context, binder); + return; + case 788: + C1087.m(context, binder); + return; + case 789: + C1088.m(context, binder); + return; + case 790: + C944.mManager(context, binder); + return; + case 791: + C1090.m(context, binder); + return; + case 792: + C1091.m(context, binder); + return; + case 793: + C1092.m(context, binder); + return; + case 794: + C1093.m(context, binder); + return; + case 795: + C1094.m(context, binder); + return; + case 796: + C1095.m(context, binder); + return; + case 797: + C1096.m(context, binder); + return; + case 798: + C1097.m(context, binder); + return; + case 799: + C1098.m(context, binder); + return; + case 800: + C1099.m(context, binder); + return; + case 801: + C1100.m(context, binder); + return; + case 802: + C1101.m(context, binder); + C1102.m(context, binder); + C1103.m(context, binder); + C1104.m(context, binder); + C1105.m(context, binder); + C1106.m(context, binder); + C1107.m(context, binder); + C1108.m(context, binder); + return; + case 803: + C1109.m(context, binder); + return; + case 804: + C1110.m(context, binder); + return; + case 805: + C1111.m(context, binder); + return; + case 806: + C1112.m(context, binder); + return; + case 807: + C1113.m(context, binder); + return; + case 808: + C1114.m(context, binder); + C1115.m(context, binder); + C1116.m(context, binder); + C1117.m(context, binder); + return; + case 809: + C1118.m(context, binder); + return; + case 810: + C1119.m(context, binder); + C1120.m(context, binder); + C1121.m(context, binder); + return; + case 811: + C1122.m(context, binder); + return; + case 812: + C1123.m(context, binder); + return; + case 813: + C1124.m(context, binder); + return; + case 814: + C1125.m(context, binder); + return; + case 815: + C1126.m(context, binder); + return; + case 816: + C1127.m(context, binder); + return; + case 817: + C1128.m(context, binder); + return; + case 818: + C1129.m(context, binder); + return; + case 819: + C1130.m(context, binder); + return; + case 820: + C1131.m(context, binder); + return; + case 821: + C1132.m(context, binder); + return; + case 822: + C1133.m(context, binder); + return; + case 823: + C1134.m(context, binder); + return; + case 824: + C1135.m(context, binder); + return; + case 825: + C1136.m(context, binder); + return; + case 826: + C1137.m(context, binder); + C1138.m(context, binder); + C1139.m(context, binder); + C1140.m(context, binder); + C1141.m(context, binder); + C1142.m(context, binder); + C1143.m(context, binder); + C1144.m(context, binder); + C1145.m(context, binder); + C1146.m(context, binder); + C1147.m(context, binder); + C1148.m(context, binder); + C1149.m(context, binder); + C1150.m(context, binder); + C1151.m(context, binder); + C1152.m(context, binder); + C1153.m(context, binder); + C1154.m(context, binder); + C1155.m(context, binder); + C1156.m(context, binder); + C1157.m(context, binder); + C1158.m(context, binder); + return; + case 827: + C1159.m(context, binder); + return; + case 828: + C457.mMap(context, binder); + return; + case 829: + C1161.m(context, binder); + C1162.m(context, binder); + C1163.m(context, binder); + C1164.m(context, binder); + C1165.m(context, binder); + C1166.m(context, binder); + C1167.m(context, binder); + C1168.m(context, binder); + C1169.m(context, binder); + C1170.m(context, binder); + C1171.m(context, binder); + C1172.m(context, binder); + C1173.m(context, binder); + C1174.m(context, binder); + C1175.m(context, binder); + C1176.m(context, binder); + C1177.m(context, binder); + C1178.m(context, binder); + C1179.m(context, binder); + C1180.m(context, binder); + C1181.m(context, binder); + C1181a.m(context, binder); + C1181b.m(context, binder); + return; + case 830: + C1184.m(context, binder); + return; + case 831: + C1185.m(context, binder); + return; + case 832: + C1186.m(context, binder); + return; + case 833: + C1187.m(context, binder); + return; + case 834: + C1188.m(context, binder); + return; + case 835: + C1189.m(context, binder); + return; + case 836: + C1190.m(context, binder); + return; + case 837: + C1191.m(context, binder); + return; + case 838: + C1192.m(context, binder); + return; + case 839: + C1193.m(context, binder); + return; + case 840: + C1194.m(context, binder); + return; + case 841: + C1195.m(context, binder); + return; + case 842: + C1196.m(context, binder); + return; + case 843: + C1197.m(context, binder); + return; + case 844: + C1198.m(context, binder); + return; + case 845: + C1199.m(context, binder); + return; + case 846: + C1200.m(context, binder); + return; + case 847: + C1201.m(context, binder); + return; + case 848: + C1202.m(context, binder); + return; + case 849: + C1203.m(context, binder); + return; + case 850: + C1204.m(context, binder); + return; + case 851: + C1205.m(context, binder); + return; + case 852: + C1206.m(context, binder); + return; + case 853: + C1207.m(context, binder); + return; + case 854: + C1208.m(context, binder); + return; + case 855: + C1209.m(context, binder); + return; + case 856: + C1210.m(context, binder); + return; + case 857: + C1211.m(context, binder); + return; + case 858: + C1212.m(context, binder); + return; + default: + return; + } + } + } + + public static void main(String[] args) { + System.out.println("passed"); + } + + static boolean doThrow = false; +} diff --git a/test/945-obsolete-native/expected.txt b/test/945-obsolete-native/expected.txt deleted file mode 100644 index 83efda144d..0000000000 --- a/test/945-obsolete-native/expected.txt +++ /dev/null @@ -1,9 +0,0 @@ -hello -Not doing anything here -goodbye -hello -transforming calling function -goodbye -Hello - Transformed -Not doing anything here -Goodbye - Transformed diff --git a/test/945-obsolete-native/info.txt b/test/945-obsolete-native/info.txt deleted file mode 100644 index c8b892cedd..0000000000 --- a/test/945-obsolete-native/info.txt +++ /dev/null @@ -1 +0,0 @@ -Tests basic obsolete method support diff --git a/test/945-obsolete-native/obsolete_native.cc b/test/945-obsolete-native/obsolete_native.cc deleted file mode 100644 index 061e7afbbc..0000000000 --- a/test/945-obsolete-native/obsolete_native.cc +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <inttypes.h> -#include <memory> -#include <stdio.h> - -#include "android-base/stringprintf.h" - -#include "android-base/stringprintf.h" -#include "base/logging.h" -#include "base/macros.h" -#include "jni.h" -#include "openjdkjvmti/jvmti.h" -#include "ScopedLocalRef.h" -#include "ti-agent/common_helper.h" -#include "ti-agent/common_load.h" - -namespace art { -namespace Test945ObsoleteNative { - -extern "C" JNIEXPORT void JNICALL Java_Main_bindTest945ObsoleteNative( - JNIEnv* env, jclass klass ATTRIBUTE_UNUSED) { - BindFunctions(jvmti_env, env, "Transform"); -} - -extern "C" JNIEXPORT void JNICALL Java_Transform_doExecute(JNIEnv* env, - jclass klass ATTRIBUTE_UNUSED, - jobject runnable) { - jclass runnable_klass = env->FindClass("java/lang/Runnable"); - DCHECK(runnable_klass != nullptr); - jmethodID run_method = env->GetMethodID(runnable_klass, "run", "()V"); - env->CallVoidMethod(runnable, run_method); -} - - -} // namespace Test945ObsoleteNative -} // namespace art diff --git a/test/945-obsolete-native/run b/test/945-obsolete-native/run deleted file mode 100755 index c6e62ae6cd..0000000000 --- a/test/945-obsolete-native/run +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# -# Copyright 2016 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -./default-run "$@" --jvmti diff --git a/test/945-obsolete-native/src/Main.java b/test/945-obsolete-native/src/Main.java deleted file mode 100644 index 5e2154e9a3..0000000000 --- a/test/945-obsolete-native/src/Main.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.util.Base64; - -public class Main { - // class Transform { - // public void sayHi(Runnable r) { - // System.out.println("Hello - Transformed"); - // doExecute(r); - // System.out.println("Goodbye - Transformed"); - // } - // - // private static native void doExecute(Runnable r); - // } - private static final byte[] CLASS_BYTES = Base64.getDecoder().decode( - "yv66vgAAADQAIgoACAASCQATABQIABUKABYAFwoABwAYCAAZBwAaBwAbAQAGPGluaXQ+AQADKClW" + - "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7" + - "KVYBAAlkb0V4ZWN1dGUBAApTb3VyY2VGaWxlAQAOVHJhbnNmb3JtLmphdmEMAAkACgcAHAwAHQAe" + - "AQATSGVsbG8gLSBUcmFuc2Zvcm1lZAcAHwwAIAAhDAAPAA4BABVHb29kYnllIC0gVHJhbnNmb3Jt" + - "ZWQBAAlUcmFuc2Zvcm0BABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291" + - "dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxu" + - "AQAVKExqYXZhL2xhbmcvU3RyaW5nOylWACAABwAIAAAAAAADAAAACQAKAAEACwAAAB0AAQABAAAA" + - "BSq3AAGxAAAAAQAMAAAABgABAAAAEQABAA0ADgABAAsAAAA5AAIAAgAAABWyAAISA7YABCu4AAWy" + - "AAISBrYABLEAAAABAAwAAAASAAQAAAATAAgAFAAMABUAFAAWAQoADwAOAAAAAQAQAAAAAgAR"); - private static final byte[] DEX_BYTES = Base64.getDecoder().decode( - "ZGV4CjAzNQB1fZcJR/opPuXacK8mIla5shH0LSg72qJYAwAAcAAAAHhWNBIAAAAAAAAAALgCAAAR" + - "AAAAcAAAAAcAAAC0AAAAAwAAANAAAAABAAAA9AAAAAUAAAD8AAAAAQAAACQBAAAUAgAARAEAAKIB" + - "AACqAQAAwQEAANYBAADjAQAA+gEAAA4CAAAkAgAAOAIAAEwCAABcAgAAXwIAAGMCAABuAgAAggIA" + - "AIcCAACQAgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAoAAAAGAAAAAAAAAAsAAAAGAAAA" + - "lAEAAAsAAAAGAAAAnAEAAAUAAQAOAAAAAAAAAAAAAAAAAAEADAAAAAAAAQAQAAAAAQACAA8AAAAC" + - "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAJAAAAAAAAAKUCAAAAAAAAAQABAAEAAACXAgAABAAAAHAQ" + - "BAAAAA4ABAACAAIAAACcAgAAFAAAAGIAAAAbAQIAAABuIAMAEABxEAEAAwBiAAAAGwEBAAAAbiAD" + - "ABAADgABAAAAAwAAAAEAAAAEAAY8aW5pdD4AFUdvb2RieWUgLSBUcmFuc2Zvcm1lZAATSGVsbG8g" + - "LSBUcmFuc2Zvcm1lZAALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEv" + - "bGFuZy9PYmplY3Q7ABRMamF2YS9sYW5nL1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7ABJM" + - "amF2YS9sYW5nL1N5c3RlbTsADlRyYW5zZm9ybS5qYXZhAAFWAAJWTAAJZG9FeGVjdXRlABJlbWl0" + - "dGVyOiBqYWNrLTQuMjUAA291dAAHcHJpbnRsbgAFc2F5SGkAEQAHDgATAQAHDoc8hwAAAAIBAICA" + - "BMQCAYoCAAIB3AIADQAAAAAAAAABAAAAAAAAAAEAAAARAAAAcAAAAAIAAAAHAAAAtAAAAAMAAAAD" + - "AAAA0AAAAAQAAAABAAAA9AAAAAUAAAAFAAAA/AAAAAYAAAABAAAAJAEAAAEgAAACAAAARAEAAAEQ" + - "AAACAAAAlAEAAAIgAAARAAAAogEAAAMgAAACAAAAlwIAAAAgAAABAAAApQIAAAAQAAABAAAAuAIA" + - "AA=="); - - public static void main(String[] args) { - bindTest945ObsoleteNative(); - doTest(new Transform()); - } - - public static void doTest(Transform t) { - t.sayHi(() -> { System.out.println("Not doing anything here"); }); - t.sayHi(() -> { - System.out.println("transforming calling function"); - doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES); - }); - t.sayHi(() -> { System.out.println("Not doing anything here"); }); - } - - // Transforms the class - private static native void doCommonClassRedefinition(Class<?> target, - byte[] classfile, - byte[] dexfile); - - private static native void bindTest945ObsoleteNative(); -} diff --git a/test/945-obsolete-native/src/Transform.java b/test/945-obsolete-native/src/Transform.java deleted file mode 100644 index 2b7cc1b3a1..0000000000 --- a/test/945-obsolete-native/src/Transform.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -class Transform { - public void sayHi(Runnable r) { - System.out.println("hello"); - doExecute(r); - System.out.println("goodbye"); - } - - private static native void doExecute(Runnable r); -} diff --git a/test/Android.bp b/test/Android.bp index 00c890a834..d3244a683a 100644 --- a/test/Android.bp +++ b/test/Android.bp @@ -274,7 +274,6 @@ art_cc_defaults { "933-misc-events/misc_events.cc", "936-search-onload/search_onload.cc", "944-transform-classloaders/classloader.cc", - "945-obsolete-native/obsolete_native.cc", ], shared_libs: [ "libbase", diff --git a/test/etc/default-build b/test/etc/default-build index 330a32e0dd..e9e388646a 100755 --- a/test/etc/default-build +++ b/test/etc/default-build @@ -60,12 +60,6 @@ else HAS_SRC_DEX2OAT_UNRESOLVED=false fi -# Allow overriding ZIP_COMPRESSION_METHOD with e.g. 'store' -ZIP_COMPRESSION_METHOD="deflate" -# Align every ZIP file made by calling $ZIPALIGN command? -WITH_ZIP_ALIGN=false -ZIP_ALIGN_BYTES="-1" - DX_FLAGS="" SKIP_DX_MERGER="false" EXPERIMENTAL="" @@ -124,17 +118,6 @@ while true; do DEFAULT_EXPERIMENT="" EXPERIMENTAL="${EXPERIMENTAL} $1" shift - elif [ "x$1" = "x--zip-compression-method" ]; then - # Allow using different zip compression method, e.g. 'store' - shift - ZIP_COMPRESSION_METHOD="$1" - shift - elif [ "x$1" = "x--zip-align" ]; then - # Align ZIP entries to some # of bytes. - shift - WITH_ZIP_ALIGN=true - ZIP_ALIGN_BYTES="$1" - shift elif expr "x$1" : "x--" >/dev/null 2>&1; then echo "unknown $0 option: $1" 1>&2 exit 1 @@ -163,26 +146,6 @@ for experiment in ${EXPERIMENTAL}; do JAVAC_ARGS="${JAVAC_ARGS} ${JAVAC_EXPERIMENTAL_ARGS[${experiment}]}" done -######################################### - -# Catch all commands to 'ZIP' and prepend extra flags. -# Optionally, zipalign results to some alignment. -function zip() { - local zip_target="$1" - local entry_src="$2" - shift 2 - - command zip --compression-method "$ZIP_COMPRESSION_METHOD" "$zip_target" "$entry_src" "$@" - - if "$WITH_ZIP_ALIGN"; then - # zipalign does not operate in-place, so write results to a temp file. - local tmp_file="$(mktemp)" - "$ZIPALIGN" -f "$ZIP_ALIGN_BYTES" "$zip_target" "$tmp_file" - # replace original zip target with our temp file. - mv "$tmp_file" "$zip_target" - fi -} - if [ -e classes.dex ]; then zip $TEST_NAME.jar classes.dex exit 0 diff --git a/test/run-test b/test/run-test index 4936039095..27c700e89e 100755 --- a/test/run-test +++ b/test/run-test @@ -90,22 +90,6 @@ fi export JACK="$JACK -g -cp $JACK_CLASSPATH" -# Zipalign is not on the PATH in some configs, auto-detect it. -if [ -z "$ZIPALIGN" ]; then - if which zipalign >/dev/null; then - ZIPALIGN="zipalign"; - else - # TODO: Add a dependency for zipalign in Android.run-test.mk - # once it doesn't depend on libandroidfw (b/35246701) - case "$OSTYPE" in - darwin*) ZIPALIGN="$ANDROID_BUILD_TOP/prebuilts/sdk/tools/darwin/bin/zipalign" ;; - linux*) ZIPALIGN="$ANDROID_BUILD_TOP/prebuilts/sdk/tools/linux/bin/zipalign" ;; - *) echo "Can't find zipalign: unknown: $OSTYPE" >&2;; - esac - fi -fi -export ZIPALIGN - info="info.txt" build="build" run="run" diff --git a/test/testrunner/testrunner.py b/test/testrunner/testrunner.py index f60a6c9f2a..81b7953f3b 100755 --- a/test/testrunner/testrunner.py +++ b/test/testrunner/testrunner.py @@ -767,7 +767,10 @@ def main(): build_targets += 'test-art-host-run-test-dependencies' if 'target' in TARGET_TYPES: build_targets += 'test-art-target-run-test-dependencies' - build_command = 'make -j' + str(n_thread) + ' ' + build_targets + build_command = 'make' + build_command += ' -j' + str(n_thread) + build_command += ' -C ' + env.ANDROID_BUILD_TOP + build_command += ' ' + build_targets if subprocess.call(build_command.split()): sys.exit(1) if user_requested_test: @@ -786,7 +789,6 @@ def main(): except SystemExit: pass except: - print "hello" print_analysis() sys.exit(1) diff --git a/test/ti-agent/common_load.cc b/test/ti-agent/common_load.cc index 351857d1d9..c5a93568c6 100644 --- a/test/ti-agent/common_load.cc +++ b/test/ti-agent/common_load.cc @@ -122,7 +122,6 @@ static AgentLib agents[] = { { "942-private-recursive", common_redefine::OnLoad, nullptr }, { "943-private-recursive-jit", common_redefine::OnLoad, nullptr }, { "944-transform-classloaders", common_redefine::OnLoad, nullptr }, - { "945-obsolete-native", common_redefine::OnLoad, nullptr }, }; static AgentLib* FindAgent(char* name) { |