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