From: Alex Light Date: Thu, 15 Dec 2016 00:59:05 +0000 (+0000) Subject: Revert "Basic obsolete methods support" X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=b81a9840b44480bfeacd74b8d9f51e06f295411d;p=android-x86%2Fart.git Revert "Basic obsolete methods support" This reverts commit d8936da27b792d1ca02e59c92456a1a53c7b9905. Reason for revert: Some sort of race in JIT Change-Id: Ibb4e520bb0721d6d7aa2c841a52eb5baff07740e --- diff --git a/compiler/image_writer.h b/compiler/image_writer.h index cc7df1ce2..c5374838f 100644 --- a/compiler/image_writer.h +++ b/compiler/image_writer.h @@ -27,7 +27,6 @@ #include #include -#include "art_method.h" #include "base/bit_utils.h" #include "base/dchecked_vector.h" #include "base/enums.h" diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h index c78db3eb6..ef03bb3dd 100644 --- a/runtime/art_method-inl.h +++ b/runtime/art_method-inl.h @@ -134,7 +134,8 @@ inline ArtMethod* ArtMethod::GetDexCacheResolvedMethod(uint16_t method_index, // NOTE: Unchecked, i.e. not throwing AIOOB. We don't even know the length here // without accessing the DexCache and we don't want to do that in release build. DCHECK_LT(method_index, - GetInterfaceMethodIfProxy(pointer_size)->GetDexCache()->NumResolvedMethods()); + GetInterfaceMethodIfProxy(pointer_size)->GetDeclaringClass() + ->GetDexCache()->NumResolvedMethods()); ArtMethod* method = mirror::DexCache::GetElementPtrSize(GetDexCacheResolvedMethods(pointer_size), method_index, pointer_size); @@ -153,7 +154,8 @@ inline void ArtMethod::SetDexCacheResolvedMethod(uint16_t method_index, // NOTE: Unchecked, i.e. not throwing AIOOB. We don't even know the length here // without accessing the DexCache and we don't want to do that in release build. DCHECK_LT(method_index, - GetInterfaceMethodIfProxy(pointer_size)->GetDexCache()->NumResolvedMethods()); + GetInterfaceMethodIfProxy(pointer_size)->GetDeclaringClass() + ->GetDexCache()->NumResolvedMethods()); DCHECK(new_method == nullptr || new_method->GetDeclaringClass() != nullptr); mirror::DexCache::SetElementPtrSize(GetDexCacheResolvedMethods(pointer_size), method_index, @@ -184,7 +186,8 @@ template inline mirror::Class* ArtMethod::GetDexCacheResolvedType(dex::TypeIndex type_index, PointerSize pointer_size) { if (kWithCheck) { - mirror::DexCache* dex_cache = GetInterfaceMethodIfProxy(pointer_size)->GetDexCache(); + mirror::DexCache* dex_cache = + GetInterfaceMethodIfProxy(pointer_size)->GetDeclaringClass()->GetDexCache(); if (UNLIKELY(type_index.index_ >= dex_cache->NumResolvedTypes())) { ThrowArrayIndexOutOfBoundsException(type_index.index_, dex_cache->NumResolvedTypes()); return nullptr; @@ -330,7 +333,7 @@ inline const char* ArtMethod::GetName() { } inline const DexFile::CodeItem* ArtMethod::GetCodeItem() { - return GetDexFile()->GetCodeItem(GetCodeItemOffset()); + return GetDeclaringClass()->GetDexFile().GetCodeItem(GetCodeItemOffset()); } inline bool ArtMethod::IsResolvedTypeIdx(dex::TypeIndex type_idx, PointerSize pointer_size) { @@ -395,20 +398,11 @@ inline mirror::ClassLoader* ArtMethod::GetClassLoader() { } inline mirror::DexCache* ArtMethod::GetDexCache() { - if (LIKELY(!IsObsolete())) { - return GetDeclaringClass()->GetDexCache(); - } else { - DCHECK(!IsProxyMethod()); + DCHECK(!IsProxyMethod()); + if (UNLIKELY(IsObsolete())) { return GetObsoleteDexCache(); - } -} - -inline mirror::StringDexCacheType* ArtMethod::GetDexCacheStrings() { - if (LIKELY(!IsObsolete())) { - return GetDeclaringClass()->GetDexCacheStrings(); } else { - DCHECK(!IsProxyMethod()); - return GetObsoleteDexCache()->GetStrings(); + return GetDeclaringClass()->GetDexCache(); } } diff --git a/runtime/art_method.h b/runtime/art_method.h index 83ed1db7e..3bc6f5d4f 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -27,7 +27,6 @@ #include "invoke_type.h" #include "method_reference.h" #include "modifiers.h" -#include "mirror/dex_cache.h" #include "mirror/object.h" #include "obj_ptr.h" #include "read_barrier_option.h" @@ -221,12 +220,6 @@ class ArtMethod FINAL { return !IsIntrinsic() && (GetAccessFlags() & kAccObsoleteMethod) != 0; } - void SetIsObsolete() { - // TODO We should really support redefining intrinsic if possible. - DCHECK(!IsIntrinsic()); - SetAccessFlags(GetAccessFlags() | kAccObsoleteMethod); - } - template bool IsNative() { return (GetAccessFlags() & kAccNative) != 0; @@ -333,10 +326,6 @@ class ArtMethod FINAL { ALWAYS_INLINE ArtMethod* GetDexCacheResolvedMethod(uint16_t method_index, PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_); - - ALWAYS_INLINE mirror::StringDexCacheType* GetDexCacheStrings() - REQUIRES_SHARED(Locks::mutator_lock_); - ALWAYS_INLINE void SetDexCacheResolvedMethod(uint16_t method_index, ArtMethod* new_method, PointerSize pointer_size) diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index 14c9c2135..f6eeffca7 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -563,7 +563,7 @@ inline ArtMethod* FindMethodFromCode(uint32_t method_idx, HandleWrapperObjPtr h_this(hs2.NewHandleWrapper(this_object)); Handle h_referring_class(hs2.NewHandle(referrer->GetDeclaringClass())); const dex::TypeIndex method_type_idx = - referrer->GetDexFile()->GetMethodId(method_idx).class_idx_; + h_referring_class->GetDexFile().GetMethodId(method_idx).class_idx_; mirror::Class* method_reference_class = class_linker->ResolveType(method_type_idx, referrer); if (UNLIKELY(method_reference_class == nullptr)) { // Bad type idx. @@ -673,7 +673,8 @@ inline ArtField* FindFieldFast(uint32_t field_idx, ArtMethod* referrer, FindFiel size_t expected_size) { ScopedAssertNoThreadSuspension ants(__FUNCTION__); ArtField* resolved_field = - referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize); + referrer->GetDeclaringClass()->GetDexCache()->GetResolvedField(field_idx, + kRuntimePointerSize); if (UNLIKELY(resolved_field == nullptr)) { return nullptr; } @@ -732,7 +733,7 @@ inline ArtMethod* FindMethodFast(uint32_t method_idx, } mirror::Class* referring_class = referrer->GetDeclaringClass(); ArtMethod* resolved_method = - referrer->GetDexCache()->GetResolvedMethod(method_idx, kRuntimePointerSize); + referring_class->GetDexCache()->GetResolvedMethod(method_idx, kRuntimePointerSize); if (UNLIKELY(resolved_method == nullptr)) { return nullptr; } @@ -758,9 +759,9 @@ inline ArtMethod* FindMethodFast(uint32_t method_idx, } else if (type == kSuper) { // TODO This lookup is rather slow. dex::TypeIndex method_type_idx = - referrer->GetDexFile()->GetMethodId(method_idx).class_idx_; + referring_class->GetDexFile().GetMethodId(method_idx).class_idx_; mirror::Class* method_reference_class = - referrer->GetDexCache()->GetResolvedType(method_type_idx); + referring_class->GetDexCache()->GetResolvedType(method_type_idx); if (method_reference_class == nullptr) { // Need to do full type resolution... return nullptr; diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc index 3956af4c9..870d1ae9b 100644 --- a/runtime/instrumentation.cc +++ b/runtime/instrumentation.cc @@ -557,10 +557,8 @@ void Instrumentation::RemoveListener(InstrumentationListener* listener, uint32_t } Instrumentation::InstrumentationLevel Instrumentation::GetCurrentInstrumentationLevel() const { - if (interpreter_stubs_installed_ && interpret_only_) { + if (interpreter_stubs_installed_) { return InstrumentationLevel::kInstrumentWithInterpreter; - } else if (interpreter_stubs_installed_) { - return InstrumentationLevel::kInstrumentWithInterpreterAndJit; } else if (entry_exit_stubs_installed_) { return InstrumentationLevel::kInstrumentWithInstrumentationStubs; } else { @@ -568,14 +566,6 @@ Instrumentation::InstrumentationLevel Instrumentation::GetCurrentInstrumentation } } -bool Instrumentation::RequiresInstrumentationInstallation(InstrumentationLevel new_level) const { - // We need to reinstall instrumentation if we go to a different level or if the current level is - // kInstrumentWithInterpreterAndJit since that level does not force all code to always use the - // interpreter and so we might have started running optimized code again. - return new_level == InstrumentationLevel::kInstrumentWithInterpreterAndJit || - GetCurrentInstrumentationLevel() != new_level; -} - void Instrumentation::ConfigureStubs(const char* key, InstrumentationLevel desired_level) { // Store the instrumentation level for this key or remove it. if (desired_level == InstrumentationLevel::kInstrumentNothing) { @@ -595,7 +585,8 @@ void Instrumentation::ConfigureStubs(const char* key, InstrumentationLevel desir interpret_only_ = (requested_level == InstrumentationLevel::kInstrumentWithInterpreter) || forced_interpret_only_; - if (!RequiresInstrumentationInstallation(requested_level)) { + InstrumentationLevel current_level = GetCurrentInstrumentationLevel(); + if (requested_level == current_level) { // We're already set. return; } @@ -604,7 +595,7 @@ void Instrumentation::ConfigureStubs(const char* key, InstrumentationLevel desir Locks::mutator_lock_->AssertExclusiveHeld(self); Locks::thread_list_lock_->AssertNotHeld(self); if (requested_level > InstrumentationLevel::kInstrumentNothing) { - if (requested_level >= InstrumentationLevel::kInstrumentWithInterpreterAndJit) { + if (requested_level == InstrumentationLevel::kInstrumentWithInterpreter) { interpreter_stubs_installed_ = true; entry_exit_stubs_installed_ = true; } else { @@ -851,8 +842,7 @@ void Instrumentation::EnableDeoptimization() { void Instrumentation::DisableDeoptimization(const char* key) { CHECK_EQ(deoptimization_enabled_, true); // If we deoptimized everything, undo it. - InstrumentationLevel level = GetCurrentInstrumentationLevel(); - if (level == InstrumentationLevel::kInstrumentWithInterpreter) { + if (interpreter_stubs_installed_) { UndeoptimizeEverything(key); } // Undeoptimized selected methods. @@ -879,14 +869,6 @@ bool Instrumentation::ShouldNotifyMethodEnterExitEvents() const { return !deoptimization_enabled_ && !interpreter_stubs_installed_; } -// TODO we don't check deoptimization_enabled_ because currently there isn't really any support for -// multiple users of instrumentation. Since this is just a temporary state anyway pending work to -// ensure that the current_method doesn't get kept across suspend points this should be okay. -// TODO Remove once b/33630159 is resolved. -void Instrumentation::ReJitEverything(const char* key) { - ConfigureStubs(key, InstrumentationLevel::kInstrumentWithInterpreterAndJit); -} - void Instrumentation::DeoptimizeEverything(const char* key) { CHECK(deoptimization_enabled_); ConfigureStubs(key, InstrumentationLevel::kInstrumentWithInterpreter); diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h index 872efac6a..1e5fcf2c0 100644 --- a/runtime/instrumentation.h +++ b/runtime/instrumentation.h @@ -133,9 +133,6 @@ class Instrumentation { enum class InstrumentationLevel { kInstrumentNothing, // execute without instrumentation kInstrumentWithInstrumentationStubs, // execute with instrumentation entry/exit stubs - kInstrumentWithInterpreterAndJit, // execute with interpreter initially and later the JIT - // (if it is enabled). This level is special in that it - // always requires re-instrumentation. kInstrumentWithInterpreter // execute with interpreter }; @@ -166,13 +163,6 @@ class Instrumentation { } bool ShouldNotifyMethodEnterExitEvents() const REQUIRES_SHARED(Locks::mutator_lock_); - // Executes everything with the interpreter/jit (if available). - void ReJitEverything(const char* key) - REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_) - REQUIRES(!Locks::thread_list_lock_, - !Locks::classlinker_classes_lock_, - !deoptimized_methods_lock_); - // Executes everything with interpreter. void DeoptimizeEverything(const char* key) REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_) @@ -445,10 +435,6 @@ class Instrumentation { private: InstrumentationLevel GetCurrentInstrumentationLevel() const; - // Returns true if moving to the given instrumentation level requires the installation of stubs. - // False otherwise. - bool RequiresInstrumentationInstallation(InstrumentationLevel new_level) const; - // Does the job of installing or removing instrumentation code within methods. // In order to support multiple clients using instrumentation at the same time, // the caller must pass a unique key (a string) identifying it so we remind which diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index 02a99e76d..c9a5b44c5 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -249,16 +249,17 @@ static inline ObjPtr ResolveString(Thread* self, } } ArtMethod* method = shadow_frame.GetMethod(); + ObjPtr declaring_class = method->GetDeclaringClass(); // MethodVerifier refuses methods with string_idx out of bounds. DCHECK_LT(string_idx.index_ % mirror::DexCache::kDexCacheStringCacheSize, - method->GetDexFile()->NumStringIds()); + declaring_class->GetDexFile().NumStringIds()); ObjPtr string_ptr = - mirror::StringDexCachePair::Lookup(method->GetDexCacheStrings(), + mirror::StringDexCachePair::Lookup(declaring_class->GetDexCacheStrings(), string_idx.index_, mirror::DexCache::kDexCacheStringCacheSize).Read(); if (UNLIKELY(string_ptr == nullptr)) { StackHandleScope<1> hs(self); - Handle dex_cache(hs.NewHandle(method->GetDexCache())); + Handle dex_cache(hs.NewHandle(declaring_class->GetDexCache())); string_ptr = Runtime::Current()->GetClassLinker()->ResolveString(*method->GetDexFile(), string_idx, dex_cache); diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc index 38c4728ea..93f50ad2b 100644 --- a/runtime/jit/jit_code_cache.cc +++ b/runtime/jit/jit_code_cache.cc @@ -624,38 +624,6 @@ size_t JitCodeCache::CodeCacheSize() { return CodeCacheSizeLocked(); } -// This invalidates old_method. Once this function returns one can no longer use old_method to -// execute code unless it is fixed up. This fixup will happen later in the process of installing a -// class redefinition. -// TODO We should add some info to ArtMethod to note that 'old_method' has been invalidated and -// shouldn't be used since it is no longer logically in the jit code cache. -// TODO We should add DCHECKS that validate that the JIT is paused when this method is entered. -void JitCodeCache::MoveObsoleteMethod(ArtMethod* old_method, ArtMethod* new_method) { - MutexLock mu(Thread::Current(), lock_); - // Update ProfilingInfo to the new one. - if (old_method->GetProfilingInfo(kRuntimePointerSize) != nullptr) { - DCHECK_EQ(old_method->GetProfilingInfo(kRuntimePointerSize)->GetMethod(), old_method); - ProfilingInfo* info = old_method->GetProfilingInfo(kRuntimePointerSize); - // Since the JIT should be paused and all threads suspended by the time this is called these - // checks should always pass. - DCHECK(!info->IsInUseByCompiler()); - new_method->SetProfilingInfo(info); - info->method_ = new_method; - } - // Update method_code_map_ to point to the new method. - for (auto& it : method_code_map_) { - if (it.second == old_method) { - it.second = new_method; - } - } - // Update osr_code_map_ to point to the new method. - auto code_map = osr_code_map_.find(old_method); - if (code_map != osr_code_map_.end()) { - osr_code_map_.Put(new_method, code_map->second); - osr_code_map_.erase(old_method); - } -} - size_t JitCodeCache::CodeCacheSizeLocked() { return used_memory_for_code_; } diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h index 5bfe66180..30e2efbac 100644 --- a/runtime/jit/jit_code_cache.h +++ b/runtime/jit/jit_code_cache.h @@ -217,11 +217,6 @@ class JitCodeCache { void DisallowInlineCacheAccess() REQUIRES(!lock_); void BroadcastForInlineCacheAccess() REQUIRES(!lock_); - // Notify the code cache that the method at the pointer 'old_method' is being moved to the pointer - // 'new_method' since it is being made obsolete. - void MoveObsoleteMethod(ArtMethod* old_method, ArtMethod* new_method) - REQUIRES(!lock_) REQUIRES(Locks::mutator_lock_); - private: // Take ownership of maps. JitCodeCache(MemMap* code_map, diff --git a/runtime/jit/profiling_info.h b/runtime/jit/profiling_info.h index 9fbf2e3af..9902bb584 100644 --- a/runtime/jit/profiling_info.h +++ b/runtime/jit/profiling_info.h @@ -128,9 +128,7 @@ class ProfilingInfo { const uint32_t number_of_inline_caches_; // Method this profiling info is for. - // Not 'const' as JVMTI introduces obsolete methods that we implement by creating new ArtMethods. - // See JitCodeCache::MoveObsoleteMethod. - ArtMethod* method_; + ArtMethod* const method_; // Whether the ArtMethod is currently being compiled. This flag // is implicitly guarded by the JIT code cache lock. diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h index 6f88cc5df..ec265e5ab 100644 --- a/runtime/mirror/dex_cache.h +++ b/runtime/mirror/dex_cache.h @@ -19,6 +19,7 @@ #include "array.h" #include "art_field.h" +#include "art_method.h" #include "class.h" #include "dex_file_types.h" #include "object.h" @@ -26,7 +27,6 @@ namespace art { -class ArtMethod; struct DexCacheOffsets; class DexFile; class ImageWriter; diff --git a/runtime/openjdkjvmti/ti_redefine.cc b/runtime/openjdkjvmti/ti_redefine.cc index 429409a50..d0349b987 100644 --- a/runtime/openjdkjvmti/ti_redefine.cc +++ b/runtime/openjdkjvmti/ti_redefine.cc @@ -38,8 +38,6 @@ #include "events-inl.h" #include "gc/allocation_listener.h" #include "instrumentation.h" -#include "jit/jit.h" -#include "jit/jit_code_cache.h" #include "jni_env_ext-inl.h" #include "jvmti_allocator.h" #include "mirror/class.h" @@ -51,142 +49,6 @@ namespace openjdkjvmti { -// This visitor walks thread stacks and allocates and sets up the obsolete methods. It also does -// some basic sanity checks that the obsolete method is sane. -class ObsoleteMethodStackVisitor : public art::StackVisitor { - protected: - ObsoleteMethodStackVisitor( - art::Thread* thread, - art::LinearAlloc* allocator, - const std::unordered_set& obsoleted_methods, - /*out*/std::unordered_map* obsolete_maps, - /*out*/bool* success, - /*out*/std::string* error_msg) - : StackVisitor(thread, - /*context*/nullptr, - StackVisitor::StackWalkKind::kIncludeInlinedFrames), - allocator_(allocator), - obsoleted_methods_(obsoleted_methods), - obsolete_maps_(obsolete_maps), - success_(success), - is_runtime_frame_(false), - error_msg_(error_msg) {} - - ~ObsoleteMethodStackVisitor() OVERRIDE {} - - public: - // Returns true if we successfully installed obsolete methods on this thread, filling - // obsolete_maps_ with the translations if needed. Returns false and fills error_msg_ if we fail. - // The stack is cleaned up when we fail. - static bool UpdateObsoleteFrames( - art::Thread* thread, - art::LinearAlloc* allocator, - const std::unordered_set& obsoleted_methods, - /*out*/std::unordered_map* obsolete_maps, - /*out*/std::string* error_msg) REQUIRES(art::Locks::mutator_lock_) { - bool success = true; - ObsoleteMethodStackVisitor visitor(thread, - allocator, - obsoleted_methods, - obsolete_maps, - &success, - error_msg); - visitor.WalkStack(); - if (!success) { - RestoreFrames(thread, *obsolete_maps); - return false; - } else { - return true; - } - } - - static void RestoreFrames( - art::Thread* thread ATTRIBUTE_UNUSED, - const std::unordered_map& obsolete_maps ATTRIBUTE_UNUSED) - REQUIRES(art::Locks::mutator_lock_) { - LOG(FATAL) << "Restoring stack frames is not yet supported."; - } - - bool VisitFrame() OVERRIDE REQUIRES(art::Locks::mutator_lock_) { - art::ArtMethod* old_method = GetMethod(); - // TODO REMOVE once either current_method doesn't stick around through suspend points or deopt - // works through runtime methods. - bool prev_was_runtime_frame_ = is_runtime_frame_; - is_runtime_frame_ = old_method->IsRuntimeMethod(); - if (obsoleted_methods_.find(old_method) != obsoleted_methods_.end()) { - // This works since when we deoptimize we set shadow frames for all frames until a - // native/runtime transition and for those set the return PC to a function that will complete - // the deoptimization. This does leave us with the unfortunate side-effect that frames just - // below runtime frames cannot be deoptimized at the moment. - // TODO REMOVE once either current_method doesn't stick around through suspend points or deopt - // works through runtime methods. - // TODO b/33616143 - if (!IsShadowFrame() && prev_was_runtime_frame_) { - *error_msg_ = art::StringPrintf("Deoptimization failed due to runtime method in stack."); - *success_ = false; - return false; - } - // We cannot ensure that the right dex file is used in inlined frames so we don't support - // redefining them. - DCHECK(!IsInInlinedFrame()) << "Inlined frames are not supported when using redefinition"; - // TODO We should really support intrinsic obsolete methods. - // TODO We should really support redefining intrinsics. - // We don't support intrinsics so check for them here. - DCHECK(!old_method->IsIntrinsic()); - art::ArtMethod* new_obsolete_method = nullptr; - auto obsolete_method_pair = obsolete_maps_->find(old_method); - if (obsolete_method_pair == obsolete_maps_->end()) { - // Create a new Obsolete Method and put it in the list. - art::Runtime* runtime = art::Runtime::Current(); - art::ClassLinker* cl = runtime->GetClassLinker(); - auto ptr_size = cl->GetImagePointerSize(); - const size_t method_size = art::ArtMethod::Size(ptr_size); - auto* method_storage = allocator_->Alloc(GetThread(), method_size); - if (method_storage == nullptr) { - *success_ = false; - *error_msg_ = art::StringPrintf("Unable to allocate storage for obsolete version of '%s'", - old_method->PrettyMethod().c_str()); - return false; - } - new_obsolete_method = new (method_storage) art::ArtMethod(); - new_obsolete_method->CopyFrom(old_method, ptr_size); - new_obsolete_method->SetIsObsolete(); - obsolete_maps_->insert({old_method, new_obsolete_method}); - // Update JIT Data structures to point to the new method. - art::jit::Jit* jit = art::Runtime::Current()->GetJit(); - if (jit != nullptr && jit->GetCodeCache()->ContainsMethod(old_method)) { - // Notify the JIT we are making this obsolete method. It will update it's maps and change - // entrypoint etc over. - jit->GetCodeCache()->MoveObsoleteMethod(old_method, new_obsolete_method); - } - DCHECK_EQ(new_obsolete_method->GetDeclaringClass(), old_method->GetDeclaringClass()); - } else { - new_obsolete_method = obsolete_method_pair->second; - } - DCHECK(new_obsolete_method != nullptr); - SetMethod(new_obsolete_method); - } - *success_ = true; - return true; - } - - private: - // The linear allocator we should use to make new methods. - art::LinearAlloc* allocator_; - // The set of all methods which could be obsoleted. - const std::unordered_set& obsoleted_methods_; - // A map from the original to the newly allocated obsolete method for frames on this thread. The - // values in this map must be added to the obsolete_methods_ (and obsolete_dex_caches_) fields of - // the redefined classes ClassExt by the caller. - std::unordered_map* obsolete_maps_; - bool* success_; - // TODO REMOVE once either current_method doesn't stick around through suspend points or deopt - // works through runtime methods. - bool is_runtime_frame_; - std::string* error_msg_; -}; - - // Moves dex data to an anonymous, read-only mmap'd region. std::unique_ptr Redefiner::MoveDataToMemMap(const std::string& original_location, jint data_len, @@ -210,8 +72,6 @@ std::unique_ptr Redefiner::MoveDataToMemMap(const std::string& orig return map; } -// TODO This should handle doing multiple classes at once so we need to do less cleanup when things -// go wrong. jvmtiError Redefiner::RedefineClass(ArtJvmTiEnv* env, art::Runtime* runtime, art::Thread* self, @@ -252,8 +112,6 @@ jvmtiError Redefiner::RedefineClass(ArtJvmTiEnv* env, *error_msg = os.str(); return ERR(INVALID_CLASS_FORMAT); } - // Stop JIT for the duration of this redefine. - art::jit::ScopedJitSuspend suspend_jit; // Get shared mutator lock. art::ScopedObjectAccess soa(self); art::StackHandleScope<1> hs(self); @@ -434,109 +292,6 @@ bool Redefiner::FinishRemainingAllocations( return true; } -struct CallbackCtx { - Redefiner* const r; - art::LinearAlloc* allocator; - std::unordered_map obsolete_map; - std::unordered_set obsolete_methods; - bool success; - std::string* error_msg; - - CallbackCtx(Redefiner* self, art::LinearAlloc* alloc, std::string* error) - : r(self), allocator(alloc), success(true), error_msg(error) {} -}; - -void DoRestoreObsoleteMethodsCallback(art::Thread* t, void* vdata) NO_THREAD_SAFETY_ANALYSIS { - CallbackCtx* data = reinterpret_cast(vdata); - ObsoleteMethodStackVisitor::RestoreFrames(t, data->obsolete_map); -} - -void DoAllocateObsoleteMethodsCallback(art::Thread* t, void* vdata) NO_THREAD_SAFETY_ANALYSIS { - CallbackCtx* data = reinterpret_cast(vdata); - if (data->success) { - // Don't do anything if we already failed once. - data->success = ObsoleteMethodStackVisitor::UpdateObsoleteFrames(t, - data->allocator, - data->obsolete_methods, - &data->obsolete_map, - data->error_msg); - } -} - -void Redefiner::AddAllDeclaredMethods( - art::mirror::Class* art_klass, - art::PointerSize ptr_size, - /*out*/std::unordered_set* declared_methods) { - for (auto& m : art_klass->GetDeclaredMethods(ptr_size)) { - declared_methods->insert(&m); - } -} - -bool Redefiner::AllocateObsoleteMethods(art::mirror::Class* art_klass) { - art::ScopedAssertNoThreadSuspension ns("No thread suspension during thread stack walking"); - art::mirror::ClassExt* ext = art_klass->GetExtData(); - CHECK(ext->GetObsoleteMethods() != nullptr); - CallbackCtx ctx(this, art_klass->GetClassLoader()->GetAllocator(), error_msg_); - AddAllDeclaredMethods(art_klass, art::kRuntimePointerSize, &ctx.obsolete_methods); - for (art::ArtMethod* old_method : ctx.obsolete_methods) { - if (old_method->IsIntrinsic()) { - *error_msg_ = art::StringPrintf("Method '%s' is intrinsic and cannot be made obsolete!", - old_method->PrettyMethod().c_str()); - return false; - } - } - { - art::MutexLock mu(self_, *art::Locks::thread_list_lock_); - art::ThreadList* list = art::Runtime::Current()->GetThreadList(); - list->ForEach(DoAllocateObsoleteMethodsCallback, static_cast(&ctx)); - if (!ctx.success) { - list->ForEach(DoRestoreObsoleteMethodsCallback, static_cast(&ctx)); - return false; - } - } - FillObsoleteMethodMap(art_klass, ctx.obsolete_map); - return true; -} - -void Redefiner::FillObsoleteMethodMap( - art::mirror::Class* art_klass, - const std::unordered_map& obsoletes) { - int32_t index = 0; - art::mirror::ClassExt* ext_data = art_klass->GetExtData(); - art::mirror::PointerArray* obsolete_methods = ext_data->GetObsoleteMethods(); - art::mirror::ObjectArray* obsolete_dex_caches = - ext_data->GetObsoleteDexCaches(); - int32_t num_method_slots = obsolete_methods->GetLength(); - // Find the first empty index. - for (; index < num_method_slots; index++) { - if (obsolete_methods->GetElementPtrSize( - index, art::kRuntimePointerSize) == nullptr) { - break; - } - } - // Make sure we have enough space. - CHECK_GT(num_method_slots, static_cast(obsoletes.size() + index)); - CHECK(obsolete_dex_caches->Get(index) == nullptr); - // Fill in the map. - for (auto& obs : obsoletes) { - obsolete_methods->SetElementPtrSize(index, obs.second, art::kRuntimePointerSize); - obsolete_dex_caches->Set(index, art_klass->GetDexCache()); - index++; - } -} - -// TODO It should be possible to only deoptimize the specific obsolete methods. -// TODO ReJitEverything can (sort of) fail. In certain cases it will skip deoptimizing some frames. -// If one of these frames is an obsolete method we have a problem. b/33616143 -// TODO This shouldn't be necessary once we can ensure that the current method is not kept in -// registers across suspend points. -// TODO Pending b/33630159 -void Redefiner::EnsureObsoleteMethodsAreDeoptimized() { - art::ScopedAssertNoThreadSuspension nts("Deoptimizing everything!"); - art::instrumentation::Instrumentation* i = runtime_->GetInstrumentation(); - i->ReJitEverything("libOpenJkdJvmti - Class Redefinition"); -} - jvmtiError Redefiner::Run() { art::StackHandleScope<5> hs(self_); // TODO We might want to have a global lock (or one based on the class being redefined at least) @@ -586,8 +341,7 @@ jvmtiError Redefiner::Run() { art::ObjPtr original_dex_file_cookie(nullptr); if (!UpdateJavaDexFile(java_dex_file.Get(), new_dex_file_cookie.Get(), - &original_dex_file_cookie) || - !AllocateObsoleteMethods(art_class.Get())) { + &original_dex_file_cookie)) { // Release suspendAll runtime_->GetThreadList()->ResumeAll(); // Get back shared mutator lock as expected for return. @@ -603,20 +357,18 @@ jvmtiError Redefiner::Run() { self_->TransitionFromSuspendedToRunnable(); return result_; } - // Ensure that obsolete methods are deoptimized. This is needed since optimized methods may have - // pointers to their ArtMethod's stashed in registers that they then use to attempt to hit the - // DexCache. - // TODO This can fail (leave some methods optimized) near runtime methods (including - // quick-to-interpreter transition function). - // TODO Mingyao@ suggested we could maybe just do a retry loop instead of fixing the above. - // TODO We probably don't need this at all once we have a way to ensure that the - // current_art_method is never stashed in a (physical) register by the JIT and lost to the - // stack-walker. - EnsureObsoleteMethodsAreDeoptimized(); - // TODO Verify the new Class. - // TODO Failure then undo updates to class - // TODO Shrink the obsolete method maps if possible? - // TODO find appropriate class loader. + // Update the ClassObjects Keep the old DexCache (and other stuff) around so we can restore + // functions/fields. + // Verify the new Class. + // Failure then undo updates to class + // Do stack walks and allocate obsolete methods + // Shrink the obsolete method maps if possible? + // TODO find appropriate class loader. Allocate new dex files array. Pause all java treads. + // Replace dex files array. Do stack scan + allocate obsoletes. Remove array if possible. + // TODO We might want to ensure that all threads are stopped for this! + // AddDexToClassPath(); + // TODO + // Release suspendAll // TODO Put this into a scoped thing. runtime_->GetThreadList()->ResumeAll(); // Get back shared mutator lock as expected for return. @@ -669,23 +421,19 @@ bool Redefiner::UpdateClass(art::ObjPtr mclass, } const art::DexFile::ProtoId* proto_id = dex_file_->FindProtoId(method_return_idx, new_type_list); - // TODO Return false, cleanup. CHECK(proto_id != nullptr || old_type_list == nullptr); + // TODO Return false, cleanup. const art::DexFile::MethodId* method_id = dex_file_->FindMethodId(declaring_class_id, *new_name_id, *proto_id); - // TODO Return false, cleanup. CHECK(method_id != nullptr); + // TODO Return false, cleanup. uint32_t dex_method_idx = dex_file_->GetIndexForMethodId(*method_id); method.SetDexMethodIndex(dex_method_idx); linker->SetEntryPointsToInterpreter(&method); method.SetCodeItemOffset(dex_file_->FindCodeItemOffset(*class_def, dex_method_idx)); method.SetDexCacheResolvedMethods(new_dex_cache->GetResolvedMethods(), image_pointer_size); method.SetDexCacheResolvedTypes(new_dex_cache->GetResolvedTypes(), image_pointer_size); - if (!method.IsNative()) { - // Reset profiling info. - method.SetProfilingInfo(nullptr); - } } // Update the class fields. // Need to update class last since the ArtMethod gets its DexFile from the class (which is needed diff --git a/runtime/openjdkjvmti/ti_redefine.h b/runtime/openjdkjvmti/ti_redefine.h index 2e3df0c9f..c819acd5a 100644 --- a/runtime/openjdkjvmti/ti_redefine.h +++ b/runtime/openjdkjvmti/ti_redefine.h @@ -64,8 +64,6 @@ namespace openjdkjvmti { // Class that can redefine a single class's methods. -// TODO We should really make this be driven by an outside class so we can do multiple classes at -// the same time and have less required cleanup. class Redefiner { public: // Redefine the given class with the given dex data. Note this function does not take ownership of @@ -126,15 +124,6 @@ class Redefiner { // in the future. For now we will just take the memory hit. bool EnsureClassAllocationsFinished() REQUIRES_SHARED(art::Locks::mutator_lock_); - // Ensure that obsolete methods are deoptimized. This is needed since optimized methods may have - // pointers to their ArtMethods stashed in registers that they then use to attempt to hit the - // DexCache. - // TODO Make this fallible - void EnsureObsoleteMethodsAreDeoptimized() - REQUIRES(art::Locks::mutator_lock_) - REQUIRES(!art::Locks::thread_list_lock_, - !art::Locks::classlinker_classes_lock_); - art::mirror::ClassLoader* GetClassLoader() REQUIRES_SHARED(art::Locks::mutator_lock_); // This finds the java.lang.DexFile we will add the native DexFile to as part of the classpath. @@ -173,17 +162,6 @@ class Redefiner { bool UpdateClass(art::ObjPtr mclass, art::ObjPtr new_dex_cache) REQUIRES(art::Locks::mutator_lock_); - - bool AllocateObsoleteMethods(art::mirror::Class* art_klass) REQUIRES(art::Locks::mutator_lock_); - - void AddAllDeclaredMethods(art::mirror::Class* art_klass, - art::PointerSize ptr_size, - /*out*/std::unordered_set* declared_methods) - REQUIRES_SHARED(art::Locks::mutator_lock_); - - void FillObsoleteMethodMap(art::mirror::Class* art_klass, - const std::unordered_map& obsoletes) - REQUIRES(art::Locks::mutator_lock_); }; } // namespace openjdkjvmti diff --git a/runtime/stack.cc b/runtime/stack.cc index 726ca2f30..792da88a6 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -614,23 +614,6 @@ std::string StackVisitor::DescribeLocation() const { return result; } -static instrumentation::InstrumentationStackFrame& GetInstrumentationStackFrame(Thread* thread, - uint32_t depth) { - CHECK_LT(depth, thread->GetInstrumentationStack()->size()); - return thread->GetInstrumentationStack()->at(depth); -} - -void StackVisitor::SetMethod(ArtMethod* method) { - DCHECK(GetMethod() != nullptr); - if (cur_shadow_frame_ != nullptr) { - cur_shadow_frame_->SetMethod(method); - } else { - DCHECK(cur_quick_frame_ != nullptr); - CHECK(!IsInInlinedFrame()) << "We do not support setting inlined method's ArtMethod!"; - *cur_quick_frame_ = method; - } -} - static void AssertPcIsWithinQuickCode(ArtMethod* method, uintptr_t pc) REQUIRES_SHARED(Locks::mutator_lock_) { if (method->IsNative() || method->IsRuntimeMethod() || method->IsProxyMethod()) { @@ -792,8 +775,8 @@ template void StackVisitor::WalkStack(bool include_transitions) { DCHECK(thread_ == Thread::Current() || thread_->IsSuspended()); CHECK_EQ(cur_depth_, 0U); - size_t instrumentation_stack_depth = 0; bool exit_stubs_installed = Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled(); + uint32_t instrumentation_stack_depth = 0; size_t inlined_frames_count = 0; for (const ManagedStack* current_fragment = thread_->GetManagedStack(); @@ -856,7 +839,7 @@ void StackVisitor::WalkStack(bool include_transitions) { if (reinterpret_cast(GetQuickInstrumentationExitPc()) == return_pc) { CHECK_LT(instrumentation_stack_depth, thread_->GetInstrumentationStack()->size()); const instrumentation::InstrumentationStackFrame& instrumentation_frame = - GetInstrumentationStackFrame(thread_, instrumentation_stack_depth); + thread_->GetInstrumentationStack()->at(instrumentation_stack_depth); instrumentation_stack_depth++; if (GetMethod() == Runtime::Current()->GetCalleeSaveMethod(Runtime::kSaveAllCalleeSaves)) { diff --git a/runtime/stack.h b/runtime/stack.h index 9dceb2931..b1e99e5fd 100644 --- a/runtime/stack.h +++ b/runtime/stack.h @@ -327,12 +327,6 @@ class ShadowFrame { } } - void SetMethod(ArtMethod* method) REQUIRES(Locks::mutator_lock_) { - DCHECK(method != nullptr); - DCHECK(method_ != nullptr); - method_ = method; - } - ArtMethod* GetMethod() const REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(method_ != nullptr); return method_; @@ -616,10 +610,6 @@ class StackVisitor { ArtMethod* GetMethod() const REQUIRES_SHARED(Locks::mutator_lock_); - // Sets this stack frame's method pointer. This requires a full lock of the MutatorLock. This - // doesn't work with inlined methods. - void SetMethod(ArtMethod* method) REQUIRES(Locks::mutator_lock_); - ArtMethod* GetOuterMethod() const { return *GetCurrentQuickFrame(); } diff --git a/test/914-hello-obsolescence/build b/test/914-hello-obsolescence/build deleted file mode 100755 index 898e2e54a..000000000 --- a/test/914-hello-obsolescence/build +++ /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-build "$@" --experimental agents diff --git a/test/914-hello-obsolescence/expected.txt b/test/914-hello-obsolescence/expected.txt deleted file mode 100644 index 83efda144..000000000 --- a/test/914-hello-obsolescence/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/914-hello-obsolescence/info.txt b/test/914-hello-obsolescence/info.txt deleted file mode 100644 index c8b892ced..000000000 --- a/test/914-hello-obsolescence/info.txt +++ /dev/null @@ -1 +0,0 @@ -Tests basic obsolete method support diff --git a/test/914-hello-obsolescence/run b/test/914-hello-obsolescence/run deleted file mode 100755 index b2f0b049a..000000000 --- a/test/914-hello-obsolescence/run +++ /dev/null @@ -1,44 +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. - -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -lib=tiagentd -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so - lib=tiagent -fi - -if [[ "$@" == *"--jvm"* ]]; then - arg="jvm" -else - arg="art" - if [[ "$@" != *"--debuggable"* ]]; then - other_args=" -Xcompiler-option --debuggable " - else - other_args="" - fi -fi - - -./default-run "$@" --experimental agents \ - --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=914-hello-obsolescence,${arg} \ - --android-runtime-option -Xplugin:${plugin} \ - --android-runtime-option -Xfully-deoptable \ - ${other_args} \ - --args ${lib} diff --git a/test/914-hello-obsolescence/src/Main.java b/test/914-hello-obsolescence/src/Main.java deleted file mode 100644 index 46266efb2..000000000 --- a/test/914-hello-obsolescence/src/Main.java +++ /dev/null @@ -1,73 +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"); - // r.run(); - // System.out.println("Goodbye - Transformed"); - // } - // } - private static final byte[] CLASS_BYTES = Base64.getDecoder().decode( - "yv66vgAAADQAJAoACAARCQASABMIABQKABUAFgsAFwAYCAAZBwAaBwAbAQAGPGluaXQ+AQADKClW" + - "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7" + - "KVYBAApTb3VyY2VGaWxlAQAOVHJhbnNmb3JtLmphdmEMAAkACgcAHAwAHQAeAQATSGVsbG8gLSBU" + - "cmFuc2Zvcm1lZAcAHwwAIAAhBwAiDAAjAAoBABVHb29kYnllIC0gVHJhbnNmb3JtZWQBAAlUcmFu" + - "c2Zvcm0BABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZh" + - "L2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZh" + - "L2xhbmcvU3RyaW5nOylWAQASamF2YS9sYW5nL1J1bm5hYmxlAQADcnVuACAABwAIAAAAAAACAAAA" + - "CQAKAAEACwAAAB0AAQABAAAABSq3AAGxAAAAAQAMAAAABgABAAAAAQABAA0ADgABAAsAAAA7AAIA" + - "AgAAABeyAAISA7YABCu5AAUBALIAAhIGtgAEsQAAAAEADAAAABIABAAAAAMACAAEAA4ABQAWAAYA" + - "AQAPAAAAAgAQ"); - private static final byte[] DEX_BYTES = Base64.getDecoder().decode( - "ZGV4CjAzNQAYeAMMXgYWxoeSHAS9EWKCCtVRSAGpqZVQAwAAcAAAAHhWNBIAAAAAAAAAALACAAAR" + - "AAAAcAAAAAcAAAC0AAAAAwAAANAAAAABAAAA9AAAAAUAAAD8AAAAAQAAACQBAAAMAgAARAEAAKIB" + - "AACqAQAAwQEAANYBAADjAQAA+gEAAA4CAAAkAgAAOAIAAEwCAABcAgAAXwIAAGMCAAB3AgAAfAIA" + - "AIUCAACKAgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAoAAAAGAAAAAAAAAAsAAAAGAAAA" + - "lAEAAAsAAAAGAAAAnAEAAAUAAQANAAAAAAAAAAAAAAAAAAEAEAAAAAEAAgAOAAAAAgAAAAAAAAAD" + - "AAAADwAAAAAAAAAAAAAAAgAAAAAAAAAJAAAAAAAAAJ8CAAAAAAAAAQABAAEAAACRAgAABAAAAHAQ" + - "AwAAAA4ABAACAAIAAACWAgAAFAAAAGIAAAAbAQIAAABuIAIAEAByEAQAAwBiAAAAGwEBAAAAbiAC" + - "ABAADgABAAAAAwAAAAEAAAAEAAY8aW5pdD4AFUdvb2RieWUgLSBUcmFuc2Zvcm1lZAATSGVsbG8g" + - "LSBUcmFuc2Zvcm1lZAALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEv" + - "bGFuZy9PYmplY3Q7ABRMamF2YS9sYW5nL1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7ABJM" + - "amF2YS9sYW5nL1N5c3RlbTsADlRyYW5zZm9ybS5qYXZhAAFWAAJWTAASZW1pdHRlcjogamFjay00" + - "LjEzAANvdXQAB3ByaW50bG4AA3J1bgAFc2F5SGkAAQAHDgADAQAHDoc8hwAAAAEBAICABMQCAQHc" + - "AgAAAA0AAAAAAAAAAQAAAAAAAAABAAAAEQAAAHAAAAACAAAABwAAALQAAAADAAAAAwAAANAAAAAE" + - "AAAAAQAAAPQAAAAFAAAABQAAAPwAAAAGAAAAAQAAACQBAAABIAAAAgAAAEQBAAABEAAAAgAAAJQB" + - "AAACIAAAEQAAAKIBAAADIAAAAgAAAJECAAAAIAAAAQAAAJ8CAAAAEAAAAQAAALACAAA="); - - public static void main(String[] args) { - System.loadLibrary(args[1]); - 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); -} diff --git a/test/914-hello-obsolescence/src/Transform.java b/test/914-hello-obsolescence/src/Transform.java deleted file mode 100644 index 8cda6cdf5..000000000 --- a/test/914-hello-obsolescence/src/Transform.java +++ /dev/null @@ -1,30 +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) { - // Use lower 'h' to make sure the string will have a different string id - // than the transformation (the transformation code is the same except - // the actual printed String, which was making the test inacurately passing - // in JIT mode when loading the string from the dex cache, as the string ids - // of the two different strings were the same). - // We know the string ids will be different because lexicographically: - // "Hello" < "LTransform;" < "hello". - System.out.println("hello"); - r.run(); - System.out.println("goodbye"); - } -} diff --git a/test/915-obsolete-2/build b/test/915-obsolete-2/build deleted file mode 100755 index 898e2e54a..000000000 --- a/test/915-obsolete-2/build +++ /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-build "$@" --experimental agents diff --git a/test/915-obsolete-2/expected.txt b/test/915-obsolete-2/expected.txt deleted file mode 100644 index 04aff3a6d..000000000 --- a/test/915-obsolete-2/expected.txt +++ /dev/null @@ -1,21 +0,0 @@ -Pre Start private method call -hello - private -Post Start private method call -Not doing anything here -Pre Finish private method call -goodbye - private -Post Finish private method call -Pre Start private method call -hello - private -Post Start private method call -transforming calling function -Pre Finish private method call -Goodbye - private - Transformed -Post Finish private method call -Pre Start private method call - Transformed -Hello - private - Transformed -Post Start private method call - Transformed -Not doing anything here -Pre Finish private method call - Transformed -Goodbye - private - Transformed -Post Finish private method call - Transformed diff --git a/test/915-obsolete-2/info.txt b/test/915-obsolete-2/info.txt deleted file mode 100644 index c8b892ced..000000000 --- a/test/915-obsolete-2/info.txt +++ /dev/null @@ -1 +0,0 @@ -Tests basic obsolete method support diff --git a/test/915-obsolete-2/run b/test/915-obsolete-2/run deleted file mode 100755 index bfe227fe2..000000000 --- a/test/915-obsolete-2/run +++ /dev/null @@ -1,44 +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. - -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -lib=tiagentd -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so - lib=tiagent -fi - -if [[ "$@" == *"--jvm"* ]]; then - arg="jvm" -else - arg="art" - if [[ "$@" != *"--debuggable"* ]]; then - other_args=" -Xcompiler-option --debuggable " - else - other_args="" - fi -fi - - -./default-run "$@" --experimental agents \ - --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=915-obsolete-2,${arg} \ - --android-runtime-option -Xplugin:${plugin} \ - --android-runtime-option -Xfully-deoptable \ - ${other_args} \ - --args ${lib} diff --git a/test/915-obsolete-2/src/Main.java b/test/915-obsolete-2/src/Main.java deleted file mode 100644 index bbeb72685..000000000 --- a/test/915-obsolete-2/src/Main.java +++ /dev/null @@ -1,99 +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 { - // private void Start() { - // System.out.println("Hello - private - Transformed"); - // } - // - // private void Finish() { - // System.out.println("Goodbye - private - Transformed"); - // } - // - // public void sayHi(Runnable r) { - // System.out.println("Pre Start private method call - Transformed"); - // Start(); - // System.out.println("Post Start private method call - Transformed"); - // r.run(); - // System.out.println("Pre Finish private method call - Transformed"); - // Finish(); - // System.out.println("Post Finish private method call - Transformed"); - // } - // } - private static final byte[] CLASS_BYTES = Base64.getDecoder().decode( - "yv66vgAAADQAMgoADgAZCQAaABsIABwKAB0AHggAHwgAIAoADQAhCAAiCwAjACQIACUKAA0AJggA" + - "JwcAKAcAKQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAAVTdGFydAEA" + - "BkZpbmlzaAEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7KVYBAApTb3VyY2VGaWxlAQAO" + - "VHJhbnNmb3JtLmphdmEMAA8AEAcAKgwAKwAsAQAdSGVsbG8gLSBwcml2YXRlIC0gVHJhbnNmb3Jt" + - "ZWQHAC0MAC4ALwEAH0dvb2RieWUgLSBwcml2YXRlIC0gVHJhbnNmb3JtZWQBACtQcmUgU3RhcnQg" + - "cHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkDAATABABACxQb3N0IFN0YXJ0IHByaXZh" + - "dGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAcAMAwAMQAQAQAsUHJlIEZpbmlzaCBwcml2YXRl" + - "IG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQMABQAEAEALVBvc3QgRmluaXNoIHByaXZhdGUgbWV0" + - "aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAEACVRyYW5zZm9ybQEAEGphdmEvbGFuZy9PYmplY3QBABBq" + - "YXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9Q" + - "cmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABJqYXZhL2xhbmcv" + - "UnVubmFibGUBAANydW4AIAANAA4AAAAAAAQAAAAPABAAAQARAAAAHQABAAEAAAAFKrcAAbEAAAAB" + - "ABIAAAAGAAEAAAABAAIAEwAQAAEAEQAAACUAAgABAAAACbIAAhIDtgAEsQAAAAEAEgAAAAoAAgAA" + - "AAMACAAEAAIAFAAQAAEAEQAAACUAAgABAAAACbIAAhIFtgAEsQAAAAEAEgAAAAoAAgAAAAcACAAI" + - "AAEAFQAWAAEAEQAAAGMAAgACAAAAL7IAAhIGtgAEKrcAB7IAAhIItgAEK7kACQEAsgACEgq2AAQq" + - "twALsgACEgy2AASxAAAAAQASAAAAIgAIAAAACwAIAAwADAANABQADgAaAA8AIgAQACYAEQAuABIA" + - "AQAXAAAAAgAY"); - private static final byte[] DEX_BYTES = Base64.getDecoder().decode( - "ZGV4CjAzNQCM0QYTJmX+NsZXkImojgSkJtXyuew3oaXcBAAAcAAAAHhWNBIAAAAAAAAAADwEAAAX" + - "AAAAcAAAAAcAAADMAAAAAwAAAOgAAAABAAAADAEAAAcAAAAUAQAAAQAAAEwBAABwAwAAbAEAAD4C" + - "AABGAgAATgIAAG8CAACOAgAAmwIAALICAADGAgAA3AIAAPACAAAEAwAAMwMAAGEDAACPAwAAvAMA" + - "AMMDAADTAwAA1gMAANoDAADuAwAA8wMAAPwDAAABBAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAA" + - "EAAAABAAAAAGAAAAAAAAABEAAAAGAAAAMAIAABEAAAAGAAAAOAIAAAUAAQATAAAAAAAAAAAAAAAA" + - "AAAAAQAAAAAAAAAOAAAAAAABABYAAAABAAIAFAAAAAIAAAAAAAAAAwAAABUAAAAAAAAAAAAAAAIA" + - "AAAAAAAADwAAAAAAAAAmBAAAAAAAAAEAAQABAAAACAQAAAQAAABwEAUAAAAOAAMAAQACAAAADQQA" + - "AAkAAABiAAAAGwECAAAAbiAEABAADgAAAAMAAQACAAAAEwQAAAkAAABiAAAAGwEDAAAAbiAEABAA" + - "DgAAAAQAAgACAAAAGQQAACoAAABiAAAAGwENAAAAbiAEABAAcBACAAIAYgAAABsBCwAAAG4gBAAQ" + - "AHIQBgADAGIAAAAbAQwAAABuIAQAEABwEAEAAgBiAAAAGwEKAAAAbiAEABAADgABAAAAAwAAAAEA" + - "AAAEAAY8aW5pdD4ABkZpbmlzaAAfR29vZGJ5ZSAtIHByaXZhdGUgLSBUcmFuc2Zvcm1lZAAdSGVs" + - "bG8gLSBwcml2YXRlIC0gVHJhbnNmb3JtZWQAC0xUcmFuc2Zvcm07ABVMamF2YS9pby9QcmludFN0" + - "cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwAUTGphdmEvbGFuZy9SdW5uYWJsZTsAEkxqYXZhL2xh" + - "bmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AC1Qb3N0IEZpbmlzaCBwcml2YXRlIG1ldGhv" + - "ZCBjYWxsIC0gVHJhbnNmb3JtZWQALFBvc3QgU3RhcnQgcHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRy" + - "YW5zZm9ybWVkACxQcmUgRmluaXNoIHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAAr" + - "UHJlIFN0YXJ0IHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAAFU3RhcnQADlRyYW5z" + - "Zm9ybS5qYXZhAAFWAAJWTAASZW1pdHRlcjogamFjay00LjEzAANvdXQAB3ByaW50bG4AA3J1bgAF" + - "c2F5SGkAAQAHDgAHAAcOhwADAAcOhwALAQAHDoc8hzyHPIcAAAADAQCAgATsAgEChAMBAqgDAwHM" + - "Aw0AAAAAAAAAAQAAAAAAAAABAAAAFwAAAHAAAAACAAAABwAAAMwAAAADAAAAAwAAAOgAAAAEAAAA" + - "AQAAAAwBAAAFAAAABwAAABQBAAAGAAAAAQAAAEwBAAABIAAABAAAAGwBAAABEAAAAgAAADACAAAC" + - "IAAAFwAAAD4CAAADIAAABAAAAAgEAAAAIAAAAQAAACYEAAAAEAAAAQAAADwEAAA="); - - public static void main(String[] args) { - System.loadLibrary(args[1]); - 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); -} diff --git a/test/915-obsolete-2/src/Transform.java b/test/915-obsolete-2/src/Transform.java deleted file mode 100644 index e914e2947..000000000 --- a/test/915-obsolete-2/src/Transform.java +++ /dev/null @@ -1,35 +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 { - private void Start() { - System.out.println("hello - private"); - } - - private void Finish() { - System.out.println("goodbye - private"); - } - - public void sayHi(Runnable r) { - System.out.println("Pre Start private method call"); - Start(); - System.out.println("Post Start private method call"); - r.run(); - System.out.println("Pre Finish private method call"); - Finish(); - System.out.println("Post Finish private method call"); - } -} diff --git a/test/916-obsolete-jit/build b/test/916-obsolete-jit/build deleted file mode 100755 index 898e2e54a..000000000 --- a/test/916-obsolete-jit/build +++ /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-build "$@" --experimental agents diff --git a/test/916-obsolete-jit/expected.txt b/test/916-obsolete-jit/expected.txt deleted file mode 100644 index 04aff3a6d..000000000 --- a/test/916-obsolete-jit/expected.txt +++ /dev/null @@ -1,21 +0,0 @@ -Pre Start private method call -hello - private -Post Start private method call -Not doing anything here -Pre Finish private method call -goodbye - private -Post Finish private method call -Pre Start private method call -hello - private -Post Start private method call -transforming calling function -Pre Finish private method call -Goodbye - private - Transformed -Post Finish private method call -Pre Start private method call - Transformed -Hello - private - Transformed -Post Start private method call - Transformed -Not doing anything here -Pre Finish private method call - Transformed -Goodbye - private - Transformed -Post Finish private method call - Transformed diff --git a/test/916-obsolete-jit/info.txt b/test/916-obsolete-jit/info.txt deleted file mode 100644 index c8b892ced..000000000 --- a/test/916-obsolete-jit/info.txt +++ /dev/null @@ -1 +0,0 @@ -Tests basic obsolete method support diff --git a/test/916-obsolete-jit/run b/test/916-obsolete-jit/run deleted file mode 100755 index 25c2c0747..000000000 --- a/test/916-obsolete-jit/run +++ /dev/null @@ -1,47 +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. - -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -lib=tiagentd -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so - lib=tiagent -fi - -if [[ "$@" == *"--jit"* ]]; then - other_args="" -else - other_args="--jit" -fi -if [[ "$@" == *"--jvm"* ]]; then - arg="jvm" -else - arg="art" - if [[ "$@" != *"--debuggable"* ]]; then - other_args="$other_args -Xcompiler-option --debuggable " - fi -fi - - -./default-run "$@" --experimental agents \ - --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=915-obsolete-2,${arg} \ - --android-runtime-option -Xplugin:${plugin} \ - --android-runtime-option -Xfully-deoptable \ - ${other_args} \ - --args ${lib} diff --git a/test/916-obsolete-jit/src/Main.java b/test/916-obsolete-jit/src/Main.java deleted file mode 100644 index d4fa667ad..000000000 --- a/test/916-obsolete-jit/src/Main.java +++ /dev/null @@ -1,142 +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 { - private static boolean do_print = false; - - public static boolean doPrint() { - return do_print; - } - - // Since the transformed code isn't really an issue this is the same as test 915. - // class Transform { - // private void Start() { - // System.out.println("Hello - private - Transformed"); - // } - // - // private void Finish() { - // System.out.println("Goodbye - private - Transformed"); - // } - // - // public void sayHi(Runnable r) { - // System.out.println("Pre Start private method call - Transformed"); - // Start(); - // System.out.println("Post Start private method call - Transformed"); - // r.run(); - // System.out.println("Pre Finish private method call - Transformed"); - // Finish(); - // System.out.println("Post Finish private method call - Transformed"); - // } - // } - private static final byte[] CLASS_BYTES = Base64.getDecoder().decode( - "yv66vgAAADQAMgoADgAZCQAaABsIABwKAB0AHggAHwgAIAoADQAhCAAiCwAjACQIACUKAA0AJggA" + - "JwcAKAcAKQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAAVTdGFydAEA" + - "BkZpbmlzaAEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7KVYBAApTb3VyY2VGaWxlAQAO" + - "VHJhbnNmb3JtLmphdmEMAA8AEAcAKgwAKwAsAQAdSGVsbG8gLSBwcml2YXRlIC0gVHJhbnNmb3Jt" + - "ZWQHAC0MAC4ALwEAH0dvb2RieWUgLSBwcml2YXRlIC0gVHJhbnNmb3JtZWQBACtQcmUgU3RhcnQg" + - "cHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkDAATABABACxQb3N0IFN0YXJ0IHByaXZh" + - "dGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAcAMAwAMQAQAQAsUHJlIEZpbmlzaCBwcml2YXRl" + - "IG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQMABQAEAEALVBvc3QgRmluaXNoIHByaXZhdGUgbWV0" + - "aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAEACVRyYW5zZm9ybQEAEGphdmEvbGFuZy9PYmplY3QBABBq" + - "YXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9Q" + - "cmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABJqYXZhL2xhbmcv" + - "UnVubmFibGUBAANydW4AIAANAA4AAAAAAAQAAAAPABAAAQARAAAAHQABAAEAAAAFKrcAAbEAAAAB" + - "ABIAAAAGAAEAAAABAAIAEwAQAAEAEQAAACUAAgABAAAACbIAAhIDtgAEsQAAAAEAEgAAAAoAAgAA" + - "AAMACAAEAAIAFAAQAAEAEQAAACUAAgABAAAACbIAAhIFtgAEsQAAAAEAEgAAAAoAAgAAAAcACAAI" + - "AAEAFQAWAAEAEQAAAGMAAgACAAAAL7IAAhIGtgAEKrcAB7IAAhIItgAEK7kACQEAsgACEgq2AAQq" + - "twALsgACEgy2AASxAAAAAQASAAAAIgAIAAAACwAIAAwADAANABQADgAaAA8AIgAQACYAEQAuABIA" + - "AQAXAAAAAgAY"); - private static final byte[] DEX_BYTES = Base64.getDecoder().decode( - "ZGV4CjAzNQCM0QYTJmX+NsZXkImojgSkJtXyuew3oaXcBAAAcAAAAHhWNBIAAAAAAAAAADwEAAAX" + - "AAAAcAAAAAcAAADMAAAAAwAAAOgAAAABAAAADAEAAAcAAAAUAQAAAQAAAEwBAABwAwAAbAEAAD4C" + - "AABGAgAATgIAAG8CAACOAgAAmwIAALICAADGAgAA3AIAAPACAAAEAwAAMwMAAGEDAACPAwAAvAMA" + - "AMMDAADTAwAA1gMAANoDAADuAwAA8wMAAPwDAAABBAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAA" + - "EAAAABAAAAAGAAAAAAAAABEAAAAGAAAAMAIAABEAAAAGAAAAOAIAAAUAAQATAAAAAAAAAAAAAAAA" + - "AAAAAQAAAAAAAAAOAAAAAAABABYAAAABAAIAFAAAAAIAAAAAAAAAAwAAABUAAAAAAAAAAAAAAAIA" + - "AAAAAAAADwAAAAAAAAAmBAAAAAAAAAEAAQABAAAACAQAAAQAAABwEAUAAAAOAAMAAQACAAAADQQA" + - "AAkAAABiAAAAGwECAAAAbiAEABAADgAAAAMAAQACAAAAEwQAAAkAAABiAAAAGwEDAAAAbiAEABAA" + - "DgAAAAQAAgACAAAAGQQAACoAAABiAAAAGwENAAAAbiAEABAAcBACAAIAYgAAABsBCwAAAG4gBAAQ" + - "AHIQBgADAGIAAAAbAQwAAABuIAQAEABwEAEAAgBiAAAAGwEKAAAAbiAEABAADgABAAAAAwAAAAEA" + - "AAAEAAY8aW5pdD4ABkZpbmlzaAAfR29vZGJ5ZSAtIHByaXZhdGUgLSBUcmFuc2Zvcm1lZAAdSGVs" + - "bG8gLSBwcml2YXRlIC0gVHJhbnNmb3JtZWQAC0xUcmFuc2Zvcm07ABVMamF2YS9pby9QcmludFN0" + - "cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwAUTGphdmEvbGFuZy9SdW5uYWJsZTsAEkxqYXZhL2xh" + - "bmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AC1Qb3N0IEZpbmlzaCBwcml2YXRlIG1ldGhv" + - "ZCBjYWxsIC0gVHJhbnNmb3JtZWQALFBvc3QgU3RhcnQgcHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRy" + - "YW5zZm9ybWVkACxQcmUgRmluaXNoIHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAAr" + - "UHJlIFN0YXJ0IHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAAFU3RhcnQADlRyYW5z" + - "Zm9ybS5qYXZhAAFWAAJWTAASZW1pdHRlcjogamFjay00LjEzAANvdXQAB3ByaW50bG4AA3J1bgAF" + - "c2F5SGkAAQAHDgAHAAcOhwADAAcOhwALAQAHDoc8hzyHPIcAAAADAQCAgATsAgEChAMBAqgDAwHM" + - "Aw0AAAAAAAAAAQAAAAAAAAABAAAAFwAAAHAAAAACAAAABwAAAMwAAAADAAAAAwAAAOgAAAAEAAAA" + - "AQAAAAwBAAAFAAAABwAAABQBAAAGAAAAAQAAAEwBAAABIAAABAAAAGwBAAABEAAAAgAAADACAAAC" + - "IAAAFwAAAD4CAAADIAAABAAAAAgEAAAAIAAAAQAAACYEAAAAEAAAAQAAADwEAAA="); - - public static void main(String[] args) { - System.loadLibrary(args[1]); - doTest(new Transform()); - } - - // TODO Workaround to (1) inability to ensure that current_method is not put into a register by - // the JIT and/or (2) inability to deoptimize frames near runtime functions. - // TODO Fix one/both of these issues. - public static void doCall(Runnable r) { - r.run(); - } - - private static boolean interpreting = true; - public static void doTest(Transform t) { - do_print = false; - Runnable noop = () -> {}; - long j = 0; - do { - for (int i = 0; i < 10000; i++) { - t.sayHi(noop); - j++; - } - t.sayHi(() -> { - // TODO 2 is wrong It is checking a piece of this lambda method but should be fine due to - // how we implement lambdas. Be sure to fix before really submitting. - interpreting = Main.isInterpretedFunction("LTransform;->sayHi()V"); - }); - if (j >= 1000000) { - System.out.println("FAIL: Could not make sayHi be Jitted!"); - return; - } - j++; - } while(interpreting); - // Start printing. - do_print = true; - t.sayHi(() -> { - System.out.println("Not doing anything here"); - }); - t.sayHi(() -> { - if (Main.isInterpretedFunction("LTransform;->sayHi()V")) { - System.out.println("FAIL: sayHi is being interpreted!"); - } - System.out.println("transforming calling function"); - doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES); - }); - t.sayHi(() -> { System.out.println("Not doing anything here"); }); - } - - private static native boolean isInterpretedFunction(String name); - - // Transforms the class - private static native void doCommonClassRedefinition(Class target, - byte[] classfile, - byte[] dexfile); -} diff --git a/test/916-obsolete-jit/src/Transform.java b/test/916-obsolete-jit/src/Transform.java deleted file mode 100644 index a22f3891a..000000000 --- a/test/916-obsolete-jit/src/Transform.java +++ /dev/null @@ -1,52 +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 { - private void Start() { - if (Main.doPrint()) { - System.out.println("hello - private"); - } - } - - private void Finish() { - if (Main.doPrint()) { - System.out.println("goodbye - private"); - } - } - - public void sayHi(Runnable r) { - if (Main.doPrint()) { - System.out.println("Pre Start private method call"); - } - Start(); - if (Main.doPrint()) { - System.out.println("Post Start private method call"); - } - // TODO Revist with b/33616143 - // TODO Uncomment this - // r.run(); - // TODO This is a very temporary fix until we get either deoptimization near runtime frames - // working, forcing current method to be always read from the stack or both working. - Main.doCall(r); - if (Main.doPrint()) { - System.out.println("Pre Finish private method call"); - } - Finish(); - if (Main.doPrint()) { - System.out.println("Post Finish private method call"); - } - } -} diff --git a/test/Android.bp b/test/Android.bp index c42ffc9b9..2625f5641 100644 --- a/test/Android.bp +++ b/test/Android.bp @@ -243,8 +243,6 @@ art_cc_defaults { name: "libtiagent-defaults", defaults: ["libartagent-defaults"], srcs: [ - // This is to get the IsInterpreted native method. - "common/stack_inspect.cc", "ti-agent/common_load.cc", "ti-agent/common_helper.cc", "901-hello-ti-agent/basics.cc", diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index 7cdca6276..2f1ca6d29 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -280,9 +280,6 @@ TEST_ART_BROKEN_TARGET_TESTS += \ 911-get-stack-trace \ 912-classes \ 913-heaps \ - 914-hello-obsolescence \ - 915-obsolete-2 \ - 916-obsolete-jit \ ifneq (,$(filter target,$(TARGET_TYPES))) ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,target,$(RUN_TYPES),$(PREBUILD_TYPES), \ diff --git a/test/common/stack_inspect.cc b/test/common/stack_inspect.cc index eefaabca9..4df2d470e 100644 --- a/test/common/stack_inspect.cc +++ b/test/common/stack_inspect.cc @@ -52,53 +52,6 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInterpreted(JNIEnv* env, jclas return IsInterpreted(env, klass, 1); } -// public static native boolean isInterpreted(int depth); - -extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInterpretedAt(JNIEnv* env, - jclass klass, - jint depth) { - return IsInterpreted(env, klass, depth); -} - - -// public static native boolean isInterpretedFunction(String smali); - -struct MethodIsInterpretedVisitor : public StackVisitor { - public: - MethodIsInterpretedVisitor(Thread* thread, std::string shorty) - : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames), - shorty_(shorty), - method_is_interpreted_(false) {} - - virtual bool VisitFrame() OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) { - if (!GetMethod()->IsRuntimeMethod() && shorty_ == GetMethod()->GetShorty()) { - method_is_interpreted_ = IsShadowFrame(); - return false; - } - return true; - } - - bool IsInterpreted() { - return method_is_interpreted_; - } - - private: - const std::string shorty_; - bool method_is_interpreted_; -}; - -extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInterpretedFunction(JNIEnv* env, - jclass klass ATTRIBUTE_UNUSED, - jstring name) { - if (Runtime::Current() == nullptr) { - return JNI_TRUE; - } - ScopedObjectAccess soa(env); - MethodIsInterpretedVisitor v(soa.Self(), soa.Decode(name)->ToModifiedUtf8()); - v.WalkStack(); - return v.IsInterpreted(); -} - // public static native void assertIsInterpreted(); extern "C" JNIEXPORT void JNICALL Java_Main_assertIsInterpreted(JNIEnv* env, jclass klass) { diff --git a/test/etc/default-build b/test/etc/default-build index faa0813fd..51ae1752a 100755 --- a/test/etc/default-build +++ b/test/etc/default-build @@ -69,7 +69,6 @@ DEFAULT_EXPERIMENT="no-experiment" # Setup experimental flag mappings in a bash associative array. declare -A JACK_EXPERIMENTAL_ARGS -JACK_EXPERIMENTAL_ARGS["agents"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24" JACK_EXPERIMENTAL_ARGS["default-methods"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24" JACK_EXPERIMENTAL_ARGS["lambdas"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24" JACK_EXPERIMENTAL_ARGS["method-handles"]="-D jack.java.source.version=1.7 -D jack.android.min-api-level=o-b1" @@ -77,14 +76,12 @@ JACK_EXPERIMENTAL_ARGS["method-handles"]="-D jack.java.source.version=1.7 -D jac declare -A SMALI_EXPERIMENTAL_ARGS SMALI_EXPERIMENTAL_ARGS["default-methods"]="--api-level 24" SMALI_EXPERIMENTAL_ARGS["method-handles"]="--api-level 26" -SMALI_EXPERIMENTAL_ARGS["agents"]="--api-level 26" declare -A JAVAC_EXPERIMENTAL_ARGS JAVAC_EXPERIMENTAL_ARGS["default-methods"]="-source 1.8 -target 1.8" JAVAC_EXPERIMENTAL_ARGS["lambdas"]="-source 1.8 -target 1.8" JAVAC_EXPERIMENTAL_ARGS["method-handles"]="-source 1.8 -target 1.8" JAVAC_EXPERIMENTAL_ARGS[${DEFAULT_EXPERIMENT}]="-source 1.7 -target 1.7" -JAVAC_EXPERIMENTAL_ARGS["agents"]="-source 1.8 -target 1.8" while true; do if [ "x$1" = "x--dx-option" ]; then diff --git a/test/ti-agent/common_helper.cc b/test/ti-agent/common_helper.cc index ebf1e4621..3e2b16802 100644 --- a/test/ti-agent/common_helper.cc +++ b/test/ti-agent/common_helper.cc @@ -18,11 +18,8 @@ #include -#include "art_method.h" #include "jni.h" #include "openjdkjvmti/jvmti.h" -#include "scoped_thread_state_change-inl.h" -#include "stack.h" #include "ti-agent/common_load.h" #include "utils.h" diff --git a/test/ti-agent/common_load.cc b/test/ti-agent/common_load.cc index 826c5ad49..2795cbc25 100644 --- a/test/ti-agent/common_load.cc +++ b/test/ti-agent/common_load.cc @@ -66,8 +66,6 @@ AgentLib agents[] = { { "911-get-stack-trace", Test911GetStackTrace::OnLoad, nullptr }, { "912-classes", Test912Classes::OnLoad, nullptr }, { "913-heaps", Test913Heaps::OnLoad, nullptr }, - { "914-hello-obsolescence", common_redefine::OnLoad, nullptr }, - { "915-obsolete-2", common_redefine::OnLoad, nullptr }, }; static AgentLib* FindAgent(char* name) {