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