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);
 };