Add more standard structural redefinition entrypoints
Add structural redefinition extension function and event that mirror
the 'RedefineClasses' function and 'ClassFileLoadHook' event. The new
extension function is called
'com.android.art.class.structurally_redefine_classes' and the new
extension event is called
'com.android.art.class.structural_dex_file_load_hook'.
These extensions are the preferred way to use structural redefinition.
Like the standard 'RedefineClasses' multiple classes may be redefined
at a time.
The structural_dex_file_load_hook is triggered prior to the
can_retransform_classes ClassFileLoadHook. It is triggered on all
classes, even ones that cannot be structurally changed by
class-loading, class redefinition or by calling the RetransformClasses
function.
Calling 'structurally_redefine_classes' with new definitions that do
not require structural changes will fall back to non-structural
redefinition.
Test: ./test.py --host
Bug: 134162467
Change-Id: If4810930470c5c6509cf6db779910006e114b39f
diff --git a/openjdkjvmti/ti_class_definition.h b/openjdkjvmti/ti_class_definition.h
index 224e664..cb0853b 100644
--- a/openjdkjvmti/ti_class_definition.h
+++ b/openjdkjvmti/ti_class_definition.h
@@ -40,6 +40,7 @@
#include "base/array_ref.h"
#include "base/mem_map.h"
+#include "events.h"
namespace openjdkjvmti {
@@ -65,7 +66,8 @@
current_dex_file_(),
redefined_(false),
from_class_ext_(false),
- initialized_(false) {}
+ initialized_(false),
+ structural_transform_update_(false) {}
void InitFirstLoad(const char* descriptor,
art::Handle<art::mirror::ClassLoader> klass_loader,
@@ -76,7 +78,7 @@
ArtClassDefinition(ArtClassDefinition&& o) = default;
ArtClassDefinition& operator=(ArtClassDefinition&& o) = default;
- void SetNewDexData(jint new_dex_len, unsigned char* new_dex_data) {
+ void SetNewDexData(jint new_dex_len, unsigned char* new_dex_data, ArtJvmtiEvent event) {
DCHECK(IsInitialized());
if (new_dex_data == nullptr) {
return;
@@ -86,10 +88,17 @@
dex_data_memory_.resize(new_dex_len);
memcpy(dex_data_memory_.data(), new_dex_data, new_dex_len);
dex_data_ = art::ArrayRef<const unsigned char>(dex_data_memory_);
+ if (event == ArtJvmtiEvent::kStructuralDexFileLoadHook) {
+ structural_transform_update_ = true;
+ }
}
}
}
+ bool HasStructuralChanges() const {
+ return structural_transform_update_;
+ }
+
art::ArrayRef<const unsigned char> GetNewOriginalDexFile() const {
DCHECK(IsInitialized());
if (redefined_) {
@@ -187,6 +196,9 @@
bool initialized_;
+ // Set if we had a new dex from the given transform type.
+ bool structural_transform_update_;
+
DISALLOW_COPY_AND_ASSIGN(ArtClassDefinition);
};