Merge "Revert "Implement RetransformClasses""
diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
index 32e3948..90467db 100644
--- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc
+++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
@@ -631,17 +631,7 @@
   }
 
   static jvmtiError RetransformClasses(jvmtiEnv* env, jint class_count, const jclass* classes) {
-    std::string error_msg;
-    jvmtiError res = Transformer::RetransformClasses(ArtJvmTiEnv::AsArtJvmTiEnv(env),
-                                                     art::Runtime::Current(),
-                                                     art::Thread::Current(),
-                                                     class_count,
-                                                     classes,
-                                                     &error_msg);
-    if (res != OK) {
-      LOG(WARNING) << "FAILURE TO RETRANFORM " << error_msg;
-    }
-    return res;
+    return ERR(NOT_IMPLEMENTED);
   }
 
   static jvmtiError RedefineClasses(jvmtiEnv* env,
@@ -1265,6 +1255,78 @@
     *format_ptr = jvmtiJlocationFormat::JVMTI_JLOCATION_JVMBCI;
     return ERR(NONE);
   }
+
+  // TODO Remove this once events are working.
+  static jvmtiError RetransformClassWithHook(jvmtiEnv* env,
+                                             jclass klass,
+                                             jvmtiEventClassFileLoadHook hook) {
+    std::vector<jclass> classes;
+    classes.push_back(klass);
+    return RetransformClassesWithHook(reinterpret_cast<ArtJvmTiEnv*>(env), classes, hook);
+  }
+
+  // TODO This will be called by the event handler for the art::ti Event Load Event
+  static jvmtiError RetransformClassesWithHook(ArtJvmTiEnv* env,
+                                               const std::vector<jclass>& classes,
+                                               jvmtiEventClassFileLoadHook hook) {
+    if (!IsValidEnv(env)) {
+      return ERR(INVALID_ENVIRONMENT);
+    }
+    jvmtiError res = OK;
+    std::string error;
+    for (jclass klass : classes) {
+      JNIEnv* jni_env = nullptr;
+      jobject loader = nullptr;
+      std::string name;
+      jobject protection_domain = nullptr;
+      jint data_len = 0;
+      unsigned char* dex_data = nullptr;
+      jvmtiError ret = OK;
+      std::string location;
+      if ((ret = GetTransformationData(env,
+                                       klass,
+                                       /*out*/&location,
+                                       /*out*/&jni_env,
+                                       /*out*/&loader,
+                                       /*out*/&name,
+                                       /*out*/&protection_domain,
+                                       /*out*/&data_len,
+                                       /*out*/&dex_data)) != OK) {
+        // TODO Do something more here? Maybe give log statements?
+        return ret;
+      }
+      jint new_data_len = 0;
+      unsigned char* new_dex_data = nullptr;
+      hook(env,
+           jni_env,
+           klass,
+           loader,
+           name.c_str(),
+           protection_domain,
+           data_len,
+           dex_data,
+           /*out*/&new_data_len,
+           /*out*/&new_dex_data);
+      // Check if anything actually changed.
+      if ((new_data_len != 0 || new_dex_data != nullptr) && new_dex_data != dex_data) {
+        jvmtiClassDefinition def = { klass, new_data_len, new_dex_data };
+        res = Redefiner::RedefineClasses(env,
+                                         art::Runtime::Current(),
+                                         art::Thread::Current(),
+                                         1,
+                                         &def,
+                                         &error);
+        env->Deallocate(new_dex_data);
+      }
+      // Deallocate the old dex data.
+      env->Deallocate(dex_data);
+      if (res != OK) {
+        LOG(ERROR) << "FAILURE TO REDEFINE " << error;
+        return res;
+      }
+    }
+    return OK;
+  }
 };
 
 static bool IsJvmtiVersion(jint version) {
@@ -1307,7 +1369,10 @@
 
 // The actual struct holding all of the entrypoints into the jvmti interface.
 const jvmtiInterface_1 gJvmtiInterface = {
-  nullptr,  // reserved1
+  // SPECIAL FUNCTION: RetransformClassWithHook Is normally reserved1
+  // TODO Remove once we have events working.
+  reinterpret_cast<void*>(JvmtiFunctions::RetransformClassWithHook),
+  // nullptr,  // reserved1
   JvmtiFunctions::SetEventNotificationMode,
   nullptr,  // reserved3
   JvmtiFunctions::GetAllThreads,
diff --git a/runtime/openjdkjvmti/art_jvmti.h b/runtime/openjdkjvmti/art_jvmti.h
index 1c84d4d..5eadc5a 100644
--- a/runtime/openjdkjvmti/art_jvmti.h
+++ b/runtime/openjdkjvmti/art_jvmti.h
@@ -47,7 +47,6 @@
 namespace openjdkjvmti {
 
 extern const jvmtiInterface_1 gJvmtiInterface;
-extern EventHandler gEventHandler;
 
 // A structure that is a jvmtiEnv with additional information for the runtime.
 struct ArtJvmTiEnv : public jvmtiEnv {
@@ -125,29 +124,6 @@
   return ret;
 }
 
-struct ArtClassDefinition {
-  jclass klass;
-  jobject loader;
-  std::string name;
-  jobject protection_domain;
-  jint dex_len;
-  JvmtiUniquePtr dex_data;
-  bool modified;
-
-  ArtClassDefinition() = default;
-  ArtClassDefinition(ArtClassDefinition&& o) = default;
-
-  void SetNewDexData(ArtJvmTiEnv* env, jint new_dex_len, unsigned char* new_dex_data) {
-    if (new_dex_data == nullptr) {
-      return;
-    } else if (new_dex_data != dex_data.get() || new_dex_len != dex_len) {
-      modified = true;
-      dex_len = new_dex_len;
-      dex_data = MakeJvmtiUniquePtr(env, new_dex_data);
-    }
-  }
-};
-
 const jvmtiCapabilities kPotentialCapabilities = {
     .can_tag_objects                                 = 1,
     .can_generate_field_modification_events          = 0,
@@ -158,7 +134,7 @@
     .can_get_current_contended_monitor               = 0,
     .can_get_monitor_info                            = 0,
     .can_pop_frame                                   = 0,
-    .can_redefine_classes                            = 1,
+    .can_redefine_classes                            = 0,
     .can_signal_thread                               = 0,
     .can_get_source_file_name                        = 0,
     .can_get_line_numbers                            = 0,
@@ -186,7 +162,7 @@
     .can_get_owned_monitor_stack_depth_info          = 0,
     .can_get_constant_pool                           = 0,
     .can_set_native_method_prefix                    = 0,
-    .can_retransform_classes                         = 1,
+    .can_retransform_classes                         = 0,
     .can_retransform_any_class                       = 0,
     .can_generate_resource_exhaustion_heap_events    = 0,
     .can_generate_resource_exhaustion_threads_events = 0,
diff --git a/runtime/openjdkjvmti/events-inl.h b/runtime/openjdkjvmti/events-inl.h
index 21ec731..1e07bc6 100644
--- a/runtime/openjdkjvmti/events-inl.h
+++ b/runtime/openjdkjvmti/events-inl.h
@@ -115,95 +115,9 @@
 }
 
 template <typename ...Args>
-inline void EventHandler::DispatchClassFileLoadHookEvent(art::Thread*,
-                                                         ArtJvmtiEvent event,
-                                                         Args... args ATTRIBUTE_UNUSED) const {
-  CHECK(event == ArtJvmtiEvent::kClassFileLoadHookRetransformable ||
-        event == ArtJvmtiEvent::kClassFileLoadHookNonRetransformable);
-  LOG(FATAL) << "Incorrect arguments to ClassFileLoadHook!";
-}
-
-// TODO Locking of some type!
-template <>
-inline void EventHandler::DispatchClassFileLoadHookEvent(art::Thread* thread,
-                                                         ArtJvmtiEvent event,
-                                                         JNIEnv* jnienv,
-                                                         jclass class_being_redefined,
-                                                         jobject loader,
-                                                         const char* name,
-                                                         jobject protection_domain,
-                                                         jint class_data_len,
-                                                         const unsigned char* class_data,
-                                                         jint* new_class_data_len,
-                                                         unsigned char** new_class_data) const {
-  CHECK(event == ArtJvmtiEvent::kClassFileLoadHookRetransformable ||
-        event == ArtJvmtiEvent::kClassFileLoadHookNonRetransformable);
-  using FnType = void(jvmtiEnv*            /* jvmti_env */,
-                      JNIEnv*              /* jnienv */,
-                      jclass               /* class_being_redefined */,
-                      jobject              /* loader */,
-                      const char*          /* name */,
-                      jobject              /* protection_domain */,
-                      jint                 /* class_data_len */,
-                      const unsigned char* /* class_data */,
-                      jint*                /* new_class_data_len */,
-                      unsigned char**      /* new_class_data */);
-  jint current_len = class_data_len;
-  unsigned char* current_class_data = const_cast<unsigned char*>(class_data);
-  ArtJvmTiEnv* last_env = nullptr;
-  for (ArtJvmTiEnv* env : envs) {
-    if (ShouldDispatch(event, env, thread)) {
-      jint new_len;
-      unsigned char* new_data;
-      FnType* callback = GetCallback<FnType>(env, event);
-      callback(env,
-               jnienv,
-               class_being_redefined,
-               loader,
-               name,
-               protection_domain,
-               current_len,
-               current_class_data,
-               &new_len,
-               &new_data);
-      if (new_data != nullptr && new_data != current_class_data) {
-        // Destroy the data the last transformer made. We skip this if the previous state was the
-        // initial one since we don't know here which jvmtiEnv allocated it.
-        // NB Currently this doesn't matter since all allocations just go to malloc but in the
-        // future we might have jvmtiEnv's keep track of their allocations for leak-checking.
-        if (last_env != nullptr) {
-          last_env->Deallocate(current_class_data);
-        }
-        last_env = env;
-        current_class_data = new_data;
-        current_len = new_len;
-      }
-    }
-  }
-  if (last_env != nullptr) {
-    *new_class_data_len = current_len;
-    *new_class_data = current_class_data;
-  }
-}
-
-template <typename ...Args>
 inline void EventHandler::DispatchEvent(art::Thread* thread,
                                         ArtJvmtiEvent event,
                                         Args... args) const {
-  switch (event) {
-    case ArtJvmtiEvent::kClassFileLoadHookRetransformable:
-    case ArtJvmtiEvent::kClassFileLoadHookNonRetransformable:
-      return DispatchClassFileLoadHookEvent(thread, event, args...);
-    default:
-      return GenericDispatchEvent(thread, event, args...);
-  }
-}
-
-// TODO Locking of some type!
-template <typename ...Args>
-inline void EventHandler::GenericDispatchEvent(art::Thread* thread,
-                                               ArtJvmtiEvent event,
-                                               Args... args) const {
   using FnType = void(jvmtiEnv*, Args...);
   for (ArtJvmTiEnv* env : envs) {
     if (ShouldDispatch(event, env, thread)) {
diff --git a/runtime/openjdkjvmti/events.h b/runtime/openjdkjvmti/events.h
index 08a8765..7990141 100644
--- a/runtime/openjdkjvmti/events.h
+++ b/runtime/openjdkjvmti/events.h
@@ -178,15 +178,6 @@
   ALWAYS_INLINE
   inline void RecalculateGlobalEventMask(ArtJvmtiEvent event);
 
-  template <typename ...Args>
-  ALWAYS_INLINE inline void GenericDispatchEvent(art::Thread* thread,
-                                                 ArtJvmtiEvent event,
-                                                 Args... args) const;
-  template <typename ...Args>
-  ALWAYS_INLINE inline void DispatchClassFileLoadHookEvent(art::Thread* thread,
-                                                           ArtJvmtiEvent event,
-                                                           Args... args) const;
-
   void HandleEventType(ArtJvmtiEvent event, bool enable);
 
   // List of all JvmTiEnv objects that have been created, in their creation order.
diff --git a/runtime/openjdkjvmti/ti_redefine.cc b/runtime/openjdkjvmti/ti_redefine.cc
index 28ea267..6af51c4 100644
--- a/runtime/openjdkjvmti/ti_redefine.cc
+++ b/runtime/openjdkjvmti/ti_redefine.cc
@@ -242,12 +242,14 @@
   }
 }
 
+// TODO This should handle doing multiple classes at once so we need to do less cleanup when things
+// go wrong.
 jvmtiError Redefiner::RedefineClasses(ArtJvmTiEnv* env,
                                       art::Runtime* runtime,
                                       art::Thread* self,
                                       jint class_count,
                                       const jvmtiClassDefinition* definitions,
-                                      /*out*/std::string* error_msg) {
+                                      std::string* error_msg) {
   if (env == nullptr) {
     *error_msg = "env was null!";
     return ERR(INVALID_ENVIRONMENT);
@@ -261,83 +263,46 @@
     *error_msg = "null definitions!";
     return ERR(NULL_POINTER);
   }
-  std::vector<ArtClassDefinition> def_vector;
-  def_vector.reserve(class_count);
-  for (jint i = 0; i < class_count; i++) {
-    ArtClassDefinition def;
-    def.dex_len = definitions[i].class_byte_count;
-    def.dex_data = MakeJvmtiUniquePtr(env, const_cast<unsigned char*>(definitions[i].class_bytes));
-    // We are definitely modified.
-    def.modified = true;
-    jvmtiError res = Transformer::FillInTransformationData(env, definitions[i].klass, &def);
-    if (res != OK) {
-      return res;
-    }
-    def_vector.push_back(std::move(def));
-  }
-  // Call all the transformation events.
-  jvmtiError res = Transformer::RetransformClassesDirect(env,
-                                                         self,
-                                                         &def_vector);
-  if (res != OK) {
-    // Something went wrong with transformation!
-    return res;
-  }
-  return RedefineClassesDirect(env, runtime, self, def_vector, error_msg);
-}
-
-jvmtiError Redefiner::RedefineClassesDirect(ArtJvmTiEnv* env,
-                                            art::Runtime* runtime,
-                                            art::Thread* self,
-                                            const std::vector<ArtClassDefinition>& definitions,
-                                            std::string* error_msg) {
-  DCHECK(env != nullptr);
-  if (definitions.size() == 0) {
-    // We don't actually need to do anything. Just return OK.
-    return OK;
-  }
   // Stop JIT for the duration of this redefine since the JIT might concurrently compile a method we
   // are going to redefine.
   art::jit::ScopedJitSuspend suspend_jit;
   // Get shared mutator lock so we can lock all the classes.
   art::ScopedObjectAccess soa(self);
   std::vector<Redefiner::ClassRedefinition> redefinitions;
-  redefinitions.reserve(definitions.size());
+  redefinitions.reserve(class_count);
   Redefiner r(runtime, self, error_msg);
-  for (const ArtClassDefinition& def : definitions) {
-    // Only try to transform classes that have been modified.
-    if (def.modified) {
-      jvmtiError res = r.AddRedefinition(env, def);
-      if (res != OK) {
-        return res;
-      }
+  for (jint i = 0; i < class_count; i++) {
+    jvmtiError res = r.AddRedefinition(env, definitions[i]);
+    if (res != OK) {
+      return res;
     }
   }
   return r.Run();
 }
 
-jvmtiError Redefiner::AddRedefinition(ArtJvmTiEnv* env, const ArtClassDefinition& def) {
+jvmtiError Redefiner::AddRedefinition(ArtJvmTiEnv* env, const jvmtiClassDefinition& def) {
   std::string original_dex_location;
   jvmtiError ret = OK;
   if ((ret = GetClassLocation(env, def.klass, &original_dex_location))) {
     *error_msg_ = "Unable to get original dex file location!";
     return ret;
   }
-  char* generic_ptr_unused = nullptr;
-  char* signature_ptr = nullptr;
-  if ((ret = env->GetClassSignature(def.klass, &signature_ptr, &generic_ptr_unused)) != OK) {
-    *error_msg_ = "Unable to get class signature!";
-    return ret;
-  }
-  JvmtiUniquePtr generic_unique_ptr(MakeJvmtiUniquePtr(env, generic_ptr_unused));
-  JvmtiUniquePtr signature_unique_ptr(MakeJvmtiUniquePtr(env, signature_ptr));
   std::unique_ptr<art::MemMap> map(MoveDataToMemMap(original_dex_location,
-                                                    def.dex_len,
-                                                    def.dex_data.get(),
+                                                    def.class_byte_count,
+                                                    def.class_bytes,
                                                     error_msg_));
   std::ostringstream os;
+  char* generic_ptr_unused = nullptr;
+  char* signature_ptr = nullptr;
+  if (env->GetClassSignature(def.klass, &signature_ptr, &generic_ptr_unused) != OK) {
+    *error_msg_ = "A jclass passed in does not seem to be valid";
+    return ERR(INVALID_CLASS);
+  }
+  // These will make sure we deallocate the signature.
+  JvmtiUniquePtr sig_unique_ptr(MakeJvmtiUniquePtr(env, signature_ptr));
+  JvmtiUniquePtr generic_unique_ptr(MakeJvmtiUniquePtr(env, generic_ptr_unused));
   if (map.get() == nullptr) {
-    os << "Failed to create anonymous mmap for modified dex file of class " << def.name
+    os << "Failed to create anonymous mmap for modified dex file of class " << signature_ptr
        << "in dex file " << original_dex_location << " because: " << *error_msg_;
     *error_msg_ = os.str();
     return ERR(OUT_OF_MEMORY);
@@ -354,7 +319,7 @@
                                                                   /*verify_checksum*/true,
                                                                   error_msg_));
   if (dex_file.get() == nullptr) {
-    os << "Unable to load modified dex file for " << def.name << ": " << *error_msg_;
+    os << "Unable to load modified dex file for " << signature_ptr << ": " << *error_msg_;
     *error_msg_ = os.str();
     return ERR(INVALID_CLASS_FORMAT);
   }
@@ -1024,16 +989,17 @@
 // Performs updates to class that will allow us to verify it.
 void Redefiner::ClassRedefinition::UpdateClass(art::ObjPtr<art::mirror::Class> mclass,
                                                art::ObjPtr<art::mirror::DexCache> new_dex_cache) {
-  DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
-  const art::DexFile::ClassDef& class_def = dex_file_->GetClassDef(0);
-  UpdateMethods(mclass, new_dex_cache, class_def);
+  const art::DexFile::ClassDef* class_def = art::OatFile::OatDexFile::FindClassDef(
+      *dex_file_, class_sig_.c_str(), art::ComputeModifiedUtf8Hash(class_sig_.c_str()));
+  DCHECK(class_def != nullptr);
+  UpdateMethods(mclass, new_dex_cache, *class_def);
   UpdateFields(mclass);
 
   // Update the class fields.
   // Need to update class last since the ArtMethod gets its DexFile from the class (which is needed
   // to call GetReturnTypeDescriptor and GetParameterTypeList above).
   mclass->SetDexCache(new_dex_cache.Ptr());
-  mclass->SetDexClassDefIndex(dex_file_->GetIndexForClassDef(class_def));
+  mclass->SetDexClassDefIndex(dex_file_->GetIndexForClassDef(*class_def));
   mclass->SetDexTypeIndex(dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(class_sig_.c_str())));
 }
 
diff --git a/runtime/openjdkjvmti/ti_redefine.h b/runtime/openjdkjvmti/ti_redefine.h
index f8d51ad..8626bc5 100644
--- a/runtime/openjdkjvmti/ti_redefine.h
+++ b/runtime/openjdkjvmti/ti_redefine.h
@@ -72,25 +72,13 @@
  public:
   // Redefine the given classes with the given dex data. Note this function does not take ownership
   // of the dex_data pointers. It is not used after this call however and may be freed if desired.
-  // The caller is responsible for freeing it. The runtime makes its own copy of the data. This
-  // function does not call the transformation events.
-  // TODO Check modified flag of the definitions.
-  static jvmtiError RedefineClassesDirect(ArtJvmTiEnv* env,
-                                          art::Runtime* runtime,
-                                          art::Thread* self,
-                                          const std::vector<ArtClassDefinition>& definitions,
-                                          /*out*/std::string* error_msg);
-
-  // Redefine the given classes with the given dex data. Note this function does not take ownership
-  // of the dex_data pointers. It is not used after this call however and may be freed if desired.
   // The caller is responsible for freeing it. The runtime makes its own copy of the data.
-  // TODO This function should call the transformation events.
   static jvmtiError RedefineClasses(ArtJvmTiEnv* env,
                                     art::Runtime* runtime,
                                     art::Thread* self,
                                     jint class_count,
                                     const jvmtiClassDefinition* definitions,
-                                    /*out*/std::string* error_msg);
+                                    std::string* error_msg);
 
   static jvmtiError IsModifiableClass(jvmtiEnv* env, jclass klass, jboolean* is_redefinable);
 
@@ -221,7 +209,7 @@
         redefinitions_(),
         error_msg_(error_msg) { }
 
-  jvmtiError AddRedefinition(ArtJvmTiEnv* env, const ArtClassDefinition& def)
+  jvmtiError AddRedefinition(ArtJvmTiEnv* env, const jvmtiClassDefinition& def)
       REQUIRES_SHARED(art::Locks::mutator_lock_);
 
   static jvmtiError GetClassRedefinitionError(art::Handle<art::mirror::Class> klass,
diff --git a/runtime/openjdkjvmti/transform.cc b/runtime/openjdkjvmti/transform.cc
index 2809cb6..f545125 100644
--- a/runtime/openjdkjvmti/transform.cc
+++ b/runtime/openjdkjvmti/transform.cc
@@ -38,7 +38,6 @@
 #include "class_linker.h"
 #include "dex_file.h"
 #include "dex_file_types.h"
-#include "events-inl.h"
 #include "gc_root-inl.h"
 #include "globals.h"
 #include "jni_env_ext-inl.h"
@@ -53,76 +52,12 @@
 #include "scoped_thread_state_change-inl.h"
 #include "stack.h"
 #include "thread_list.h"
-#include "ti_redefine.h"
 #include "transform.h"
 #include "utf.h"
 #include "utils/dex_cache_arrays_layout-inl.h"
 
 namespace openjdkjvmti {
 
-jvmtiError Transformer::RetransformClassesDirect(
-      ArtJvmTiEnv* env,
-      art::Thread* self,
-      /*in-out*/std::vector<ArtClassDefinition>* definitions) {
-  for (ArtClassDefinition& def : *definitions) {
-    jint new_len = -1;
-    unsigned char* new_data = nullptr;
-    // Static casts are so that we get the right template initialization for the special event
-    // handling code required by the ClassFileLoadHooks.
-    gEventHandler.DispatchEvent(self,
-                                ArtJvmtiEvent::kClassFileLoadHookRetransformable,
-                                GetJniEnv(env),
-                                static_cast<jclass>(def.klass),
-                                static_cast<jobject>(def.loader),
-                                static_cast<const char*>(def.name.c_str()),
-                                static_cast<jobject>(def.protection_domain),
-                                static_cast<jint>(def.dex_len),
-                                static_cast<const unsigned char*>(def.dex_data.get()),
-                                static_cast<jint*>(&new_len),
-                                static_cast<unsigned char**>(&new_data));
-    def.SetNewDexData(env, new_len, new_data);
-  }
-  return OK;
-}
-
-jvmtiError Transformer::RetransformClasses(ArtJvmTiEnv* env,
-                                           art::Runtime* runtime,
-                                           art::Thread* self,
-                                           jint class_count,
-                                           const jclass* classes,
-                                           /*out*/std::string* error_msg) {
-  if (env == nullptr) {
-    *error_msg = "env was null!";
-    return ERR(INVALID_ENVIRONMENT);
-  } else if (class_count < 0) {
-    *error_msg = "class_count was less then 0";
-    return ERR(ILLEGAL_ARGUMENT);
-  } else if (class_count == 0) {
-    // We don't actually need to do anything. Just return OK.
-    return OK;
-  } else if (classes == nullptr) {
-    *error_msg = "null classes!";
-    return ERR(NULL_POINTER);
-  }
-  // A holder that will Deallocate all the class bytes buffers on destruction.
-  std::vector<ArtClassDefinition> definitions;
-  jvmtiError res = OK;
-  for (jint i = 0; i < class_count; i++) {
-    ArtClassDefinition def;
-    res = FillInTransformationData(env, classes[i], &def);
-    if (res != OK) {
-      return res;
-    }
-    definitions.push_back(std::move(def));
-  }
-  res = RetransformClassesDirect(env, self, &definitions);
-  if (res != OK) {
-    return res;
-  }
-  return Redefiner::RedefineClassesDirect(env, runtime, self, definitions, error_msg);
-}
-
-// TODO Move this somewhere else, ti_class?
 jvmtiError GetClassLocation(ArtJvmTiEnv* env, jclass klass, /*out*/std::string* location) {
   JNIEnv* jni_env = nullptr;
   jint ret = env->art_vm->GetEnv(reinterpret_cast<void**>(&jni_env), JNI_VERSION_1_1);
@@ -138,61 +73,42 @@
   return OK;
 }
 
-// TODO Implement this for real once transformed dex data is actually saved.
-jvmtiError Transformer::GetDexDataForRetransformation(ArtJvmTiEnv* env,
-                                                      art::Handle<art::mirror::Class> klass,
-                                                      /*out*/jint* dex_data_len,
-                                                      /*out*/unsigned char** dex_data) {
-  // TODO De-quicken the dex file before passing it to the agents.
-  LOG(WARNING) << "Dex file is not de-quickened yet! Quickened dex instructions might be present";
-  LOG(WARNING) << "Caching of initial dex data is not yet performed! Dex data might have been "
-               << "transformed by agent already";
-  const art::DexFile& dex = klass->GetDexFile();
-  *dex_data_len = static_cast<jint>(dex.Size());
-  unsigned char* new_dex_data = nullptr;
-  jvmtiError alloc_error = env->Allocate(*dex_data_len, &new_dex_data);
+// TODO Move this function somewhere more appropriate.
+// Gets the data surrounding the given class.
+jvmtiError GetTransformationData(ArtJvmTiEnv* env,
+                                 jclass klass,
+                                 /*out*/std::string* location,
+                                 /*out*/JNIEnv** jni_env_ptr,
+                                 /*out*/jobject* loader,
+                                 /*out*/std::string* name,
+                                 /*out*/jobject* protection_domain,
+                                 /*out*/jint* data_len,
+                                 /*out*/unsigned char** dex_data) {
+  jint ret = env->art_vm->GetEnv(reinterpret_cast<void**>(jni_env_ptr), JNI_VERSION_1_1);
+  if (ret != JNI_OK) {
+    // TODO Different error might be better?
+    return ERR(INTERNAL);
+  }
+  JNIEnv* jni_env = *jni_env_ptr;
+  art::ScopedObjectAccess soa(jni_env);
+  art::StackHandleScope<3> hs(art::Thread::Current());
+  art::Handle<art::mirror::Class> hs_klass(hs.NewHandle(soa.Decode<art::mirror::Class>(klass)));
+  *loader = soa.AddLocalReference<jobject>(hs_klass->GetClassLoader());
+  *name = art::mirror::Class::ComputeName(hs_klass)->ToModifiedUtf8();
+  // TODO is this always null?
+  *protection_domain = nullptr;
+  const art::DexFile& dex = hs_klass->GetDexFile();
+  *location = dex.GetLocation();
+  *data_len = static_cast<jint>(dex.Size());
+  // TODO We should maybe change env->Allocate to allow us to mprotect this memory and stop writes.
+  jvmtiError alloc_error = env->Allocate(*data_len, dex_data);
   if (alloc_error != OK) {
     return alloc_error;
   }
   // Copy the data into a temporary buffer.
-  memcpy(reinterpret_cast<void*>(new_dex_data),
-         reinterpret_cast<const void*>(dex.Begin()),
-         *dex_data_len);
-  *dex_data = new_dex_data;
-  return OK;
-}
-
-// TODO Move this function somewhere more appropriate.
-// Gets the data surrounding the given class.
-// TODO Make this less magical.
-jvmtiError Transformer::FillInTransformationData(ArtJvmTiEnv* env,
-                                                 jclass klass,
-                                                 ArtClassDefinition* def) {
-  JNIEnv* jni_env = GetJniEnv(env);
-  if (jni_env == nullptr) {
-    // TODO Different error might be better?
-    return ERR(INTERNAL);
-  }
-  art::ScopedObjectAccess soa(jni_env);
-  art::StackHandleScope<3> hs(art::Thread::Current());
-  art::Handle<art::mirror::Class> hs_klass(hs.NewHandle(soa.Decode<art::mirror::Class>(klass)));
-  if (hs_klass.IsNull()) {
-    return ERR(INVALID_CLASS);
-  }
-  def->klass = klass;
-  def->loader = soa.AddLocalReference<jobject>(hs_klass->GetClassLoader());
-  def->name = art::mirror::Class::ComputeName(hs_klass)->ToModifiedUtf8();
-  // TODO is this always null?
-  def->protection_domain = nullptr;
-  if (def->dex_data.get() == nullptr) {
-    unsigned char* new_data;
-    jvmtiError res = GetDexDataForRetransformation(env, hs_klass, &def->dex_len, &new_data);
-    if (res == OK) {
-      def->dex_data = MakeJvmtiUniquePtr(env, new_data);
-    } else {
-      return res;
-    }
-  }
+  memcpy(reinterpret_cast<void*>(*dex_data),
+          reinterpret_cast<const void*>(dex.Begin()),
+          *data_len);
   return OK;
 }
 
diff --git a/runtime/openjdkjvmti/transform.h b/runtime/openjdkjvmti/transform.h
index 0ff2bd1..0ad5099 100644
--- a/runtime/openjdkjvmti/transform.h
+++ b/runtime/openjdkjvmti/transform.h
@@ -43,30 +43,16 @@
 
 jvmtiError GetClassLocation(ArtJvmTiEnv* env, jclass klass, /*out*/std::string* location);
 
-class Transformer {
- public:
-  static jvmtiError RetransformClassesDirect(
-      ArtJvmTiEnv* env, art::Thread* self, /*in-out*/std::vector<ArtClassDefinition>* definitions);
-
-  static jvmtiError RetransformClasses(ArtJvmTiEnv* env,
-                                       art::Runtime* runtime,
-                                       art::Thread* self,
-                                       jint class_count,
-                                       const jclass* classes,
-                                       /*out*/std::string* error_msg);
-
-  // Gets the data surrounding the given class.
-  static jvmtiError FillInTransformationData(ArtJvmTiEnv* env,
-                                             jclass klass,
-                                             ArtClassDefinition* def);
-
- private:
-  static jvmtiError GetDexDataForRetransformation(ArtJvmTiEnv* env,
-                                                  art::Handle<art::mirror::Class> klass,
-                                                  /*out*/jint* dex_data_length,
-                                                  /*out*/unsigned char** dex_data)
-      REQUIRES_SHARED(art::Locks::mutator_lock_);
-};
+// Gets the data surrounding the given class.
+jvmtiError GetTransformationData(ArtJvmTiEnv* env,
+                                 jclass klass,
+                                 /*out*/std::string* location,
+                                 /*out*/JNIEnv** jni_env_ptr,
+                                 /*out*/jobject* loader,
+                                 /*out*/std::string* name,
+                                 /*out*/jobject* protection_domain,
+                                 /*out*/jint* data_len,
+                                 /*out*/unsigned char** dex_data);
 
 }  // namespace openjdkjvmti
 
diff --git a/test/921-hello-failure/expected.txt b/test/921-hello-failure/expected.txt
index 9615e6b..1c1d4d9 100644
--- a/test/921-hello-failure/expected.txt
+++ b/test/921-hello-failure/expected.txt
@@ -21,11 +21,3 @@
 Transformation error : java.lang.Exception(Failed to redefine classes <LTransform;, LTransform2;> due to JVMTI_ERROR_NAMES_DONT_MATCH)
 hello - MultiRedef
 hello2 - MultiRedef
-hello - MultiRetrans
-hello2 - MultiRetrans
-Transformation error : java.lang.Exception(Failed to retransform classes <LTransform2;, LTransform;> due to JVMTI_ERROR_NAMES_DONT_MATCH)
-hello - MultiRetrans
-hello2 - MultiRetrans
-Transformation error : java.lang.Exception(Failed to retransform classes <LTransform;, LTransform2;> due to JVMTI_ERROR_NAMES_DONT_MATCH)
-hello - MultiRetrans
-hello2 - MultiRetrans
diff --git a/test/921-hello-failure/src/Main.java b/test/921-hello-failure/src/Main.java
index 43d6e9e..1fe2599 100644
--- a/test/921-hello-failure/src/Main.java
+++ b/test/921-hello-failure/src/Main.java
@@ -25,7 +25,6 @@
     MissingInterface.doTest(new Transform2());
     ReorderInterface.doTest(new Transform2());
     MultiRedef.doTest(new Transform(), new Transform2());
-    MultiRetrans.doTest(new Transform(), new Transform2());
   }
 
   // Transforms the class. This throws an exception if something goes wrong.
@@ -48,20 +47,7 @@
                                    dex_files.toArray(new byte[0][]));
   }
 
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) throws Exception {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
   public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
                                                            byte[][] classfiles,
                                                            byte[][] dexfiles) throws Exception;
-  public static native void doCommonClassRetransformation(Class<?>... target) throws Exception;
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
 }
diff --git a/test/921-hello-failure/src/MultiRetrans.java b/test/921-hello-failure/src/MultiRetrans.java
deleted file mode 100644
index 95aaf07..0000000
--- a/test/921-hello-failure/src/MultiRetrans.java
+++ /dev/null
@@ -1,108 +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.util.Base64;
-
-class MultiRetrans {
-
-  // class NotTransform {
-  //   public void sayHi(String name) {
-  //     throw new Error("Should not be called!");
-  //   }
-  // }
-  private static CommonClassDefinition INVALID_DEFINITION_T1 = new CommonClassDefinition(
-      Transform.class,
-      Base64.getDecoder().decode(
-          "yv66vgAAADQAFQoABgAPBwAQCAARCgACABIHABMHABQBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAP" +
-          "TGluZU51bWJlclRhYmxlAQAFc2F5SGkBABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAApTb3VyY2VG" +
-          "aWxlAQARTm90VHJhbnNmb3JtLmphdmEMAAcACAEAD2phdmEvbGFuZy9FcnJvcgEAFVNob3VsZCBu" +
-          "b3QgYmUgY2FsbGVkIQwABwAMAQAMTm90VHJhbnNmb3JtAQAQamF2YS9sYW5nL09iamVjdAAgAAUA" +
-          "BgAAAAAAAgAAAAcACAABAAkAAAAdAAEAAQAAAAUqtwABsQAAAAEACgAAAAYAAQAAAAEAAQALAAwA" +
-          "AQAJAAAAIgADAAIAAAAKuwACWRIDtwAEvwAAAAEACgAAAAYAAQAAAAMAAQANAAAAAgAO"),
-      Base64.getDecoder().decode(
-          "ZGV4CjAzNQDLV95i5xnv6iUi6uIeDoY5jP5Xe9NP1AiYAgAAcAAAAHhWNBIAAAAAAAAAAAQCAAAL" +
-          "AAAAcAAAAAUAAACcAAAAAgAAALAAAAAAAAAAAAAAAAQAAADIAAAAAQAAAOgAAACQAQAACAEAAEoB" +
-          "AABSAQAAYgEAAHUBAACJAQAAnQEAALABAADHAQAAygEAAM4BAADiAQAAAQAAAAIAAAADAAAABAAA" +
-          "AAcAAAAHAAAABAAAAAAAAAAIAAAABAAAAEQBAAAAAAAAAAAAAAAAAQAKAAAAAQABAAAAAAACAAAA" +
-          "AAAAAAAAAAAAAAAAAgAAAAAAAAAFAAAAAAAAAPQBAAAAAAAAAQABAAEAAADpAQAABAAAAHAQAwAA" +
-          "AA4ABAACAAIAAADuAQAACQAAACIAAQAbAQYAAABwIAIAEAAnAAAAAQAAAAMABjxpbml0PgAOTE5v" +
-          "dFRyYW5zZm9ybTsAEUxqYXZhL2xhbmcvRXJyb3I7ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZh" +
-          "L2xhbmcvU3RyaW5nOwARTm90VHJhbnNmb3JtLmphdmEAFVNob3VsZCBub3QgYmUgY2FsbGVkIQAB" +
-          "VgACVkwAEmVtaXR0ZXI6IGphY2stNC4yMAAFc2F5SGkAAQAHDgADAQAHDgAAAAEBAICABIgCAQGg" +
-          "AgAADAAAAAAAAAABAAAAAAAAAAEAAAALAAAAcAAAAAIAAAAFAAAAnAAAAAMAAAACAAAAsAAAAAUA" +
-          "AAAEAAAAyAAAAAYAAAABAAAA6AAAAAEgAAACAAAACAEAAAEQAAABAAAARAEAAAIgAAALAAAASgEA" +
-          "AAMgAAACAAAA6QEAAAAgAAABAAAA9AEAAAAQAAABAAAABAIAAA=="));
-
-  // Valid redefinition of Transform2
-  // class Transform2 implements Iface1, Iface2 {
-  //   public void sayHi(String name) {
-  //     throw new Error("Should not be called!");
-  //   }
-  // }
-  private static CommonClassDefinition VALID_DEFINITION_T2 = new CommonClassDefinition(
-      Transform2.class,
-      Base64.getDecoder().decode(
-          "yv66vgAAADQAGQoABgARBwASCAATCgACABQHABUHABYHABcHABgBAAY8aW5pdD4BAAMoKVYBAARD" +
-          "b2RlAQAPTGluZU51bWJlclRhYmxlAQAFc2F5SGkBABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAApT" +
-          "b3VyY2VGaWxlAQAPVHJhbnNmb3JtMi5qYXZhDAAJAAoBAA9qYXZhL2xhbmcvRXJyb3IBABVTaG91" +
-          "bGQgbm90IGJlIGNhbGxlZCEMAAkADgEAClRyYW5zZm9ybTIBABBqYXZhL2xhbmcvT2JqZWN0AQAG" +
-          "SWZhY2UxAQAGSWZhY2UyACAABQAGAAIABwAIAAAAAgAAAAkACgABAAsAAAAdAAEAAQAAAAUqtwAB" +
-          "sQAAAAEADAAAAAYAAQAAAAEAAQANAA4AAQALAAAAIgADAAIAAAAKuwACWRIDtwAEvwAAAAEADAAA" +
-          "AAYAAQAAAAMAAQAPAAAAAgAQ"),
-      Base64.getDecoder().decode(
-          "ZGV4CjAzNQDSWls05CPkX+gbTGMVRvx9dc9vozzVbu7AAgAAcAAAAHhWNBIAAAAAAAAAACwCAAAN" +
-          "AAAAcAAAAAcAAACkAAAAAgAAAMAAAAAAAAAAAAAAAAQAAADYAAAAAQAAAPgAAACoAQAAGAEAAGIB" +
-          "AABqAQAAdAEAAH4BAACMAQAAnwEAALMBAADHAQAA3gEAAO8BAADyAQAA9gEAAAoCAAABAAAAAgAA" +
-          "AAMAAAAEAAAABQAAAAYAAAAJAAAACQAAAAYAAAAAAAAACgAAAAYAAABcAQAAAgAAAAAAAAACAAEA" +
-          "DAAAAAMAAQAAAAAABAAAAAAAAAACAAAAAAAAAAQAAABUAQAACAAAAAAAAAAcAgAAAAAAAAEAAQAB" +
-          "AAAAEQIAAAQAAABwEAMAAAAOAAQAAgACAAAAFgIAAAkAAAAiAAMAGwEHAAAAcCACABAAJwAAAAIA" +
-          "AAAAAAEAAQAAAAUABjxpbml0PgAITElmYWNlMTsACExJZmFjZTI7AAxMVHJhbnNmb3JtMjsAEUxq" +
-          "YXZhL2xhbmcvRXJyb3I7ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAV" +
-          "U2hvdWxkIG5vdCBiZSBjYWxsZWQhAA9UcmFuc2Zvcm0yLmphdmEAAVYAAlZMABJlbWl0dGVyOiBq" +
-          "YWNrLTQuMjAABXNheUhpAAEABw4AAwEABw4AAAABAQCAgASYAgEBsAIAAAwAAAAAAAAAAQAAAAAA" +
-          "AAABAAAADQAAAHAAAAACAAAABwAAAKQAAAADAAAAAgAAAMAAAAAFAAAABAAAANgAAAAGAAAAAQAA" +
-          "APgAAAABIAAAAgAAABgBAAABEAAAAgAAAFQBAAACIAAADQAAAGIBAAADIAAAAgAAABECAAAAIAAA" +
-          "AQAAABwCAAAAEAAAAQAAACwCAAA="));
-
-  public static void doTest(Transform t1, Transform2 t2) {
-    t1.sayHi("MultiRetrans");
-    t2.sayHi("MultiRetrans");
-    try {
-      Main.addMultiTransformationResults(VALID_DEFINITION_T2, INVALID_DEFINITION_T1);
-      Main.enableCommonRetransformation(true);
-      Main.doCommonClassRetransformation(Transform2.class, Transform.class);
-    } catch (Exception e) {
-      System.out.println(
-          "Transformation error : " + e.getClass().getName() + "(" + e.getMessage() + ")");
-    } finally {
-      Main.enableCommonRetransformation(false);
-    }
-    t1.sayHi("MultiRetrans");
-    t2.sayHi("MultiRetrans");
-    try {
-      Main.addMultiTransformationResults(VALID_DEFINITION_T2, INVALID_DEFINITION_T1);
-      Main.enableCommonRetransformation(true);
-      Main.doCommonClassRetransformation(Transform.class, Transform2.class);
-    } catch (Exception e) {
-      System.out.println(
-          "Transformation error : " + e.getClass().getName() + "(" + e.getMessage() + ")");
-    } finally {
-      Main.enableCommonRetransformation(false);
-    }
-    t1.sayHi("MultiRetrans");
-    t2.sayHi("MultiRetrans");
-  }
-}
diff --git a/test/930-hello-retransform/build b/test/930-hello-retransform/build
deleted file mode 100755
index 898e2e5..0000000
--- a/test/930-hello-retransform/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/930-hello-retransform/expected.txt b/test/930-hello-retransform/expected.txt
deleted file mode 100644
index 4774b81..0000000
--- a/test/930-hello-retransform/expected.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-hello
-Goodbye
diff --git a/test/930-hello-retransform/info.txt b/test/930-hello-retransform/info.txt
deleted file mode 100644
index 875a5f6..0000000
--- a/test/930-hello-retransform/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Tests basic functions in the jvmti plugin.
diff --git a/test/930-hello-retransform/run b/test/930-hello-retransform/run
deleted file mode 100755
index 4379349..0000000
--- a/test/930-hello-retransform/run
+++ /dev/null
@@ -1,19 +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 "$@" --experimental agents \
-                   --experimental runtime-plugins \
-                   --jvmti
diff --git a/test/930-hello-retransform/src/Main.java b/test/930-hello-retransform/src/Main.java
deleted file mode 100644
index 12194c3..0000000
--- a/test/930-hello-retransform/src/Main.java
+++ /dev/null
@@ -1,70 +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 {
-
-  /**
-   * base64 encoded class/dex file for
-   * class Transform {
-   *   public void sayHi() {
-   *    System.out.println("Goodbye");
-   *   }
-   * }
-   */
-  private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
-    "yv66vgAAADQAHAoABgAOCQAPABAIABEKABIAEwcAFAcAFQEABjxpbml0PgEAAygpVgEABENvZGUB" +
-    "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAA5UcmFuc2Zvcm0uamF2YQwA" +
-    "BwAIBwAWDAAXABgBAAdHb29kYnllBwAZDAAaABsBAAlUcmFuc2Zvcm0BABBqYXZhL2xhbmcvT2Jq" +
-    "ZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2ph" +
-    "dmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWACAABQAG" +
-    "AAAAAAACAAAABwAIAAEACQAAAB0AAQABAAAABSq3AAGxAAAAAQAKAAAABgABAAAAEQABAAsACAAB" +
-    "AAkAAAAlAAIAAQAAAAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAATAAgAFAABAAwAAAACAA0=");
-  private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
-    "ZGV4CjAzNQCLXSBQ5FiS3f16krSYZFF8xYZtFVp0GRXMAgAAcAAAAHhWNBIAAAAAAAAAACwCAAAO" +
-    "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACsAQAAIAEAAGIB" +
-    "AABqAQAAcwEAAIABAACXAQAAqwEAAL8BAADTAQAA4wEAAOYBAADqAQAA/gEAAAMCAAAMAgAAAgAA" +
-    "AAMAAAAEAAAABQAAAAYAAAAIAAAACAAAAAUAAAAAAAAACQAAAAUAAABcAQAABAABAAsAAAAAAAAA" +
-    "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAHAAAAAAAAAB4CAAAA" +
-    "AAAAAQABAAEAAAATAgAABAAAAHAQAwAAAA4AAwABAAIAAAAYAgAACQAAAGIAAAAbAQEAAABuIAIA" +
-    "EAAOAAAAAQAAAAMABjxpbml0PgAHR29vZGJ5ZQALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50" +
-    "U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xh" +
-    "bmcvU3lzdGVtOwAOVHJhbnNmb3JtLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTMuMzYAA291" +
-    "dAAHcHJpbnRsbgAFc2F5SGkAEQAHDgATAAcOhQAAAAEBAICABKACAQG4Ag0AAAAAAAAAAQAAAAAA" +
-    "AAABAAAADgAAAHAAAAACAAAABgAAAKgAAAADAAAAAgAAAMAAAAAEAAAAAQAAANgAAAAFAAAABAAA" +
-    "AOAAAAAGAAAAAQAAAAABAAABIAAAAgAAACABAAABEAAAAQAAAFwBAAACIAAADgAAAGIBAAADIAAA" +
-    "AgAAABMCAAAAIAAAAQAAAB4CAAAAEAAAAQAAACwCAAA=");
-
-  public static void main(String[] args) {
-    System.loadLibrary(args[1]);
-    doTest(new Transform());
-  }
-
-  public static void doTest(Transform t) {
-    t.sayHi();
-    addCommonTransformationResult("Transform", CLASS_BYTES, DEX_BYTES);
-    enableCommonRetransformation(true);
-    doCommonClassRetransformation(Transform.class);
-    t.sayHi();
-  }
-
-  // Transforms the class
-  private static native void doCommonClassRetransformation(Class<?>... target);
-  private static native void enableCommonRetransformation(boolean enable);
-  private static native void addCommonTransformationResult(String target_name,
-                                                           byte[] class_bytes,
-                                                           byte[] dex_bytes);
-}
diff --git a/test/930-hello-retransform/src/Transform.java b/test/930-hello-retransform/src/Transform.java
deleted file mode 100644
index 8e8af35..0000000
--- a/test/930-hello-retransform/src/Transform.java
+++ /dev/null
@@ -1,28 +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() {
-    // 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:
-    // "Goodbye" < "LTransform;" < "hello".
-    System.out.println("hello");
-  }
-}
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 38b88e4..e604c93 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -309,7 +309,6 @@
   927-timers \
   928-jni-table \
   929-search \
