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