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