xref: /aosp_15_r20/art/openjdkjvmti/ti_redefine.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /* Copyright (C) 2016 The Android Open Source Project
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * This file implements interfaces from the file jvmti.h. This implementation
5  * is licensed under the same terms as the file jvmti.h.  The
6  * copyright and license information for the file jvmti.h follows.
7  *
8  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
9  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10  *
11  * This code is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU General Public License version 2 only, as
13  * published by the Free Software Foundation.  Oracle designates this
14  * particular file as subject to the "Classpath" exception as provided
15  * by Oracle in the LICENSE file that accompanied this code.
16  *
17  * This code is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20  * version 2 for more details (a copy is included in the LICENSE file that
21  * accompanied this code).
22  *
23  * You should have received a copy of the GNU General Public License version
24  * 2 along with this work; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26  *
27  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28  * or visit www.oracle.com if you need additional information or have any
29  * questions.
30  */
31 
32 #include "ti_redefine.h"
33 
34 #include <algorithm>
35 #include <atomic>
36 #include <iterator>
37 #include <limits>
38 #include <sstream>
39 #include <string_view>
40 #include <unordered_map>
41 
42 #include <android-base/logging.h>
43 #include <android-base/stringprintf.h>
44 
45 #include "alloc_manager.h"
46 #include "android-base/macros.h"
47 #include "android-base/thread_annotations.h"
48 #include "art_field-inl.h"
49 #include "art_field.h"
50 #include "art_jvmti.h"
51 #include "art_method-inl.h"
52 #include "art_method.h"
53 #include "base/array_ref.h"
54 #include "base/casts.h"
55 #include "base/globals.h"
56 #include "base/iteration_range.h"
57 #include "base/length_prefixed_array.h"
58 #include "base/locks.h"
59 #include "base/pointer_size.h"
60 #include "base/stl_util.h"
61 #include "base/utils.h"
62 #include "class_linker-inl.h"
63 #include "class_linker.h"
64 #include "class_root-inl.h"
65 #include "class_status.h"
66 #include "debugger.h"
67 #include "dex/art_dex_file_loader.h"
68 #include "dex/class_accessor-inl.h"
69 #include "dex/class_accessor.h"
70 #include "dex/dex_file.h"
71 #include "dex/dex_file_loader.h"
72 #include "dex/dex_file_types.h"
73 #include "dex/primitive.h"
74 #include "dex/signature-inl.h"
75 #include "dex/signature.h"
76 #include "events-inl.h"
77 #include "events.h"
78 #include "gc/allocation_listener.h"
79 #include "gc/heap.h"
80 #include "gc/heap-inl.h"
81 #include "gc/heap-visit-objects-inl.h"
82 #include "handle.h"
83 #include "handle_scope.h"
84 #include "instrumentation.h"
85 #include "intern_table.h"
86 #include "jit/jit.h"
87 #include "jit/jit_code_cache.h"
88 #include "jni/jni_env_ext-inl.h"
89 #include "jni/jni_id_manager.h"
90 #include "jvmti.h"
91 #include "jvmti_allocator.h"
92 #include "linear_alloc-inl.h"
93 #include "mirror/array-alloc-inl.h"
94 #include "mirror/array.h"
95 #include "mirror/class-alloc-inl.h"
96 #include "mirror/class-inl.h"
97 #include "mirror/class-refvisitor-inl.h"
98 #include "mirror/class.h"
99 #include "mirror/class_ext-inl.h"
100 #include "mirror/dex_cache-inl.h"
101 #include "mirror/dex_cache.h"
102 #include "mirror/executable-inl.h"
103 #include "mirror/field-inl.h"
104 #include "mirror/field.h"
105 #include "mirror/method.h"
106 #include "mirror/method_handle_impl-inl.h"
107 #include "mirror/object.h"
108 #include "mirror/object_array-alloc-inl.h"
109 #include "mirror/object_array-inl.h"
110 #include "mirror/object_array.h"
111 #include "mirror/string.h"
112 #include "mirror/var_handle.h"
113 #include "nativehelper/scoped_local_ref.h"
114 #include "non_debuggable_classes.h"
115 #include "obj_ptr.h"
116 #include "object_lock.h"
117 #include "reflective_value_visitor.h"
118 #include "runtime.h"
119 #include "runtime_globals.h"
120 #include "scoped_thread_state_change.h"
121 #include "stack.h"
122 #include "thread.h"
123 #include "thread_list.h"
124 #include "ti_breakpoint.h"
125 #include "ti_class_definition.h"
126 #include "ti_class_loader.h"
127 #include "ti_heap.h"
128 #include "ti_logging.h"
129 #include "ti_thread.h"
130 #include "transform.h"
131 #include "verifier/class_verifier.h"
132 #include "verifier/verifier_enums.h"
133 #include "well_known_classes-inl.h"
134 #include "write_barrier.h"
135 
136 namespace openjdkjvmti {
137 
138 // Debug check to force us to directly check we saw all methods and fields exactly once directly.
139 // Normally we don't need to do this since if any are missing the count will be different
140 constexpr bool kCheckAllMethodsSeenOnce = art::kIsDebugBuild;
141 
142 using android::base::StringPrintf;
143 
144 // A helper that fills in a classes obsolete_methods_ and obsolete_dex_caches_ classExt fields as
145 // they are created. This ensures that we can always call any method of an obsolete ArtMethod object
146 // almost as soon as they are created since the GetObsoleteDexCache method will succeed.
147 class ObsoleteMap {
148  public:
FindObsoleteVersion(art::ArtMethod * original) const149   art::ArtMethod* FindObsoleteVersion(art::ArtMethod* original) const
150       REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) {
151     auto method_pair = id_map_.find(original);
152     if (method_pair != id_map_.end()) {
153       art::ArtMethod* res = obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(
154           method_pair->second, art::kRuntimePointerSize);
155       DCHECK(res != nullptr);
156       return res;
157     } else {
158       return nullptr;
159     }
160   }
161 
RecordObsolete(art::ArtMethod * original,art::ArtMethod * obsolete)162   void RecordObsolete(art::ArtMethod* original, art::ArtMethod* obsolete)
163       REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) {
164     DCHECK(original != nullptr);
165     DCHECK(obsolete != nullptr);
166     int32_t slot = next_free_slot_++;
167     DCHECK_LT(slot, obsolete_methods_->GetLength());
168     DCHECK(nullptr ==
169            obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(slot, art::kRuntimePointerSize));
170     DCHECK(nullptr == obsolete_dex_caches_->Get(slot));
171     obsolete_methods_->SetElementPtrSize(slot, obsolete, art::kRuntimePointerSize);
172     obsolete_dex_caches_->Set(slot, original_dex_cache_);
173     id_map_.insert({original, slot});
174   }
175 
ObsoleteMap(art::ObjPtr<art::mirror::PointerArray> obsolete_methods,art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> obsolete_dex_caches,art::ObjPtr<art::mirror::DexCache> original_dex_cache)176   ObsoleteMap(art::ObjPtr<art::mirror::PointerArray> obsolete_methods,
177               art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> obsolete_dex_caches,
178               art::ObjPtr<art::mirror::DexCache> original_dex_cache)
179       : next_free_slot_(0),
180         obsolete_methods_(obsolete_methods),
181         obsolete_dex_caches_(obsolete_dex_caches),
182         original_dex_cache_(original_dex_cache) {
183     // Figure out where the first unused slot in the obsolete_methods_ array is.
184     while (obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(
185         next_free_slot_, art::kRuntimePointerSize) != nullptr) {
186       DCHECK(obsolete_dex_caches_->Get(next_free_slot_) != nullptr);
187       next_free_slot_++;
188     }
189     // Check that the same slot in obsolete_dex_caches_ is free.
190     DCHECK(obsolete_dex_caches_->Get(next_free_slot_) == nullptr);
191   }
192 
193   struct ObsoleteMethodPair {
194     art::ArtMethod* old_method;
195     art::ArtMethod* obsolete_method;
196   };
197 
198   class ObsoleteMapIter {
199    public:
200     using iterator_category = std::forward_iterator_tag;
201     using value_type = ObsoleteMethodPair;
202     using difference_type = ptrdiff_t;
203     using pointer = void;    // Unsupported.
204     using reference = void;  // Unsupported.
205 
operator *() const206     ObsoleteMethodPair operator*() const
207         REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) {
208       art::ArtMethod* obsolete = map_->obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(
209           iter_->second, art::kRuntimePointerSize);
210       DCHECK(obsolete != nullptr);
211       return { iter_->first, obsolete };
212     }
213 
operator ==(ObsoleteMapIter other) const214     bool operator==(ObsoleteMapIter other) const {
215       return map_ == other.map_ && iter_ == other.iter_;
216     }
217 
operator !=(ObsoleteMapIter other) const218     bool operator!=(ObsoleteMapIter other) const {
219       return !(*this == other);
220     }
221 
operator ++(int)222     ObsoleteMapIter operator++(int) {
223       ObsoleteMapIter retval = *this;
224       ++(*this);
225       return retval;
226     }
227 
operator ++()228     ObsoleteMapIter operator++() {
229       ++iter_;
230       return *this;
231     }
232 
233    private:
ObsoleteMapIter(const ObsoleteMap * map,std::unordered_map<art::ArtMethod *,int32_t>::const_iterator iter)234     ObsoleteMapIter(const ObsoleteMap* map,
235                     std::unordered_map<art::ArtMethod*, int32_t>::const_iterator iter)
236         : map_(map), iter_(iter) {}
237 
238     const ObsoleteMap* map_;
239     std::unordered_map<art::ArtMethod*, int32_t>::const_iterator iter_;
240 
241     friend class ObsoleteMap;
242   };
243 
end() const244   ObsoleteMapIter end() const {
245     return ObsoleteMapIter(this, id_map_.cend());
246   }
247 
begin() const248   ObsoleteMapIter begin() const {
249     return ObsoleteMapIter(this, id_map_.cbegin());
250   }
251 
252  private:
253   int32_t next_free_slot_;
254   std::unordered_map<art::ArtMethod*, int32_t> id_map_;
255   // Pointers to the fields in mirror::ClassExt. These can be held as ObjPtr since this is only used
256   // when we have an exclusive mutator_lock_ (i.e. all threads are suspended).
257   art::ObjPtr<art::mirror::PointerArray> obsolete_methods_;
258   art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> obsolete_dex_caches_;
259   art::ObjPtr<art::mirror::DexCache> original_dex_cache_;
260 };
261 
262 // This visitor walks thread stacks and allocates and sets up the obsolete methods. It also does
263 // some basic soundness checks that the obsolete method is valid.
264 class ObsoleteMethodStackVisitor : public art::StackVisitor {
265  protected:
ObsoleteMethodStackVisitor(art::Thread * thread,art::LinearAlloc * allocator,const std::unordered_set<art::ArtMethod * > & obsoleted_methods,ObsoleteMap * obsolete_maps)266   ObsoleteMethodStackVisitor(
267       art::Thread* thread,
268       art::LinearAlloc* allocator,
269       const std::unordered_set<art::ArtMethod*>& obsoleted_methods,
270       ObsoleteMap* obsolete_maps)
271         : StackVisitor(thread,
272                        /*context=*/nullptr,
273                        StackVisitor::StackWalkKind::kIncludeInlinedFrames),
274           allocator_(allocator),
275           obsoleted_methods_(obsoleted_methods),
276           obsolete_maps_(obsolete_maps) { }
277 
~ObsoleteMethodStackVisitor()278   ~ObsoleteMethodStackVisitor() override {}
279 
280  public:
281   // Returns true if we successfully installed obsolete methods on this thread, filling
282   // obsolete_maps_ with the translations if needed. Returns false and fills error_msg if we fail.
283   // The stack is cleaned up when we fail.
UpdateObsoleteFrames(art::Thread * thread,art::LinearAlloc * allocator,const std::unordered_set<art::ArtMethod * > & obsoleted_methods,ObsoleteMap * obsolete_maps)284   static void UpdateObsoleteFrames(
285       art::Thread* thread,
286       art::LinearAlloc* allocator,
287       const std::unordered_set<art::ArtMethod*>& obsoleted_methods,
288       ObsoleteMap* obsolete_maps) REQUIRES(art::Locks::mutator_lock_) {
289     ObsoleteMethodStackVisitor visitor(thread,
290                                        allocator,
291                                        obsoleted_methods,
292                                        obsolete_maps);
293     visitor.WalkStack();
294   }
295 
VisitFrame()296   bool VisitFrame() override REQUIRES(art::Locks::mutator_lock_) {
297     art::ScopedAssertNoThreadSuspension snts("Fixing up the stack for obsolete methods.");
298     art::ArtMethod* old_method = GetMethod();
299     if (obsoleted_methods_.find(old_method) != obsoleted_methods_.end()) {
300       // We cannot ensure that the right dex file is used in inlined frames so we don't support
301       // redefining them.
302       DCHECK(!IsInInlinedFrame()) << "Inlined frames are not supported when using redefinition: "
303                                   << old_method->PrettyMethod() << " is inlined into "
304                                   << GetOuterMethod()->PrettyMethod();
305       art::ArtMethod* new_obsolete_method = obsolete_maps_->FindObsoleteVersion(old_method);
306       if (new_obsolete_method == nullptr) {
307         // Create a new Obsolete Method and put it in the list.
308         art::Runtime* runtime = art::Runtime::Current();
309         art::ClassLinker* cl = runtime->GetClassLinker();
310         auto ptr_size = cl->GetImagePointerSize();
311         const size_t method_size = art::ArtMethod::Size(ptr_size);
312         auto* method_storage = allocator_->Alloc(art::Thread::Current(),
313                                                  method_size,
314                                                  art::LinearAllocKind::kArtMethod);
315         CHECK(method_storage != nullptr) << "Unable to allocate storage for obsolete version of '"
316                                          << old_method->PrettyMethod() << "'";
317         new_obsolete_method = new (method_storage) art::ArtMethod();
318         new_obsolete_method->CopyFrom(old_method, ptr_size);
319         DCHECK_EQ(new_obsolete_method->GetDeclaringClass(), old_method->GetDeclaringClass());
320         new_obsolete_method->SetIsObsolete();
321         new_obsolete_method->SetDontCompile();
322         cl->SetEntryPointsForObsoleteMethod(new_obsolete_method);
323         obsolete_maps_->RecordObsolete(old_method, new_obsolete_method);
324       }
325       DCHECK(new_obsolete_method != nullptr);
326       SetMethod(new_obsolete_method);
327     }
328     return true;
329   }
330 
331  private:
332   // The linear allocator we should use to make new methods.
333   art::LinearAlloc* allocator_;
334   // The set of all methods which could be obsoleted.
335   const std::unordered_set<art::ArtMethod*>& obsoleted_methods_;
336   // A map from the original to the newly allocated obsolete method for frames on this thread. The
337   // values in this map are added to the obsolete_methods_ (and obsolete_dex_caches_) fields of
338   // the redefined classes ClassExt as it is filled.
339   ObsoleteMap* obsolete_maps_;
340 };
341 
342 namespace {
343 // We need to make sure we only have one redefinition in progress. Redefining involves
344 // re-verification and potentially new allocations among other things. So we only allow one
345 // redefinition at a time.
346 static std::mutex redefinition_lock;
347 }  // namespace
348 
349 template <RedefinitionType kType>
350 jvmtiError
IsModifiableClassGeneric(jvmtiEnv * env,jclass klass,jboolean * is_redefinable)351 Redefiner::IsModifiableClassGeneric(jvmtiEnv* env, jclass klass, jboolean* is_redefinable) {
352   if (env == nullptr) {
353     return ERR(INVALID_ENVIRONMENT);
354   }
355   art::Thread* self = art::Thread::Current();
356   art::ScopedObjectAccess soa(self);
357   art::StackHandleScope<1> hs(self);
358   art::ObjPtr<art::mirror::Object> obj(self->DecodeJObject(klass));
359   if (obj.IsNull() || !obj->IsClass()) {
360     return ERR(INVALID_CLASS);
361   }
362   art::Handle<art::mirror::Class> h_klass(hs.NewHandle(obj->AsClass()));
363   std::string err_unused;
364   *is_redefinable =
365       Redefiner::CanRedefineClass<kType>(h_klass, &err_unused) != ERR(UNMODIFIABLE_CLASS)
366           ? JNI_TRUE
367           : JNI_FALSE;
368   return OK;
369 }
370 
371 jvmtiError
IsStructurallyModifiableClass(jvmtiEnv * env,jclass klass,jboolean * is_redefinable)372 Redefiner::IsStructurallyModifiableClass(jvmtiEnv* env, jclass klass, jboolean* is_redefinable) {
373   return Redefiner::IsModifiableClassGeneric<RedefinitionType::kStructural>(
374       env, klass, is_redefinable);
375 }
376 
IsModifiableClass(jvmtiEnv * env,jclass klass,jboolean * is_redefinable)377 jvmtiError Redefiner::IsModifiableClass(jvmtiEnv* env, jclass klass, jboolean* is_redefinable) {
378   return Redefiner::IsModifiableClassGeneric<RedefinitionType::kNormal>(env, klass, is_redefinable);
379 }
380 
381 template <RedefinitionType kType>
CanRedefineClass(jclass klass,std::string * error_msg)382 jvmtiError Redefiner::CanRedefineClass(jclass klass, /*out*/ std::string* error_msg) {
383   art::Thread* self = art::Thread::Current();
384   art::ScopedObjectAccess soa(self);
385   art::StackHandleScope<1> hs(self);
386   art::ObjPtr<art::mirror::Object> obj(self->DecodeJObject(klass));
387   if (obj.IsNull() || !obj->IsClass()) {
388     return ERR(INVALID_CLASS);
389   }
390   art::Handle<art::mirror::Class> h_klass(hs.NewHandle(obj->AsClass()));
391   return Redefiner::CanRedefineClass<kType>(h_klass, error_msg);
392 }
393 
394 template <RedefinitionType kType>
CanRedefineClass(art::Handle<art::mirror::Class> klass,std::string * error_msg)395 jvmtiError Redefiner::CanRedefineClass(art::Handle<art::mirror::Class> klass,
396                                        /*out*/ std::string* error_msg) {
397   art::Thread* self = art::Thread::Current();
398   if (!klass->IsResolved()) {
399     // It's only a problem to try to retransform/redefine a unprepared class if it's happening on
400     // the same thread as the class-linking process. If it's on another thread we will be able to
401     // wait for the preparation to finish and continue from there.
402     if (klass->GetLockOwnerThreadId() == self->GetThreadId()) {
403       *error_msg = "Modification of class " + klass->PrettyClass() +
404           " from within the classes ClassLoad callback is not supported to prevent deadlocks." +
405           " Please use ClassFileLoadHook directly instead.";
406       return ERR(INTERNAL);
407     } else {
408       LOG(WARNING) << klass->PrettyClass() << " is not yet resolved. Attempting to transform "
409                    << "it could cause arbitrary length waits as the class is being resolved.";
410     }
411   }
412   if (klass->IsPrimitive()) {
413     *error_msg = "Modification of primitive classes is not supported";
414     return ERR(UNMODIFIABLE_CLASS);
415   } else if (klass->IsInterface()) {
416     *error_msg = "Modification of Interface classes is currently not supported";
417     return ERR(UNMODIFIABLE_CLASS);
418   } else if (klass->IsStringClass()) {
419     *error_msg = "Modification of String class is not supported";
420     return ERR(UNMODIFIABLE_CLASS);
421   } else if (klass->IsArrayClass()) {
422     *error_msg = "Modification of Array classes is not supported";
423     return ERR(UNMODIFIABLE_CLASS);
424   } else if (klass->IsProxyClass()) {
425     *error_msg = "Modification of proxy classes is not supported";
426     return ERR(UNMODIFIABLE_CLASS);
427   }
428 
429   for (jclass c : art::NonDebuggableClasses::GetNonDebuggableClasses()) {
430     if (klass.Get() == self->DecodeJObject(c)->AsClass()) {
431       *error_msg = "Class might have stack frames that cannot be made obsolete";
432       return ERR(UNMODIFIABLE_CLASS);
433     }
434   }
435 
436   if (kType == RedefinitionType::kStructural) {
437     // Class initialization interacts really badly with structural redefinition since we need to
438     // make the old class obsolete. We currently just blanket don't allow it.
439     // TODO It might be nice to allow this at some point.
440     if (klass->IsInitializing() &&
441        !klass->IsInitialized() &&
442         klass->GetClinitThreadId() == self->GetTid()) {
443       // We are in the class-init running on this thread.
444       *error_msg = "Modification of class " + klass->PrettyClass() + " during class" +
445                    " initialization is not allowed.";
446       return ERR(INTERNAL);
447     }
448     if (!art::Runtime::Current()->GetClassLinker()->EnsureInitialized(
449             self, klass, /*can_init_fields=*/true, /*can_init_parents=*/true)) {
450       self->AssertPendingException();
451       *error_msg = "Class " + klass->PrettyClass() + " failed initialization. Structural" +
452                    " redefinition of erroneous classes is not allowed. Failure was: " +
453                    self->GetException()->Dump();
454       self->ClearException();
455       return ERR(INVALID_CLASS);
456     }
457     if (klass->IsMirrored()) {
458       std::string pc(klass->PrettyClass());
459       *error_msg = StringPrintf("Class %s is a mirror class and cannot be structurally redefined.",
460                                 pc.c_str());
461       return ERR(UNMODIFIABLE_CLASS);
462     }
463     // Check Thread specifically since it's not a root but too many things reach into it with Unsafe
464     // too allow structural redefinition.
465     if (klass->IsAssignableFrom(art::WellKnownClasses::java_lang_Thread.Get())) {
466       *error_msg =
467           "java.lang.Thread has fields accessed using sun.misc.unsafe directly. It is not "
468           "safe to structurally redefine it.";
469       return ERR(UNMODIFIABLE_CLASS);
470     }
471     auto has_pointer_marker =
472         [](art::ObjPtr<art::mirror::Class> k) REQUIRES_SHARED(art::Locks::mutator_lock_) {
473           // Check for fields/methods which were returned before moving to index jni id type.
474           // TODO We might want to rework how this is done. Once full redefinition is implemented we
475           // will need to check any subtypes too.
476           art::ObjPtr<art::mirror::ClassExt> ext(k->GetExtData());
477           if (!ext.IsNull()) {
478             if (ext->HasInstanceFieldPointerIdMarker() || ext->HasMethodPointerIdMarker() ||
479                 ext->HasStaticFieldPointerIdMarker()) {
480               return true;
481             }
482           }
483           return false;
484         };
485     if (has_pointer_marker(klass.Get())) {
486       *error_msg =
487           StringPrintf("%s has active pointer jni-ids and cannot be redefined structurally",
488                        klass->PrettyClass().c_str());
489       return ERR(UNMODIFIABLE_CLASS);
490     }
491     jvmtiError res = OK;
492     art::ClassFuncVisitor cfv(
493       [&](art::ObjPtr<art::mirror::Class> k) REQUIRES_SHARED(art::Locks::mutator_lock_) {
494         // if there is any class 'K' that is a subtype (i.e. extends) klass and has pointer-jni-ids
495         // we cannot structurally redefine the class 'k' since we would structurally redefine the
496         // subtype.
497         if (k->IsLoaded() && klass->IsAssignableFrom(k) && has_pointer_marker(k)) {
498           *error_msg = StringPrintf(
499               "%s has active pointer jni-ids from subtype %s and cannot be redefined structurally",
500               klass->PrettyClass().c_str(),
501               k->PrettyClass().c_str());
502           res = ERR(UNMODIFIABLE_CLASS);
503           return false;
504         }
505         return true;
506       });
507     art::Runtime::Current()->GetClassLinker()->VisitClasses(&cfv);
508     return res;
509   }
510   return OK;
511 }
512 
513 template jvmtiError Redefiner::CanRedefineClass<RedefinitionType::kNormal>(
514     art::Handle<art::mirror::Class> klass, /*out*/ std::string* error_msg);
515 template jvmtiError Redefiner::CanRedefineClass<RedefinitionType::kStructural>(
516     art::Handle<art::mirror::Class> klass, /*out*/ std::string* error_msg);
517 
518 // Moves dex data to an anonymous, read-only mmap'd region.
MoveDataToMemMap(const std::string & original_location,art::ArrayRef<const unsigned char> data,std::string * error_msg)519 art::MemMap Redefiner::MoveDataToMemMap(const std::string& original_location,
520                                         art::ArrayRef<const unsigned char> data,
521                                         std::string* error_msg) {
522   std::string modified_location = StringPrintf("%s-transformed", original_location.c_str());
523   // A dangling multi-dex location appended to bootclasspath can cause inaccuracy in oat file
524   // validation. For simplicity, just convert it to a normal location.
525   size_t pos = modified_location.find(art::DexFileLoader::kMultiDexSeparator);
526   if (pos != std::string::npos) {
527     modified_location[pos] = '-';
528   }
529   art::MemMap map = art::MemMap::MapAnonymous(
530       modified_location.c_str(),
531       data.size(),
532       PROT_READ|PROT_WRITE,
533       /*low_4gb=*/ false,
534       error_msg);
535   if (LIKELY(map.IsValid())) {
536     memcpy(map.Begin(), data.data(), data.size());
537     // Make the dex files mmap read only. This matches how other DexFiles are mmaped and prevents
538     // programs from corrupting it.
539     map.Protect(PROT_READ);
540   }
541   return map;
542 }
543 
ClassRedefinition(Redefiner * driver,jclass klass,const art::DexFile * redefined_dex_file,const char * class_sig,art::ArrayRef<const unsigned char> orig_dex_file)544 Redefiner::ClassRedefinition::ClassRedefinition(
545     Redefiner* driver,
546     jclass klass,
547     const art::DexFile* redefined_dex_file,
548     const char* class_sig,
549     art::ArrayRef<const unsigned char> orig_dex_file) :
550       driver_(driver),
551       klass_(klass),
552       dex_file_(redefined_dex_file),
553       class_sig_(class_sig),
554       original_dex_file_(orig_dex_file) {
555 }
556 
~ClassRedefinition()557 Redefiner::ClassRedefinition::~ClassRedefinition() {
558   if (art::kIsDebugBuild) {
559     if (dex_file_ != nullptr) {
560       art::Thread* self = art::Thread::Current();
561       art::ClassLinker* cl = art::Runtime::Current()->GetClassLinker();
562       CHECK(!cl->IsDexFileRegistered(self, *dex_file_));
563     }
564   }
565 }
566 
567 template<RedefinitionType kType>
RedefineClassesGeneric(jvmtiEnv * jenv,jint class_count,const jvmtiClassDefinition * definitions)568 jvmtiError Redefiner::RedefineClassesGeneric(jvmtiEnv* jenv,
569                                              jint class_count,
570                                              const jvmtiClassDefinition* definitions) {
571   art::Runtime* runtime = art::Runtime::Current();
572   art::Thread* self = art::Thread::Current();
573   ArtJvmTiEnv* env = ArtJvmTiEnv::AsArtJvmTiEnv(jenv);
574   if (env == nullptr) {
575     JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE env was null!";
576     return ERR(INVALID_ENVIRONMENT);
577   } else if (class_count < 0) {
578     JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE class_count was less then 0";
579     return ERR(ILLEGAL_ARGUMENT);
580   } else if (class_count == 0) {
581     // We don't actually need to do anything. Just return OK.
582     return OK;
583   } else if (definitions == nullptr) {
584     JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE null definitions!";
585     return ERR(NULL_POINTER);
586   }
587   std::string error_msg;
588   std::vector<ArtClassDefinition> def_vector;
589   def_vector.reserve(class_count);
590   for (jint i = 0; i < class_count; i++) {
591     jvmtiError res =
592         Redefiner::CanRedefineClass<RedefinitionType::kNormal>(definitions[i].klass, &error_msg);
593     if (res != OK) {
594       JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE " << error_msg;
595       return res;
596     }
597     ArtClassDefinition def;
598     res = def.Init(self, definitions[i]);
599     if (res != OK) {
600       JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE bad definition " << i;
601       return res;
602     }
603     def_vector.push_back(std::move(def));
604   }
605 
606   // Call necessary hooks. According to the spec we should send class file load hooks here. We
607   // handle it slightly differently to support structural redefinition. Look at the comments
608   // in Transformer::CallClassFileLoadHooks for more details.
609   Transformer::CallClassFileLoadHooks<kType>(self, &def_vector);
610 
611   jvmtiError res = RedefineClassesDirect(env, runtime, self, def_vector, kType, &error_msg);
612   if (res != OK) {
613     JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE " << error_msg;
614   }
615   return res;
616 }
617 
StructurallyRedefineClasses(jvmtiEnv * jenv,jint class_count,const jvmtiClassDefinition * definitions)618 jvmtiError Redefiner::StructurallyRedefineClasses(jvmtiEnv* jenv,
619                                                   jint class_count,
620                                                   const jvmtiClassDefinition* definitions) {
621   ArtJvmTiEnv* art_env = ArtJvmTiEnv::AsArtJvmTiEnv(jenv);
622   if (art_env == nullptr) {
623     return ERR(INVALID_ENVIRONMENT);
624   } else if (art_env->capabilities.can_redefine_classes != 1) {
625     return ERR(MUST_POSSESS_CAPABILITY);
626   }
627   return RedefineClassesGeneric<RedefinitionType::kStructural>(jenv, class_count, definitions);
628 }
629 
RedefineClasses(jvmtiEnv * jenv,jint class_count,const jvmtiClassDefinition * definitions)630 jvmtiError Redefiner::RedefineClasses(jvmtiEnv* jenv,
631                                       jint class_count,
632                                       const jvmtiClassDefinition* definitions) {
633   return RedefineClassesGeneric<RedefinitionType::kNormal>(jenv, class_count, definitions);
634 }
635 
RedefineClassesDirect(ArtJvmTiEnv * env,art::Runtime * runtime,art::Thread * self,const std::vector<ArtClassDefinition> & definitions,RedefinitionType type,std::string * error_msg)636 jvmtiError Redefiner::RedefineClassesDirect(ArtJvmTiEnv* env,
637                                             art::Runtime* runtime,
638                                             art::Thread* self,
639                                             const std::vector<ArtClassDefinition>& definitions,
640                                             RedefinitionType type,
641                                             std::string* error_msg) {
642   DCHECK(env != nullptr);
643   if (definitions.size() == 0) {
644     // We don't actually need to do anything. Just return OK.
645     return OK;
646   }
647 
648   // Take a lock to avoid any concurrent redefinitions.
649   // TODO(mythria): It is hard to reason that it is safe to hold locks here. It is probably okay,
650   // since the thread is suspended and we know the thread isn't in the middle of allocations. The
651   // current implementation of redefinition is prone to deadlocks. For example, we pause allocations
652   // and then allocate new objects which could trigger a GC. This is unsafe. See b/359829378 for
653   // more details. Ideally we should rework the code so that:
654   // 1. Estimate the size required for the new allocations
655   // 2. Ensure we have the required space
656   // 3. Acquire any locks required (this would also include the lock to prevent
657   // concurrent redefinitions)
658   // 3. SuspendAll the threads
659   // 4. If the estimated size is no longer sufficient - retry from 1.
660   // 5. Finish redefinition.
661   //
662   // Step 4 is required because there might be allocations after we have estimated and before we
663   // suspend all threads. This isn't expected to be frequent so we shouldn't usually need to retry
664   // multiple times.
665   // Using a lock here is a short-term fix to block on concurrent redefinitions (instead of
666   // returning an error) while we rework the redefinition code.
667   // art::MutexLock lg(self, redefinition_lock);
668   std::lock_guard<std::mutex> lg(redefinition_lock);
669 
670   // We need to fiddle with the verification class flags. To do this we need to make sure there are
671   // no concurrent redefinitions of the same class at the same time. For simplicity and because
672   // this is not expected to be a common occurrence we will just wrap the whole thing in a TOP-level
673   // lock.
674   Redefiner r(env, runtime, self, type, error_msg);
675 
676   // Stop JIT for the duration of this redefine since the JIT might concurrently compile a method we
677   // are going to redefine.
678   // TODO We should prevent user-code suspensions to make sure this isn't held for too long.
679   art::jit::ScopedJitSuspend suspend_jit;
680   // Get shared mutator lock so we can lock all the classes.
681   art::ScopedObjectAccess soa(self);
682   for (const ArtClassDefinition& def : definitions) {
683     // Only try to transform classes that have been modified.
684     if (def.IsModified()) {
685       jvmtiError res = r.AddRedefinition(env, def);
686       if (res != OK) {
687         return res;
688       }
689     }
690   }
691   jvmtiError res = r.Run();
692   return res;
693 }
694 
AddRedefinition(ArtJvmTiEnv * env,const ArtClassDefinition & def)695 jvmtiError Redefiner::AddRedefinition(ArtJvmTiEnv* env, const ArtClassDefinition& def) {
696   std::string original_dex_location;
697   jvmtiError ret = OK;
698   if ((ret = GetClassLocation(env, def.GetClass(), &original_dex_location))) {
699     *error_msg_ = "Unable to get original dex file location!";
700     return ret;
701   }
702   char* generic_ptr_unused = nullptr;
703   char* signature_ptr = nullptr;
704   if ((ret = env->GetClassSignature(def.GetClass(), &signature_ptr, &generic_ptr_unused)) != OK) {
705     *error_msg_ = "Unable to get class signature!";
706     return ret;
707   }
708   JvmtiUniquePtr<char> generic_unique_ptr(MakeJvmtiUniquePtr(env, generic_ptr_unused));
709   JvmtiUniquePtr<char> signature_unique_ptr(MakeJvmtiUniquePtr(env, signature_ptr));
710   art::MemMap map = MoveDataToMemMap(original_dex_location, def.GetDexData(), error_msg_);
711   std::ostringstream os;
712   if (!map.IsValid()) {
713     os << "Failed to create anonymous mmap for modified dex file of class " << def.GetName()
714        << "in dex file " << original_dex_location << " because: " << *error_msg_;
715     *error_msg_ = os.str();
716     return ERR(OUT_OF_MEMORY);
717   }
718   if (map.Size() < sizeof(art::DexFile::Header)) {
719     *error_msg_ = "Could not read dex file header because dex_data was too short";
720     return ERR(INVALID_CLASS_FORMAT);
721   }
722   std::string name = map.GetName();
723   uint32_t checksum = reinterpret_cast<const art::DexFile::Header*>(map.Begin())->checksum_;
724   art::ArtDexFileLoader dex_file_loader(std::move(map), name);
725   std::unique_ptr<const art::DexFile> dex_file(dex_file_loader.Open(checksum,
726                                                                     /*verify=*/true,
727                                                                     /*verify_checksum=*/true,
728                                                                     error_msg_));
729   if (dex_file.get() == nullptr) {
730     os << "Unable to load modified dex file for " << def.GetName() << ": " << *error_msg_;
731     *error_msg_ = os.str();
732     return ERR(INVALID_CLASS_FORMAT);
733   }
734   redefinitions_.push_back(
735       Redefiner::ClassRedefinition(this,
736                                    def.GetClass(),
737                                    dex_file.release(),
738                                    signature_ptr,
739                                    def.GetNewOriginalDexFile()));
740   return OK;
741 }
742 
GetMirrorClass()743 art::ObjPtr<art::mirror::Class> Redefiner::ClassRedefinition::GetMirrorClass() {
744   return driver_->self_->DecodeJObject(klass_)->AsClass();
745 }
746 
GetClassLoader()747 art::ObjPtr<art::mirror::ClassLoader> Redefiner::ClassRedefinition::GetClassLoader() {
748   return GetMirrorClass()->GetClassLoader();
749 }
750 
CreateNewDexCache(art::Handle<art::mirror::ClassLoader> loader)751 art::mirror::DexCache* Redefiner::ClassRedefinition::CreateNewDexCache(
752     art::Handle<art::mirror::ClassLoader> loader) {
753   art::StackHandleScope<2> hs(driver_->self_);
754   art::ClassLinker* cl = driver_->runtime_->GetClassLinker();
755   art::Handle<art::mirror::DexCache> cache(hs.NewHandle(
756       art::ObjPtr<art::mirror::DexCache>::DownCast(
757           art::GetClassRoot<art::mirror::DexCache>(cl)->AllocObject(driver_->self_))));
758   if (cache.IsNull()) {
759     driver_->self_->AssertPendingOOMException();
760     return nullptr;
761   }
762   art::Handle<art::mirror::String> location(hs.NewHandle(
763       cl->GetInternTable()->InternStrong(dex_file_->GetLocation().c_str())));
764   if (location.IsNull()) {
765     driver_->self_->AssertPendingOOMException();
766     return nullptr;
767   }
768   art::WriterMutexLock mu(driver_->self_, *art::Locks::dex_lock_);
769   cache->SetLocation(location.Get());
770   cache->Initialize(dex_file_.get(), loader.Get());
771   return cache.Get();
772 }
773 
RecordFailure(jvmtiError result,const std::string & class_sig,const std::string & error_msg)774 void Redefiner::RecordFailure(jvmtiError result,
775                               const std::string& class_sig,
776                               const std::string& error_msg) {
777   *error_msg_ = StringPrintf("Unable to perform redefinition of '%s': %s",
778                              class_sig.c_str(),
779                              error_msg.c_str());
780   result_ = result;
781 }
782 
AllocateOrGetOriginalDexFile()783 art::mirror::Object* Redefiner::ClassRedefinition::AllocateOrGetOriginalDexFile() {
784   // If we have been specifically given a new set of bytes use that
785   if (original_dex_file_.size() != 0) {
786     return art::mirror::ByteArray::AllocateAndFill(
787         driver_->self_,
788         reinterpret_cast<const signed char*>(original_dex_file_.data()),
789         original_dex_file_.size()).Ptr();
790   }
791 
792   // See if we already have one set.
793   art::ObjPtr<art::mirror::ClassExt> ext(GetMirrorClass()->GetExtData());
794   if (!ext.IsNull()) {
795     art::ObjPtr<art::mirror::Object> old_original_dex_file(ext->GetOriginalDexFile());
796     if (!old_original_dex_file.IsNull()) {
797       // We do. Use it.
798       return old_original_dex_file.Ptr();
799     }
800   }
801 
802   // return the current dex_cache which has the dex file in it.
803   art::ObjPtr<art::mirror::DexCache> current_dex_cache(GetMirrorClass()->GetDexCache());
804   return current_dex_cache.Ptr();
805 }
806 
807 struct CallbackCtx {
808   ObsoleteMap* obsolete_map;
809   art::LinearAlloc* allocator;
810   std::unordered_set<art::ArtMethod*> obsolete_methods;
811 
CallbackCtxopenjdkjvmti::CallbackCtx812   explicit CallbackCtx(ObsoleteMap* map, art::LinearAlloc* alloc)
813       : obsolete_map(map), allocator(alloc) {}
814 };
815 
DoAllocateObsoleteMethodsCallback(art::Thread * t,void * vdata)816 void DoAllocateObsoleteMethodsCallback(art::Thread* t, void* vdata) NO_THREAD_SAFETY_ANALYSIS {
817   CallbackCtx* data = reinterpret_cast<CallbackCtx*>(vdata);
818   ObsoleteMethodStackVisitor::UpdateObsoleteFrames(t,
819                                                    data->allocator,
820                                                    data->obsolete_methods,
821                                                    data->obsolete_map);
822 }
823 
824 // This creates any ArtMethod* structures needed for obsolete methods and ensures that the stack is
825 // updated so they will be run.
826 // TODO Rewrite so we can do this only once regardless of how many redefinitions there are.
FindAndAllocateObsoleteMethods(art::ObjPtr<art::mirror::Class> art_klass)827 void Redefiner::ClassRedefinition::FindAndAllocateObsoleteMethods(
828     art::ObjPtr<art::mirror::Class> art_klass) {
829   DCHECK(!IsStructuralRedefinition());
830   art::ScopedAssertNoThreadSuspension ns("No thread suspension during thread stack walking");
831   art::ObjPtr<art::mirror::ClassExt> ext = art_klass->GetExtData();
832   CHECK(ext->GetObsoleteMethods() != nullptr);
833   art::ClassLinker* linker = driver_->runtime_->GetClassLinker();
834   // This holds pointers to the obsolete methods map fields which are updated as needed.
835   ObsoleteMap map(ext->GetObsoleteMethods(), ext->GetObsoleteDexCaches(), art_klass->GetDexCache());
836   CallbackCtx ctx(&map, linker->GetAllocatorForClassLoader(art_klass->GetClassLoader()));
837   // Add all the declared methods to the map
838   for (auto& m : art_klass->GetDeclaredMethods(art::kRuntimePointerSize)) {
839     if (m.IsIntrinsic()) {
840       LOG(WARNING) << "Redefining intrinsic method " << m.PrettyMethod() << ". This may cause the "
841                    << "unexpected use of the original definition of " << m.PrettyMethod() << "in "
842                    << "methods that have already been compiled.";
843     }
844     // It is possible to simply filter out some methods where they cannot really become obsolete,
845     // such as native methods and keep their original (possibly optimized) implementations. We don't
846     // do this, however, since we would need to mark these functions (still in the classes
847     // declared_methods array) as obsolete so we will find the correct dex file to get meta-data
848     // from (for example about stack-frame size). Furthermore we would be unable to get some useful
849     // error checking from the interpreter which ensure we don't try to start executing obsolete
850     // methods.
851     ctx.obsolete_methods.insert(&m);
852   }
853   {
854     art::MutexLock mu(driver_->self_, *art::Locks::thread_list_lock_);
855     art::ThreadList* list = art::Runtime::Current()->GetThreadList();
856     list->ForEach(DoAllocateObsoleteMethodsCallback, static_cast<void*>(&ctx));
857     // After we've done walking all threads' stacks and updating method pointers on them,
858     // update JIT data structures (used by the stack walk above) to point to the new methods.
859     art::jit::Jit* jit = art::Runtime::Current()->GetJit();
860     if (jit != nullptr) {
861       for (const ObsoleteMap::ObsoleteMethodPair& it : *ctx.obsolete_map) {
862         // Notify the JIT we are making this obsolete method. It will update the jit's internal
863         // structures to keep track of the new obsolete method.
864         jit->GetCodeCache()->MoveObsoleteMethod(it.old_method, it.obsolete_method);
865       }
866     }
867   }
868 }
869 
870 namespace {
871 template <typename T> struct SignatureType {};
872 template <> struct SignatureType<art::ArtField> { using type = std::string_view; };
873 template <> struct SignatureType<art::ArtMethod> { using type = art::Signature; };
874 
875 template <typename T> struct NameAndSignature {
876  public:
877   using SigType = typename SignatureType<T>::type;
878 
879   NameAndSignature(const art::DexFile* dex_file, uint32_t id);
880 
NameAndSignatureopenjdkjvmti::__anond2bfe4210211::NameAndSignature881   NameAndSignature(const std::string_view& name, const SigType& sig) : name_(name), sig_(sig) {}
882 
operator ==openjdkjvmti::__anond2bfe4210211::NameAndSignature883   bool operator==(const NameAndSignature<T>& o) const {
884     return name_ == o.name_ && sig_ == o.sig_;
885   }
886 
operator !=openjdkjvmti::__anond2bfe4210211::NameAndSignature887   bool operator!=(const NameAndSignature<T>& o) const {
888     return !(*this == o);
889   }
890 
dumpopenjdkjvmti::__anond2bfe4210211::NameAndSignature891   std::ostream& dump(std::ostream& os) const {
892     return os << "'" << name_ << "' (sig: " << sig_ << ")";
893   }
894 
ToStringopenjdkjvmti::__anond2bfe4210211::NameAndSignature895   std::string ToString() const {
896     std::ostringstream os;
897     os << *this;
898     return os.str();
899   }
900 
901   std::string_view name_;
902   SigType sig_;
903 };
904 
905 template <typename T>
operator <<(std::ostream & os,const NameAndSignature<T> & nas)906 std::ostream& operator<<(std::ostream& os, const NameAndSignature<T>& nas) {
907   return nas.dump(os);
908 }
909 
910 using FieldNameAndSignature = NameAndSignature<art::ArtField>;
911 template <>
NameAndSignature(const art::DexFile * dex_file,uint32_t id)912 FieldNameAndSignature::NameAndSignature(const art::DexFile* dex_file, uint32_t id)
913     : FieldNameAndSignature(dex_file->GetFieldName(dex_file->GetFieldId(id)),
914                             dex_file->GetFieldTypeDescriptor(dex_file->GetFieldId(id))) {}
915 
916 using MethodNameAndSignature = NameAndSignature<art::ArtMethod>;
917 template <>
NameAndSignature(const art::DexFile * dex_file,uint32_t id)918 MethodNameAndSignature::NameAndSignature(const art::DexFile* dex_file, uint32_t id)
919     : MethodNameAndSignature(dex_file->GetMethodName(dex_file->GetMethodId(id)),
920                              dex_file->GetMethodSignature(dex_file->GetMethodId(id))) {}
921 
922 }  // namespace
923 
RecordNewMethodAdded()924 void Redefiner::ClassRedefinition::RecordNewMethodAdded() {
925   DCHECK(driver_->IsStructuralRedefinition());
926   added_methods_ = true;
927 }
RecordNewFieldAdded()928 void Redefiner::ClassRedefinition::RecordNewFieldAdded() {
929   DCHECK(driver_->IsStructuralRedefinition());
930   added_fields_ = true;
931 }
932 
CheckMethods()933 bool Redefiner::ClassRedefinition::CheckMethods() {
934   art::StackHandleScope<1> hs(driver_->self_);
935   art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass()));
936   DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
937 
938   // Make sure we have the same number of methods (or the same or greater if we're structural).
939   art::ClassAccessor accessor(*dex_file_, dex_file_->GetClassDef(0));
940   uint32_t num_new_method = accessor.NumMethods();
941   uint32_t num_old_method = h_klass->GetDeclaredMethodsSlice(art::kRuntimePointerSize).size();
942   const bool is_structural = driver_->IsStructuralRedefinition();
943   if (!is_structural && num_new_method != num_old_method) {
944     bool bigger = num_new_method > num_old_method;
945     RecordFailure(bigger ? ERR(UNSUPPORTED_REDEFINITION_METHOD_ADDED)
946                          : ERR(UNSUPPORTED_REDEFINITION_METHOD_DELETED),
947                   StringPrintf("Total number of declared methods changed from %d to %d",
948                                num_old_method,
949                                num_new_method));
950     return false;
951   }
952 
953   // Skip all of the fields. We should have already checked this.
954   // Check each of the methods. NB we don't need to specifically check for removals since the 2 dex
955   // files have the same number of methods, which means there must be an equal amount of additions
956   // and removals. We should have already checked the fields.
957   const art::DexFile& old_dex_file = h_klass->GetDexFile();
958   art::ClassAccessor old_accessor(old_dex_file, *h_klass->GetClassDef());
959   // We need this to check for methods going missing in structural cases.
960   std::vector<bool> seen_old_methods(
961       (kCheckAllMethodsSeenOnce || is_structural) ? old_accessor.NumMethods() : 0, false);
962   const auto old_methods = old_accessor.GetMethods();
963   for (const art::ClassAccessor::Method& new_method : accessor.GetMethods()) {
964     // Get the data on the method we are searching for
965     MethodNameAndSignature new_method_id(dex_file_.get(), new_method.GetIndex());
966     const auto old_iter =
967         std::find_if(old_methods.cbegin(), old_methods.cend(), [&](const auto& current_old_method) {
968           MethodNameAndSignature old_method_id(&old_dex_file, current_old_method.GetIndex());
969           return old_method_id == new_method_id;
970         });
971 
972     if (!new_method.IsStaticOrDirect()) {
973       RecordHasVirtualMembers();
974     }
975     if (old_iter == old_methods.cend()) {
976       if (is_structural) {
977         RecordNewMethodAdded();
978       } else {
979         RecordFailure(
980             ERR(UNSUPPORTED_REDEFINITION_METHOD_ADDED),
981             StringPrintf("Unknown virtual method %s was added!", new_method_id.ToString().c_str()));
982         return false;
983       }
984     } else if (new_method.GetAccessFlags() != old_iter->GetAccessFlags()) {
985       RecordFailure(
986           ERR(UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED),
987           StringPrintf("method %s had different access flags", new_method_id.ToString().c_str()));
988       return false;
989     } else if (kCheckAllMethodsSeenOnce || is_structural) {
990       // We only need this if we are structural.
991       size_t off = std::distance(old_methods.cbegin(), old_iter);
992       DCHECK(!seen_old_methods[off])
993           << "field at " << off << "("
994           << MethodNameAndSignature(&old_dex_file, old_iter->GetIndex()) << ") already seen?";
995       seen_old_methods[off] = true;
996     }
997   }
998   if ((kCheckAllMethodsSeenOnce || is_structural) &&
999       !std::all_of(seen_old_methods.cbegin(), seen_old_methods.cend(), [](auto x) { return x; })) {
1000     DCHECK(is_structural) << "We should have hit an earlier failure before getting here!";
1001     auto first_fail =
1002         std::find_if(seen_old_methods.cbegin(), seen_old_methods.cend(), [](auto x) { return !x; });
1003     auto off = std::distance(seen_old_methods.cbegin(), first_fail);
1004     auto fail = old_methods.cbegin();
1005     std::advance(fail, off);
1006     RecordFailure(
1007         ERR(UNSUPPORTED_REDEFINITION_METHOD_DELETED),
1008         StringPrintf("Method %s missing!",
1009                      MethodNameAndSignature(&old_dex_file, fail->GetIndex()).ToString().c_str()));
1010     return false;
1011   }
1012   return true;
1013 }
1014 
CheckFields()1015 bool Redefiner::ClassRedefinition::CheckFields() {
1016   art::StackHandleScope<1> hs(driver_->self_);
1017   art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass()));
1018   DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
1019   art::ClassAccessor new_accessor(*dex_file_, dex_file_->GetClassDef(0));
1020 
1021   const art::DexFile& old_dex_file = h_klass->GetDexFile();
1022   art::ClassAccessor old_accessor(old_dex_file, *h_klass->GetClassDef());
1023   // Instance and static fields can be differentiated by their flags so no need to check them
1024   // separately.
1025   std::vector<bool> seen_old_fields(old_accessor.NumFields(), false);
1026   const auto old_fields = old_accessor.GetFields();
1027   for (const art::ClassAccessor::Field& new_field : new_accessor.GetFields()) {
1028     // Get the data on the method we are searching for
1029     FieldNameAndSignature new_field_id(dex_file_.get(), new_field.GetIndex());
1030     const auto old_iter =
1031         std::find_if(old_fields.cbegin(), old_fields.cend(), [&](const auto& old_iter) {
1032           FieldNameAndSignature old_field_id(&old_dex_file, old_iter.GetIndex());
1033           return old_field_id == new_field_id;
1034         });
1035     if (!new_field.IsStatic()) {
1036       RecordHasVirtualMembers();
1037     }
1038     if (old_iter == old_fields.cend()) {
1039       if (driver_->IsStructuralRedefinition()) {
1040         RecordNewFieldAdded();
1041       } else {
1042         RecordFailure(ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
1043                       StringPrintf("Unknown field %s added!", new_field_id.ToString().c_str()));
1044         return false;
1045       }
1046     } else if (new_field.GetAccessFlags() != old_iter->GetAccessFlags()) {
1047       RecordFailure(
1048           ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
1049           StringPrintf("Field %s had different access flags", new_field_id.ToString().c_str()));
1050       return false;
1051     } else {
1052       size_t off = std::distance(old_fields.cbegin(), old_iter);
1053       DCHECK(!seen_old_fields[off])
1054           << "field at " << off << "(" << FieldNameAndSignature(&old_dex_file, old_iter->GetIndex())
1055           << ") already seen?";
1056       seen_old_fields[off] = true;
1057     }
1058   }
1059   if (!std::all_of(seen_old_fields.cbegin(), seen_old_fields.cend(), [](auto x) { return x; })) {
1060     auto first_fail =
1061         std::find_if(seen_old_fields.cbegin(), seen_old_fields.cend(), [](auto x) { return !x; });
1062     auto off = std::distance(seen_old_fields.cbegin(), first_fail);
1063     auto fail = old_fields.cbegin();
1064     std::advance(fail, off);
1065     RecordFailure(
1066         ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
1067         StringPrintf("Field %s is missing!",
1068                      FieldNameAndSignature(&old_dex_file, fail->GetIndex()).ToString().c_str()));
1069     return false;
1070   }
1071   return true;
1072 }
1073 
CheckClass()1074 bool Redefiner::ClassRedefinition::CheckClass() {
1075   art::StackHandleScope<1> hs(driver_->self_);
1076   // Easy check that only 1 class def is present.
1077   if (dex_file_->NumClassDefs() != 1) {
1078     RecordFailure(ERR(ILLEGAL_ARGUMENT),
1079                   StringPrintf("Expected 1 class def in dex file but found %d",
1080                                dex_file_->NumClassDefs()));
1081     return false;
1082   }
1083   // Get the ClassDef from the new DexFile.
1084   // Since the dex file has only a single class def the index is always 0.
1085   const art::dex::ClassDef& def = dex_file_->GetClassDef(0);
1086   // Get the class as it is now.
1087   art::Handle<art::mirror::Class> current_class(hs.NewHandle(GetMirrorClass()));
1088 
1089   // Check the access flags didn't change.
1090   if (def.GetJavaAccessFlags() != (current_class->GetAccessFlags() & art::kAccValidClassFlags)) {
1091     RecordFailure(ERR(UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED),
1092                   "Cannot change modifiers of class by redefinition");
1093     return false;
1094   }
1095 
1096   // Check class name.
1097   // These should have been checked by the dexfile verifier on load.
1098   DCHECK_NE(def.class_idx_, art::dex::TypeIndex::Invalid()) << "Invalid type index";
1099   const std::string_view descriptor = dex_file_->GetTypeDescriptorView(def.class_idx_);
1100   if (!current_class->DescriptorEquals(descriptor)) {
1101     std::string storage;
1102     RecordFailure(ERR(NAMES_DONT_MATCH),
1103                   StringPrintf("expected file to contain class called '%s' but found '%s'!",
1104                                current_class->GetDescriptor(&storage),
1105                                std::string(descriptor).c_str()));
1106     return false;
1107   }
1108   if (current_class->IsObjectClass()) {
1109     if (def.superclass_idx_ != art::dex::TypeIndex::Invalid()) {
1110       RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Superclass added!");
1111       return false;
1112     }
1113   } else {
1114     const std::string_view super_descriptor = dex_file_->GetTypeDescriptorView(def.superclass_idx_);
1115     if (!current_class->GetSuperClass()->DescriptorEquals(super_descriptor)) {
1116       RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Superclass changed");
1117       return false;
1118     }
1119   }
1120   const art::dex::TypeList* interfaces = dex_file_->GetInterfacesList(def);
1121   if (interfaces == nullptr) {
1122     if (current_class->NumDirectInterfaces() != 0) {
1123       // TODO Support this for kStructural.
1124       RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Interfaces added");
1125       return false;
1126     }
1127   } else {
1128     DCHECK(!current_class->IsProxyClass());
1129     const art::dex::TypeList* current_interfaces = current_class->GetInterfaceTypeList();
1130     if (current_interfaces == nullptr || current_interfaces->Size() != interfaces->Size()) {
1131       // TODO Support this for kStructural.
1132       RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Interfaces added or removed");
1133       return false;
1134     }
1135     // The order of interfaces is (barely) meaningful so we error if it changes.
1136     const art::DexFile& orig_dex_file = current_class->GetDexFile();
1137     for (uint32_t i = 0; i < interfaces->Size(); i++) {
1138       if (dex_file_->GetTypeDescriptorView(interfaces->GetTypeItem(i).type_idx_) !=
1139           orig_dex_file.GetTypeDescriptorView(current_interfaces->GetTypeItem(i).type_idx_)) {
1140         RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED),
1141                       "Interfaces changed or re-ordered");
1142         return false;
1143       }
1144     }
1145   }
1146   return true;
1147 }
1148 
CheckRedefinable()1149 bool Redefiner::ClassRedefinition::CheckRedefinable() {
1150   std::string err;
1151   art::StackHandleScope<1> hs(driver_->self_);
1152 
1153   art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass()));
1154   jvmtiError res;
1155   if (driver_->type_ == RedefinitionType::kStructural && this->IsStructuralRedefinition()) {
1156     res = Redefiner::CanRedefineClass<RedefinitionType::kStructural>(h_klass, &err);
1157   } else {
1158     res = Redefiner::CanRedefineClass<RedefinitionType::kNormal>(h_klass, &err);
1159   }
1160   if (res != OK) {
1161     RecordFailure(res, err);
1162     return false;
1163   } else {
1164     return true;
1165   }
1166 }
1167 
CheckRedefinitionIsValid()1168 bool Redefiner::ClassRedefinition::CheckRedefinitionIsValid() {
1169   return CheckClass() && CheckFields() && CheckMethods() && CheckRedefinable();
1170 }
1171 
1172 class RedefinitionDataIter;
1173 
1174 // A wrapper that lets us hold onto the arbitrary sized data needed for redefinitions in a
1175 // reasonable way. This adds no fields to the normal ObjectArray. By doing this we can avoid
1176 // having to deal with the fact that we need to hold an arbitrary number of references live.
1177 class RedefinitionDataHolder {
1178  public:
1179   enum DataSlot : int32_t {
1180     kSlotSourceClassLoader = 0,
1181     kSlotJavaDexFile = 1,
1182     kSlotNewDexFileCookie = 2,
1183     kSlotNewDexCache = 3,
1184     kSlotMirrorClass = 4,
1185     kSlotOrigDexFile = 5,
1186     kSlotOldObsoleteMethods = 6,
1187     kSlotOldDexCaches = 7,
1188     kSlotNewClassObject = 8,
1189     kSlotOldInstanceObjects = 9,
1190     kSlotNewInstanceObjects = 10,
1191     kSlotOldClasses = 11,
1192     kSlotNewClasses = 12,
1193 
1194     // Must be last one.
1195     kNumSlots = 13,
1196   };
1197 
1198   // This needs to have a HandleScope passed in that is capable of creating a new Handle without
1199   // overflowing. Only one handle will be created. This object has a lifetime identical to that of
1200   // the passed in handle-scope.
RedefinitionDataHolder(art::StackHandleScope<1> * hs,art::Runtime * runtime,art::Thread * self,std::vector<Redefiner::ClassRedefinition> * redefinitions)1201   RedefinitionDataHolder(art::StackHandleScope<1>* hs,
1202                          art::Runtime* runtime,
1203                          art::Thread* self,
1204                          std::vector<Redefiner::ClassRedefinition>* redefinitions)
1205       REQUIRES_SHARED(art::Locks::mutator_lock_) :
1206     arr_(hs->NewHandle(art::mirror::ObjectArray<art::mirror::Object>::Alloc(
1207         self,
1208         art::GetClassRoot<art::mirror::ObjectArray<art::mirror::Object>>(runtime->GetClassLinker()),
1209         redefinitions->size() * kNumSlots))),
1210     redefinitions_(redefinitions),
1211     initialized_(redefinitions_->size(), false),
1212     actually_structural_(redefinitions_->size(), false),
1213     initial_structural_(redefinitions_->size(), false) {}
1214 
1215   ~RedefinitionDataHolder() REQUIRES_SHARED(art::Locks::mutator_lock_);
1216 
IsNull() const1217   bool IsNull() const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1218     return arr_.IsNull();
1219   }
1220 
GetSourceClassLoader(jint klass_index) const1221   art::ObjPtr<art::mirror::ClassLoader> GetSourceClassLoader(jint klass_index) const
1222       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1223     return art::ObjPtr<art::mirror::ClassLoader>::DownCast(
1224         GetSlot(klass_index, kSlotSourceClassLoader));
1225   }
GetJavaDexFile(jint klass_index) const1226   art::ObjPtr<art::mirror::Object> GetJavaDexFile(jint klass_index) const
1227       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1228     return GetSlot(klass_index, kSlotJavaDexFile);
1229   }
GetNewDexFileCookie(jint klass_index) const1230   art::ObjPtr<art::mirror::LongArray> GetNewDexFileCookie(jint klass_index) const
1231       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1232     return art::ObjPtr<art::mirror::LongArray>::DownCast(
1233         GetSlot(klass_index, kSlotNewDexFileCookie));
1234   }
GetNewDexCache(jint klass_index) const1235   art::ObjPtr<art::mirror::DexCache> GetNewDexCache(jint klass_index) const
1236       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1237     return art::ObjPtr<art::mirror::DexCache>::DownCast(GetSlot(klass_index, kSlotNewDexCache));
1238   }
GetMirrorClass(jint klass_index) const1239   art::ObjPtr<art::mirror::Class> GetMirrorClass(jint klass_index) const
1240       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1241     return art::ObjPtr<art::mirror::Class>::DownCast(GetSlot(klass_index, kSlotMirrorClass));
1242   }
1243 
GetOriginalDexFile(jint klass_index) const1244   art::ObjPtr<art::mirror::Object> GetOriginalDexFile(jint klass_index) const
1245       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1246     return art::ObjPtr<art::mirror::Object>::DownCast(GetSlot(klass_index, kSlotOrigDexFile));
1247   }
1248 
GetOldObsoleteMethods(jint klass_index) const1249   art::ObjPtr<art::mirror::PointerArray> GetOldObsoleteMethods(jint klass_index) const
1250       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1251     return art::ObjPtr<art::mirror::PointerArray>::DownCast(
1252         GetSlot(klass_index, kSlotOldObsoleteMethods));
1253   }
1254 
GetOldDexCaches(jint klass_index) const1255   art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> GetOldDexCaches(
1256       jint klass_index) const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1257     return art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>>::DownCast(
1258         GetSlot(klass_index, kSlotOldDexCaches));
1259   }
1260 
GetNewClassObject(jint klass_index) const1261   art::ObjPtr<art::mirror::Class> GetNewClassObject(jint klass_index) const
1262       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1263     return art::ObjPtr<art::mirror::Class>::DownCast(GetSlot(klass_index, kSlotNewClassObject));
1264   }
1265 
GetOldInstanceObjects(jint klass_index) const1266   art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> GetOldInstanceObjects(
1267       jint klass_index) const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1268     return art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>>::DownCast(
1269         GetSlot(klass_index, kSlotOldInstanceObjects));
1270   }
1271 
GetNewInstanceObjects(jint klass_index) const1272   art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> GetNewInstanceObjects(
1273       jint klass_index) const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1274     return art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>>::DownCast(
1275         GetSlot(klass_index, kSlotNewInstanceObjects));
1276   }
GetOldClasses(jint klass_index) const1277   art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> GetOldClasses(jint klass_index) const
1278       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1279     return art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>>::DownCast(
1280         GetSlot(klass_index, kSlotOldClasses));
1281   }
GetNewClasses(jint klass_index) const1282   art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> GetNewClasses(jint klass_index) const
1283       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1284     return art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>>::DownCast(
1285         GetSlot(klass_index, kSlotNewClasses));
1286   }
IsInitialized(jint klass_index)1287   bool IsInitialized(jint klass_index) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1288     return initialized_[klass_index];
1289   }
IsActuallyStructural(jint klass_index)1290   bool IsActuallyStructural(jint klass_index) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1291     return actually_structural_[klass_index];
1292   }
1293 
IsInitialStructural(jint klass_index)1294   bool IsInitialStructural(jint klass_index) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1295     return initial_structural_[klass_index];
1296   }
1297 
SetSourceClassLoader(jint klass_index,art::ObjPtr<art::mirror::ClassLoader> loader)1298   void SetSourceClassLoader(jint klass_index, art::ObjPtr<art::mirror::ClassLoader> loader)
1299       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1300     SetSlot(klass_index, kSlotSourceClassLoader, loader);
1301   }
SetJavaDexFile(jint klass_index,art::ObjPtr<art::mirror::Object> dexfile)1302   void SetJavaDexFile(jint klass_index, art::ObjPtr<art::mirror::Object> dexfile)
1303       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1304     SetSlot(klass_index, kSlotJavaDexFile, dexfile);
1305   }
SetNewDexFileCookie(jint klass_index,art::ObjPtr<art::mirror::LongArray> cookie)1306   void SetNewDexFileCookie(jint klass_index, art::ObjPtr<art::mirror::LongArray> cookie)
1307       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1308     SetSlot(klass_index, kSlotNewDexFileCookie, cookie);
1309   }
SetNewDexCache(jint klass_index,art::ObjPtr<art::mirror::DexCache> cache)1310   void SetNewDexCache(jint klass_index, art::ObjPtr<art::mirror::DexCache> cache)
1311       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1312     SetSlot(klass_index, kSlotNewDexCache, cache);
1313   }
SetMirrorClass(jint klass_index,art::ObjPtr<art::mirror::Class> klass)1314   void SetMirrorClass(jint klass_index, art::ObjPtr<art::mirror::Class> klass)
1315       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1316     SetSlot(klass_index, kSlotMirrorClass, klass);
1317   }
SetOriginalDexFile(jint klass_index,art::ObjPtr<art::mirror::Object> bytes)1318   void SetOriginalDexFile(jint klass_index, art::ObjPtr<art::mirror::Object> bytes)
1319       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1320     SetSlot(klass_index, kSlotOrigDexFile, bytes);
1321   }
SetOldObsoleteMethods(jint klass_index,art::ObjPtr<art::mirror::PointerArray> methods)1322   void SetOldObsoleteMethods(jint klass_index, art::ObjPtr<art::mirror::PointerArray> methods)
1323       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1324     SetSlot(klass_index, kSlotOldObsoleteMethods, methods);
1325   }
SetOldDexCaches(jint klass_index,art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> caches)1326   void SetOldDexCaches(jint klass_index,
1327                        art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> caches)
1328       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1329     SetSlot(klass_index, kSlotOldDexCaches, caches);
1330   }
1331 
SetNewClassObject(jint klass_index,art::ObjPtr<art::mirror::Class> klass)1332   void SetNewClassObject(jint klass_index, art::ObjPtr<art::mirror::Class> klass)
1333       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1334     SetSlot(klass_index, kSlotNewClassObject, klass);
1335   }
1336 
SetOldInstanceObjects(jint klass_index,art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)1337   void SetOldInstanceObjects(jint klass_index,
1338                              art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)
1339       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1340     SetSlot(klass_index, kSlotOldInstanceObjects, objs);
1341   }
SetNewInstanceObjects(jint klass_index,art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)1342   void SetNewInstanceObjects(jint klass_index,
1343                              art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)
1344       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1345     SetSlot(klass_index, kSlotNewInstanceObjects, objs);
1346   }
SetOldClasses(jint klass_index,art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)1347   void SetOldClasses(jint klass_index,
1348                      art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)
1349       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1350     SetSlot(klass_index, kSlotOldClasses, klasses);
1351   }
SetNewClasses(jint klass_index,art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)1352   void SetNewClasses(jint klass_index,
1353                      art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)
1354       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1355     SetSlot(klass_index, kSlotNewClasses, klasses);
1356   }
SetInitialized(jint klass_index)1357   void SetInitialized(jint klass_index) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1358     initialized_[klass_index] = true;
1359   }
SetActuallyStructural(jint klass_index)1360   void SetActuallyStructural(jint klass_index) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1361     actually_structural_[klass_index] = true;
1362   }
SetInitialStructural(jint klass_index)1363   void SetInitialStructural(jint klass_index) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1364     initial_structural_[klass_index] = true;
1365   }
Length() const1366   int32_t Length() const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1367     return arr_->GetLength() / kNumSlots;
1368   }
1369 
GetRedefinitions()1370   std::vector<Redefiner::ClassRedefinition>* GetRedefinitions()
1371       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1372     return redefinitions_;
1373   }
1374 
operator ==(const RedefinitionDataHolder & other) const1375   bool operator==(const RedefinitionDataHolder& other) const
1376       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1377     return arr_.Get() == other.arr_.Get();
1378   }
1379 
operator !=(const RedefinitionDataHolder & other) const1380   bool operator!=(const RedefinitionDataHolder& other) const
1381       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1382     return !(*this == other);
1383   }
1384 
1385   RedefinitionDataIter begin() REQUIRES_SHARED(art::Locks::mutator_lock_);
1386   RedefinitionDataIter end() REQUIRES_SHARED(art::Locks::mutator_lock_);
1387 
1388  private:
1389   mutable art::Handle<art::mirror::ObjectArray<art::mirror::Object>> arr_;
1390   std::vector<Redefiner::ClassRedefinition>* redefinitions_;
1391   // Used to mark a particular redefinition as fully initialized.
1392   std::vector<bool> initialized_;
1393   // Used to mark a redefinition as 'actually' structural. That is either the redefinition is
1394   // structural or a superclass is.
1395   std::vector<bool> actually_structural_;
1396   // Used to mark a redefinition as the initial structural redefinition. This redefinition will take
1397   // care of updating all of its subtypes.
1398   std::vector<bool> initial_structural_;
1399 
GetSlot(jint klass_index,DataSlot slot) const1400   art::ObjPtr<art::mirror::Object> GetSlot(jint klass_index, DataSlot slot) const
1401       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1402     DCHECK_LT(klass_index, Length());
1403     return arr_->Get((kNumSlots * klass_index) + slot);
1404   }
1405 
SetSlot(jint klass_index,DataSlot slot,art::ObjPtr<art::mirror::Object> obj)1406   void SetSlot(jint klass_index,
1407                DataSlot slot,
1408                art::ObjPtr<art::mirror::Object> obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1409     DCHECK(!art::Runtime::Current()->IsActiveTransaction());
1410     DCHECK_LT(klass_index, Length());
1411     arr_->Set<false>((kNumSlots * klass_index) + slot, obj);
1412   }
1413 
1414   DISALLOW_COPY_AND_ASSIGN(RedefinitionDataHolder);
1415 };
1416 
1417 class RedefinitionDataIter {
1418  public:
RedefinitionDataIter(int32_t idx,RedefinitionDataHolder & holder)1419   RedefinitionDataIter(int32_t idx, RedefinitionDataHolder& holder) : idx_(idx), holder_(holder) {}
1420 
1421   RedefinitionDataIter(const RedefinitionDataIter&) = default;
1422   RedefinitionDataIter(RedefinitionDataIter&&) = default;
1423   // Assignments are deleted because holder_ is a reference.
1424   RedefinitionDataIter& operator=(const RedefinitionDataIter&) = delete;
1425   RedefinitionDataIter& operator=(RedefinitionDataIter&&) = delete;
1426 
operator ==(const RedefinitionDataIter & other) const1427   bool operator==(const RedefinitionDataIter& other) const
1428       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1429     return idx_ == other.idx_ && holder_ == other.holder_;
1430   }
1431 
operator !=(const RedefinitionDataIter & other) const1432   bool operator!=(const RedefinitionDataIter& other) const
1433       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1434     return !(*this == other);
1435   }
1436 
operator ++()1437   RedefinitionDataIter operator++() {  // Value after modification.
1438     idx_++;
1439     return *this;
1440   }
1441 
operator ++(int)1442   RedefinitionDataIter operator++(int) {
1443     RedefinitionDataIter temp = *this;
1444     idx_++;
1445     return temp;
1446   }
1447 
operator +(ssize_t delta) const1448   RedefinitionDataIter operator+(ssize_t delta) const {
1449     RedefinitionDataIter temp = *this;
1450     temp += delta;
1451     return temp;
1452   }
1453 
operator +=(ssize_t delta)1454   RedefinitionDataIter& operator+=(ssize_t delta) {
1455     idx_ += delta;
1456     return *this;
1457   }
1458 
1459   // Compat for STL iterators.
operator *()1460   RedefinitionDataIter& operator*() {
1461     return *this;
1462   }
1463 
GetRedefinition()1464   Redefiner::ClassRedefinition& GetRedefinition() REQUIRES_SHARED(art::Locks::mutator_lock_) {
1465     return (*holder_.GetRedefinitions())[idx_];
1466   }
1467 
GetHolder()1468   RedefinitionDataHolder& GetHolder() {
1469     return holder_;
1470   }
1471 
GetSourceClassLoader() const1472   art::ObjPtr<art::mirror::ClassLoader> GetSourceClassLoader() const
1473       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1474     return holder_.GetSourceClassLoader(idx_);
1475   }
GetJavaDexFile() const1476   art::ObjPtr<art::mirror::Object> GetJavaDexFile() const
1477       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1478     return holder_.GetJavaDexFile(idx_);
1479   }
GetNewDexFileCookie() const1480   art::ObjPtr<art::mirror::LongArray> GetNewDexFileCookie() const
1481       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1482     return holder_.GetNewDexFileCookie(idx_);
1483   }
GetNewDexCache() const1484   art::ObjPtr<art::mirror::DexCache> GetNewDexCache() const
1485       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1486     return holder_.GetNewDexCache(idx_);
1487   }
GetMirrorClass() const1488   art::ObjPtr<art::mirror::Class> GetMirrorClass() const
1489       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1490     return holder_.GetMirrorClass(idx_);
1491   }
GetOriginalDexFile() const1492   art::ObjPtr<art::mirror::Object> GetOriginalDexFile() const
1493       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1494     return holder_.GetOriginalDexFile(idx_);
1495   }
GetOldObsoleteMethods() const1496   art::ObjPtr<art::mirror::PointerArray> GetOldObsoleteMethods() const
1497       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1498     return holder_.GetOldObsoleteMethods(idx_);
1499   }
GetOldDexCaches() const1500   art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> GetOldDexCaches() const
1501       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1502     return holder_.GetOldDexCaches(idx_);
1503   }
1504 
GetNewClassObject() const1505   art::ObjPtr<art::mirror::Class> GetNewClassObject() const
1506       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1507     return holder_.GetNewClassObject(idx_);
1508   }
1509 
GetOldInstanceObjects() const1510   art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> GetOldInstanceObjects() const
1511       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1512     return holder_.GetOldInstanceObjects(idx_);
1513   }
GetNewInstanceObjects() const1514   art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> GetNewInstanceObjects() const
1515       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1516     return holder_.GetNewInstanceObjects(idx_);
1517   }
GetOldClasses() const1518   art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> GetOldClasses() const
1519       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1520     return holder_.GetOldClasses(idx_);
1521   }
GetNewClasses() const1522   art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> GetNewClasses() const
1523       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1524     return holder_.GetNewClasses(idx_);
1525   }
IsInitialized() const1526   bool IsInitialized() const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1527     return holder_.IsInitialized(idx_);
1528   }
IsActuallyStructural() const1529   bool IsActuallyStructural() const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1530     return holder_.IsActuallyStructural(idx_);
1531   }
IsInitialStructural() const1532   bool IsInitialStructural() const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1533     return holder_.IsInitialStructural(idx_);
1534   }
GetIndex() const1535   int32_t GetIndex() const {
1536     return idx_;
1537   }
1538 
SetSourceClassLoader(art::mirror::ClassLoader * loader)1539   void SetSourceClassLoader(art::mirror::ClassLoader* loader)
1540       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1541     holder_.SetSourceClassLoader(idx_, loader);
1542   }
SetJavaDexFile(art::ObjPtr<art::mirror::Object> dexfile)1543   void SetJavaDexFile(art::ObjPtr<art::mirror::Object> dexfile)
1544       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1545     holder_.SetJavaDexFile(idx_, dexfile);
1546   }
SetNewDexFileCookie(art::ObjPtr<art::mirror::LongArray> cookie)1547   void SetNewDexFileCookie(art::ObjPtr<art::mirror::LongArray> cookie)
1548       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1549     holder_.SetNewDexFileCookie(idx_, cookie);
1550   }
SetNewDexCache(art::ObjPtr<art::mirror::DexCache> cache)1551   void SetNewDexCache(art::ObjPtr<art::mirror::DexCache> cache)
1552       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1553     holder_.SetNewDexCache(idx_, cache);
1554   }
SetMirrorClass(art::ObjPtr<art::mirror::Class> klass)1555   void SetMirrorClass(art::ObjPtr<art::mirror::Class> klass)
1556       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1557     holder_.SetMirrorClass(idx_, klass);
1558   }
SetOriginalDexFile(art::ObjPtr<art::mirror::Object> bytes)1559   void SetOriginalDexFile(art::ObjPtr<art::mirror::Object> bytes)
1560       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1561     holder_.SetOriginalDexFile(idx_, bytes);
1562   }
SetOldObsoleteMethods(art::ObjPtr<art::mirror::PointerArray> methods)1563   void SetOldObsoleteMethods(art::ObjPtr<art::mirror::PointerArray> methods)
1564       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1565     holder_.SetOldObsoleteMethods(idx_, methods);
1566   }
SetOldDexCaches(art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> caches)1567   void SetOldDexCaches(art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> caches)
1568       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1569     holder_.SetOldDexCaches(idx_, caches);
1570   }
SetNewClassObject(art::ObjPtr<art::mirror::Class> klass)1571   void SetNewClassObject(art::ObjPtr<art::mirror::Class> klass)
1572       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1573     holder_.SetNewClassObject(idx_, klass);
1574   }
SetOldInstanceObjects(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)1575   void SetOldInstanceObjects(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)
1576       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1577     holder_.SetOldInstanceObjects(idx_, objs);
1578   }
SetNewInstanceObjects(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)1579   void SetNewInstanceObjects(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)
1580       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1581     holder_.SetNewInstanceObjects(idx_, objs);
1582   }
SetOldClasses(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)1583   void SetOldClasses(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)
1584       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1585     holder_.SetOldClasses(idx_, klasses);
1586   }
SetNewClasses(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)1587   void SetNewClasses(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)
1588       REQUIRES_SHARED(art::Locks::mutator_lock_) {
1589     holder_.SetNewClasses(idx_, klasses);
1590   }
SetInitialized()1591   void SetInitialized() REQUIRES_SHARED(art::Locks::mutator_lock_) {
1592     holder_.SetInitialized(idx_);
1593   }
SetActuallyStructural()1594   void SetActuallyStructural() REQUIRES_SHARED(art::Locks::mutator_lock_) {
1595     holder_.SetActuallyStructural(idx_);
1596   }
SetInitialStructural()1597   void SetInitialStructural() REQUIRES_SHARED(art::Locks::mutator_lock_) {
1598     holder_.SetInitialStructural(idx_);
1599   }
1600 
1601  private:
1602   int32_t idx_;
1603   RedefinitionDataHolder& holder_;
1604 };
1605 
begin()1606 RedefinitionDataIter RedefinitionDataHolder::begin() {
1607   return RedefinitionDataIter(0, *this);
1608 }
1609 
end()1610 RedefinitionDataIter RedefinitionDataHolder::end() {
1611   return RedefinitionDataIter(Length(), *this);
1612 }
1613 
~RedefinitionDataHolder()1614 RedefinitionDataHolder::~RedefinitionDataHolder() {
1615   art::Thread* self = art::Thread::Current();
1616   art::ClassLinker* cl = art::Runtime::Current()->GetClassLinker();
1617   for (RedefinitionDataIter data = begin(); data != end(); ++data) {
1618     art::ObjPtr<art::mirror::DexCache> dex_cache = data.GetNewDexCache();
1619     // When redefinition fails, the dex file will be deleted in the
1620     // `ClassRedefinition` destructor. To avoid having a heap `DexCache` pointing
1621     // to a dangling pointer, we clear the entries of those dex caches that are
1622     // not registered in the runtime.
1623     if (dex_cache != nullptr &&
1624         dex_cache->GetDexFile() != nullptr &&
1625         !cl->IsDexFileRegistered(self, *dex_cache->GetDexFile())) {
1626       dex_cache->ResetNativeArrays();
1627       dex_cache->SetDexFile(nullptr);
1628     }
1629   }
1630 }
1631 
CheckVerification(const RedefinitionDataIter & iter)1632 bool Redefiner::ClassRedefinition::CheckVerification(const RedefinitionDataIter& iter) {
1633   DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
1634   art::StackHandleScope<3> hs(driver_->self_);
1635   std::string error;
1636   // TODO Make verification log level lower
1637   art::verifier::FailureKind failure =
1638       art::verifier::ClassVerifier::VerifyClass(driver_->self_,
1639                                                 /*verifier_deps=*/nullptr,
1640                                                 dex_file_.get(),
1641                                                 hs.NewHandle(iter.GetNewClassObject() != nullptr
1642                                                                 ? iter.GetNewClassObject()
1643                                                                 : iter.GetMirrorClass()),
1644                                                 hs.NewHandle(iter.GetNewDexCache()),
1645                                                 hs.NewHandle(GetClassLoader()),
1646                                                 /*class_def=*/ dex_file_->GetClassDef(0),
1647                                                 /*callbacks=*/ nullptr,
1648                                                 /*log_level=*/
1649                                                 art::verifier::HardFailLogMode::kLogWarning,
1650                                                 art::Runtime::Current()->GetTargetSdkVersion(),
1651                                                 &error);
1652   if (failure == art::verifier::FailureKind::kHardFailure) {
1653     RecordFailure(ERR(FAILS_VERIFICATION), "Failed to verify class. Error was: " + error);
1654     return false;
1655   }
1656   return true;
1657 }
1658 
1659 // Looks through the previously allocated cookies to see if we need to update them with another new
1660 // dexfile. This is so that even if multiple classes with the same classloader are redefined at
1661 // once they are all added to the classloader.
AllocateAndRememberNewDexFileCookie(art::Handle<art::mirror::ClassLoader> source_class_loader,art::Handle<art::mirror::Object> dex_file_obj,RedefinitionDataIter * cur_data)1662 bool Redefiner::ClassRedefinition::AllocateAndRememberNewDexFileCookie(
1663     art::Handle<art::mirror::ClassLoader> source_class_loader,
1664     art::Handle<art::mirror::Object> dex_file_obj,
1665     /*out*/RedefinitionDataIter* cur_data) {
1666   art::StackHandleScope<2> hs(driver_->self_);
1667   art::MutableHandle<art::mirror::LongArray> old_cookie(
1668       hs.NewHandle<art::mirror::LongArray>(nullptr));
1669   bool has_older_cookie = false;
1670   // See if we already have a cookie that a previous redefinition got from the same classloader
1671   // and the same JavaDex file.
1672   for (auto old_data = cur_data->GetHolder().begin(); old_data != *cur_data; ++old_data) {
1673     if (old_data.GetSourceClassLoader() == source_class_loader.Get() &&
1674         old_data.GetJavaDexFile() == dex_file_obj.Get()) {
1675       // Since every instance of this JavaDex file should have the same cookie associated with it we
1676       // can stop looking here.
1677       has_older_cookie = true;
1678       old_cookie.Assign(old_data.GetNewDexFileCookie());
1679       break;
1680     }
1681   }
1682   if (old_cookie.IsNull()) {
1683     // No older cookie. Get it directly from the dex_file_obj
1684     // We should not have seen this classloader elsewhere.
1685     CHECK(!has_older_cookie);
1686     old_cookie.Assign(ClassLoaderHelper::GetDexFileCookie(dex_file_obj));
1687   }
1688   // Use the old cookie to generate the new one with the new DexFile* added in.
1689   art::Handle<art::mirror::LongArray>
1690       new_cookie(hs.NewHandle(ClassLoaderHelper::AllocateNewDexFileCookie(driver_->self_,
1691                                                                           old_cookie,
1692                                                                           dex_file_.get())));
1693   // Make sure the allocation worked.
1694   if (new_cookie.IsNull()) {
1695     return false;
1696   }
1697 
1698   // Save the cookie.
1699   cur_data->SetNewDexFileCookie(new_cookie.Get());
1700   // If there are other copies of the same classloader and the same JavaDex file we need to
1701   // make sure that we all have the same cookie.
1702   if (has_older_cookie) {
1703     for (auto old_data = cur_data->GetHolder().begin(); old_data != *cur_data; ++old_data) {
1704       // We will let the GC take care of the cookie we allocated for this one.
1705       if (old_data.GetSourceClassLoader() == source_class_loader.Get() &&
1706           old_data.GetJavaDexFile() == dex_file_obj.Get()) {
1707         old_data.SetNewDexFileCookie(new_cookie.Get());
1708       }
1709     }
1710   }
1711 
1712   return true;
1713 }
1714 
CompareClasses(art::ObjPtr<art::mirror::Class> l,art::ObjPtr<art::mirror::Class> r)1715 bool CompareClasses(art::ObjPtr<art::mirror::Class> l, art::ObjPtr<art::mirror::Class> r)
1716     REQUIRES_SHARED(art::Locks::mutator_lock_) {
1717   auto parents = [](art::ObjPtr<art::mirror::Class> c) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1718     uint32_t res = 0;
1719     while (!c->IsObjectClass()) {
1720       res++;
1721       c = c->GetSuperClass();
1722     }
1723     return res;
1724   };
1725   return parents(l.Ptr()) < parents(r.Ptr());
1726 }
1727 
CollectAndCreateNewInstances(RedefinitionDataIter * cur_data)1728 bool Redefiner::ClassRedefinition::CollectAndCreateNewInstances(
1729     /*out*/ RedefinitionDataIter* cur_data) {
1730   if (!cur_data->IsInitialStructural()) {
1731     // An earlier structural redefinition already remade all the instances.
1732     return true;
1733   }
1734   art::gc::Heap* heap = driver_->runtime_->GetHeap();
1735   art::VariableSizedHandleScope hs(driver_->self_);
1736   art::Handle<art::mirror::Class> old_klass(hs.NewHandle(cur_data->GetMirrorClass()));
1737   std::vector<art::Handle<art::mirror::Object>> old_instances;
1738   auto is_instance = [&](art::mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1739     return obj->InstanceOf(old_klass.Get());
1740   };
1741   heap->VisitObjects([&](art::mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1742     if (is_instance(obj)) {
1743       old_instances.push_back(hs.NewHandle(obj));
1744     }
1745   });
1746   VLOG(plugin) << "Collected " << old_instances.size() << " instances to recreate!";
1747   art::Handle<art::mirror::ObjectArray<art::mirror::Class>> old_classes_arr(
1748       hs.NewHandle(cur_data->GetOldClasses()));
1749   art::Handle<art::mirror::ObjectArray<art::mirror::Class>> new_classes_arr(
1750       hs.NewHandle(cur_data->GetNewClasses()));
1751   DCHECK_EQ(old_classes_arr->GetLength(), new_classes_arr->GetLength());
1752   DCHECK_GT(old_classes_arr->GetLength(), 0);
1753   art::Handle<art::mirror::Class> obj_array_class(
1754       hs.NewHandle(art::GetClassRoot<art::mirror::ObjectArray<art::mirror::Object>>(
1755           driver_->runtime_->GetClassLinker())));
1756   art::Handle<art::mirror::ObjectArray<art::mirror::Object>> old_instances_arr(
1757       hs.NewHandle(art::mirror::ObjectArray<art::mirror::Object>::Alloc(
1758           driver_->self_, obj_array_class.Get(), old_instances.size())));
1759   if (old_instances_arr.IsNull()) {
1760     driver_->self_->AssertPendingOOMException();
1761     driver_->self_->ClearException();
1762     RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate old_instance arrays!");
1763     return false;
1764   }
1765   for (uint32_t i = 0; i < old_instances.size(); ++i) {
1766     old_instances_arr->Set(i, old_instances[i].Get());
1767   }
1768   cur_data->SetOldInstanceObjects(old_instances_arr.Get());
1769 
1770   art::Handle<art::mirror::ObjectArray<art::mirror::Object>> new_instances_arr(
1771       hs.NewHandle(art::mirror::ObjectArray<art::mirror::Object>::Alloc(
1772           driver_->self_, obj_array_class.Get(), old_instances.size())));
1773   if (new_instances_arr.IsNull()) {
1774     driver_->self_->AssertPendingOOMException();
1775     driver_->self_->ClearException();
1776     RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate new_instance arrays!");
1777     return false;
1778   }
1779   for (auto pair : art::ZipCount(art::IterationRange(old_instances.begin(), old_instances.end()))) {
1780     art::Handle<art::mirror::Object> hinstance(pair.first);
1781     int32_t i = pair.second;
1782     auto iterator = art::ZipLeft(old_classes_arr.Iterate<art::mirror::Class>(),
1783                                  new_classes_arr.Iterate<art::mirror::Class>());
1784     auto it = std::find_if(iterator.begin(),
1785                            iterator.end(),
1786                            [&](auto class_pair) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1787                              return class_pair.first == hinstance->GetClass();
1788                            });
1789     DCHECK(it != iterator.end()) << "Unable to find class pair for "
1790                                  << hinstance->GetClass()->PrettyClass() << " (instance " << i
1791                                  << ")";
1792     auto [_, new_type] = *it;
1793     // Make sure when allocating the new instance we don't add it's finalizer since we will directly
1794     // replace the old object in the finalizer reference. If we added it here to we would call
1795     // finalize twice.
1796     // NB If a type is changed from being non-finalizable to finalizable the finalizers on any
1797     //    objects created before the redefine will never be called. This is (sort of) allowable by
1798     //    the spec and greatly simplifies implementation.
1799     // TODO Make it so we will always call all finalizers, even if the object when it was created
1800     // wasn't finalizable. To do this we need to be careful of handling failure correctly and making
1801     // sure that objects aren't finalized multiple times and that instances of failed redefinitions
1802     // aren't finalized.
1803     art::ObjPtr<art::mirror::Object> new_instance(
1804         new_type->Alloc</*kIsInstrumented=*/true,
1805                         art::mirror::Class::AddFinalizer::kNoAddFinalizer,
1806                         /*kCheckAddFinalizer=*/false>(
1807             driver_->self_, driver_->runtime_->GetHeap()->GetCurrentAllocator()));
1808     if (new_instance.IsNull()) {
1809       driver_->self_->AssertPendingOOMException();
1810       driver_->self_->ClearException();
1811       std::string msg(
1812           StringPrintf("Could not allocate instance %d of %zu", i, old_instances.size()));
1813       RecordFailure(ERR(OUT_OF_MEMORY), msg);
1814       return false;
1815     }
1816     new_instances_arr->Set(i, new_instance);
1817   }
1818   cur_data->SetNewInstanceObjects(new_instances_arr.Get());
1819   return true;
1820 }
1821 
FinishRemainingCommonAllocations(RedefinitionDataIter * cur_data)1822 bool Redefiner::ClassRedefinition::FinishRemainingCommonAllocations(
1823     /*out*/RedefinitionDataIter* cur_data) {
1824   art::StackHandleScope<2> hs(driver_->self_);
1825   cur_data->SetMirrorClass(GetMirrorClass());
1826   // This shouldn't allocate
1827   art::Handle<art::mirror::ClassLoader> loader(hs.NewHandle(GetClassLoader()));
1828   // The bootclasspath is handled specially so it doesn't have a j.l.DexFile.
1829   if (!art::ClassLinker::IsBootClassLoader(loader.Get())) {
1830     cur_data->SetSourceClassLoader(loader.Get());
1831     art::Handle<art::mirror::Object> dex_file_obj(hs.NewHandle(
1832         ClassLoaderHelper::FindSourceDexFileObject(driver_->self_, loader)));
1833     cur_data->SetJavaDexFile(dex_file_obj.Get());
1834     if (dex_file_obj == nullptr) {
1835       RecordFailure(ERR(INTERNAL), "Unable to find dex file!");
1836       return false;
1837     }
1838     // Allocate the new dex file cookie.
1839     if (!AllocateAndRememberNewDexFileCookie(loader, dex_file_obj, cur_data)) {
1840       driver_->self_->AssertPendingOOMException();
1841       driver_->self_->ClearException();
1842       RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate dex file array for class loader");
1843       return false;
1844     }
1845   }
1846   cur_data->SetNewDexCache(CreateNewDexCache(loader));
1847   if (cur_data->GetNewDexCache() == nullptr) {
1848     driver_->self_->AssertPendingException();
1849     driver_->self_->ClearException();
1850     RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate DexCache");
1851     return false;
1852   }
1853 
1854   // We won't always need to set this field.
1855   cur_data->SetOriginalDexFile(AllocateOrGetOriginalDexFile());
1856   if (cur_data->GetOriginalDexFile() == nullptr) {
1857     driver_->self_->AssertPendingOOMException();
1858     driver_->self_->ClearException();
1859     RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate array for original dex file");
1860     return false;
1861   }
1862   return true;
1863 }
1864 
FinishNewClassAllocations(RedefinitionDataHolder & holder,RedefinitionDataIter * cur_data)1865 bool Redefiner::ClassRedefinition::FinishNewClassAllocations(RedefinitionDataHolder &holder,
1866                                                              RedefinitionDataIter *cur_data) {
1867   if (cur_data->IsInitialized() || !cur_data->IsActuallyStructural()) {
1868     cur_data->SetInitialized();
1869     return true;
1870   }
1871 
1872   art::VariableSizedHandleScope hs(driver_->self_);
1873   // If we weren't the lowest structural redef the superclass would have already initialized us.
1874   CHECK(IsStructuralRedefinition());
1875   CHECK(cur_data->IsInitialStructural()) << "Should have already been initialized by supertype";
1876   auto setup_single_redefinition =
1877       [this](RedefinitionDataIter* data, art::Handle<art::mirror::Class> super_class)
1878           REQUIRES_SHARED(art::Locks::mutator_lock_) -> art::ObjPtr<art::mirror::Class> {
1879     art::StackHandleScope<3> chs(driver_->self_);
1880     art::Handle<art::mirror::Class> nc(
1881         chs.NewHandle(AllocateNewClassObject(chs.NewHandle(data->GetMirrorClass()),
1882                                              super_class,
1883                                              chs.NewHandle(data->GetNewDexCache()),
1884                                              /*dex_class_def_index*/ 0)));
1885     if (nc.IsNull()) {
1886       return nullptr;
1887     }
1888 
1889     data->SetNewClassObject(nc.Get());
1890     data->SetInitialized();
1891     return nc.Get();
1892   };
1893 
1894   std::vector<art::Handle<art::mirror::Class>> old_types;
1895   {
1896     art::gc::Heap* heap = driver_->runtime_->GetHeap();
1897     art::Handle<art::mirror::Class>
1898         old_klass(hs.NewHandle(cur_data->GetMirrorClass()));
1899     if (setup_single_redefinition(cur_data, hs.NewHandle(old_klass->GetSuperClass())).IsNull()) {
1900       return false;
1901     }
1902     auto is_subtype = [&](art::mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1903       // We've already waited for class defines to be finished and paused them. All classes should be
1904       // either resolved or error. We don't need to do anything with error classes, since they cannot
1905       // be accessed in any observable way.
1906       return obj->IsClass() && obj->AsClass()->IsResolved() &&
1907             old_klass->IsAssignableFrom(obj->AsClass());
1908     };
1909     heap->VisitObjects([&](art::mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1910       if (is_subtype(obj)) {
1911         old_types.push_back(hs.NewHandle(obj->AsClass()));
1912       }
1913     });
1914     DCHECK_GT(old_types.size(), 0u) << "Expected to find at least old_klass!";
1915     VLOG(plugin) << "Found " << old_types.size() << " types that are/are subtypes of "
1916                 << old_klass->PrettyClass();
1917   }
1918 
1919   art::Handle<art::mirror::Class> cls_array_class(
1920       hs.NewHandle(art::GetClassRoot<art::mirror::ObjectArray<art::mirror::Class>>(
1921           driver_->runtime_->GetClassLinker())));
1922   art::Handle<art::mirror::ObjectArray<art::mirror::Class>> old_classes_arr(
1923       hs.NewHandle(art::mirror::ObjectArray<art::mirror::Class>::Alloc(
1924           driver_->self_, cls_array_class.Get(), old_types.size())));
1925   if (old_classes_arr.IsNull()) {
1926     driver_->self_->AssertPendingOOMException();
1927     driver_->self_->ClearException();
1928     RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate old_classes arrays!");
1929     return false;
1930   }
1931   // Sort the old_types topologically.
1932   {
1933     art::ScopedAssertNoThreadSuspension sants("Sort classes");
1934     // Sort them by the distance to the base-class. This ensures that any class occurs before any of
1935     // its subtypes.
1936     std::sort(old_types.begin(),
1937               old_types.end(),
1938               [](auto& l, auto& r) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1939                 return CompareClasses(l.Get(), r.Get());
1940               });
1941   }
1942   for (uint32_t i = 0; i < old_types.size(); ++i) {
1943     DCHECK(!old_types[i].IsNull()) << i;
1944     old_classes_arr->Set(i, old_types[i].Get());
1945   }
1946   cur_data->SetOldClasses(old_classes_arr.Get());
1947   DCHECK_GT(old_classes_arr->GetLength(), 0);
1948 
1949   art::Handle<art::mirror::ObjectArray<art::mirror::Class>> new_classes_arr(
1950       hs.NewHandle(art::mirror::ObjectArray<art::mirror::Class>::Alloc(
1951           driver_->self_, cls_array_class.Get(), old_types.size())));
1952   if (new_classes_arr.IsNull()) {
1953     driver_->self_->AssertPendingOOMException();
1954     driver_->self_->ClearException();
1955     RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate new_classes arrays!");
1956     return false;
1957   }
1958 
1959   art::MutableHandle<art::mirror::DexCache> dch(hs.NewHandle<art::mirror::DexCache>(nullptr));
1960   art::MutableHandle<art::mirror::Class> superclass(hs.NewHandle<art::mirror::Class>(nullptr));
1961   for (size_t i = 0; i < old_types.size(); i++) {
1962     art::Handle<art::mirror::Class>& old_type = old_types[i];
1963     if (old_type.Get() == cur_data->GetMirrorClass()) {
1964       CHECK_EQ(i, 0u) << "original class not at index 0. Bad sort!";
1965       new_classes_arr->Set(i, cur_data->GetNewClassObject());
1966       continue;
1967     } else {
1968       auto old_super = std::find_if(old_types.begin(),
1969                                     old_types.begin() + i,
1970                                     [&](art::Handle<art::mirror::Class>& v)
1971                                         REQUIRES_SHARED(art::Locks::mutator_lock_) {
1972                                           return v.Get() == old_type->GetSuperClass();
1973                                         });
1974       // Only the GetMirrorClass should not be in this list.
1975       CHECK(old_super != old_types.begin() + i)
1976           << "from first " << i << " could not find super of " << old_type->PrettyClass()
1977           << " expected to find " << old_type->GetSuperClass()->PrettyClass();
1978       superclass.Assign(new_classes_arr->Get(std::distance(old_types.begin(), old_super)));
1979       auto new_redef = std::find_if(
1980           *cur_data + 1, holder.end(), [&](auto it) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1981             return it.GetMirrorClass() == old_type.Get();
1982           });
1983       art::ObjPtr<art::mirror::Class> new_type;
1984       if (new_redef == holder.end()) {
1985         // We aren't also redefining this subclass. Just allocate a new class and continue.
1986         dch.Assign(old_type->GetDexCache());
1987         new_type =
1988             AllocateNewClassObject(old_type, superclass, dch, old_type->GetDexClassDefIndex());
1989       } else {
1990         // This subclass is also being redefined. We need to use its new dex-file to load the new
1991         // class.
1992         CHECK(new_redef.IsActuallyStructural());
1993         CHECK(!new_redef.IsInitialStructural());
1994         new_type = setup_single_redefinition(&new_redef, superclass);
1995       }
1996       if (new_type == nullptr) {
1997         VLOG(plugin) << "Failed to load new version of class " << old_type->PrettyClass()
1998                      << " for structural redefinition!";
1999         return false;
2000       }
2001       new_classes_arr->Set(i, new_type);
2002     }
2003   }
2004   cur_data->SetNewClasses(new_classes_arr.Get());
2005   return true;
2006 }
2007 
GetNewClassSize(art::ClassAccessor & accessor)2008 uint32_t Redefiner::ClassRedefinition::GetNewClassSize(art::ClassAccessor& accessor) {
2009   uint32_t num_8bit_static_fields = 0;
2010   uint32_t num_16bit_static_fields = 0;
2011   uint32_t num_32bit_static_fields = 0;
2012   uint32_t num_64bit_static_fields = 0;
2013   uint32_t num_ref_static_fields = 0;
2014   for (const art::ClassAccessor::Field& f : accessor.GetStaticFields()) {
2015     std::string_view desc(accessor.GetDexFile().GetFieldTypeDescriptor(
2016         accessor.GetDexFile().GetFieldId(f.GetIndex())));
2017     if (desc[0] == 'L' || desc[0] == '[') {
2018       num_ref_static_fields++;
2019     } else if (desc == "Z" || desc == "B") {
2020       num_8bit_static_fields++;
2021     } else if (desc == "C" || desc == "S") {
2022       num_16bit_static_fields++;
2023     } else if (desc == "I" || desc == "F") {
2024       num_32bit_static_fields++;
2025     } else if (desc == "J" || desc == "D") {
2026       num_64bit_static_fields++;
2027     } else {
2028       LOG(FATAL) << "Unknown type descriptor! " << desc;
2029     }
2030   }
2031 
2032   return art::mirror::Class::ComputeClassSize(/*has_embedded_vtable=*/false,
2033                                               /*num_vtable_entries=*/0,
2034                                               num_8bit_static_fields,
2035                                               num_16bit_static_fields,
2036                                               num_32bit_static_fields,
2037                                               num_64bit_static_fields,
2038                                               num_ref_static_fields,
2039                                               /*num_ref_bitmap_entries=*/0,
2040                                               art::kRuntimePointerSize);
2041 }
2042 
2043 art::ObjPtr<art::mirror::Class>
AllocateNewClassObject(art::Handle<art::mirror::DexCache> cache)2044 Redefiner::ClassRedefinition::AllocateNewClassObject(art::Handle<art::mirror::DexCache> cache) {
2045   art::StackHandleScope<2> hs(driver_->self_);
2046   art::Handle<art::mirror::Class> old_class(hs.NewHandle(GetMirrorClass()));
2047   art::Handle<art::mirror::Class> super_class(hs.NewHandle(old_class->GetSuperClass()));
2048   return AllocateNewClassObject(old_class, super_class, cache, /*dex_class_def_index*/0);
2049 }
2050 
AllocateNewClassObject(art::Handle<art::mirror::Class> old_class,art::Handle<art::mirror::Class> super_class,art::Handle<art::mirror::DexCache> cache,uint16_t dex_class_def_index)2051 art::ObjPtr<art::mirror::Class> Redefiner::ClassRedefinition::AllocateNewClassObject(
2052     art::Handle<art::mirror::Class> old_class,
2053     art::Handle<art::mirror::Class> super_class,
2054     art::Handle<art::mirror::DexCache> cache,
2055     uint16_t dex_class_def_index) {
2056   // This is a stripped down DefineClass. We don't want to use DefineClass directly because it needs
2057   // to perform a lot of extra steps to tell the ClassTable and the jit and everything about a new
2058   // class. For now we will need to rely on our tests catching any issues caused by changes in how
2059   // class_linker sets up classes.
2060   // TODO Unify/move this into ClassLinker maybe.
2061   art::StackHandleScope<3> hs(driver_->self_);
2062   art::ClassLinker* linker = driver_->runtime_->GetClassLinker();
2063   const art::DexFile* dex_file = cache->GetDexFile();
2064   art::ClassAccessor accessor(*dex_file, dex_class_def_index);
2065   art::Handle<art::mirror::Class> new_class(hs.NewHandle(linker->AllocClass(
2066       driver_->self_, GetNewClassSize(accessor))));
2067   if (new_class.IsNull()) {
2068     driver_->self_->AssertPendingOOMException();
2069     RecordFailure(
2070         ERR(OUT_OF_MEMORY),
2071         "Unable to allocate class object for redefinition of " + old_class->PrettyClass());
2072     driver_->self_->ClearException();
2073     return nullptr;
2074   }
2075   new_class->SetDexCache(cache.Get());
2076   linker->SetupClass(*dex_file,
2077                      dex_file->GetClassDef(dex_class_def_index),
2078                      new_class,
2079                      old_class->GetClassLoader());
2080 
2081   // Make sure we are ready for linking. The lock isn't really needed since this isn't visible to
2082   // other threads but the linker expects it.
2083   art::ObjectLock<art::mirror::Class> lock(driver_->self_, new_class);
2084   new_class->SetClinitThreadId(driver_->self_->GetTid());
2085   // Make sure we have a valid empty iftable even if there are errors.
2086   new_class->SetIfTable(art::GetClassRoot<art::mirror::Object>(linker)->GetIfTable());
2087   linker->LoadClass(
2088       driver_->self_, *dex_file, dex_file->GetClassDef(dex_class_def_index), new_class);
2089   // NB. We know the interfaces and supers didn't change! :)
2090   art::MutableHandle<art::mirror::Class> linked_class(hs.NewHandle<art::mirror::Class>(nullptr));
2091   art::Handle<art::mirror::ObjectArray<art::mirror::Class>> proxy_ifaces(
2092       hs.NewHandle<art::mirror::ObjectArray<art::mirror::Class>>(nullptr));
2093   // No changing hierarchy so everything is loaded.
2094   new_class->SetSuperClass(super_class.Get());
2095   art::mirror::Class::SetStatus(new_class, art::ClassStatus::kLoaded, nullptr);
2096   if (!linker->LinkClass(driver_->self_, nullptr, new_class, proxy_ifaces, &linked_class)) {
2097     std::ostringstream oss;
2098     oss << "failed to link class due to "
2099         << (driver_->self_->IsExceptionPending() ? driver_->self_->GetException()->Dump()
2100                                                  : " unknown");
2101     RecordFailure(ERR(INTERNAL), oss.str());
2102     driver_->self_->ClearException();
2103     return nullptr;
2104   }
2105   // Everything is already resolved.
2106   art::ObjectLock<art::mirror::Class> objlock(driver_->self_, linked_class);
2107   // Mark the class as initialized.
2108   CHECK(old_class->IsResolved())
2109       << "Attempting to redefine an unresolved class " << old_class->PrettyClass()
2110       << " status=" << old_class->GetStatus();
2111   CHECK(linked_class->IsResolved());
2112   if (old_class->ShouldSkipHiddenApiChecks()) {
2113     // Match skip hiddenapi flag
2114     linked_class->SetSkipHiddenApiChecks();
2115   }
2116   if (old_class->IsInitialized()) {
2117     // We already verified the class earlier. No need to do it again.
2118     linker->ForceClassInitialized(driver_->self_, linked_class);
2119   } else if (old_class->GetStatus() > linked_class->GetStatus()) {
2120     // We want to match the old status.
2121     art::mirror::Class::SetStatus(linked_class, old_class->GetStatus(), driver_->self_);
2122   }
2123   // Make sure we have ext-data space for method & field ids. We won't know if we need them until
2124   // it's too late to create them.
2125   // TODO We might want to remove these arrays if they're not needed.
2126   if (!art::mirror::Class::EnsureInstanceFieldIds(linked_class) ||
2127       !art::mirror::Class::EnsureStaticFieldIds(linked_class) ||
2128       !art::mirror::Class::EnsureMethodIds(linked_class)) {
2129     driver_->self_->AssertPendingOOMException();
2130     driver_->self_->ClearException();
2131     RecordFailure(
2132         ERR(OUT_OF_MEMORY),
2133         "Unable to allocate jni-id arrays for redefinition of " + old_class->PrettyClass());
2134     return nullptr;
2135   }
2136   // Finish setting up methods.
2137   linked_class->VisitMethods([&](art::ArtMethod* m) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2138     driver_->runtime_->GetInstrumentation()->InitializeMethodsCode(m, /* aot_code= */ nullptr);
2139     m->SetNotIntrinsic();
2140     DCHECK(m->IsCopied() || m->GetDeclaringClass() == linked_class.Get())
2141         << m->PrettyMethod()
2142         << " m->GetDeclaringClass(): " << m->GetDeclaringClass()->PrettyClass()
2143         << " != linked_class.Get(): " << linked_class->PrettyClass();
2144   }, art::kRuntimePointerSize);
2145   if (art::kIsDebugBuild) {
2146     linked_class->VisitFields([&](art::ArtField* f) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2147       DCHECK_EQ(f->GetDeclaringClass(), linked_class.Get());
2148     });
2149   }
2150   // Reset ClinitThreadId back to the thread that loaded the old class. This is needed if we are in
2151   // the middle of initializing a class.
2152   linked_class->SetClinitThreadId(old_class->GetClinitThreadId());
2153   return linked_class.Get();
2154 }
2155 
UnregisterJvmtiBreakpoints()2156 void Redefiner::ClassRedefinition::UnregisterJvmtiBreakpoints() {
2157   BreakpointUtil::RemoveBreakpointsInClass(driver_->env_, GetMirrorClass().Ptr());
2158 }
2159 
UnregisterAllBreakpoints()2160 void Redefiner::UnregisterAllBreakpoints() {
2161   for (Redefiner::ClassRedefinition& redef : redefinitions_) {
2162     redef.UnregisterJvmtiBreakpoints();
2163   }
2164 }
2165 
CheckAllRedefinitionAreValid()2166 bool Redefiner::CheckAllRedefinitionAreValid() {
2167   for (Redefiner::ClassRedefinition& redef : redefinitions_) {
2168     if (!redef.CheckRedefinitionIsValid()) {
2169       return false;
2170     }
2171   }
2172   return true;
2173 }
2174 
RestoreObsoleteMethodMapsIfUnneeded(RedefinitionDataHolder & holder)2175 void Redefiner::RestoreObsoleteMethodMapsIfUnneeded(RedefinitionDataHolder& holder) {
2176   for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2177     data.GetRedefinition().RestoreObsoleteMethodMapsIfUnneeded(&data);
2178   }
2179 }
2180 
MarkStructuralChanges(RedefinitionDataHolder & holder)2181 void Redefiner::MarkStructuralChanges(RedefinitionDataHolder& holder) {
2182   for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2183     if (data.IsActuallyStructural()) {
2184       // A superclass was structural and it marked all subclasses already. No need to do anything.
2185       CHECK(!data.IsInitialStructural());
2186     } else if (data.GetRedefinition().IsStructuralRedefinition()) {
2187       data.SetActuallyStructural();
2188       data.SetInitialStructural();
2189       // Go over all potential subtypes and mark any that are actually subclasses as structural.
2190       for (RedefinitionDataIter sub_data = data + 1; sub_data != holder.end(); ++sub_data) {
2191         if (sub_data.GetRedefinition().GetMirrorClass()->IsSubClass(
2192                 data.GetRedefinition().GetMirrorClass())) {
2193           sub_data.SetActuallyStructural();
2194         }
2195       }
2196     }
2197   }
2198 }
2199 
EnsureAllClassAllocationsFinished(RedefinitionDataHolder & holder)2200 bool Redefiner::EnsureAllClassAllocationsFinished(RedefinitionDataHolder& holder) {
2201   for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2202     if (!data.GetRedefinition().EnsureClassAllocationsFinished(&data)) {
2203       return false;
2204     }
2205   }
2206   return true;
2207 }
2208 
CollectAndCreateNewInstances(RedefinitionDataHolder & holder)2209 bool Redefiner::CollectAndCreateNewInstances(RedefinitionDataHolder& holder) {
2210   for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2211     // Allocate the data this redefinition requires.
2212     if (!data.GetRedefinition().CollectAndCreateNewInstances(&data)) {
2213       return false;
2214     }
2215   }
2216   return true;
2217 }
2218 
FinishAllNewClassAllocations(RedefinitionDataHolder & holder)2219 bool Redefiner::FinishAllNewClassAllocations(RedefinitionDataHolder& holder) {
2220   for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2221     // Allocate the data this redefinition requires.
2222     if (!data.GetRedefinition().FinishNewClassAllocations(holder, &data)) {
2223       return false;
2224     }
2225   }
2226   return true;
2227 }
2228 
FinishAllRemainingCommonAllocations(RedefinitionDataHolder & holder)2229 bool Redefiner::FinishAllRemainingCommonAllocations(RedefinitionDataHolder& holder) {
2230   for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2231     // Allocate the data this redefinition requires.
2232     if (!data.GetRedefinition().FinishRemainingCommonAllocations(&data)) {
2233       return false;
2234     }
2235   }
2236   return true;
2237 }
2238 
ReleaseDexFile()2239 void Redefiner::ClassRedefinition::ReleaseDexFile() {
2240   if (art::kIsDebugBuild) {
2241     art::Thread* self = art::Thread::Current();
2242     art::ClassLinker* cl = art::Runtime::Current()->GetClassLinker();
2243     CHECK(cl->IsDexFileRegistered(self, *dex_file_));
2244   }
2245   dex_file_.release();  // NOLINT b/117926937
2246 }
2247 
ReleaseAllDexFiles()2248 void Redefiner::ReleaseAllDexFiles() {
2249   for (Redefiner::ClassRedefinition& redef : redefinitions_) {
2250     redef.ReleaseDexFile();
2251   }
2252 }
2253 
CheckAllClassesAreVerified(RedefinitionDataHolder & holder)2254 bool Redefiner::CheckAllClassesAreVerified(RedefinitionDataHolder& holder) {
2255   for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2256     if (!data.GetRedefinition().CheckVerification(data)) {
2257       return false;
2258     }
2259   }
2260   return true;
2261 }
2262 
2263 class ScopedDisableConcurrentAndMovingGc {
2264  public:
ScopedDisableConcurrentAndMovingGc(art::gc::Heap * heap,art::Thread * self)2265   ScopedDisableConcurrentAndMovingGc(art::gc::Heap* heap, art::Thread* self)
2266       : heap_(heap), self_(self) {
2267     if (heap_->IsGcConcurrentAndMoving()) {
2268       heap_->IncrementDisableMovingGC(self_);
2269     }
2270   }
2271 
~ScopedDisableConcurrentAndMovingGc()2272   ~ScopedDisableConcurrentAndMovingGc() {
2273     if (heap_->IsGcConcurrentAndMoving()) {
2274       heap_->DecrementDisableMovingGC(self_);
2275     }
2276   }
2277  private:
2278   art::gc::Heap* heap_;
2279   art::Thread* self_;
2280 };
2281 
2282 class ClassDefinitionPauser : public art::ClassLoadCallback {
2283  public:
REQUIRES_SHARED(art::Locks::mutator_lock_)2284   explicit ClassDefinitionPauser(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_)
2285       : self_(self),
2286         is_running_(false),
2287         barrier_(0),
2288         release_mu_("SuspendClassDefinition lock", art::kGenericBottomLock),
2289         release_barrier_(0),
2290         release_cond_("SuspendClassDefinition condvar", release_mu_),
2291         count_(0),
2292         release_(false) {
2293     art::Locks::mutator_lock_->AssertSharedHeld(self_);
2294   }
REQUIRES_SHARED(art::Locks::mutator_lock_)2295   ~ClassDefinitionPauser() REQUIRES_SHARED(art::Locks::mutator_lock_) {
2296     art::Locks::mutator_lock_->AssertSharedHeld(self_);
2297     CHECK(release_) << "Must call Release()";
2298   }
Release()2299   void Release() REQUIRES(art::Locks::mutator_lock_) {
2300     if (is_running_) {
2301       art::Locks::mutator_lock_->AssertExclusiveHeld(self_);
2302       uint32_t count;
2303       // Wake up everything.
2304       {
2305         art::MutexLock mu(self_, release_mu_);
2306         release_ = true;
2307         // We have an exclusive mutator so all threads must be suspended and therefore they've
2308         // either already incremented this count_ or they are stuck somewhere before it.
2309         count = count_;
2310         release_cond_.Broadcast(self_);
2311       }
2312       // Wait for all threads to leave this structs code.
2313       VLOG(plugin) << "Resuming " << count << " threads paused before class-allocation!";
2314       release_barrier_.Increment</*locks=*/art::Barrier::kAllowHoldingLocks>(self_, count);
2315     } else {
2316       release_ = true;
2317     }
2318   }
BeginDefineClass()2319   void BeginDefineClass() override REQUIRES_SHARED(art::Locks::mutator_lock_) {
2320     art::Thread* this_thread = art::Thread::Current();
2321     if (this_thread == self_) {
2322       // Allow the redefining thread to do whatever.
2323       return;
2324     }
2325     if (this_thread->GetDefineClassCount() != 0) {
2326       // We are in the middle of a recursive define-class. Don't suspend now allow it to finish.
2327       VLOG(plugin) << "Recursive DefineClass in " << *this_thread
2328                    << " allowed to proceed despite class-def pause initiated by " << *self_;
2329       return;
2330     }
2331     // If we are suspended (no mutator-lock) then the pausing thread could do everything before the
2332     // count_++ including destroying this object, causing UAF/deadlock.
2333     art::Locks::mutator_lock_->AssertSharedHeld(this_thread);
2334     ++count_;
2335     art::ScopedThreadSuspension sts(this_thread, art::ThreadState::kSuspended);
2336     {
2337       art::MutexLock mu(this_thread, release_mu_);
2338       VLOG(plugin) << "Suspending " << *this_thread << " due to class definition. class-def pause "
2339                    << "initiated by " << *self_;
2340       while (!release_) {
2341         release_cond_.Wait(this_thread);
2342       }
2343     }
2344     release_barrier_.Pass(this_thread);
2345   }
2346 
EndDefineClass()2347   void EndDefineClass() override REQUIRES_SHARED(art::Locks::mutator_lock_) {
2348     art::Thread* this_thread = art::Thread::Current();
2349     if (this_thread == self_) {
2350       // Allow the redefining thread to do whatever.
2351       return;
2352     }
2353     if (this_thread->GetDefineClassCount() == 0) {
2354       // We are done with defining classes.
2355       barrier_.Pass(this_thread);
2356     }
2357   }
2358 
ClassLoad(art::Handle<art::mirror::Class> klass)2359   void ClassLoad([[maybe_unused]] art::Handle<art::mirror::Class> klass) override {}
ClassPrepare(art::Handle<art::mirror::Class> klass1,art::Handle<art::mirror::Class> klass2)2360   void ClassPrepare([[maybe_unused]] art::Handle<art::mirror::Class> klass1,
2361                     [[maybe_unused]] art::Handle<art::mirror::Class> klass2) override {}
2362 
SetRunning()2363   void SetRunning() {
2364     is_running_ = true;
2365   }
WaitFor(uint32_t t)2366   void WaitFor(uint32_t t) REQUIRES(!art::Locks::mutator_lock_) {
2367     barrier_.Increment(self_, t);
2368   }
2369 
2370  private:
2371   art::Thread* self_;
2372   bool is_running_;
2373   art::Barrier barrier_;
2374   art::Mutex release_mu_;
2375   art::Barrier release_barrier_;
2376   art::ConditionVariable release_cond_;
2377   std::atomic<uint32_t> count_;
2378   bool release_;
2379 };
2380 
2381 class ScopedSuspendClassLoading {
2382  public:
ScopedSuspendClassLoading(art::Thread * self,art::Runtime * runtime,RedefinitionDataHolder & h)2383   ScopedSuspendClassLoading(art::Thread* self, art::Runtime* runtime, RedefinitionDataHolder& h)
2384       REQUIRES_SHARED(art::Locks::mutator_lock_)
2385       : self_(self), runtime_(runtime), pauser_() {
2386     if (std::any_of(h.begin(), h.end(), [](auto r) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2387           return r.GetRedefinition().IsStructuralRedefinition();
2388         })) {
2389       VLOG(plugin) << "Pausing Class loading for structural redefinition.";
2390       pauser_.emplace(self);
2391       {
2392         art::ScopedThreadSuspension sts(self_, art::ThreadState::kNative);
2393         uint32_t in_progress_defines = 0;
2394         {
2395           art::ScopedSuspendAll ssa(__FUNCTION__);
2396           pauser_->SetRunning();
2397           runtime_->GetRuntimeCallbacks()->AddClassLoadCallback(&pauser_.value());
2398           art::MutexLock mu(self_, *art::Locks::thread_list_lock_);
2399           runtime_->GetThreadList()->ForEach([&](art::Thread* t) {
2400             if (t != self_ && t->GetDefineClassCount() != 0) {
2401               in_progress_defines++;
2402             }
2403           });
2404           VLOG(plugin) << "Waiting for " << in_progress_defines
2405                        << " in progress class-loads to finish";
2406         }
2407         pauser_->WaitFor(in_progress_defines);
2408       }
2409     }
2410   }
~ScopedSuspendClassLoading()2411   ~ScopedSuspendClassLoading() {
2412     if (pauser_.has_value()) {
2413       art::ScopedThreadSuspension sts(self_, art::ThreadState::kNative);
2414       art::ScopedSuspendAll ssa(__FUNCTION__);
2415       pauser_->Release();
2416       runtime_->GetRuntimeCallbacks()->RemoveClassLoadCallback(&pauser_.value());
2417     }
2418   }
2419 
2420  private:
2421   art::Thread* self_;
2422   art::Runtime* runtime_;
2423   std::optional<ClassDefinitionPauser> pauser_;
2424 };
2425 
2426 class ScopedSuspendAllocations {
2427  public:
ScopedSuspendAllocations(art::Runtime * runtime,RedefinitionDataHolder & h)2428   ScopedSuspendAllocations(art::Runtime* runtime, RedefinitionDataHolder& h)
2429       REQUIRES_SHARED(art::Locks::mutator_lock_)
2430       : paused_(false) {
2431     if (std::any_of(h.begin(),
2432                     h.end(),
2433                     [](auto r) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2434                       return r.GetRedefinition().IsStructuralRedefinition();
2435                     })) {
2436       VLOG(plugin) << "Pausing allocations for structural redefinition.";
2437       paused_ = true;
2438       AllocationManager::Get()->PauseAllocations(art::Thread::Current());
2439       // Collect garbage so we don't need to recreate as much.
2440       runtime->GetHeap()->CollectGarbage(/*clear_soft_references=*/false);
2441     }
2442   }
2443 
REQUIRES_SHARED(art::Locks::mutator_lock_)2444   ~ScopedSuspendAllocations() REQUIRES_SHARED(art::Locks::mutator_lock_) {
2445     if (paused_) {
2446       AllocationManager::Get()->ResumeAllocations(art::Thread::Current());
2447     }
2448   }
2449 
2450  private:
2451   bool paused_;
2452 
2453   DISALLOW_COPY_AND_ASSIGN(ScopedSuspendAllocations);
2454 };
2455 
Run()2456 jvmtiError Redefiner::Run() {
2457   art::StackHandleScope<1> hs(self_);
2458   // Sort the redefinitions_ array topologically by class. This makes later steps easier since we
2459   // know that every class precedes all of its supertypes.
2460   std::sort(redefinitions_.begin(),
2461             redefinitions_.end(),
2462             [&](auto& l, auto& r) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2463               return CompareClasses(l.GetMirrorClass(), r.GetMirrorClass());
2464             });
2465   // Allocate an array to hold onto all java temporary objects associated with this
2466   // redefinition. We will let this be collected after the end of this function.
2467   RedefinitionDataHolder holder(&hs, runtime_, self_, &redefinitions_);
2468   if (holder.IsNull()) {
2469     self_->AssertPendingOOMException();
2470     self_->ClearException();
2471     RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate storage for temporaries");
2472     return result_;
2473   }
2474 
2475   // First we just allocate the ClassExt and its fields that we need. These can be updated
2476   // atomically without any issues (since we allocate the map arrays as empty).
2477   if (!CheckAllRedefinitionAreValid()) {
2478     return result_;
2479   }
2480   // Mark structural changes.
2481   MarkStructuralChanges(holder);
2482   // Now we pause class loading. If we are doing a structural redefinition we will need to get an
2483   // accurate picture of the classes loaded and having loads in the middle would make that
2484   // impossible. This only pauses class-loading if we actually have at least one structural
2485   // redefinition.
2486   ScopedSuspendClassLoading suspend_class_load(self_, runtime_, holder);
2487   if (!EnsureAllClassAllocationsFinished(holder) ||
2488       !FinishAllRemainingCommonAllocations(holder) ||
2489       !FinishAllNewClassAllocations(holder) ||
2490       !CheckAllClassesAreVerified(holder)) {
2491     return result_;
2492   }
2493 
2494   ScopedSuspendAllocations suspend_alloc(runtime_, holder);
2495   if (!CollectAndCreateNewInstances(holder)) {
2496     return result_;
2497   }
2498 
2499   // At this point we can no longer fail without corrupting the runtime state.
2500   for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2501     art::ClassLinker* cl = runtime_->GetClassLinker();
2502     if (data.GetSourceClassLoader() == nullptr) {
2503       // AppendToBootClassPath includes dex file registration.
2504       const art::DexFile& dex_file = data.GetRedefinition().GetDexFile();
2505       runtime_->AppendToBootClassPath(
2506           dex_file.GetLocation(), dex_file.GetLocation(), {{&dex_file, data.GetNewDexCache()}});
2507     } else {
2508       cl->RegisterExistingDexCache(data.GetNewDexCache(), data.GetSourceClassLoader());
2509     }
2510     DCHECK_EQ(cl->FindDexCache(self_, data.GetRedefinition().GetDexFile()), data.GetNewDexCache());
2511   }
2512   UnregisterAllBreakpoints();
2513 
2514   {
2515     // Disable GC and wait for it to be done if we are a moving GC.  This is fine since we are done
2516     // allocating so no deadlocks.
2517     ScopedDisableConcurrentAndMovingGc sdcamgc(runtime_->GetHeap(), self_);
2518 
2519     // Do transition to final suspension
2520     // TODO We might want to give this its own suspended state!
2521     // TODO This isn't right. We need to change state without any chance of suspend ideally!
2522     art::ScopedThreadSuspension sts(self_, art::ThreadState::kNative);
2523     art::ScopedSuspendAll ssa("Final installation of redefined Classes!", /*long_suspend=*/true);
2524     for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2525       art::ScopedAssertNoThreadSuspension nts("Updating runtime objects for redefinition");
2526       ClassRedefinition& redef = data.GetRedefinition();
2527       if (data.GetSourceClassLoader() != nullptr) {
2528         ClassLoaderHelper::UpdateJavaDexFile(data.GetJavaDexFile(), data.GetNewDexFileCookie());
2529       }
2530       redef.UpdateClass(data);
2531     }
2532     RestoreObsoleteMethodMapsIfUnneeded(holder);
2533     // TODO We should check for if any of the redefined methods are intrinsic methods here and, if
2534     // any are, force a full-world deoptimization before finishing redefinition. If we don't do this
2535     // then methods that have been jitted prior to the current redefinition being applied might
2536     // continue to use the old versions of the intrinsics!
2537     // TODO Do the dex_file release at a more reasonable place. This works but it muddles who really
2538     // owns the DexFile and when ownership is transferred.
2539     ReleaseAllDexFiles();
2540   }
2541   return OK;
2542 }
2543 
UpdateMethods(art::ObjPtr<art::mirror::Class> mclass,const art::dex::ClassDef & class_def)2544 void Redefiner::ClassRedefinition::UpdateMethods(art::ObjPtr<art::mirror::Class> mclass,
2545                                                  const art::dex::ClassDef& class_def) {
2546   art::ClassLinker* linker = driver_->runtime_->GetClassLinker();
2547   art::PointerSize image_pointer_size = linker->GetImagePointerSize();
2548   const art::dex::TypeId& declaring_class_id = dex_file_->GetTypeId(class_def.class_idx_);
2549   const art::DexFile& old_dex_file = mclass->GetDexFile();
2550   // Update methods.
2551   for (art::ArtMethod& method : mclass->GetDeclaredMethods(image_pointer_size)) {
2552     // Reinitialize the method by calling `CopyFrom`. This ensures for example
2553     // the entrypoint and the hotness are reset.
2554     method.CopyFrom(&method, image_pointer_size);
2555     const art::dex::StringId* new_name_id = dex_file_->FindStringId(method.GetName());
2556     art::dex::TypeIndex method_return_idx =
2557         dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(method.GetReturnTypeDescriptorView()));
2558     const auto* old_type_list = method.GetParameterTypeList();
2559     std::vector<art::dex::TypeIndex> new_type_list;
2560     for (uint32_t i = 0; old_type_list != nullptr && i < old_type_list->Size(); i++) {
2561       new_type_list.push_back(
2562           dex_file_->GetIndexForTypeId(
2563               *dex_file_->FindTypeId(
2564                   old_dex_file.GetTypeDescriptorView(
2565                       old_dex_file.GetTypeId(
2566                           old_type_list->GetTypeItem(i).type_idx_)))));
2567     }
2568     const art::dex::ProtoId* proto_id = dex_file_->FindProtoId(method_return_idx, new_type_list);
2569     CHECK(proto_id != nullptr || old_type_list == nullptr);
2570     const art::dex::MethodId* method_id = dex_file_->FindMethodId(declaring_class_id,
2571                                                                   *new_name_id,
2572                                                                   *proto_id);
2573     CHECK(method_id != nullptr);
2574     uint32_t dex_method_idx = dex_file_->GetIndexForMethodId(*method_id);
2575     method.SetDexMethodIndex(dex_method_idx);
2576     driver_->runtime_->GetInstrumentation()->InitializeMethodsCode(&method, /*aot_code=*/ nullptr);
2577     if (method.HasCodeItem()) {
2578       method.SetCodeItem(
2579           dex_file_->GetCodeItem(dex_file_->FindCodeItemOffset(class_def, dex_method_idx)),
2580           dex_file_->IsCompactDexFile());
2581     }
2582     // Clear all the intrinsics related flags.
2583     method.SetNotIntrinsic();
2584   }
2585 }
2586 
UpdateFields(art::ObjPtr<art::mirror::Class> mclass)2587 void Redefiner::ClassRedefinition::UpdateFields(art::ObjPtr<art::mirror::Class> mclass) {
2588   // TODO The IFields & SFields pointers should be combined like the methods_ arrays were.
2589   for (auto fields_iter : {mclass->GetIFields(), mclass->GetSFields()}) {
2590     for (art::ArtField& field : fields_iter) {
2591       const art::dex::TypeId* new_declaring_id =
2592           dex_file_->FindTypeId(field.GetDeclaringClassDescriptorView());
2593       const art::dex::StringId* new_name_id = dex_file_->FindStringId(field.GetName());
2594       const art::dex::TypeId* new_type_id = dex_file_->FindTypeId(field.GetTypeDescriptorView());
2595       CHECK(new_name_id != nullptr && new_type_id != nullptr && new_declaring_id != nullptr);
2596       const art::dex::FieldId* new_field_id =
2597           dex_file_->FindFieldId(*new_declaring_id, *new_name_id, *new_type_id);
2598       CHECK(new_field_id != nullptr);
2599       uint32_t new_field_index = dex_file_->GetIndexForFieldId(*new_field_id);
2600       // We only need to update the index since the other data in the ArtField cannot be updated.
2601       field.SetDexFieldIndex(new_field_index);
2602     }
2603   }
2604 }
2605 
CollectNewFieldAndMethodMappings(const RedefinitionDataIter & data,std::map<art::ArtMethod *,art::ArtMethod * > * method_map,std::map<art::ArtField *,art::ArtField * > * field_map)2606 void Redefiner::ClassRedefinition::CollectNewFieldAndMethodMappings(
2607     const RedefinitionDataIter& data,
2608     std::map<art::ArtMethod*, art::ArtMethod*>* method_map,
2609     std::map<art::ArtField*, art::ArtField*>* field_map) {
2610   for (auto [new_cls, old_cls] :
2611        art::ZipLeft(data.GetNewClasses()->Iterate(), data.GetOldClasses()->Iterate())) {
2612     for (art::ArtField& f : old_cls->GetSFields()) {
2613       (*field_map)[&f] = new_cls->FindDeclaredStaticField(f.GetName(), f.GetTypeDescriptor());
2614     }
2615     for (art::ArtField& f : old_cls->GetIFields()) {
2616       (*field_map)[&f] = new_cls->FindDeclaredInstanceField(f.GetName(), f.GetTypeDescriptor());
2617     }
2618     auto new_methods = new_cls->GetMethods(art::kRuntimePointerSize);
2619     for (art::ArtMethod& m : old_cls->GetMethods(art::kRuntimePointerSize)) {
2620       // No support for finding methods in this way since it's generally not needed. Just do it the
2621       // easy way.
2622       auto nm_iter = std::find_if(
2623           new_methods.begin(),
2624           new_methods.end(),
2625           [&](art::ArtMethod& cand) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2626             return cand.GetNameView() == m.GetNameView() && cand.GetSignature() == m.GetSignature();
2627           });
2628       CHECK(nm_iter != new_methods.end())
2629           << "Could not find redefined version of " << m.PrettyMethod();
2630       (*method_map)[&m] = &(*nm_iter);
2631     }
2632   }
2633 }
2634 
CopyField(art::ObjPtr<art::mirror::Object> target,art::ArtField * new_field,art::ObjPtr<art::mirror::Object> source,art::ArtField & old_field)2635 static void CopyField(art::ObjPtr<art::mirror::Object> target,
2636                       art::ArtField* new_field,
2637                       art::ObjPtr<art::mirror::Object> source,
2638                       art::ArtField& old_field) REQUIRES(art::Locks::mutator_lock_) {
2639   art::Primitive::Type ftype = old_field.GetTypeAsPrimitiveType();
2640   CHECK_EQ(ftype, new_field->GetTypeAsPrimitiveType())
2641       << old_field.PrettyField() << " vs " << new_field->PrettyField();
2642   if (ftype == art::Primitive::kPrimNot) {
2643     new_field->SetObject<false>(target, old_field.GetObject(source));
2644   } else {
2645     switch (ftype) {
2646 #define UPDATE_FIELD(TYPE)                                            \
2647   case art::Primitive::kPrim##TYPE:                                   \
2648     new_field->Set##TYPE<false>(target, old_field.Get##TYPE(source)); \
2649     break
2650       UPDATE_FIELD(Int);
2651       UPDATE_FIELD(Float);
2652       UPDATE_FIELD(Long);
2653       UPDATE_FIELD(Double);
2654       UPDATE_FIELD(Short);
2655       UPDATE_FIELD(Char);
2656       UPDATE_FIELD(Byte);
2657       UPDATE_FIELD(Boolean);
2658       case art::Primitive::kPrimNot:
2659       case art::Primitive::kPrimVoid:
2660         LOG(FATAL) << "Unexpected field with type " << ftype << " found!";
2661         UNREACHABLE();
2662 #undef UPDATE_FIELD
2663     }
2664   }
2665 }
2666 
CopyFields(bool is_static,art::ObjPtr<art::mirror::Object> target,art::ObjPtr<art::mirror::Class> target_class,art::ObjPtr<art::mirror::Object> source,art::ObjPtr<art::mirror::Class> source_class)2667 static void CopyFields(bool is_static,
2668                        art::ObjPtr<art::mirror::Object> target,
2669                        art::ObjPtr<art::mirror::Class> target_class,
2670                        art::ObjPtr<art::mirror::Object> source,
2671                        art::ObjPtr<art::mirror::Class> source_class)
2672     REQUIRES(art::Locks::mutator_lock_) {
2673   DCHECK(!source_class->IsObjectClass() && !target_class->IsObjectClass())
2674       << "Should not be overriding object class fields. Target: " << target_class->PrettyClass()
2675       << " Source: " << source_class->PrettyClass();
2676   for (art::ArtField& f : (is_static ? source_class->GetSFields() : source_class->GetIFields())) {
2677     art::ArtField* new_field =
2678         (is_static ? target_class->FindDeclaredStaticField(f.GetName(), f.GetTypeDescriptor())
2679                    : target_class->FindDeclaredInstanceField(f.GetName(), f.GetTypeDescriptor()));
2680     CHECK(new_field != nullptr) << "could not find new version of " << f.PrettyField();
2681     CopyField(target, new_field, source, f);
2682   }
2683   if (!is_static && !target_class->GetSuperClass()->IsObjectClass()) {
2684     CopyFields(
2685         is_static, target, target_class->GetSuperClass(), source, source_class->GetSuperClass());
2686   }
2687 }
2688 
ClearField(art::ObjPtr<art::mirror::Object> target,art::ArtField & field)2689 static void ClearField(art::ObjPtr<art::mirror::Object> target, art::ArtField& field)
2690     REQUIRES(art::Locks::mutator_lock_) {
2691   art::Primitive::Type ftype = field.GetTypeAsPrimitiveType();
2692   if (ftype == art::Primitive::kPrimNot) {
2693     field.SetObject<false>(target, nullptr);
2694   } else {
2695     switch (ftype) {
2696 #define UPDATE_FIELD(TYPE)             \
2697   case art::Primitive::kPrim##TYPE:    \
2698     field.Set##TYPE<false>(target, 0); \
2699     break
2700       UPDATE_FIELD(Int);
2701       UPDATE_FIELD(Float);
2702       UPDATE_FIELD(Long);
2703       UPDATE_FIELD(Double);
2704       UPDATE_FIELD(Short);
2705       UPDATE_FIELD(Char);
2706       UPDATE_FIELD(Byte);
2707       UPDATE_FIELD(Boolean);
2708       case art::Primitive::kPrimNot:
2709       case art::Primitive::kPrimVoid:
2710         LOG(FATAL) << "Unexpected field with type " << ftype << " found!";
2711         UNREACHABLE();
2712 #undef UPDATE_FIELD
2713     }
2714   }
2715 }
2716 
ClearFields(bool is_static,art::ObjPtr<art::mirror::Object> target,art::ObjPtr<art::mirror::Class> target_class)2717 static void ClearFields(bool is_static,
2718                         art::ObjPtr<art::mirror::Object> target,
2719                         art::ObjPtr<art::mirror::Class> target_class)
2720     REQUIRES(art::Locks::mutator_lock_) {
2721   DCHECK(!target_class->IsObjectClass());
2722   for (art::ArtField& f : (is_static ? target_class->GetSFields() : target_class->GetIFields())) {
2723     ClearField(target, f);
2724   }
2725   if (!is_static && !target_class->GetSuperClass()->IsObjectClass()) {
2726     ClearFields(is_static, target, target_class->GetSuperClass());
2727   }
2728 }
2729 
CopyAndClearFields(bool is_static,art::ObjPtr<art::mirror::Object> target,art::ObjPtr<art::mirror::Class> target_class,art::ObjPtr<art::mirror::Object> source,art::ObjPtr<art::mirror::Class> source_class)2730 static void CopyAndClearFields(bool is_static,
2731                                art::ObjPtr<art::mirror::Object> target,
2732                                art::ObjPtr<art::mirror::Class> target_class,
2733                                art::ObjPtr<art::mirror::Object> source,
2734                                art::ObjPtr<art::mirror::Class> source_class)
2735     REQUIRES(art::Locks::mutator_lock_) {
2736   // Copy all non-j.l.Object fields
2737   CopyFields(is_static, target, target_class, source, source_class);
2738   // Copy the lock-word.
2739   target->SetLockWord(source->GetLockWord(false), false);
2740   // Clear (reset) the old one.
2741   source->SetLockWord(art::LockWord::Default(), false);
2742   art::WriteBarrier::ForEveryFieldWrite(target);
2743 
2744   // Clear the fields from the old class. We don't need it anymore.
2745   ClearFields(is_static, source, source_class);
2746   art::WriteBarrier::ForEveryFieldWrite(source);
2747 }
2748 
UpdateClassStructurally(const RedefinitionDataIter & holder)2749 void Redefiner::ClassRedefinition::UpdateClassStructurally(const RedefinitionDataIter& holder) {
2750   DCHECK(holder.IsActuallyStructural());
2751   DCHECK(holder.IsInitialStructural());
2752   // LETS GO. We've got all new class structures so no need to do all the updating of the stacks.
2753   // Instead we need to update everything else.
2754   // Just replace the class and be done with it.
2755   art::Locks::mutator_lock_->AssertExclusiveHeld(driver_->self_);
2756   art::ClassLinker* cl = driver_->runtime_->GetClassLinker();
2757   art::ScopedAssertNoThreadSuspension sants(__FUNCTION__);
2758   art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> new_classes(holder.GetNewClasses());
2759   art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> old_classes(holder.GetOldClasses());
2760   // Collect mappings from old to new fields/methods
2761   std::map<art::ArtMethod*, art::ArtMethod*> method_map;
2762   std::map<art::ArtField*, art::ArtField*> field_map;
2763   CollectNewFieldAndMethodMappings(holder, &method_map, &field_map);
2764   art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> new_instances(
2765       holder.GetNewInstanceObjects());
2766   art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> old_instances(
2767       holder.GetOldInstanceObjects());
2768   // Once we do the ReplaceReferences old_classes will have the new_classes in it. We want to keep
2769   // ahold of the old classes so copy them now.
2770   std::vector<art::ObjPtr<art::mirror::Class>> old_classes_vec(old_classes->Iterate().begin(),
2771                                                                old_classes->Iterate().end());
2772   // Copy over the static fields of the class and all the instance fields.
2773   for (auto [new_class, old_class] : art::ZipLeft(new_classes->Iterate(), old_classes->Iterate())) {
2774     CHECK(!new_class.IsNull());
2775     CHECK(!old_class.IsNull());
2776     CHECK(!old_class->IsErroneous());
2777     if (old_class->GetStatus() > new_class->GetStatus()) {
2778       // Some verification/initialization step happened during interval between
2779       // creating the new class and now. Just copy the new status.
2780       new_class->SetStatusLocked(old_class->GetStatus());
2781     }
2782     CopyAndClearFields(true, new_class, new_class, old_class, old_class);
2783   }
2784 
2785   // Copy and clear the fields of the old-instances.
2786   for (auto [new_instance, old_instance] :
2787        art::ZipLeft(new_instances->Iterate(), old_instances->Iterate())) {
2788     CopyAndClearFields(/*is_static=*/false,
2789                        new_instance,
2790                        new_instance->GetClass(),
2791                        old_instance,
2792                        old_instance->GetClass());
2793   }
2794   // Mark old class and methods obsolete. Copy over any native implementation as well.
2795   for (auto [old_class, new_class] : art::ZipLeft(old_classes->Iterate(), new_classes->Iterate())) {
2796     old_class->SetObsoleteObject();
2797     // Mark methods obsolete and copy native implementation. We need to wait
2798     // until later to actually clear the jit data. We copy the native
2799     // implementation here since we don't want to race with any threads doing
2800     // RegisterNatives.
2801     for (art::ArtMethod& m : old_class->GetMethods(art::kRuntimePointerSize)) {
2802       if (m.IsNative()) {
2803         art::ArtMethod* new_method =
2804             new_class->FindClassMethod(m.GetNameView(), m.GetSignature(), art::kRuntimePointerSize);
2805         DCHECK(new_class->GetMethodsSlice(art::kRuntimePointerSize).Contains(new_method))
2806             << "Could not find method " << m.PrettyMethod() << " declared in new class!";
2807         DCHECK(new_method->IsNative());
2808         new_method->SetEntryPointFromJni(m.GetEntryPointFromJni());
2809       }
2810       m.SetIsObsolete();
2811       cl->SetEntryPointsForObsoleteMethod(&m);
2812       if (m.IsInvokable()) {
2813         m.SetDontCompile();
2814       }
2815     }
2816   }
2817   // Update live pointers in ART code.
2818   auto could_change_resolution_of = [&](auto* field_or_method,
2819                                         const auto& info) REQUIRES(art::Locks::mutator_lock_) {
2820     constexpr bool is_method = std::is_same_v<art::ArtMethod*, decltype(field_or_method)>;
2821     static_assert(is_method || std::is_same_v<art::ArtField*, decltype(field_or_method)>,
2822                   "Input is not field or method!");
2823     // Only dex-cache is used for resolution
2824     if (LIKELY(info.GetType() != art::ReflectionSourceType::kSourceDexCacheResolvedField &&
2825                info.GetType() != art::ReflectionSourceType::kSourceDexCacheResolvedMethod)) {
2826       return false;
2827     }
2828     if constexpr (is_method) {
2829       // Only direct methods are used without further indirection through a vtable/IFTable.
2830       // Constructors cannot be shadowed.
2831       if (LIKELY(!field_or_method->IsDirect() || field_or_method->IsConstructor())) {
2832         return false;
2833       }
2834     } else {
2835       // Only non-private fields can be shadowed in a manner that's visible.
2836       if (LIKELY(field_or_method->IsPrivate())) {
2837         return false;
2838       }
2839     }
2840     // We can only shadow things from our superclasses
2841     auto orig_classes_iter = old_classes->Iterate();
2842     auto replacement_classes_iter = new_classes->Iterate();
2843     art::ObjPtr<art::mirror::Class> f_or_m_class = field_or_method->GetDeclaringClass();
2844     if (LIKELY(!f_or_m_class->IsAssignableFrom(holder.GetMirrorClass()) &&
2845                std::find(orig_classes_iter.begin(), orig_classes_iter.end(), f_or_m_class) ==
2846                    orig_classes_iter.end())) {
2847       return false;
2848     }
2849     if constexpr (is_method) {
2850       return std::any_of(
2851           replacement_classes_iter.begin(),
2852           replacement_classes_iter.end(),
2853           [&](art::ObjPtr<art::mirror::Class> cand) REQUIRES(art::Locks::mutator_lock_) {
2854             auto direct_methods = cand->GetDirectMethods(art::kRuntimePointerSize);
2855             return std::find_if(direct_methods.begin(),
2856                                 direct_methods.end(),
2857                                 [&](art::ArtMethod& m) REQUIRES(art::Locks::mutator_lock_) {
2858                                   return UNLIKELY(m.HasSameNameAndSignature(field_or_method));
2859                                 }) != direct_methods.end();
2860           });
2861     } else {
2862       auto pred = [&](art::ArtField& f) REQUIRES(art::Locks::mutator_lock_) {
2863         return std::string_view(f.GetName()) == std::string_view(field_or_method->GetName()) &&
2864                std::string_view(f.GetTypeDescriptor()) ==
2865                    std::string_view(field_or_method->GetTypeDescriptor());
2866       };
2867       if (field_or_method->IsStatic()) {
2868         return std::any_of(
2869             replacement_classes_iter.begin(),
2870             replacement_classes_iter.end(),
2871             [&](art::ObjPtr<art::mirror::Class> cand) REQUIRES(art::Locks::mutator_lock_) {
2872               auto sfields = cand->GetSFields();
2873               return std::find_if(sfields.begin(), sfields.end(), pred) != sfields.end();
2874             });
2875       } else {
2876         return std::any_of(
2877             replacement_classes_iter.begin(),
2878             replacement_classes_iter.end(),
2879             [&](art::ObjPtr<art::mirror::Class> cand) REQUIRES(art::Locks::mutator_lock_) {
2880               auto ifields = cand->GetIFields();
2881               return std::find_if(ifields.begin(), ifields.end(), pred) != ifields.end();
2882             });
2883       }
2884     }
2885   };
2886   // TODO Performing 2 stack-walks back to back isn't the greatest. We might want to try to combine
2887   // it with the one ReplaceReferences does. Doing so would be rather complicated though.
2888   driver_->runtime_->VisitReflectiveTargets(
2889       [&](art::ArtField* f, const auto& info) REQUIRES(art::Locks::mutator_lock_) {
2890         DCHECK(f != nullptr) << info;
2891         auto it = field_map.find(f);
2892         if (UNLIKELY(could_change_resolution_of(f, info))) {
2893           // Dex-cache Resolution might change. Just clear the resolved value.
2894           VLOG(plugin) << "Clearing resolution " << info << " for (field) " << f->PrettyField();
2895           return static_cast<art::ArtField*>(nullptr);
2896         } else if (it != field_map.end()) {
2897           VLOG(plugin) << "Updating " << info << " object for (field) "
2898                        << it->second->PrettyField();
2899           return it->second;
2900         }
2901         return f;
2902       },
2903       [&](art::ArtMethod* m, const auto& info) REQUIRES(art::Locks::mutator_lock_) {
2904         DCHECK(m != nullptr) << info;
2905         auto it = method_map.find(m);
2906         if (UNLIKELY(could_change_resolution_of(m, info))) {
2907           // Dex-cache Resolution might change. Just clear the resolved value.
2908           VLOG(plugin) << "Clearing resolution " << info << " for (method) " << m->PrettyMethod();
2909           return static_cast<art::ArtMethod*>(nullptr);
2910         } else if (it != method_map.end()) {
2911           VLOG(plugin) << "Updating " << info << " object for (method) "
2912                       << it->second->PrettyMethod();
2913           return it->second;
2914         }
2915         return m;
2916       });
2917 
2918   // Force every frame of every thread to deoptimize (any frame might have eg offsets compiled in).
2919   driver_->runtime_->GetInstrumentation()->DeoptimizeAllThreadFrames();
2920 
2921   std::unordered_map<art::ObjPtr<art::mirror::Object>,
2922                      art::ObjPtr<art::mirror::Object>,
2923                      art::HashObjPtr> map;
2924   for (auto [new_class, old_class] : art::ZipLeft(new_classes->Iterate(), old_classes->Iterate())) {
2925     map.emplace(old_class, new_class);
2926   }
2927   for (auto [new_instance, old_instance] :
2928        art::ZipLeft(new_instances->Iterate(), old_instances->Iterate())) {
2929     map.emplace(old_instance, new_instance);
2930     // Bare-bones check that the mapping is correct.
2931     CHECK(new_instance->GetClass() == map[old_instance->GetClass()]->AsClass())
2932         << new_instance->GetClass()->PrettyClass() << " vs "
2933         << map[old_instance->GetClass()]->AsClass()->PrettyClass();
2934   }
2935 
2936   // Actually perform the general replacement. This doesn't affect ArtMethod/ArtFields. It does
2937   // affect the declaring_class field of all the obsolete objects, which is unfortunate and needs to
2938   // be undone. This replaces the mirror::Class in 'holder' as well. It's magic!
2939   HeapExtensions::ReplaceReferences(driver_->self_, map);
2940 
2941   // Undo the replacement of old_class with new_class for the methods / fields on the old_class.
2942   // It is hard to ensure that we don't replace the declaring class of the old class field / methods
2943   // isn't impacted by ReplaceReferences. It is just simpler to undo the replacement here.
2944   std::for_each(
2945       old_classes_vec.cbegin(),
2946       old_classes_vec.cend(),
2947       [](art::ObjPtr<art::mirror::Class> orig) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2948         orig->VisitMethods(
2949             [&](art::ArtMethod* method) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2950               if (method->IsCopied()) {
2951                 // Copied methods have interfaces as their declaring class.
2952                 return;
2953               }
2954               method->SetDeclaringClass(orig);
2955             },
2956             art::kRuntimePointerSize);
2957         orig->VisitFields([&](art::ArtField* field) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2958           field->SetDeclaringClass(orig);
2959         });
2960       });
2961 
2962   // Save the old class so that the JIT gc doesn't get confused by it being collected before the
2963   // jit code. This is also needed to keep the dex-caches of any obsolete methods live.
2964   for (auto [new_class, old_class] :
2965        art::ZipLeft(new_classes->Iterate(), art::MakeIterationRange(old_classes_vec))) {
2966     new_class->GetExtData()->SetObsoleteClass(old_class);
2967   }
2968 
2969   art::jit::Jit* jit = driver_->runtime_->GetJit();
2970   if (jit != nullptr) {
2971     // Clear jit.
2972     // TODO We might want to have some way to tell the JIT not to wait the kJitSamplesBatchSize
2973     // invokes to start compiling things again.
2974     jit->GetCodeCache()->InvalidateAllCompiledCode();
2975   }
2976 
2977   // Clear thread caches
2978   {
2979     // TODO We might be able to avoid doing this but given the rather unstructured nature of the
2980     // interpreter cache it's probably not worth the effort.
2981     art::MutexLock mu(driver_->self_, *art::Locks::thread_list_lock_);
2982     driver_->runtime_->GetThreadList()->ForEach(
2983         [](art::Thread* t) { t->GetInterpreterCache()->Clear(t); });
2984   }
2985 
2986   if (art::kIsDebugBuild) {
2987     // Just make sure we didn't screw up any of the now obsolete methods or fields. We need their
2988     // declaring-class to still be the obolete class
2989     std::for_each(
2990         old_classes_vec.cbegin(),
2991         old_classes_vec.cend(),
2992         [](art::ObjPtr<art::mirror::Class> orig) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2993           orig->VisitMethods(
2994               [&](art::ArtMethod* method) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2995                 if (method->IsCopied()) {
2996                   // Copied methods have interfaces as their declaring class.
2997                   return;
2998                 }
2999                 DCHECK_EQ(method->GetDeclaringClass(), orig)
3000                     << method->GetDeclaringClass()->PrettyClass() << " vs " << orig->PrettyClass();
3001               },
3002               art::kRuntimePointerSize);
3003           orig->VisitFields([&](art::ArtField* field) REQUIRES_SHARED(art::Locks::mutator_lock_) {
3004             DCHECK_EQ(field->GetDeclaringClass(), orig)
3005                 << field->GetDeclaringClass()->PrettyClass() << " vs " << orig->PrettyClass();
3006           });
3007         });
3008   }
3009 }
3010 
3011 // Redefines the class in place
UpdateClassInPlace(const RedefinitionDataIter & holder)3012 void Redefiner::ClassRedefinition::UpdateClassInPlace(const RedefinitionDataIter& holder) {
3013   art::ObjPtr<art::mirror::Class> mclass(holder.GetMirrorClass());
3014   // TODO Rewrite so we don't do a stack walk for each and every class.
3015   FindAndAllocateObsoleteMethods(mclass);
3016   art::ObjPtr<art::mirror::DexCache> new_dex_cache(holder.GetNewDexCache());
3017   art::ObjPtr<art::mirror::Object> original_dex_file(holder.GetOriginalDexFile());
3018   DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
3019   const art::dex::ClassDef& class_def = dex_file_->GetClassDef(0);
3020   UpdateMethods(mclass, class_def);
3021   UpdateFields(mclass);
3022 
3023   art::ObjPtr<art::mirror::ClassExt> ext(mclass->GetExtData());
3024   CHECK(!ext.IsNull());
3025   ext->SetOriginalDexFile(original_dex_file);
3026 
3027   // If this is the first time the class is being redefined, store
3028   // the native DexFile pointer and initial ClassDef index in ClassExt.
3029   // This preserves the pointer for hiddenapi access checks which need
3030   // to read access flags from the initial DexFile.
3031   if (ext->GetPreRedefineDexFile() == nullptr) {
3032     ext->SetPreRedefineDexFile(&mclass->GetDexFile());
3033     ext->SetPreRedefineClassDefIndex(mclass->GetDexClassDefIndex());
3034   }
3035 
3036   // Update the class fields.
3037   // Need to update class last since the ArtMethod gets its DexFile from the class (which is needed
3038   // to call GetReturnTypeDescriptor and GetParameterTypeList above).
3039   mclass->SetDexCache(new_dex_cache.Ptr());
3040   mclass->SetDexClassDefIndex(dex_file_->GetIndexForClassDef(class_def));
3041   mclass->SetDexTypeIndex(dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(class_sig_.c_str())));
3042 
3043   // Notify the jit that all the methods in this class were redefined. Need to do this last since
3044   // the jit relies on the dex_file_ being correct (for native methods at least) to find the method
3045   // meta-data.
3046   art::jit::Jit* jit = driver_->runtime_->GetJit();
3047   if (jit != nullptr) {
3048     art::PointerSize image_pointer_size =
3049         driver_->runtime_->GetClassLinker()->GetImagePointerSize();
3050     auto code_cache = jit->GetCodeCache();
3051     // Non-invokable methods don't have any JIT data associated with them so we don't need to tell
3052     // the jit about them.
3053     for (art::ArtMethod& method : mclass->GetDeclaredMethods(image_pointer_size)) {
3054       if (method.IsInvokable()) {
3055         code_cache->NotifyMethodRedefined(&method);
3056       }
3057     }
3058   }
3059 }
3060 
3061 // Performs final updates to class for redefinition.
UpdateClass(const RedefinitionDataIter & holder)3062 void Redefiner::ClassRedefinition::UpdateClass(const RedefinitionDataIter& holder) {
3063   CHECK(holder.IsInitialized());
3064   if (holder.IsInitialStructural()) {
3065     UpdateClassStructurally(holder);
3066   } else if (!holder.IsActuallyStructural()) {
3067     UpdateClassInPlace(holder);
3068   }
3069 }
3070 
3071 // Restores the old obsolete methods maps if it turns out they weren't needed (ie there were no new
3072 // obsolete methods).
RestoreObsoleteMethodMapsIfUnneeded(const RedefinitionDataIter * cur_data)3073 void Redefiner::ClassRedefinition::RestoreObsoleteMethodMapsIfUnneeded(
3074     const RedefinitionDataIter* cur_data) {
3075   if (cur_data->IsActuallyStructural()) {
3076     // We didn't touch these in this case.
3077     return;
3078   }
3079   art::ObjPtr<art::mirror::Class> klass = GetMirrorClass();
3080   art::ObjPtr<art::mirror::ClassExt> ext = klass->GetExtData();
3081   art::ObjPtr<art::mirror::PointerArray> methods = ext->GetObsoleteMethods();
3082   art::ObjPtr<art::mirror::PointerArray> old_methods = cur_data->GetOldObsoleteMethods();
3083   int32_t old_length = old_methods == nullptr ? 0 : old_methods->GetLength();
3084   int32_t expected_length =
3085       old_length + klass->NumDirectMethods() + klass->NumDeclaredVirtualMethods();
3086   // Check to make sure we are only undoing this one.
3087   if (methods.IsNull()) {
3088     // No new obsolete methods! We can get rid of the maps.
3089     ext->SetObsoleteArrays(cur_data->GetOldObsoleteMethods(), cur_data->GetOldDexCaches());
3090   } else if (expected_length == methods->GetLength()) {
3091     for (int32_t i = 0; i < expected_length; i++) {
3092       art::ArtMethod* expected = nullptr;
3093       if (i < old_length) {
3094         expected = old_methods->GetElementPtrSize<art::ArtMethod*>(i, art::kRuntimePointerSize);
3095       }
3096       if (methods->GetElementPtrSize<art::ArtMethod*>(i, art::kRuntimePointerSize) != expected) {
3097         // We actually have some new obsolete methods. Just abort since we cannot safely shrink the
3098         // obsolete methods array.
3099         return;
3100       }
3101     }
3102     // No new obsolete methods! We can get rid of the maps.
3103     ext->SetObsoleteArrays(cur_data->GetOldObsoleteMethods(), cur_data->GetOldDexCaches());
3104   }
3105 }
3106 
3107 // This function does all (java) allocations we need to do for the Class being redefined.
3108 // TODO Change this name maybe?
EnsureClassAllocationsFinished(RedefinitionDataIter * cur_data)3109 bool Redefiner::ClassRedefinition::EnsureClassAllocationsFinished(
3110     /*out*/RedefinitionDataIter* cur_data) {
3111   art::StackHandleScope<2> hs(driver_->self_);
3112   art::Handle<art::mirror::Class> klass(hs.NewHandle(
3113       driver_->self_->DecodeJObject(klass_)->AsClass()));
3114   if (klass == nullptr) {
3115     RecordFailure(ERR(INVALID_CLASS), "Unable to decode class argument!");
3116     return false;
3117   }
3118   // Allocate the classExt
3119   art::Handle<art::mirror::ClassExt> ext =
3120       hs.NewHandle(art::mirror::Class::EnsureExtDataPresent(klass, driver_->self_));
3121   if (ext == nullptr) {
3122     // No memory. Clear exception (it's not useful) and return error.
3123     driver_->self_->AssertPendingOOMException();
3124     driver_->self_->ClearException();
3125     RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate ClassExt");
3126     return false;
3127   }
3128   if (!cur_data->IsActuallyStructural()) {
3129     CHECK(!IsStructuralRedefinition());
3130     // First save the old values of the 2 arrays that make up the obsolete methods maps. Then
3131     // allocate the 2 arrays that make up the obsolete methods map. Since the contents of the arrays
3132     // are only modified when all threads (other than the modifying one) are suspended we don't need
3133     // to worry about missing the unsynchronized writes to the array. We do synchronize when setting
3134     // it however, since that can happen at any time.
3135     cur_data->SetOldObsoleteMethods(ext->GetObsoleteMethods());
3136     cur_data->SetOldDexCaches(ext->GetObsoleteDexCaches());
3137     // FIXME: The `ClassExt::ExtendObsoleteArrays()` is non-atomic and does not ensure proper
3138     // memory visibility, so it can race with `ArtMethod::GetObsoleteDexCache()`.
3139     // We should allocate the new arrays here but record it in the redefinition data and set the
3140     // new arrays in `ClassExt` later with all other threads suspended.
3141     if (!art::mirror::ClassExt::ExtendObsoleteArrays(
3142             ext, driver_->self_, klass->GetDeclaredMethodsSlice(art::kRuntimePointerSize).size())) {
3143       // OOM. Clear exception and return error.
3144       driver_->self_->AssertPendingOOMException();
3145       driver_->self_->ClearException();
3146       RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate/extend obsolete methods map");
3147       return false;
3148     }
3149   }
3150   return true;
3151 }
3152 
3153 }  // namespace openjdkjvmti
3154