-  930-hello-retransform \
 
 ifneq (,$(filter target,$(TARGET_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,target,$(RUN_TYPES),$(PREBUILD_TYPES), \
diff --git a/test/ti-agent/common_helper.cc b/test/ti-agent/common_helper.cc
index 8799c91..2c6d3ed 100644
--- a/test/ti-agent/common_helper.cc
+++ b/test/ti-agent/common_helper.cc
@@ -18,7 +18,6 @@
 
 #include <stdio.h>
 #include <sstream>
-#include <deque>
 
 #include "art_method.h"
 #include "jni.h"
@@ -61,17 +60,17 @@
   return true;
 }
 
+namespace common_redefine {
 
-template <bool is_redefine>
-static void throwCommonRedefinitionError(jvmtiEnv* jvmti,
-                                         JNIEnv* env,
-                                         jint num_targets,
-                                         jclass* target,
-                                         jvmtiError res) {
+static void throwRedefinitionError(jvmtiEnv* jvmti,
+                                   JNIEnv* env,
+                                   jint num_targets,
+                                   jclass* target,
+                                   jvmtiError res) {
   std::stringstream err;
   char* error = nullptr;
   jvmti->GetErrorName(res, &error);
-  err << "Failed to " << (is_redefine ? "redefine" : "retransform") << " class";
+  err << "Failed to redefine class";
   if (num_targets > 1) {
     err << "es";
   }
@@ -93,16 +92,6 @@
   env->ThrowNew(env->FindClass("java/lang/Exception"), message.c_str());
 }
 
-namespace common_redefine {
-
-static void throwRedefinitionError(jvmtiEnv* jvmti,
-                                   JNIEnv* env,
-                                   jint num_targets,
-                                   jclass* target,
-                                   jvmtiError res) {
-  return throwCommonRedefinitionError<true>(jvmti, env, num_targets, target, res);
-}
-
 static void DoMultiClassRedefine(jvmtiEnv* jvmti_env,
                                  JNIEnv* env,
                                  jint num_redefines,
@@ -172,138 +161,7 @@
                               dex_files.data());
 }
 
-// Get all capabilities except those related to retransformation.
-jint OnLoad(JavaVM* vm,
-            char* options ATTRIBUTE_UNUSED,
-            void* reserved ATTRIBUTE_UNUSED) {
-  if (vm->GetEnv(reinterpret_cast<void**>(&jvmti_env), JVMTI_VERSION_1_0)) {
-    printf("Unable to get jvmti env!\n");
-    return 1;
-  }
-  jvmtiCapabilities caps;
-  jvmti_env->GetPotentialCapabilities(&caps);
-  caps.can_retransform_classes = 0;
-  caps.can_retransform_any_class = 0;
-  jvmti_env->AddCapabilities(&caps);
-  return 0;
-}
-
-}  // namespace common_redefine
-
-namespace common_retransform {
-
-struct CommonTransformationResult {
-  std::vector<unsigned char> class_bytes;
-  std::vector<unsigned char> dex_bytes;
-
-  CommonTransformationResult(size_t class_size, size_t dex_size)
-      : class_bytes(class_size), dex_bytes(dex_size) {}
-
-  CommonTransformationResult() = default;
-  CommonTransformationResult(CommonTransformationResult&&) = default;
-  CommonTransformationResult(CommonTransformationResult&) = default;
-};
-
-// Map from class name to transformation result.
-std::map<std::string, std::deque<CommonTransformationResult>> gTransformations;
-
-extern "C" JNIEXPORT void JNICALL Java_Main_addCommonTransformationResult(JNIEnv* env,
-                                                                          jclass,
-                                                                          jstring class_name,
-                                                                          jbyteArray class_array,
-                                                                          jbyteArray dex_array) {
-  const char* name_chrs = env->GetStringUTFChars(class_name, nullptr);
-  std::string name_str(name_chrs);
-  env->ReleaseStringUTFChars(class_name, name_chrs);
-  CommonTransformationResult trans(env->GetArrayLength(class_array),
-                                   env->GetArrayLength(dex_array));
-  if (env->ExceptionOccurred()) {
-    return;
-  }
-  env->GetByteArrayRegion(class_array,
-                          0,
-                          env->GetArrayLength(class_array),
-                          reinterpret_cast<jbyte*>(trans.class_bytes.data()));
-  if (env->ExceptionOccurred()) {
-    return;
-  }
-  env->GetByteArrayRegion(dex_array,
-                          0,
-                          env->GetArrayLength(dex_array),
-                          reinterpret_cast<jbyte*>(trans.dex_bytes.data()));
-  if (env->ExceptionOccurred()) {
-    return;
-  }
-  if (gTransformations.find(name_str) == gTransformations.end()) {
-    std::deque<CommonTransformationResult> list;
-    gTransformations[name_str] = std::move(list);
-  }
-  gTransformations[name_str].push_back(std::move(trans));
-}
-
-// The hook we are using.
-void JNICALL CommonClassFileLoadHookRetransformable(jvmtiEnv* jvmti_env,
-                                                    JNIEnv* jni_env ATTRIBUTE_UNUSED,
-                                                    jclass class_being_redefined ATTRIBUTE_UNUSED,
-                                                    jobject loader ATTRIBUTE_UNUSED,
-                                                    const char* name,
-                                                    jobject protection_domain ATTRIBUTE_UNUSED,
-                                                    jint class_data_len ATTRIBUTE_UNUSED,
-                                                    const unsigned char* class_dat ATTRIBUTE_UNUSED,
-                                                    jint* new_class_data_len,
-                                                    unsigned char** new_class_data) {
-  std::string name_str(name);
-  if (gTransformations.find(name_str) != gTransformations.end()) {
-    CommonTransformationResult& res = gTransformations[name_str][0];
-    const std::vector<unsigned char>& desired_array = IsJVM() ? res.class_bytes : res.dex_bytes;
-    unsigned char* new_data;
-    jvmti_env->Allocate(desired_array.size(), &new_data);
-    memcpy(new_data, desired_array.data(), desired_array.size());
-    *new_class_data = new_data;
-    *new_class_data_len = desired_array.size();
-    gTransformations[name_str].pop_front();
-  }
-}
-
-extern "C" JNIEXPORT void Java_Main_enableCommonRetransformation(JNIEnv* env,
-                                                                 jclass,
-                                                                 jboolean enable) {
-  jvmtiError res = jvmti_env->SetEventNotificationMode(enable ? JVMTI_ENABLE : JVMTI_DISABLE,
-                                                       JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
-                                                       nullptr);
-  if (res != JVMTI_ERROR_NONE) {
-    JvmtiErrorToException(env, res);
-  }
-}
-
-static void throwRetransformationError(jvmtiEnv* jvmti,
-                                       JNIEnv* env,
-                                       jint num_targets,
-                                       jclass* targets,
-                                       jvmtiError res) {
-  return throwCommonRedefinitionError<false>(jvmti, env, num_targets, targets, res);
-}
-
-static void DoClassRetransformation(jvmtiEnv* jvmti_env, JNIEnv* env, jobjectArray targets) {
-  std::vector<jclass> classes;
-  jint len = env->GetArrayLength(targets);
-  for (jint i = 0; i < len; i++) {
-    classes.push_back(static_cast<jclass>(env->GetObjectArrayElement(targets, i)));
-  }
-  jvmtiError res = jvmti_env->RetransformClasses(len, classes.data());
-  if (res != JVMTI_ERROR_NONE) {
-    throwRetransformationError(jvmti_env, env, len, classes.data(), res);
-  }
-}
-
-// TODO Write something useful.
-extern "C" JNIEXPORT void JNICALL Java_Main_doCommonClassRetransformation(JNIEnv* env,
-                                                                          jclass,
-                                                                          jobjectArray targets) {
-  DoClassRetransformation(jvmti_env, env, targets);
-}
-
-// Get all capabilities except those related to retransformation.
+// Don't do anything
 jint OnLoad(JavaVM* vm,
             char* options ATTRIBUTE_UNUSED,
             void* reserved ATTRIBUTE_UNUSED) {
@@ -312,16 +170,9 @@
     return 1;
   }
   SetAllCapabilities(jvmti_env);
-  jvmtiEventCallbacks cb;
-  memset(&cb, 0, sizeof(cb));
-  cb.ClassFileLoadHook = CommonClassFileLoadHookRetransformable;
-  if (jvmti_env->SetEventCallbacks(&cb, sizeof(cb)) != JVMTI_ERROR_NONE) {
-    printf("Unable to set class file load hook cb!\n");
-    return 1;
-  }
   return 0;
 }
 
-}  // namespace common_retransform
+}  // namespace common_redefine
 
 }  // namespace art
