diff options
| -rw-r--r-- | runtime/openjdkjvmti/ti_class.cc | 4 | ||||
| -rw-r--r-- | runtime/openjdkjvmti/ti_class_definition.cc | 124 | ||||
| -rw-r--r-- | runtime/openjdkjvmti/ti_class_definition.h | 92 | ||||
| -rw-r--r-- | runtime/openjdkjvmti/ti_redefine.cc | 28 | ||||
| -rw-r--r-- | runtime/openjdkjvmti/ti_redefine.h | 3 | ||||
| -rw-r--r-- | runtime/openjdkjvmti/transform.cc | 129 | ||||
| -rw-r--r-- | runtime/openjdkjvmti/transform.h | 12 |
7 files changed, 207 insertions, 185 deletions
diff --git a/runtime/openjdkjvmti/ti_class.cc b/runtime/openjdkjvmti/ti_class.cc index 4cdb148ff4..e94c4e6112 100644 --- a/runtime/openjdkjvmti/ti_class.cc +++ b/runtime/openjdkjvmti/ti_class.cc @@ -81,9 +81,9 @@ static std::unique_ptr<const art::DexFile> MakeSingleDexFile(art::Thread* self, REQUIRES_SHARED(art::Locks::mutator_lock_) { // Make the mmap std::string error_msg; + art::ArraySlice<const unsigned char> final_data(final_dex_data, final_len); std::unique_ptr<art::MemMap> map(Redefiner::MoveDataToMemMap(orig_location, - final_len, - final_dex_data, + final_data, &error_msg)); if (map.get() == nullptr) { LOG(WARNING) << "Unable to allocate mmap for redefined dex file! Error was: " << error_msg; diff --git a/runtime/openjdkjvmti/ti_class_definition.cc b/runtime/openjdkjvmti/ti_class_definition.cc index de8d8fe576..153692b2fe 100644 --- a/runtime/openjdkjvmti/ti_class_definition.cc +++ b/runtime/openjdkjvmti/ti_class_definition.cc @@ -31,11 +31,14 @@ #include "ti_class_definition.h" +#include "base/array_slice.h" #include "dex_file.h" +#include "fixed_up_dex_file.h" #include "handle_scope-inl.h" #include "handle.h" #include "mirror/class-inl.h" #include "mirror/object-inl.h" +#include "reflection.h" #include "thread.h" namespace openjdkjvmti { @@ -43,15 +46,130 @@ namespace openjdkjvmti { bool ArtClassDefinition::IsModified() const { // RedefineClasses calls always are 'modified' since they need to change the original_dex_file of // the class. - if (redefined) { + if (redefined_) { return true; } // Check if the dex file we want to set is the same as the current one. // Unfortunately we need to do this check even if no modifications have been done since it could // be that agents were removed in the mean-time so we still have a different dex file. The dex // checksum means this is likely to be fairly fast. - return static_cast<jint>(original_dex_file.size()) != dex_len || - memcmp(&original_dex_file.At(0), dex_data.get(), dex_len) != 0; + return static_cast<jint>(original_dex_file_.size()) != dex_len_ || + memcmp(&original_dex_file_.At(0), dex_data_.get(), dex_len_) != 0; +} + +jvmtiError ArtClassDefinition::InitCommon(ArtJvmTiEnv* env, jclass klass) { + JNIEnv* jni_env = GetJniEnv(env); + if (jni_env == nullptr) { + return ERR(INTERNAL); + } + art::ScopedObjectAccess soa(jni_env); + art::ObjPtr<art::mirror::Class> m_klass(soa.Decode<art::mirror::Class>(klass)); + if (m_klass.IsNull()) { + return ERR(INVALID_CLASS); + } + klass_ = klass; + loader_ = soa.AddLocalReference<jobject>(m_klass->GetClassLoader()); + std::string descriptor_store; + std::string descriptor(m_klass->GetDescriptor(&descriptor_store)); + name_ = descriptor.substr(1, descriptor.size() - 2); + // Android doesn't really have protection domains. + protection_domain_ = nullptr; + return OK; +} + +// Gets the data surrounding the given class. +static jvmtiError GetDexDataForRetransformation(ArtJvmTiEnv* env, + art::Handle<art::mirror::Class> klass, + /*out*/jint* dex_data_len, + /*out*/unsigned char** dex_data) + REQUIRES_SHARED(art::Locks::mutator_lock_) { + art::StackHandleScope<3> hs(art::Thread::Current()); + art::Handle<art::mirror::ClassExt> ext(hs.NewHandle(klass->GetExtData())); + const art::DexFile* dex_file = nullptr; + if (!ext.IsNull()) { + art::Handle<art::mirror::Object> orig_dex(hs.NewHandle(ext->GetOriginalDexFile())); + if (!orig_dex.IsNull()) { + if (orig_dex->IsArrayInstance()) { + DCHECK(orig_dex->GetClass()->GetComponentType()->IsPrimitiveByte()); + art::Handle<art::mirror::ByteArray> orig_dex_bytes( + hs.NewHandle(art::down_cast<art::mirror::ByteArray*>(orig_dex->AsArray()))); + *dex_data_len = static_cast<jint>(orig_dex_bytes->GetLength()); + return CopyDataIntoJvmtiBuffer( + env, + reinterpret_cast<const unsigned char*>(orig_dex_bytes->GetData()), + *dex_data_len, + /*out*/dex_data); + } else if (orig_dex->IsDexCache()) { + dex_file = orig_dex->AsDexCache()->GetDexFile(); + } else { + DCHECK_EQ(orig_dex->GetClass()->GetPrimitiveType(), art::Primitive::kPrimLong); + art::ObjPtr<art::mirror::Class> prim_long_class( + art::Runtime::Current()->GetClassLinker()->GetClassRoot( + art::ClassLinker::kPrimitiveLong)); + art::JValue val; + if (!art::UnboxPrimitiveForResult(orig_dex.Get(), prim_long_class, &val)) { + // This should never happen. + return ERR(INTERNAL); + } + dex_file = reinterpret_cast<const art::DexFile*>(static_cast<uintptr_t>(val.GetJ())); + } + } + } + if (dex_file == nullptr) { + dex_file = &klass->GetDexFile(); + } + std::unique_ptr<FixedUpDexFile> fixed_dex_file(FixedUpDexFile::Create(*dex_file)); + *dex_data_len = static_cast<jint>(fixed_dex_file->Size()); + return CopyDataIntoJvmtiBuffer(env, + fixed_dex_file->Begin(), + fixed_dex_file->Size(), + /*out*/dex_data); +} + +jvmtiError ArtClassDefinition::Init(ArtJvmTiEnv* env, jclass klass) { + jvmtiError res = InitCommon(env, klass); + if (res != OK) { + return res; + } + unsigned char* new_data = nullptr; + art::Thread* self = art::Thread::Current(); + art::ScopedObjectAccess soa(self); + art::StackHandleScope<1> hs(self); + art::Handle<art::mirror::Class> m_klass(hs.NewHandle(self->DecodeJObject(klass)->AsClass())); + res = GetDexDataForRetransformation(env, m_klass, &dex_len_, &new_data); + if (res != OK) { + return res; + } + dex_data_ = MakeJvmtiUniquePtr(env, new_data); + if (m_klass->GetExtData() == nullptr || m_klass->GetExtData()->GetOriginalDexFile() == nullptr) { + // We have never redefined class this yet. Keep track of what the (de-quickened) dex file looks + // like so we can tell if anything has changed. Really we would like to just always do the + // 'else' block but the fact that we de-quickened stuff screws us over. + unsigned char* original_data_memory = nullptr; + res = CopyDataIntoJvmtiBuffer(env, dex_data_.get(), dex_len_, &original_data_memory); + original_dex_file_memory_ = MakeJvmtiUniquePtr(env, original_data_memory); + original_dex_file_ = art::ArraySlice<const unsigned char>(original_data_memory, dex_len_); + } else { + // We know that we have been redefined at least once (there is an original_dex_file set in + // the class) so we can just use the current dex file directly. + const art::DexFile& dex_file = m_klass->GetDexFile(); + original_dex_file_ = art::ArraySlice<const unsigned char>(dex_file.Begin(), dex_file.Size()); + } + return res; +} + +jvmtiError ArtClassDefinition::Init(ArtJvmTiEnv* env, const jvmtiClassDefinition& def) { + jvmtiError res = InitCommon(env, def.klass); + if (res != OK) { + return res; + } + unsigned char* new_data = nullptr; + original_dex_file_ = art::ArraySlice<const unsigned char>(def.class_bytes, def.class_byte_count); + redefined_ = true; + dex_len_ = def.class_byte_count; + res = CopyDataIntoJvmtiBuffer(env, def.class_bytes, def.class_byte_count, /*out*/ &new_data); + dex_data_ = MakeJvmtiUniquePtr(env, new_data); + return res; } } // namespace openjdkjvmti diff --git a/runtime/openjdkjvmti/ti_class_definition.h b/runtime/openjdkjvmti/ti_class_definition.h index 7a2e922c4c..43d0c3fc62 100644 --- a/runtime/openjdkjvmti/ti_class_definition.h +++ b/runtime/openjdkjvmti/ti_class_definition.h @@ -39,46 +39,39 @@ namespace openjdkjvmti { // A struct that stores data needed for redefining/transforming classes. This structure should only // even be accessed from a single thread and must not survive past the completion of the // redefinition/retransformation function that created it. -struct ArtClassDefinition { +class ArtClassDefinition { public: - jclass klass; - jobject loader; - std::string name; - jobject protection_domain; - jint dex_len; - JvmtiUniquePtr<unsigned char> dex_data; - JvmtiUniquePtr<unsigned char> original_dex_file_memory; - art::ArraySlice<const unsigned char> original_dex_file; - ArtClassDefinition() - : klass(nullptr), - loader(nullptr), - name(), - protection_domain(nullptr), - dex_len(0), - dex_data(nullptr), - original_dex_file_memory(nullptr), - original_dex_file(), - redefined(false) {} + : klass_(nullptr), + loader_(nullptr), + name_(), + protection_domain_(nullptr), + dex_len_(0), + dex_data_(nullptr), + original_dex_file_memory_(nullptr), + original_dex_file_(), + redefined_(false) {} + + jvmtiError Init(ArtJvmTiEnv* env, jclass klass); + jvmtiError Init(ArtJvmTiEnv* env, const jvmtiClassDefinition& def); ArtClassDefinition(ArtClassDefinition&& o) = default; + ArtClassDefinition& operator=(ArtClassDefinition&& o) = default; void SetNewDexData(ArtJvmTiEnv* env, jint new_dex_len, unsigned char* new_dex_data) { + DCHECK(IsInitialized()); if (new_dex_data == nullptr) { return; - } else if (new_dex_data != dex_data.get() || new_dex_len != dex_len) { - dex_len = new_dex_len; - dex_data = MakeJvmtiUniquePtr(env, new_dex_data); + } else if (new_dex_data != dex_data_.get() || new_dex_len != dex_len_) { + dex_len_ = new_dex_len; + dex_data_ = MakeJvmtiUniquePtr(env, new_dex_data); } } - void SetRedefined() { - redefined = true; - } - art::ArraySlice<const unsigned char> GetNewOriginalDexFile() const { - if (redefined) { - return original_dex_file; + DCHECK(IsInitialized()); + if (redefined_) { + return original_dex_file_; } else { return art::ArraySlice<const unsigned char>(); } @@ -86,8 +79,49 @@ struct ArtClassDefinition { bool IsModified() const; + bool IsInitialized() const { + return klass_ != nullptr; + } + + jclass GetClass() const { + DCHECK(IsInitialized()); + return klass_; + } + + jobject GetLoader() const { + DCHECK(IsInitialized()); + return loader_; + } + + const std::string& GetName() const { + DCHECK(IsInitialized()); + return name_; + } + + jobject GetProtectionDomain() const { + DCHECK(IsInitialized()); + return protection_domain_; + } + + art::ArraySlice<const unsigned char> GetDexData() const { + DCHECK(IsInitialized()); + return art::ArraySlice<const unsigned char>(dex_data_.get(), dex_len_); + } + private: - bool redefined; + jvmtiError InitCommon(ArtJvmTiEnv* env, jclass klass); + + jclass klass_; + jobject loader_; + std::string name_; + jobject protection_domain_; + jint dex_len_; + JvmtiUniquePtr<unsigned char> dex_data_; + JvmtiUniquePtr<unsigned char> original_dex_file_memory_; + art::ArraySlice<const unsigned char> original_dex_file_; + bool redefined_; + + DISALLOW_COPY_AND_ASSIGN(ArtClassDefinition); }; } // namespace openjdkjvmti diff --git a/runtime/openjdkjvmti/ti_redefine.cc b/runtime/openjdkjvmti/ti_redefine.cc index 95a1b007ca..6e0d9a0be8 100644 --- a/runtime/openjdkjvmti/ti_redefine.cc +++ b/runtime/openjdkjvmti/ti_redefine.cc @@ -261,13 +261,12 @@ jvmtiError Redefiner::GetClassRedefinitionError(art::Handle<art::mirror::Class> // Moves dex data to an anonymous, read-only mmap'd region. std::unique_ptr<art::MemMap> Redefiner::MoveDataToMemMap(const std::string& original_location, - jint data_len, - const unsigned char* dex_data, + art::ArraySlice<const unsigned char> data, std::string* error_msg) { std::unique_ptr<art::MemMap> map(art::MemMap::MapAnonymous( StringPrintf("%s-transformed", original_location.c_str()).c_str(), nullptr, - data_len, + data.size(), PROT_READ|PROT_WRITE, /*low_4gb*/false, /*reuse*/false, @@ -275,7 +274,7 @@ std::unique_ptr<art::MemMap> Redefiner::MoveDataToMemMap(const std::string& orig if (map == nullptr) { return map; } - memcpy(map->Begin(), dex_data, data_len); + memcpy(map->Begin(), &data.At(0), data.size()); // Make the dex files mmap read only. This matches how other DexFiles are mmaped and prevents // programs from corrupting it. map->Protect(PROT_READ); @@ -344,13 +343,7 @@ jvmtiError Redefiner::RedefineClasses(ArtJvmTiEnv* env, memcpy(class_bytes_copy, definitions[i].class_bytes, definitions[i].class_byte_count); ArtClassDefinition def; - def.dex_len = definitions[i].class_byte_count; - def.dex_data = MakeJvmtiUniquePtr(env, class_bytes_copy); - // We are definitely modified. - def.SetRedefined(); - def.original_dex_file = art::ArraySlice<const unsigned char>(definitions[i].class_bytes, - definitions[i].class_byte_count); - res = Transformer::FillInTransformationData(env, definitions[i].klass, &def); + res = def.Init(env, definitions[i]); if (res != OK) { return res; } @@ -399,25 +392,24 @@ jvmtiError Redefiner::RedefineClassesDirect(ArtJvmTiEnv* env, jvmtiError Redefiner::AddRedefinition(ArtJvmTiEnv* env, const ArtClassDefinition& def) { std::string original_dex_location; jvmtiError ret = OK; - if ((ret = GetClassLocation(env, def.klass, &original_dex_location))) { + if ((ret = GetClassLocation(env, def.GetClass(), &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) { + if ((ret = env->GetClassSignature(def.GetClass(), &signature_ptr, &generic_ptr_unused)) != OK) { *error_msg_ = "Unable to get class signature!"; return ret; } JvmtiUniquePtr<char> generic_unique_ptr(MakeJvmtiUniquePtr(env, generic_ptr_unused)); JvmtiUniquePtr<char> 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.GetDexData(), error_msg_)); std::ostringstream os; 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 " << def.GetName() << "in dex file " << original_dex_location << " because: " << *error_msg_; *error_msg_ = os.str(); return ERR(OUT_OF_MEMORY); @@ -434,13 +426,13 @@ jvmtiError Redefiner::AddRedefinition(ArtJvmTiEnv* env, const ArtClassDefinition /*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 " << def.GetName() << ": " << *error_msg_; *error_msg_ = os.str(); return ERR(INVALID_CLASS_FORMAT); } redefinitions_.push_back( Redefiner::ClassRedefinition(this, - def.klass, + def.GetClass(), dex_file.release(), signature_ptr, def.GetNewOriginalDexFile())); diff --git a/runtime/openjdkjvmti/ti_redefine.h b/runtime/openjdkjvmti/ti_redefine.h index 6c09d46e89..809a681902 100644 --- a/runtime/openjdkjvmti/ti_redefine.h +++ b/runtime/openjdkjvmti/ti_redefine.h @@ -99,8 +99,7 @@ class Redefiner { static jvmtiError IsModifiableClass(jvmtiEnv* env, jclass klass, jboolean* is_redefinable); static std::unique_ptr<art::MemMap> MoveDataToMemMap(const std::string& original_location, - jint data_len, - const unsigned char* dex_data, + art::ArraySlice<const unsigned char> data, std::string* error_msg); private: diff --git a/runtime/openjdkjvmti/transform.cc b/runtime/openjdkjvmti/transform.cc index 8e38a364ff..15d8dd0fc2 100644 --- a/runtime/openjdkjvmti/transform.cc +++ b/runtime/openjdkjvmti/transform.cc @@ -39,7 +39,6 @@ #include "dex_file.h" #include "dex_file_types.h" #include "events-inl.h" -#include "fixed_up_dex_file.h" #include "gc_root-inl.h" #include "globals.h" #include "jni_env_ext-inl.h" @@ -53,7 +52,6 @@ #include "mirror/class_loader-inl.h" #include "mirror/string-inl.h" #include "oat_file.h" -#include "reflection.h" #include "scoped_thread_state_change-inl.h" #include "stack.h" #include "thread_list.h" @@ -72,17 +70,18 @@ jvmtiError Transformer::RetransformClassesDirect( for (ArtClassDefinition& def : *definitions) { jint new_len = -1; unsigned char* new_data = nullptr; + art::ArraySlice<const unsigned char> dex_data = def.GetDexData(); event_handler->DispatchEvent<ArtJvmtiEvent::kClassFileLoadHookRetransformable>( self, GetJniEnv(env), - def.klass, - def.loader, - def.name.c_str(), - def.protection_domain, - def.dex_len, - static_cast<const unsigned char*>(def.dex_data.get()), - &new_len, - &new_data); + def.GetClass(), + def.GetLoader(), + def.GetName().c_str(), + def.GetProtectionDomain(), + static_cast<jint>(dex_data.size()), + &dex_data.At(0), + /*out*/&new_len, + /*out*/&new_data); def.SetNewDexData(env, new_len, new_data); } return OK; @@ -120,7 +119,7 @@ jvmtiError Transformer::RetransformClasses(ArtJvmTiEnv* env, return ERR(UNMODIFIABLE_CLASS); } ArtClassDefinition def; - res = FillInTransformationData(env, classes[i], &def); + res = def.Init(env, classes[i]); if (res != OK) { return res; } @@ -149,112 +148,4 @@ jvmtiError GetClassLocation(ArtJvmTiEnv* env, jclass klass, /*out*/std::string* return OK; } -jvmtiError Transformer::GetDexDataForRetransformation(ArtJvmTiEnv* env, - art::Handle<art::mirror::Class> klass, - /*out*/jint* dex_data_len, - /*out*/unsigned char** dex_data) { - art::StackHandleScope<3> hs(art::Thread::Current()); - art::Handle<art::mirror::ClassExt> ext(hs.NewHandle(klass->GetExtData())); - const art::DexFile* dex_file = nullptr; - if (!ext.IsNull()) { - art::Handle<art::mirror::Object> orig_dex(hs.NewHandle(ext->GetOriginalDexFile())); - if (!orig_dex.IsNull()) { - if (orig_dex->IsArrayInstance()) { - DCHECK(orig_dex->GetClass()->GetComponentType()->IsPrimitiveByte()); - art::Handle<art::mirror::ByteArray> orig_dex_bytes( - hs.NewHandle(art::down_cast<art::mirror::ByteArray*>(orig_dex->AsArray()))); - *dex_data_len = static_cast<jint>(orig_dex_bytes->GetLength()); - return CopyDataIntoJvmtiBuffer( - env, - reinterpret_cast<const unsigned char*>(orig_dex_bytes->GetData()), - *dex_data_len, - /*out*/dex_data); - } else if (orig_dex->IsDexCache()) { - dex_file = orig_dex->AsDexCache()->GetDexFile(); - } else { - DCHECK_EQ(orig_dex->GetClass()->GetPrimitiveType(), art::Primitive::kPrimLong); - art::ObjPtr<art::mirror::Class> prim_long_class( - art::Runtime::Current()->GetClassLinker()->GetClassRoot( - art::ClassLinker::kPrimitiveLong)); - art::JValue val; - if (!art::UnboxPrimitiveForResult(orig_dex.Get(), prim_long_class, &val)) { - // This should never happen. - return ERR(INTERNAL); - } - dex_file = reinterpret_cast<const art::DexFile*>(static_cast<uintptr_t>(val.GetJ())); - } - } - } - if (dex_file == nullptr) { - dex_file = &klass->GetDexFile(); - } - std::unique_ptr<FixedUpDexFile> fixed_dex_file(FixedUpDexFile::Create(*dex_file)); - *dex_data_len = static_cast<jint>(fixed_dex_file->Size()); - return CopyDataIntoJvmtiBuffer(env, - fixed_dex_file->Begin(), - fixed_dex_file->Size(), - /*out*/dex_data); -} - -// 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()); - std::string descriptor_store; - std::string descriptor(hs_klass->GetDescriptor(&descriptor_store)); - def->name = descriptor.substr(1, descriptor.size() - 2); - // 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); - // TODO This whole thing is a bit of a mess. - // We need to keep track of what the runtime should think an unmodified dex file is since - // we need to be able to tell if anything changes. This might be different then the currently - // loaded dex file since we need to un-quicken stuff. - if (hs_klass->GetExtData() == nullptr || - hs_klass->GetExtData()->GetOriginalDexFile() == nullptr) { - // We have never redefined this yet. Keep track of what the (de-quickened) dex file looks - // like so we can tell if anything has changed. - // Really we would like to just always do the 'else' block but the fact that we de-quickened - // stuff screws us over. - unsigned char* original_data_memory = nullptr; - res = env->Allocate(def->dex_len, &original_data_memory); - if (res != OK) { - return res; - } - memcpy(original_data_memory, new_data, def->dex_len); - def->original_dex_file_memory = MakeJvmtiUniquePtr(env, original_data_memory); - def->original_dex_file = art::ArraySlice<const unsigned char>(original_data_memory, - def->dex_len); - } else { - // We know that we have been redefined at least once (there is an original_dex_file set in - // the class) so we can just use the current dex file directly. - def->original_dex_file = art::ArraySlice<const unsigned char>( - hs_klass->GetDexFile().Begin(), hs_klass->GetDexFile().Size()); - } - } else { - return res; - } - } - return OK; -} - } // namespace openjdkjvmti diff --git a/runtime/openjdkjvmti/transform.h b/runtime/openjdkjvmti/transform.h index c6a36e8e20..ba40e04b44 100644 --- a/runtime/openjdkjvmti/transform.h +++ b/runtime/openjdkjvmti/transform.h @@ -61,18 +61,6 @@ class Transformer { 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_); }; } // namespace openjdkjvmti |