Use original dex file for retransformation.
The spec requires us to pass the dex file as it appeared before any
retransformation-capable agents had modified it to the
ClassFileLoadHooks when RetransformClasses is called. We do this by
saving the initial dex file bytes into the class as a byte[].
Bug: 32369916
Test: mma -j40 test-art-host
Change-Id: Ic6af3738cd2a831e91ba1144f502fa58b3c333e4
diff --git a/runtime/openjdkjvmti/ti_redefine.h b/runtime/openjdkjvmti/ti_redefine.h
index f8d51ad..29a7e1f 100644
--- a/runtime/openjdkjvmti/ti_redefine.h
+++ b/runtime/openjdkjvmti/ti_redefine.h
@@ -38,6 +38,7 @@
#include "art_jvmti.h"
#include "art_method.h"
+#include "base/array_slice.h"
#include "class_linker.h"
#include "dex_file.h"
#include "gc_root-inl.h"
@@ -56,6 +57,7 @@
#include "obj_ptr.h"
#include "scoped_thread_state_change-inl.h"
#include "stack.h"
+#include "ti_class_definition.h"
#include "thread_list.h"
#include "transform.h"
#include "utf.h"
@@ -100,7 +102,8 @@
ClassRedefinition(Redefiner* driver,
jclass klass,
const art::DexFile* redefined_dex_file,
- const char* class_sig)
+ const char* class_sig,
+ art::ArraySlice<const unsigned char> orig_dex_file)
REQUIRES_SHARED(art::Locks::mutator_lock_);
// NO_THREAD_SAFETY_ANALYSIS so we can unlock the class in the destructor.
@@ -111,7 +114,8 @@
: driver_(other.driver_),
klass_(other.klass_),
dex_file_(std::move(other.dex_file_)),
- class_sig_(std::move(other.class_sig_)) {
+ class_sig_(std::move(other.class_sig_)),
+ original_dex_file_(other.original_dex_file_) {
other.driver_ = nullptr;
}
@@ -130,15 +134,15 @@
art::mirror::LongArray* AllocateDexFileCookie(art::Handle<art::mirror::Object> j_dex_file_obj)
REQUIRES_SHARED(art::Locks::mutator_lock_);
+ // This may return nullptr with a OOME pending if allocation fails.
+ art::mirror::ByteArray* AllocateOrGetOriginalDexFileBytes()
+ REQUIRES_SHARED(art::Locks::mutator_lock_);
+
void RecordFailure(jvmtiError e, const std::string& err) {
driver_->RecordFailure(e, class_sig_, err);
}
- bool FinishRemainingAllocations(
- /*out*/art::MutableHandle<art::mirror::ClassLoader>* source_class_loader,
- /*out*/art::MutableHandle<art::mirror::Object>* source_dex_file_obj,
- /*out*/art::MutableHandle<art::mirror::LongArray>* new_dex_file_cookie,
- /*out*/art::MutableHandle<art::mirror::DexCache>* new_dex_cache)
+ bool FinishRemainingAllocations(int32_t klass_index, /*out*/RedefinitionDataHolder* holder)
REQUIRES_SHARED(art::Locks::mutator_lock_);
void FindAndAllocateObsoleteMethods(art::mirror::Class* art_klass)
@@ -191,7 +195,8 @@
REQUIRES(art::Locks::mutator_lock_);
void UpdateClass(art::ObjPtr<art::mirror::Class> mclass,
- art::ObjPtr<art::mirror::DexCache> new_dex_cache)
+ art::ObjPtr<art::mirror::DexCache> new_dex_cache,
+ art::ObjPtr<art::mirror::ByteArray> original_dex_file)
REQUIRES(art::Locks::mutator_lock_);
void ReleaseDexFile() REQUIRES_SHARED(art::Locks::mutator_lock_);
@@ -201,6 +206,7 @@
jclass klass_;
std::unique_ptr<const art::DexFile> dex_file_;
std::string class_sig_;
+ art::ArraySlice<const unsigned char> original_dex_file_;
};
jvmtiError result_;