diff --git a/test/ti-agent/common_helper.h b/test/ti-agent/common_helper.h
index 8599fc4..642ca03 100644
--- a/test/ti-agent/common_helper.h
+++ b/test/ti-agent/common_helper.h
@@ -27,10 +27,6 @@
 jint OnLoad(JavaVM* vm, char* options, void* reserved);
 
 }  // namespace common_redefine
-namespace common_retransform {
-jint OnLoad(JavaVM* vm, char* options, void* reserved);
-}  // namespace common_retransform
-
 
 extern bool RuntimeIsJVM;
 
diff --git a/test/ti-agent/common_load.cc b/test/ti-agent/common_load.cc
index 1b11442..521e672 100644
--- a/test/ti-agent/common_load.cc
+++ b/test/ti-agent/common_load.cc
@@ -64,9 +64,8 @@
   { "916-obsolete-jit", common_redefine::OnLoad, nullptr },
   { "917-fields-transformation", common_redefine::OnLoad, nullptr },
   { "919-obsolete-fields", common_redefine::OnLoad, nullptr },
-  { "921-hello-failure", common_retransform::OnLoad, nullptr },
+  { "921-hello-failure", common_redefine::OnLoad, nullptr },
   { "926-multi-obsolescence", common_redefine::OnLoad, nullptr },
-  { "930-hello-retransform", common_retransform::OnLoad, nullptr },
 };
 
 static AgentLib* FindAgent(char* name) {