blob: 53bf4df3d176ad3c8444efd396ce76993d609e09 [file] [log] [blame]
Alex Lighta01de592016-11-15 10:43:06 -08001/* 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
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000034#include <algorithm>
35#include <atomic>
Alex Lighte7a33542019-04-10 14:22:49 -070036#include <iterator>
Alex Lighta01de592016-11-15 10:43:06 -080037#include <limits>
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000038#include <sstream>
Vladimir Markoeb37ba52019-02-05 14:10:38 +000039#include <string_view>
Alex Lighte7a33542019-04-10 14:22:49 -070040#include <unordered_map>
Alex Lighta01de592016-11-15 10:43:06 -080041
Andreas Gampe57943812017-12-06 21:39:13 -080042#include <android-base/logging.h>
43#include <android-base/stringprintf.h>
Andreas Gampe46ee31b2016-12-14 10:11:49 -080044
Alex Light986914b2019-11-19 01:12:25 +000045#include "alloc_manager.h"
46#include "android-base/macros.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000047#include "android-base/thread_annotations.h"
Andreas Gampea1d2f952017-04-20 22:53:58 -070048#include "art_field-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000049#include "art_field.h"
Alex Lighta01de592016-11-15 10:43:06 -080050#include "art_jvmti.h"
Steven Morelande431e272017-07-18 16:53:49 -070051#include "art_method-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000052#include "art_method.h"
Vladimir Markoe1993c72017-06-14 17:01:38 +010053#include "base/array_ref.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000054#include "base/casts.h"
55#include "base/enums.h"
56#include "base/globals.h"
Alex Light270db1c2019-12-03 12:20:01 +000057#include "base/iteration_range.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000058#include "base/length_prefixed_array.h"
Alex Light270db1c2019-12-03 12:20:01 +000059#include "base/locks.h"
60#include "base/stl_util.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000061#include "base/utils.h"
Andreas Gampec6ea7d02017-02-01 16:46:28 -080062#include "class_linker-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000063#include "class_linker.h"
Vladimir Markob4eb1b12018-05-24 11:09:38 +010064#include "class_root.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000065#include "class_status.h"
Alex Light5643caf2017-02-08 11:39:07 -080066#include "debugger.h"
David Sehr013fd802018-01-11 22:55:24 -080067#include "dex/art_dex_file_loader.h"
Mathieu Chartier4ac9ade2018-07-24 10:27:21 -070068#include "dex/class_accessor-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000069#include "dex/class_accessor.h"
David Sehr9e734c72018-01-04 17:56:19 -080070#include "dex/dex_file.h"
71#include "dex/dex_file_loader.h"
72#include "dex/dex_file_types.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000073#include "dex/primitive.h"
Andreas Gampead1aa632019-01-02 10:30:54 -080074#include "dex/signature-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000075#include "dex/signature.h"
Alex Lighta01de592016-11-15 10:43:06 -080076#include "events-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000077#include "events.h"
Alex Lighta01de592016-11-15 10:43:06 -080078#include "gc/allocation_listener.h"
Alex Light6abd5392017-01-05 17:53:00 -080079#include "gc/heap.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000080#include "gc/heap-inl.h"
81#include "gc/heap-visit-objects-inl.h"
82#include "handle.h"
83#include "handle_scope.h"
Alex Lighta01de592016-11-15 10:43:06 -080084#include "instrumentation.h"
Alex Light07f06212017-06-01 14:01:43 -070085#include "intern_table.h"
Alex Light5643caf2017-02-08 11:39:07 -080086#include "jdwp/jdwp.h"
87#include "jdwp/jdwp_constants.h"
88#include "jdwp/jdwp_event.h"
89#include "jdwp/object_registry.h"
Alex Lightdba61482016-12-21 08:20:29 -080090#include "jit/jit.h"
91#include "jit/jit_code_cache.h"
Vladimir Markoa3ad0cd2018-05-04 10:06:38 +010092#include "jni/jni_env_ext-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000093#include "jni/jni_id_manager.h"
94#include "jvmti.h"
Alex Lighta01de592016-11-15 10:43:06 -080095#include "jvmti_allocator.h"
Vladimir Marko5924a4a2018-05-29 17:40:41 +010096#include "linear_alloc.h"
Andreas Gampe8e0f0432018-10-24 13:38:03 -070097#include "mirror/array-alloc-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000098#include "mirror/array.h"
Andreas Gampe70f5fd02018-10-24 19:58:37 -070099#include "mirror/class-alloc-inl.h"
Alex Light6161f132017-01-25 10:30:20 -0800100#include "mirror/class-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000101#include "mirror/class-refvisitor-inl.h"
102#include "mirror/class.h"
Vladimir Markobb206de2019-03-28 10:30:32 +0000103#include "mirror/class_ext-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000104#include "mirror/dex_cache-inl.h"
105#include "mirror/dex_cache.h"
106#include "mirror/executable-inl.h"
107#include "mirror/field-inl.h"
108#include "mirror/method.h"
109#include "mirror/method_handle_impl-inl.h"
Alex Lighta01de592016-11-15 10:43:06 -0800110#include "mirror/object.h"
Andreas Gampe52ecb652018-10-24 15:18:21 -0700111#include "mirror/object_array-alloc-inl.h"
112#include "mirror/object_array-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000113#include "mirror/object_array.h"
114#include "mirror/string.h"
Alex Lightc18eba32019-09-24 14:36:27 -0700115#include "mirror/var_handle.h"
Andreas Gampe373a9b52017-10-18 09:01:57 -0700116#include "nativehelper/scoped_local_ref.h"
Alex Lighte77b48b2017-02-22 11:08:06 -0800117#include "non_debuggable_classes.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000118#include "obj_ptr.h"
Alex Lighta01de592016-11-15 10:43:06 -0800119#include "object_lock.h"
Alex Light24627892019-11-06 10:28:21 -0800120#include "reflective_value_visitor.h"
Alex Lighta01de592016-11-15 10:43:06 -0800121#include "runtime.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000122#include "runtime_globals.h"
Alex Light986914b2019-11-19 01:12:25 +0000123#include "scoped_thread_state_change.h"
Vladimir Marko5924a4a2018-05-29 17:40:41 +0100124#include "stack.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000125#include "thread.h"
Vladimir Marko5924a4a2018-05-29 17:40:41 +0100126#include "thread_list.h"
Alex Lighta26e3492017-06-27 17:55:37 -0700127#include "ti_breakpoint.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000128#include "ti_class_definition.h"
Alex Lighteb98b082017-01-25 13:02:32 -0800129#include "ti_class_loader.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000130#include "ti_heap.h"
131#include "ti_logging.h"
132#include "ti_thread.h"
Alex Light0e692732017-01-10 15:00:05 -0800133#include "transform.h"
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700134#include "verifier/class_verifier.h"
Andreas Gampe6d7abbd2017-04-24 13:19:09 -0700135#include "verifier/verifier_enums.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000136#include "well_known_classes.h"
137#include "write_barrier.h"
Alex Lighta01de592016-11-15 10:43:06 -0800138
139namespace openjdkjvmti {
140
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000141// Debug check to force us to directly check we saw all methods and fields exactly once directly.
142// Normally we don't need to do this since if any are missing the count will be different
143constexpr bool kCheckAllMethodsSeenOnce = art::kIsDebugBuild;
144
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800145using android::base::StringPrintf;
146
Alex Lighteee0bd42017-02-14 15:31:45 +0000147// A helper that fills in a classes obsolete_methods_ and obsolete_dex_caches_ classExt fields as
148// they are created. This ensures that we can always call any method of an obsolete ArtMethod object
149// almost as soon as they are created since the GetObsoleteDexCache method will succeed.
150class ObsoleteMap {
151 public:
Alex Lighte7a33542019-04-10 14:22:49 -0700152 art::ArtMethod* FindObsoleteVersion(art::ArtMethod* original) const
Alex Lighteee0bd42017-02-14 15:31:45 +0000153 REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) {
154 auto method_pair = id_map_.find(original);
155 if (method_pair != id_map_.end()) {
156 art::ArtMethod* res = obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(
157 method_pair->second, art::kRuntimePointerSize);
158 DCHECK(res != nullptr);
Alex Lighteee0bd42017-02-14 15:31:45 +0000159 return res;
160 } else {
161 return nullptr;
162 }
163 }
164
165 void RecordObsolete(art::ArtMethod* original, art::ArtMethod* obsolete)
166 REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) {
167 DCHECK(original != nullptr);
168 DCHECK(obsolete != nullptr);
169 int32_t slot = next_free_slot_++;
170 DCHECK_LT(slot, obsolete_methods_->GetLength());
171 DCHECK(nullptr ==
172 obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(slot, art::kRuntimePointerSize));
173 DCHECK(nullptr == obsolete_dex_caches_->Get(slot));
174 obsolete_methods_->SetElementPtrSize(slot, obsolete, art::kRuntimePointerSize);
175 obsolete_dex_caches_->Set(slot, original_dex_cache_);
176 id_map_.insert({original, slot});
177 }
178
179 ObsoleteMap(art::ObjPtr<art::mirror::PointerArray> obsolete_methods,
180 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> obsolete_dex_caches,
181 art::ObjPtr<art::mirror::DexCache> original_dex_cache)
182 : next_free_slot_(0),
183 obsolete_methods_(obsolete_methods),
184 obsolete_dex_caches_(obsolete_dex_caches),
185 original_dex_cache_(original_dex_cache) {
186 // Figure out where the first unused slot in the obsolete_methods_ array is.
187 while (obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(
188 next_free_slot_, art::kRuntimePointerSize) != nullptr) {
189 DCHECK(obsolete_dex_caches_->Get(next_free_slot_) != nullptr);
190 next_free_slot_++;
191 }
192 // Sanity check that the same slot in obsolete_dex_caches_ is free.
193 DCHECK(obsolete_dex_caches_->Get(next_free_slot_) == nullptr);
194 }
195
Alex Lighte7a33542019-04-10 14:22:49 -0700196 struct ObsoleteMethodPair {
197 art::ArtMethod* old_method;
198 art::ArtMethod* obsolete_method;
199 };
200
Vladimir Markoeab02482019-05-09 10:28:17 +0100201 class ObsoleteMapIter {
Alex Lighte7a33542019-04-10 14:22:49 -0700202 public:
Vladimir Markoeab02482019-05-09 10:28:17 +0100203 using iterator_category = std::forward_iterator_tag;
204 using value_type = ObsoleteMethodPair;
205 using difference_type = ptrdiff_t;
206 using pointer = void; // Unsupported.
207 using reference = void; // Unsupported.
208
Alex Lighte7a33542019-04-10 14:22:49 -0700209 ObsoleteMethodPair operator*() const
210 REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) {
Vladimir Markoeab02482019-05-09 10:28:17 +0100211 art::ArtMethod* obsolete = map_->obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(
212 iter_->second, art::kRuntimePointerSize);
Alex Lighte7a33542019-04-10 14:22:49 -0700213 DCHECK(obsolete != nullptr);
214 return { iter_->first, obsolete };
215 }
216
217 bool operator==(ObsoleteMapIter other) const {
218 return map_ == other.map_ && iter_ == other.iter_;
219 }
220
221 bool operator!=(ObsoleteMapIter other) const {
222 return !(*this == other);
223 }
224
Vladimir Markoeab02482019-05-09 10:28:17 +0100225 ObsoleteMapIter operator++(int) {
Alex Lighte7a33542019-04-10 14:22:49 -0700226 ObsoleteMapIter retval = *this;
227 ++(*this);
228 return retval;
229 }
230
Vladimir Markoeab02482019-05-09 10:28:17 +0100231 ObsoleteMapIter operator++() {
Alex Lighte7a33542019-04-10 14:22:49 -0700232 ++iter_;
233 return *this;
234 }
235
236 private:
237 ObsoleteMapIter(const ObsoleteMap* map,
238 std::unordered_map<art::ArtMethod*, int32_t>::const_iterator iter)
239 : map_(map), iter_(iter) {}
240
241 const ObsoleteMap* map_;
Vladimir Markoeab02482019-05-09 10:28:17 +0100242 std::unordered_map<art::ArtMethod*, int32_t>::const_iterator iter_;
Alex Lighte7a33542019-04-10 14:22:49 -0700243
244 friend class ObsoleteMap;
245 };
246
247 ObsoleteMapIter end() const {
248 return ObsoleteMapIter(this, id_map_.cend());
249 }
250
251 ObsoleteMapIter begin() const {
252 return ObsoleteMapIter(this, id_map_.cbegin());
253 }
254
Alex Lighteee0bd42017-02-14 15:31:45 +0000255 private:
256 int32_t next_free_slot_;
257 std::unordered_map<art::ArtMethod*, int32_t> id_map_;
258 // Pointers to the fields in mirror::ClassExt. These can be held as ObjPtr since this is only used
259 // when we have an exclusive mutator_lock_ (i.e. all threads are suspended).
260 art::ObjPtr<art::mirror::PointerArray> obsolete_methods_;
261 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> obsolete_dex_caches_;
262 art::ObjPtr<art::mirror::DexCache> original_dex_cache_;
263};
264
Alex Lightdba61482016-12-21 08:20:29 -0800265// This visitor walks thread stacks and allocates and sets up the obsolete methods. It also does
266// some basic sanity checks that the obsolete method is sane.
267class ObsoleteMethodStackVisitor : public art::StackVisitor {
268 protected:
269 ObsoleteMethodStackVisitor(
270 art::Thread* thread,
271 art::LinearAlloc* allocator,
272 const std::unordered_set<art::ArtMethod*>& obsoleted_methods,
Alex Lighteee0bd42017-02-14 15:31:45 +0000273 ObsoleteMap* obsolete_maps)
Alex Lightdba61482016-12-21 08:20:29 -0800274 : StackVisitor(thread,
Andreas Gampe6e897762018-10-16 13:09:32 -0700275 /*context=*/nullptr,
Alex Lightdba61482016-12-21 08:20:29 -0800276 StackVisitor::StackWalkKind::kIncludeInlinedFrames),
277 allocator_(allocator),
278 obsoleted_methods_(obsoleted_methods),
Alex Light4ba388a2017-01-27 10:26:49 -0800279 obsolete_maps_(obsolete_maps) { }
Alex Lightdba61482016-12-21 08:20:29 -0800280
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100281 ~ObsoleteMethodStackVisitor() override {}
Alex Lightdba61482016-12-21 08:20:29 -0800282
283 public:
284 // Returns true if we successfully installed obsolete methods on this thread, filling
285 // obsolete_maps_ with the translations if needed. Returns false and fills error_msg if we fail.
286 // The stack is cleaned up when we fail.
Alex Light007ada22017-01-10 13:33:56 -0800287 static void UpdateObsoleteFrames(
Alex Lightdba61482016-12-21 08:20:29 -0800288 art::Thread* thread,
289 art::LinearAlloc* allocator,
290 const std::unordered_set<art::ArtMethod*>& obsoleted_methods,
Alex Lighteee0bd42017-02-14 15:31:45 +0000291 ObsoleteMap* obsolete_maps)
Alex Light007ada22017-01-10 13:33:56 -0800292 REQUIRES(art::Locks::mutator_lock_) {
Alex Lightdba61482016-12-21 08:20:29 -0800293 ObsoleteMethodStackVisitor visitor(thread,
294 allocator,
295 obsoleted_methods,
Alex Light007ada22017-01-10 13:33:56 -0800296 obsolete_maps);
Alex Lightdba61482016-12-21 08:20:29 -0800297 visitor.WalkStack();
Alex Lightdba61482016-12-21 08:20:29 -0800298 }
299
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100300 bool VisitFrame() override REQUIRES(art::Locks::mutator_lock_) {
Alex Lighteee0bd42017-02-14 15:31:45 +0000301 art::ScopedAssertNoThreadSuspension snts("Fixing up the stack for obsolete methods.");
Alex Lightdba61482016-12-21 08:20:29 -0800302 art::ArtMethod* old_method = GetMethod();
Alex Lightdba61482016-12-21 08:20:29 -0800303 if (obsoleted_methods_.find(old_method) != obsoleted_methods_.end()) {
Alex Lightdba61482016-12-21 08:20:29 -0800304 // We cannot ensure that the right dex file is used in inlined frames so we don't support
305 // redefining them.
Nicolas Geoffray226805d2018-12-14 10:59:02 +0000306 DCHECK(!IsInInlinedFrame()) << "Inlined frames are not supported when using redefinition: "
307 << old_method->PrettyMethod() << " is inlined into "
308 << GetOuterMethod()->PrettyMethod();
Alex Lighteee0bd42017-02-14 15:31:45 +0000309 art::ArtMethod* new_obsolete_method = obsolete_maps_->FindObsoleteVersion(old_method);
310 if (new_obsolete_method == nullptr) {
Alex Lightdba61482016-12-21 08:20:29 -0800311 // Create a new Obsolete Method and put it in the list.
312 art::Runtime* runtime = art::Runtime::Current();
313 art::ClassLinker* cl = runtime->GetClassLinker();
314 auto ptr_size = cl->GetImagePointerSize();
315 const size_t method_size = art::ArtMethod::Size(ptr_size);
Alex Light5c11a792017-03-10 14:29:22 -0800316 auto* method_storage = allocator_->Alloc(art::Thread::Current(), method_size);
Alex Light007ada22017-01-10 13:33:56 -0800317 CHECK(method_storage != nullptr) << "Unable to allocate storage for obsolete version of '"
318 << old_method->PrettyMethod() << "'";
Alex Lightdba61482016-12-21 08:20:29 -0800319 new_obsolete_method = new (method_storage) art::ArtMethod();
320 new_obsolete_method->CopyFrom(old_method, ptr_size);
321 DCHECK_EQ(new_obsolete_method->GetDeclaringClass(), old_method->GetDeclaringClass());
322 new_obsolete_method->SetIsObsolete();
Alex Lightfcbafb32017-02-02 15:09:54 -0800323 new_obsolete_method->SetDontCompile();
Alex Lightdb01a092017-04-03 15:39:55 -0700324 cl->SetEntryPointsForObsoleteMethod(new_obsolete_method);
Alex Lighteee0bd42017-02-14 15:31:45 +0000325 obsolete_maps_->RecordObsolete(old_method, new_obsolete_method);
Alex Lightdba61482016-12-21 08:20:29 -0800326 }
327 DCHECK(new_obsolete_method != nullptr);
328 SetMethod(new_obsolete_method);
329 }
330 return true;
331 }
332
333 private:
334 // The linear allocator we should use to make new methods.
335 art::LinearAlloc* allocator_;
336 // The set of all methods which could be obsoleted.
337 const std::unordered_set<art::ArtMethod*>& obsoleted_methods_;
338 // A map from the original to the newly allocated obsolete method for frames on this thread. The
Alex Lighteee0bd42017-02-14 15:31:45 +0000339 // values in this map are added to the obsolete_methods_ (and obsolete_dex_caches_) fields of
340 // the redefined classes ClassExt as it is filled.
341 ObsoleteMap* obsolete_maps_;
Alex Lightdba61482016-12-21 08:20:29 -0800342};
343
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000344template <RedefinitionType kType>
345jvmtiError
346Redefiner::IsModifiableClassGeneric(jvmtiEnv* env, jclass klass, jboolean* is_redefinable) {
347 if (env == nullptr) {
348 return ERR(INVALID_ENVIRONMENT);
349 }
Alex Lighte4a88632017-01-10 07:41:24 -0800350 art::Thread* self = art::Thread::Current();
351 art::ScopedObjectAccess soa(self);
352 art::StackHandleScope<1> hs(self);
353 art::ObjPtr<art::mirror::Object> obj(self->DecodeJObject(klass));
Alex Light413a8ad2019-02-14 10:19:44 -0800354 if (obj.IsNull() || !obj->IsClass()) {
Alex Lighte4a88632017-01-10 07:41:24 -0800355 return ERR(INVALID_CLASS);
356 }
357 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(obj->AsClass()));
358 std::string err_unused;
359 *is_redefinable =
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000360 Redefiner::GetClassRedefinitionError<kType>(h_klass, &err_unused) != ERR(UNMODIFIABLE_CLASS)
361 ? JNI_TRUE
362 : JNI_FALSE;
Alex Lighte4a88632017-01-10 07:41:24 -0800363 return OK;
364}
365
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000366jvmtiError
367Redefiner::IsStructurallyModifiableClass(jvmtiEnv* env, jclass klass, jboolean* is_redefinable) {
368 return Redefiner::IsModifiableClassGeneric<RedefinitionType::kStructural>(
369 env, klass, is_redefinable);
370}
371
372jvmtiError Redefiner::IsModifiableClass(jvmtiEnv* env, jclass klass, jboolean* is_redefinable) {
373 return Redefiner::IsModifiableClassGeneric<RedefinitionType::kNormal>(env, klass, is_redefinable);
374}
375
376template <RedefinitionType kType>
377jvmtiError Redefiner::GetClassRedefinitionError(jclass klass, /*out*/ std::string* error_msg) {
Alex Light9e7859c2018-04-05 13:49:43 -0700378 art::Thread* self = art::Thread::Current();
379 art::ScopedObjectAccess soa(self);
380 art::StackHandleScope<1> hs(self);
381 art::ObjPtr<art::mirror::Object> obj(self->DecodeJObject(klass));
Alex Light413a8ad2019-02-14 10:19:44 -0800382 if (obj.IsNull() || !obj->IsClass()) {
Alex Light9e7859c2018-04-05 13:49:43 -0700383 return ERR(INVALID_CLASS);
384 }
385 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(obj->AsClass()));
Alex Lightd55b8442019-10-15 15:46:07 -0700386 return Redefiner::GetClassRedefinitionError<kType>(h_klass, error_msg);
Alex Light9e7859c2018-04-05 13:49:43 -0700387}
388
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000389template <RedefinitionType kType>
Alex Lighte4a88632017-01-10 07:41:24 -0800390jvmtiError Redefiner::GetClassRedefinitionError(art::Handle<art::mirror::Class> klass,
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000391 /*out*/ std::string* error_msg) {
392 art::Thread* self = art::Thread::Current();
Alex Light9e7859c2018-04-05 13:49:43 -0700393 if (!klass->IsResolved()) {
394 // It's only a problem to try to retransform/redefine a unprepared class if it's happening on
395 // the same thread as the class-linking process. If it's on another thread we will be able to
396 // wait for the preparation to finish and continue from there.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000397 if (klass->GetLockOwnerThreadId() == self->GetThreadId()) {
Alex Light9e7859c2018-04-05 13:49:43 -0700398 *error_msg = "Modification of class " + klass->PrettyClass() +
399 " from within the classes ClassLoad callback is not supported to prevent deadlocks." +
400 " Please use ClassFileLoadHook directly instead.";
401 return ERR(INTERNAL);
402 } else {
403 LOG(WARNING) << klass->PrettyClass() << " is not yet resolved. Attempting to transform "
404 << "it could cause arbitrary length waits as the class is being resolved.";
405 }
406 }
Alex Lighte4a88632017-01-10 07:41:24 -0800407 if (klass->IsPrimitive()) {
408 *error_msg = "Modification of primitive classes is not supported";
409 return ERR(UNMODIFIABLE_CLASS);
410 } else if (klass->IsInterface()) {
411 *error_msg = "Modification of Interface classes is currently not supported";
412 return ERR(UNMODIFIABLE_CLASS);
Alex Light09f274f2017-02-21 15:00:48 -0800413 } else if (klass->IsStringClass()) {
414 *error_msg = "Modification of String class is not supported";
415 return ERR(UNMODIFIABLE_CLASS);
Alex Lighte4a88632017-01-10 07:41:24 -0800416 } else if (klass->IsArrayClass()) {
417 *error_msg = "Modification of Array classes is not supported";
418 return ERR(UNMODIFIABLE_CLASS);
419 } else if (klass->IsProxyClass()) {
420 *error_msg = "Modification of proxy classes is not supported";
421 return ERR(UNMODIFIABLE_CLASS);
422 }
423
Alex Lighte77b48b2017-02-22 11:08:06 -0800424 for (jclass c : art::NonDebuggableClasses::GetNonDebuggableClasses()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000425 if (klass.Get() == self->DecodeJObject(c)->AsClass()) {
Alex Lighte77b48b2017-02-22 11:08:06 -0800426 *error_msg = "Class might have stack frames that cannot be made obsolete";
427 return ERR(UNMODIFIABLE_CLASS);
428 }
429 }
430
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000431 if (kType == RedefinitionType::kStructural) {
Alex Lightfb119572019-09-18 15:04:53 -0700432 // Class initialization interacts really badly with structural redefinition since we need to
433 // make the old class obsolete. We currently just blanket don't allow it.
434 // TODO It might be nice to allow this at some point.
435 if (klass->IsInitializing() &&
436 !klass->IsInitialized() &&
437 klass->GetClinitThreadId() == self->GetTid()) {
438 // We are in the class-init running on this thread.
439 *error_msg = "Modification of class " + klass->PrettyClass() + " during class" +
440 " initialization is not allowed.";
441 return ERR(INTERNAL);
442 }
443 if (!art::Runtime::Current()->GetClassLinker()->EnsureInitialized(
444 self, klass, /*can_init_fields=*/true, /*can_init_parents=*/true)) {
445 self->AssertPendingException();
446 *error_msg = "Class " + klass->PrettyClass() + " failed initialization. Structural" +
447 " redefinition of erroneous classes is not allowed. Failure was: " +
448 self->GetException()->Dump();
449 self->ClearException();
450 return ERR(INVALID_CLASS);
451 }
Alex Lightf1b18fa2019-11-11 14:22:00 -0800452 if (klass->IsMirrored()) {
453 std::string pc(klass->PrettyClass());
454 *error_msg = StringPrintf("Class %s is a mirror class and cannot be structurally redefined.",
455 pc.c_str());
456 return ERR(UNMODIFIABLE_CLASS);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000457 }
458 // Check Thread specifically since it's not a root but too many things reach into it with Unsafe
459 // too allow structural redefinition.
460 if (klass->IsAssignableFrom(
461 self->DecodeJObject(art::WellKnownClasses::java_lang_Thread)->AsClass())) {
462 *error_msg =
463 "java.lang.Thread has fields accessed using sun.misc.unsafe directly. It is not "
464 "safe to structurally redefine it.";
465 return ERR(UNMODIFIABLE_CLASS);
466 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000467 // Check for fields/methods which were returned before moving to index jni id type.
468 // TODO We might want to rework how this is done. Once full redefinition is implemented we will
469 // need to check any subtypes too.
470 art::ObjPtr<art::mirror::ClassExt> ext(klass->GetExtData());
471 if (!ext.IsNull()) {
Alex Lightbc19b752019-12-02 18:54:13 +0000472 if (ext->HasInstanceFieldPointerIdMarker() ||
473 ext->HasMethodPointerIdMarker() ||
474 ext->HasStaticFieldPointerIdMarker()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000475 return ERR(UNMODIFIABLE_CLASS);
476 }
477 }
478 }
Alex Lighte4a88632017-01-10 07:41:24 -0800479 return OK;
480}
481
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000482template jvmtiError Redefiner::GetClassRedefinitionError<RedefinitionType::kNormal>(
483 art::Handle<art::mirror::Class> klass, /*out*/ std::string* error_msg);
484template jvmtiError Redefiner::GetClassRedefinitionError<RedefinitionType::kStructural>(
485 art::Handle<art::mirror::Class> klass, /*out*/ std::string* error_msg);
486
Alex Lighta01de592016-11-15 10:43:06 -0800487// Moves dex data to an anonymous, read-only mmap'd region.
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100488art::MemMap Redefiner::MoveDataToMemMap(const std::string& original_location,
489 art::ArrayRef<const unsigned char> data,
490 std::string* error_msg) {
491 art::MemMap map = art::MemMap::MapAnonymous(
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800492 StringPrintf("%s-transformed", original_location.c_str()).c_str(),
Alex Lightb7354d52017-03-30 15:17:01 -0700493 data.size(),
Alex Lighta01de592016-11-15 10:43:06 -0800494 PROT_READ|PROT_WRITE,
Andreas Gampe6e897762018-10-16 13:09:32 -0700495 /*low_4gb=*/ false,
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100496 error_msg);
497 if (LIKELY(map.IsValid())) {
498 memcpy(map.Begin(), data.data(), data.size());
499 // Make the dex files mmap read only. This matches how other DexFiles are mmaped and prevents
500 // programs from corrupting it.
501 map.Protect(PROT_READ);
Alex Lighta01de592016-11-15 10:43:06 -0800502 }
Alex Lighta01de592016-11-15 10:43:06 -0800503 return map;
504}
505
Alex Lighta7e38d82017-01-19 14:57:28 -0800506Redefiner::ClassRedefinition::ClassRedefinition(
507 Redefiner* driver,
508 jclass klass,
509 const art::DexFile* redefined_dex_file,
510 const char* class_sig,
Vladimir Markoe1993c72017-06-14 17:01:38 +0100511 art::ArrayRef<const unsigned char> orig_dex_file) :
Alex Lighta7e38d82017-01-19 14:57:28 -0800512 driver_(driver),
513 klass_(klass),
514 dex_file_(redefined_dex_file),
515 class_sig_(class_sig),
516 original_dex_file_(orig_dex_file) {
Alex Light0e692732017-01-10 15:00:05 -0800517 GetMirrorClass()->MonitorEnter(driver_->self_);
518}
519
520Redefiner::ClassRedefinition::~ClassRedefinition() {
521 if (driver_ != nullptr) {
522 GetMirrorClass()->MonitorExit(driver_->self_);
523 }
524}
525
Alex Lightd55b8442019-10-15 15:46:07 -0700526template<RedefinitionType kType>
527jvmtiError Redefiner::RedefineClassesGeneric(jvmtiEnv* jenv,
528 jint class_count,
529 const jvmtiClassDefinition* definitions) {
Alex Light3732beb2019-10-04 13:35:34 -0700530 art::Runtime* runtime = art::Runtime::Current();
531 art::Thread* self = art::Thread::Current();
532 ArtJvmTiEnv* env = ArtJvmTiEnv::AsArtJvmTiEnv(jenv);
Alex Light0e692732017-01-10 15:00:05 -0800533 if (env == nullptr) {
Alex Light3732beb2019-10-04 13:35:34 -0700534 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE env was null!";
Alex Light0e692732017-01-10 15:00:05 -0800535 return ERR(INVALID_ENVIRONMENT);
536 } else if (class_count < 0) {
Alex Light3732beb2019-10-04 13:35:34 -0700537 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE class_count was less then 0";
Alex Light0e692732017-01-10 15:00:05 -0800538 return ERR(ILLEGAL_ARGUMENT);
539 } else if (class_count == 0) {
540 // We don't actually need to do anything. Just return OK.
541 return OK;
542 } else if (definitions == nullptr) {
Alex Light3732beb2019-10-04 13:35:34 -0700543 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE null definitions!";
Alex Light0e692732017-01-10 15:00:05 -0800544 return ERR(NULL_POINTER);
545 }
Alex Light3732beb2019-10-04 13:35:34 -0700546 std::string error_msg;
Alex Light6ac57502017-01-19 15:05:06 -0800547 std::vector<ArtClassDefinition> def_vector;
548 def_vector.reserve(class_count);
549 for (jint i = 0; i < class_count; i++) {
Alex Lightd55b8442019-10-15 15:46:07 -0700550 jvmtiError res = Redefiner::GetClassRedefinitionError<RedefinitionType::kNormal>(
551 definitions[i].klass, &error_msg);
Alex Lightce6ee702017-03-06 15:46:43 -0800552 if (res != OK) {
Alex Light3732beb2019-10-04 13:35:34 -0700553 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE " << error_msg;
Alex Lightce6ee702017-03-06 15:46:43 -0800554 return res;
Alex Lightce6ee702017-03-06 15:46:43 -0800555 }
Alex Light6ac57502017-01-19 15:05:06 -0800556 ArtClassDefinition def;
Alex Light64e4c142018-01-30 13:46:37 -0800557 res = def.Init(self, definitions[i]);
Alex Light6ac57502017-01-19 15:05:06 -0800558 if (res != OK) {
Alex Light3732beb2019-10-04 13:35:34 -0700559 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE bad definition " << i;
Alex Light6ac57502017-01-19 15:05:06 -0800560 return res;
561 }
562 def_vector.push_back(std::move(def));
563 }
564 // Call all the transformation events.
Alex Lightd55b8442019-10-15 15:46:07 -0700565 Transformer::RetransformClassesDirect<kType>(self, &def_vector);
566 if (kType == RedefinitionType::kStructural) {
567 Transformer::RetransformClassesDirect<RedefinitionType::kNormal>(self, &def_vector);
568 }
569 jvmtiError res = RedefineClassesDirect(env, runtime, self, def_vector, kType, &error_msg);
Alex Light3732beb2019-10-04 13:35:34 -0700570 if (res != OK) {
571 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE " << error_msg;
572 }
573 return res;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000574}
575
Alex Lightd55b8442019-10-15 15:46:07 -0700576jvmtiError Redefiner::StructurallyRedefineClasses(jvmtiEnv* jenv,
577 jint class_count,
578 const jvmtiClassDefinition* definitions) {
579 ArtJvmTiEnv* art_env = ArtJvmTiEnv::AsArtJvmTiEnv(jenv);
580 if (art_env == nullptr) {
581 return ERR(INVALID_ENVIRONMENT);
582 } else if (art_env->capabilities.can_redefine_classes != 1) {
583 return ERR(MUST_POSSESS_CAPABILITY);
584 }
585 return RedefineClassesGeneric<RedefinitionType::kStructural>(jenv, class_count, definitions);
586}
587
588jvmtiError Redefiner::RedefineClasses(jvmtiEnv* jenv,
589 jint class_count,
590 const jvmtiClassDefinition* definitions) {
591 return RedefineClassesGeneric<RedefinitionType::kNormal>(jenv, class_count, definitions);
592}
593
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000594jvmtiError Redefiner::StructurallyRedefineClassDirect(jvmtiEnv* env,
595 jclass klass,
596 const unsigned char* data,
597 jint data_size) {
598 if (env == nullptr) {
599 return ERR(INVALID_ENVIRONMENT);
600 } else if (ArtJvmTiEnv::AsArtJvmTiEnv(env)->capabilities.can_redefine_classes != 1) {
601 JVMTI_LOG(INFO, env) << "Does not have can_redefine_classes cap!";
602 return ERR(MUST_POSSESS_CAPABILITY);
603 }
604 std::vector<ArtClassDefinition> acds;
605 ArtClassDefinition acd;
606 jvmtiError err = acd.Init(
607 art::Thread::Current(),
608 jvmtiClassDefinition{ .klass = klass, .class_byte_count = data_size, .class_bytes = data });
609 if (err != OK) {
610 return err;
611 }
612 acds.push_back(std::move(acd));
613 std::string err_msg;
614 err = RedefineClassesDirect(ArtJvmTiEnv::AsArtJvmTiEnv(env),
615 art::Runtime::Current(),
616 art::Thread::Current(),
617 acds,
618 RedefinitionType::kStructural,
619 &err_msg);
620 if (err != OK) {
621 JVMTI_LOG(WARNING, env) << "Failed structural redefinition: " << err_msg;
622 }
623 return err;
Alex Light6ac57502017-01-19 15:05:06 -0800624}
625
626jvmtiError Redefiner::RedefineClassesDirect(ArtJvmTiEnv* env,
627 art::Runtime* runtime,
628 art::Thread* self,
629 const std::vector<ArtClassDefinition>& definitions,
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000630 RedefinitionType type,
Alex Light6ac57502017-01-19 15:05:06 -0800631 std::string* error_msg) {
632 DCHECK(env != nullptr);
633 if (definitions.size() == 0) {
634 // We don't actually need to do anything. Just return OK.
635 return OK;
636 }
Alex Lightc2d0c962019-10-23 14:14:25 -0700637 // We need to fiddle with the verification class flags. To do this we need to make sure there are
638 // no concurrent redefinitions of the same class at the same time. For simplicity and because
639 // this is not expected to be a common occurrence we will just wrap the whole thing in a TOP-level
640 // lock.
641
Alex Light0e692732017-01-10 15:00:05 -0800642 // Stop JIT for the duration of this redefine since the JIT might concurrently compile a method we
643 // are going to redefine.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000644 // TODO We should prevent user-code suspensions to make sure this isn't held for too long.
Alex Light0e692732017-01-10 15:00:05 -0800645 art::jit::ScopedJitSuspend suspend_jit;
646 // Get shared mutator lock so we can lock all the classes.
647 art::ScopedObjectAccess soa(self);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000648 Redefiner r(env, runtime, self, type, error_msg);
Alex Light6ac57502017-01-19 15:05:06 -0800649 for (const ArtClassDefinition& def : definitions) {
650 // Only try to transform classes that have been modified.
Alex Light40528472017-03-28 09:07:36 -0700651 if (def.IsModified()) {
Alex Light6ac57502017-01-19 15:05:06 -0800652 jvmtiError res = r.AddRedefinition(env, def);
653 if (res != OK) {
654 return res;
655 }
Alex Light0e692732017-01-10 15:00:05 -0800656 }
657 }
658 return r.Run();
659}
660
Alex Light6ac57502017-01-19 15:05:06 -0800661jvmtiError Redefiner::AddRedefinition(ArtJvmTiEnv* env, const ArtClassDefinition& def) {
Alex Light0e692732017-01-10 15:00:05 -0800662 std::string original_dex_location;
663 jvmtiError ret = OK;
Alex Lightb7354d52017-03-30 15:17:01 -0700664 if ((ret = GetClassLocation(env, def.GetClass(), &original_dex_location))) {
Alex Light0e692732017-01-10 15:00:05 -0800665 *error_msg_ = "Unable to get original dex file location!";
666 return ret;
667 }
Alex Light52a2db52017-01-19 23:00:21 +0000668 char* generic_ptr_unused = nullptr;
669 char* signature_ptr = nullptr;
Alex Lightb7354d52017-03-30 15:17:01 -0700670 if ((ret = env->GetClassSignature(def.GetClass(), &signature_ptr, &generic_ptr_unused)) != OK) {
Alex Light6ac57502017-01-19 15:05:06 -0800671 *error_msg_ = "Unable to get class signature!";
672 return ret;
Alex Light52a2db52017-01-19 23:00:21 +0000673 }
Andreas Gampe54711412017-02-21 12:41:43 -0800674 JvmtiUniquePtr<char> generic_unique_ptr(MakeJvmtiUniquePtr(env, generic_ptr_unused));
675 JvmtiUniquePtr<char> signature_unique_ptr(MakeJvmtiUniquePtr(env, signature_ptr));
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100676 art::MemMap map = MoveDataToMemMap(original_dex_location, def.GetDexData(), error_msg_);
Alex Light6ac57502017-01-19 15:05:06 -0800677 std::ostringstream os;
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100678 if (!map.IsValid()) {
Alex Lightb7354d52017-03-30 15:17:01 -0700679 os << "Failed to create anonymous mmap for modified dex file of class " << def.GetName()
Alex Light0e692732017-01-10 15:00:05 -0800680 << "in dex file " << original_dex_location << " because: " << *error_msg_;
681 *error_msg_ = os.str();
Alex Lighta01de592016-11-15 10:43:06 -0800682 return ERR(OUT_OF_MEMORY);
683 }
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100684 if (map.Size() < sizeof(art::DexFile::Header)) {
Alex Light0e692732017-01-10 15:00:05 -0800685 *error_msg_ = "Could not read dex file header because dex_data was too short";
Alex Lighta01de592016-11-15 10:43:06 -0800686 return ERR(INVALID_CLASS_FORMAT);
687 }
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100688 std::string name = map.GetName();
689 uint32_t checksum = reinterpret_cast<const art::DexFile::Header*>(map.Begin())->checksum_;
David Sehr013fd802018-01-11 22:55:24 -0800690 const art::ArtDexFileLoader dex_file_loader;
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100691 std::unique_ptr<const art::DexFile> dex_file(dex_file_loader.Open(name,
David Sehr013fd802018-01-11 22:55:24 -0800692 checksum,
693 std::move(map),
Andreas Gampe6e897762018-10-16 13:09:32 -0700694 /*verify=*/true,
695 /*verify_checksum=*/true,
David Sehr013fd802018-01-11 22:55:24 -0800696 error_msg_));
Alex Lighta01de592016-11-15 10:43:06 -0800697 if (dex_file.get() == nullptr) {
Alex Lightb7354d52017-03-30 15:17:01 -0700698 os << "Unable to load modified dex file for " << def.GetName() << ": " << *error_msg_;
Alex Light0e692732017-01-10 15:00:05 -0800699 *error_msg_ = os.str();
Alex Lighta01de592016-11-15 10:43:06 -0800700 return ERR(INVALID_CLASS_FORMAT);
701 }
Alex Light0e692732017-01-10 15:00:05 -0800702 redefinitions_.push_back(
Alex Lighta7e38d82017-01-19 14:57:28 -0800703 Redefiner::ClassRedefinition(this,
Alex Lightb7354d52017-03-30 15:17:01 -0700704 def.GetClass(),
Alex Lighta7e38d82017-01-19 14:57:28 -0800705 dex_file.release(),
706 signature_ptr,
Alex Light40528472017-03-28 09:07:36 -0700707 def.GetNewOriginalDexFile()));
Alex Light0e692732017-01-10 15:00:05 -0800708 return OK;
Alex Lighta01de592016-11-15 10:43:06 -0800709}
710
Vladimir Marko4617d582019-03-28 13:48:31 +0000711art::ObjPtr<art::mirror::Class> Redefiner::ClassRedefinition::GetMirrorClass() {
Alex Light0e692732017-01-10 15:00:05 -0800712 return driver_->self_->DecodeJObject(klass_)->AsClass();
Alex Lighta01de592016-11-15 10:43:06 -0800713}
714
Vladimir Markoc524e9e2019-03-26 10:54:50 +0000715art::ObjPtr<art::mirror::ClassLoader> Redefiner::ClassRedefinition::GetClassLoader() {
Alex Lighta01de592016-11-15 10:43:06 -0800716 return GetMirrorClass()->GetClassLoader();
717}
718
Alex Light0e692732017-01-10 15:00:05 -0800719art::mirror::DexCache* Redefiner::ClassRedefinition::CreateNewDexCache(
720 art::Handle<art::mirror::ClassLoader> loader) {
Alex Light07f06212017-06-01 14:01:43 -0700721 art::StackHandleScope<2> hs(driver_->self_);
722 art::ClassLinker* cl = driver_->runtime_->GetClassLinker();
723 art::Handle<art::mirror::DexCache> cache(hs.NewHandle(
724 art::ObjPtr<art::mirror::DexCache>::DownCast(
Vladimir Markob4eb1b12018-05-24 11:09:38 +0100725 art::GetClassRoot<art::mirror::DexCache>(cl)->AllocObject(driver_->self_))));
Alex Light07f06212017-06-01 14:01:43 -0700726 if (cache.IsNull()) {
727 driver_->self_->AssertPendingOOMException();
728 return nullptr;
729 }
730 art::Handle<art::mirror::String> location(hs.NewHandle(
731 cl->GetInternTable()->InternStrong(dex_file_->GetLocation().c_str())));
732 if (location.IsNull()) {
733 driver_->self_->AssertPendingOOMException();
734 return nullptr;
735 }
736 art::WriterMutexLock mu(driver_->self_, *art::Locks::dex_lock_);
737 art::mirror::DexCache::InitializeDexCache(driver_->self_,
738 cache.Get(),
739 location.Get(),
740 dex_file_.get(),
741 loader.IsNull() ? driver_->runtime_->GetLinearAlloc()
742 : loader->GetAllocator(),
743 art::kRuntimePointerSize);
744 return cache.Get();
Alex Lighta01de592016-11-15 10:43:06 -0800745}
746
Alex Light0e692732017-01-10 15:00:05 -0800747void Redefiner::RecordFailure(jvmtiError result,
748 const std::string& class_sig,
749 const std::string& error_msg) {
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800750 *error_msg_ = StringPrintf("Unable to perform redefinition of '%s': %s",
Alex Light0e692732017-01-10 15:00:05 -0800751 class_sig.c_str(),
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800752 error_msg.c_str());
Alex Lighta01de592016-11-15 10:43:06 -0800753 result_ = result;
754}
755
Alex Light2f814aa2017-03-24 15:21:34 +0000756art::mirror::Object* Redefiner::ClassRedefinition::AllocateOrGetOriginalDexFile() {
Alex Lighta7e38d82017-01-19 14:57:28 -0800757 // If we have been specifically given a new set of bytes use that
758 if (original_dex_file_.size() != 0) {
Alex Light440b5d92017-01-24 15:32:25 -0800759 return art::mirror::ByteArray::AllocateAndFill(
760 driver_->self_,
Vladimir Markoe1993c72017-06-14 17:01:38 +0100761 reinterpret_cast<const signed char*>(original_dex_file_.data()),
Vladimir Markobcf17522018-06-01 13:14:32 +0100762 original_dex_file_.size()).Ptr();
Alex Lighta01de592016-11-15 10:43:06 -0800763 }
Alex Lighta7e38d82017-01-19 14:57:28 -0800764
765 // See if we already have one set.
766 art::ObjPtr<art::mirror::ClassExt> ext(GetMirrorClass()->GetExtData());
767 if (!ext.IsNull()) {
Alex Light2f814aa2017-03-24 15:21:34 +0000768 art::ObjPtr<art::mirror::Object> old_original_dex_file(ext->GetOriginalDexFile());
769 if (!old_original_dex_file.IsNull()) {
Alex Lighta7e38d82017-01-19 14:57:28 -0800770 // We do. Use it.
Alex Light2f814aa2017-03-24 15:21:34 +0000771 return old_original_dex_file.Ptr();
Alex Lighta7e38d82017-01-19 14:57:28 -0800772 }
Alex Lighta01de592016-11-15 10:43:06 -0800773 }
Alex Lighta7e38d82017-01-19 14:57:28 -0800774
Alex Light2f814aa2017-03-24 15:21:34 +0000775 // return the current dex_cache which has the dex file in it.
776 art::ObjPtr<art::mirror::DexCache> current_dex_cache(GetMirrorClass()->GetDexCache());
Alex Lighta7e38d82017-01-19 14:57:28 -0800777 // TODO Handle this or make it so it cannot happen.
Alex Light2f814aa2017-03-24 15:21:34 +0000778 if (current_dex_cache->GetDexFile()->NumClassDefs() != 1) {
Alex Lighta7e38d82017-01-19 14:57:28 -0800779 LOG(WARNING) << "Current dex file has more than one class in it. Calling RetransformClasses "
780 << "on this class might fail if no transformations are applied to it!";
Alex Lighta01de592016-11-15 10:43:06 -0800781 }
Alex Light2f814aa2017-03-24 15:21:34 +0000782 return current_dex_cache.Ptr();
Alex Lighta01de592016-11-15 10:43:06 -0800783}
784
Alex Lightdba61482016-12-21 08:20:29 -0800785struct CallbackCtx {
Alex Lighteee0bd42017-02-14 15:31:45 +0000786 ObsoleteMap* obsolete_map;
Alex Lightdba61482016-12-21 08:20:29 -0800787 art::LinearAlloc* allocator;
Alex Lightdba61482016-12-21 08:20:29 -0800788 std::unordered_set<art::ArtMethod*> obsolete_methods;
Alex Lightdba61482016-12-21 08:20:29 -0800789
Alex Lighteee0bd42017-02-14 15:31:45 +0000790 explicit CallbackCtx(ObsoleteMap* map, art::LinearAlloc* alloc)
791 : obsolete_map(map), allocator(alloc) {}
Alex Lightdba61482016-12-21 08:20:29 -0800792};
793
Alex Lightdba61482016-12-21 08:20:29 -0800794void DoAllocateObsoleteMethodsCallback(art::Thread* t, void* vdata) NO_THREAD_SAFETY_ANALYSIS {
795 CallbackCtx* data = reinterpret_cast<CallbackCtx*>(vdata);
Alex Light007ada22017-01-10 13:33:56 -0800796 ObsoleteMethodStackVisitor::UpdateObsoleteFrames(t,
797 data->allocator,
798 data->obsolete_methods,
Alex Lighteee0bd42017-02-14 15:31:45 +0000799 data->obsolete_map);
Alex Lightdba61482016-12-21 08:20:29 -0800800}
801
802// This creates any ArtMethod* structures needed for obsolete methods and ensures that the stack is
803// updated so they will be run.
Alex Light0e692732017-01-10 15:00:05 -0800804// TODO Rewrite so we can do this only once regardless of how many redefinitions there are.
Vladimir Markod93e3742018-07-18 10:58:13 +0100805void Redefiner::ClassRedefinition::FindAndAllocateObsoleteMethods(
806 art::ObjPtr<art::mirror::Class> art_klass) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000807 DCHECK(!IsStructuralRedefinition());
Alex Lightdba61482016-12-21 08:20:29 -0800808 art::ScopedAssertNoThreadSuspension ns("No thread suspension during thread stack walking");
Vladimir Markod93e3742018-07-18 10:58:13 +0100809 art::ObjPtr<art::mirror::ClassExt> ext = art_klass->GetExtData();
Alex Lightdba61482016-12-21 08:20:29 -0800810 CHECK(ext->GetObsoleteMethods() != nullptr);
Alex Light7916f202017-01-27 09:00:15 -0800811 art::ClassLinker* linker = driver_->runtime_->GetClassLinker();
Alex Lighteee0bd42017-02-14 15:31:45 +0000812 // This holds pointers to the obsolete methods map fields which are updated as needed.
813 ObsoleteMap map(ext->GetObsoleteMethods(), ext->GetObsoleteDexCaches(), art_klass->GetDexCache());
814 CallbackCtx ctx(&map, linker->GetAllocatorForClassLoader(art_klass->GetClassLoader()));
Alex Lightdba61482016-12-21 08:20:29 -0800815 // Add all the declared methods to the map
816 for (auto& m : art_klass->GetDeclaredMethods(art::kRuntimePointerSize)) {
Alex Light7532d582017-02-13 16:36:06 -0800817 if (m.IsIntrinsic()) {
818 LOG(WARNING) << "Redefining intrinsic method " << m.PrettyMethod() << ". This may cause the "
819 << "unexpected use of the original definition of " << m.PrettyMethod() << "in "
820 << "methods that have already been compiled.";
821 }
Alex Lighteee0bd42017-02-14 15:31:45 +0000822 // It is possible to simply filter out some methods where they cannot really become obsolete,
823 // such as native methods and keep their original (possibly optimized) implementations. We don't
824 // do this, however, since we would need to mark these functions (still in the classes
825 // declared_methods array) as obsolete so we will find the correct dex file to get meta-data
826 // from (for example about stack-frame size). Furthermore we would be unable to get some useful
827 // error checking from the interpreter which ensure we don't try to start executing obsolete
828 // methods.
Nicolas Geoffray7558d272017-02-10 10:01:47 +0000829 ctx.obsolete_methods.insert(&m);
Alex Lightdba61482016-12-21 08:20:29 -0800830 }
831 {
Alex Light0e692732017-01-10 15:00:05 -0800832 art::MutexLock mu(driver_->self_, *art::Locks::thread_list_lock_);
Alex Lightdba61482016-12-21 08:20:29 -0800833 art::ThreadList* list = art::Runtime::Current()->GetThreadList();
834 list->ForEach(DoAllocateObsoleteMethodsCallback, static_cast<void*>(&ctx));
Vladimir Markoeab02482019-05-09 10:28:17 +0100835 // After we've done walking all threads' stacks and updating method pointers on them,
836 // update JIT data structures (used by the stack walk above) to point to the new methods.
Alex Lighte7a33542019-04-10 14:22:49 -0700837 art::jit::Jit* jit = art::Runtime::Current()->GetJit();
838 if (jit != nullptr) {
839 for (const ObsoleteMap::ObsoleteMethodPair& it : *ctx.obsolete_map) {
840 // Notify the JIT we are making this obsolete method. It will update the jit's internal
841 // structures to keep track of the new obsolete method.
842 jit->GetCodeCache()->MoveObsoleteMethod(it.old_method, it.obsolete_method);
843 }
844 }
Alex Lightdba61482016-12-21 08:20:29 -0800845 }
Alex Lightdba61482016-12-21 08:20:29 -0800846}
847
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000848namespace {
849template <typename T> struct SignatureType {};
850template <> struct SignatureType<art::ArtField> { using type = std::string_view; };
851template <> struct SignatureType<art::ArtMethod> { using type = art::Signature; };
852
853template <typename T> struct NameAndSignature {
854 public:
855 using SigType = typename SignatureType<T>::type;
856
857 NameAndSignature(const art::DexFile* dex_file, uint32_t id);
858
859 NameAndSignature(const std::string_view& name, const SigType& sig) : name_(name), sig_(sig) {}
860
861 bool operator==(const NameAndSignature<T>& o) {
862 return name_ == o.name_ && sig_ == o.sig_;
Alex Light6161f132017-01-25 10:30:20 -0800863 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000864
865 std::ostream& dump(std::ostream& os) const {
866 return os << "'" << name_ << "' (sig: " << sig_ << ")";
867 }
868
869 std::string ToString() const {
870 std::ostringstream os;
871 os << *this;
872 return os.str();
873 }
874
875 std::string_view name_;
876 SigType sig_;
877};
878
879template <typename T>
880std::ostream& operator<<(std::ostream& os, const NameAndSignature<T>& nas) {
881 return nas.dump(os);
Alex Light6161f132017-01-25 10:30:20 -0800882}
883
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000884using FieldNameAndSignature = NameAndSignature<art::ArtField>;
885template <>
886FieldNameAndSignature::NameAndSignature(const art::DexFile* dex_file, uint32_t id)
887 : FieldNameAndSignature(dex_file->GetFieldName(dex_file->GetFieldId(id)),
888 dex_file->GetFieldTypeDescriptor(dex_file->GetFieldId(id))) {}
889
890using MethodNameAndSignature = NameAndSignature<art::ArtMethod>;
891template <>
892MethodNameAndSignature::NameAndSignature(const art::DexFile* dex_file, uint32_t id)
893 : MethodNameAndSignature(dex_file->GetMethodName(dex_file->GetMethodId(id)),
894 dex_file->GetMethodSignature(dex_file->GetMethodId(id))) {}
895
896} // namespace
897
898void Redefiner::ClassRedefinition::RecordNewMethodAdded() {
899 DCHECK(driver_->IsStructuralRedefinition());
900 added_methods_ = true;
901}
902void Redefiner::ClassRedefinition::RecordNewFieldAdded() {
903 DCHECK(driver_->IsStructuralRedefinition());
904 added_fields_ = true;
905}
906
907bool Redefiner::ClassRedefinition::CheckMethods() {
Alex Light6161f132017-01-25 10:30:20 -0800908 art::StackHandleScope<1> hs(driver_->self_);
909 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass()));
910 DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
911
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000912 // Make sure we have the same number of methods (or the same or greater if we're structural).
Mathieu Chartier4ac9ade2018-07-24 10:27:21 -0700913 art::ClassAccessor accessor(*dex_file_, dex_file_->GetClassDef(0));
914 uint32_t num_new_method = accessor.NumMethods();
Alex Light6161f132017-01-25 10:30:20 -0800915 uint32_t num_old_method = h_klass->GetDeclaredMethodsSlice(art::kRuntimePointerSize).size();
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000916 const bool is_structural = driver_->IsStructuralRedefinition();
917 if (!is_structural && num_new_method != num_old_method) {
Alex Light6161f132017-01-25 10:30:20 -0800918 bool bigger = num_new_method > num_old_method;
919 RecordFailure(bigger ? ERR(UNSUPPORTED_REDEFINITION_METHOD_ADDED)
920 : ERR(UNSUPPORTED_REDEFINITION_METHOD_DELETED),
921 StringPrintf("Total number of declared methods changed from %d to %d",
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000922 num_old_method,
923 num_new_method));
Alex Light6161f132017-01-25 10:30:20 -0800924 return false;
925 }
926
927 // Skip all of the fields. We should have already checked this.
Alex Light6161f132017-01-25 10:30:20 -0800928 // Check each of the methods. NB we don't need to specifically check for removals since the 2 dex
929 // files have the same number of methods, which means there must be an equal amount of additions
Mathieu Chartier4ac9ade2018-07-24 10:27:21 -0700930 // and removals. We should have already checked the fields.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000931 const art::DexFile& old_dex_file = h_klass->GetDexFile();
932 art::ClassAccessor old_accessor(old_dex_file, *h_klass->GetClassDef());
933 // We need this to check for methods going missing in structural cases.
934 std::vector<bool> seen_old_methods(
935 (kCheckAllMethodsSeenOnce || is_structural) ? old_accessor.NumMethods() : 0, false);
936 const auto old_methods = old_accessor.GetMethods();
937 for (const art::ClassAccessor::Method& new_method : accessor.GetMethods()) {
Alex Light6161f132017-01-25 10:30:20 -0800938 // Get the data on the method we are searching for
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000939 MethodNameAndSignature new_method_id(dex_file_.get(), new_method.GetIndex());
940 const auto old_iter =
941 std::find_if(old_methods.cbegin(), old_methods.cend(), [&](const auto& current_old_method) {
942 MethodNameAndSignature old_method_id(&old_dex_file, current_old_method.GetIndex());
943 return old_method_id == new_method_id;
944 });
945
Alex Light986914b2019-11-19 01:12:25 +0000946 if (!new_method.IsStaticOrDirect()) {
947 RecordHasVirtualMembers();
948 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000949 if (old_iter == old_methods.cend()) {
Alex Light270db1c2019-12-03 12:20:01 +0000950 if (is_structural) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000951 RecordNewMethodAdded();
952 } else {
953 RecordFailure(
954 ERR(UNSUPPORTED_REDEFINITION_METHOD_ADDED),
955 StringPrintf("Unknown virtual method %s was added!", new_method_id.ToString().c_str()));
956 return false;
957 }
958 } else if (new_method.GetAccessFlags() != old_iter->GetAccessFlags()) {
959 RecordFailure(
960 ERR(UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED),
961 StringPrintf("method %s had different access flags", new_method_id.ToString().c_str()));
Alex Light6161f132017-01-25 10:30:20 -0800962 return false;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000963 } else if (kCheckAllMethodsSeenOnce || is_structural) {
964 // We only need this if we are structural.
965 size_t off = std::distance(old_methods.cbegin(), old_iter);
966 DCHECK(!seen_old_methods[off])
967 << "field at " << off << "("
968 << MethodNameAndSignature(&old_dex_file, old_iter->GetIndex()) << ") already seen?";
969 seen_old_methods[off] = true;
Alex Light6161f132017-01-25 10:30:20 -0800970 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000971 }
972 if ((kCheckAllMethodsSeenOnce || is_structural) &&
973 !std::all_of(seen_old_methods.cbegin(), seen_old_methods.cend(), [](auto x) { return x; })) {
974 DCHECK(is_structural) << "We should have hit an earlier failure before getting here!";
975 auto first_fail =
976 std::find_if(seen_old_methods.cbegin(), seen_old_methods.cend(), [](auto x) { return !x; });
977 auto off = std::distance(seen_old_methods.cbegin(), first_fail);
978 auto fail = old_methods.cbegin();
979 std::advance(fail, off);
980 RecordFailure(
981 ERR(UNSUPPORTED_REDEFINITION_METHOD_DELETED),
982 StringPrintf("Method %s missing!",
983 FieldNameAndSignature(&old_dex_file, fail->GetIndex()).ToString().c_str()));
984 return false;
Alex Light6161f132017-01-25 10:30:20 -0800985 }
986 return true;
987}
988
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000989bool Redefiner::ClassRedefinition::CheckFields() {
Alex Light6161f132017-01-25 10:30:20 -0800990 art::StackHandleScope<1> hs(driver_->self_);
991 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass()));
992 DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
Mathieu Chartier4ac9ade2018-07-24 10:27:21 -0700993 art::ClassAccessor new_accessor(*dex_file_, dex_file_->GetClassDef(0));
994
Alex Light6161f132017-01-25 10:30:20 -0800995 const art::DexFile& old_dex_file = h_klass->GetDexFile();
Mathieu Chartier4ac9ade2018-07-24 10:27:21 -0700996 art::ClassAccessor old_accessor(old_dex_file, *h_klass->GetClassDef());
Alex Light6161f132017-01-25 10:30:20 -0800997 // Instance and static fields can be differentiated by their flags so no need to check them
998 // separately.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000999 std::vector<bool> seen_old_fields(old_accessor.NumFields(), false);
1000 const auto old_fields = old_accessor.GetFields();
Mathieu Chartier4ac9ade2018-07-24 10:27:21 -07001001 for (const art::ClassAccessor::Field& new_field : new_accessor.GetFields()) {
Alex Light6161f132017-01-25 10:30:20 -08001002 // Get the data on the method we are searching for
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001003 FieldNameAndSignature new_field_id(dex_file_.get(), new_field.GetIndex());
1004 const auto old_iter =
1005 std::find_if(old_fields.cbegin(), old_fields.cend(), [&](const auto& old_iter) {
1006 FieldNameAndSignature old_field_id(&old_dex_file, old_iter.GetIndex());
1007 return old_field_id == new_field_id;
1008 });
Alex Light986914b2019-11-19 01:12:25 +00001009 if (!new_field.IsStatic()) {
1010 RecordHasVirtualMembers();
1011 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001012 if (old_iter == old_fields.cend()) {
Alex Light270db1c2019-12-03 12:20:01 +00001013 if (driver_->IsStructuralRedefinition()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001014 RecordNewFieldAdded();
1015 } else {
1016 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
1017 StringPrintf("Unknown field %s added!", new_field_id.ToString().c_str()));
1018 return false;
1019 }
1020 } else if (new_field.GetAccessFlags() != old_iter->GetAccessFlags()) {
1021 RecordFailure(
1022 ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
1023 StringPrintf("Field %s had different access flags", new_field_id.ToString().c_str()));
Alex Light6161f132017-01-25 10:30:20 -08001024 return false;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001025 } else {
1026 size_t off = std::distance(old_fields.cbegin(), old_iter);
1027 DCHECK(!seen_old_fields[off])
1028 << "field at " << off << "(" << FieldNameAndSignature(&old_dex_file, old_iter->GetIndex())
1029 << ") already seen?";
1030 seen_old_fields[off] = true;
Alex Light6161f132017-01-25 10:30:20 -08001031 }
Alex Light6161f132017-01-25 10:30:20 -08001032 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001033 if (!std::all_of(seen_old_fields.cbegin(), seen_old_fields.cend(), [](auto x) { return x; })) {
1034 auto first_fail =
1035 std::find_if(seen_old_fields.cbegin(), seen_old_fields.cend(), [](auto x) { return !x; });
1036 auto off = std::distance(seen_old_fields.cbegin(), first_fail);
1037 auto fail = old_fields.cbegin();
1038 std::advance(fail, off);
1039 RecordFailure(
1040 ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
1041 StringPrintf("Field %s is missing!",
1042 FieldNameAndSignature(&old_dex_file, fail->GetIndex()).ToString().c_str()));
Alex Light6161f132017-01-25 10:30:20 -08001043 return false;
1044 }
1045 return true;
1046}
1047
Alex Light0e692732017-01-10 15:00:05 -08001048bool Redefiner::ClassRedefinition::CheckClass() {
Alex Light0e692732017-01-10 15:00:05 -08001049 art::StackHandleScope<1> hs(driver_->self_);
Alex Light460d1b42017-01-10 15:37:17 +00001050 // Easy check that only 1 class def is present.
1051 if (dex_file_->NumClassDefs() != 1) {
1052 RecordFailure(ERR(ILLEGAL_ARGUMENT),
1053 StringPrintf("Expected 1 class def in dex file but found %d",
1054 dex_file_->NumClassDefs()));
1055 return false;
1056 }
1057 // Get the ClassDef from the new DexFile.
1058 // Since the dex file has only a single class def the index is always 0.
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001059 const art::dex::ClassDef& def = dex_file_->GetClassDef(0);
Alex Light460d1b42017-01-10 15:37:17 +00001060 // Get the class as it is now.
1061 art::Handle<art::mirror::Class> current_class(hs.NewHandle(GetMirrorClass()));
1062
1063 // Check the access flags didn't change.
1064 if (def.GetJavaAccessFlags() != (current_class->GetAccessFlags() & art::kAccValidClassFlags)) {
1065 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED),
1066 "Cannot change modifiers of class by redefinition");
1067 return false;
1068 }
1069
1070 // Check class name.
1071 // These should have been checked by the dexfile verifier on load.
1072 DCHECK_NE(def.class_idx_, art::dex::TypeIndex::Invalid()) << "Invalid type index";
1073 const char* descriptor = dex_file_->StringByTypeIdx(def.class_idx_);
1074 DCHECK(descriptor != nullptr) << "Invalid dex file structure!";
1075 if (!current_class->DescriptorEquals(descriptor)) {
1076 std::string storage;
1077 RecordFailure(ERR(NAMES_DONT_MATCH),
1078 StringPrintf("expected file to contain class called '%s' but found '%s'!",
1079 current_class->GetDescriptor(&storage),
1080 descriptor));
1081 return false;
1082 }
1083 if (current_class->IsObjectClass()) {
1084 if (def.superclass_idx_ != art::dex::TypeIndex::Invalid()) {
1085 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Superclass added!");
1086 return false;
1087 }
1088 } else {
1089 const char* super_descriptor = dex_file_->StringByTypeIdx(def.superclass_idx_);
1090 DCHECK(descriptor != nullptr) << "Invalid dex file structure!";
1091 if (!current_class->GetSuperClass()->DescriptorEquals(super_descriptor)) {
1092 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Superclass changed");
1093 return false;
1094 }
1095 }
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001096 const art::dex::TypeList* interfaces = dex_file_->GetInterfacesList(def);
Alex Light460d1b42017-01-10 15:37:17 +00001097 if (interfaces == nullptr) {
1098 if (current_class->NumDirectInterfaces() != 0) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001099 // TODO Support this for kStructural.
Alex Light460d1b42017-01-10 15:37:17 +00001100 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Interfaces added");
1101 return false;
1102 }
1103 } else {
1104 DCHECK(!current_class->IsProxyClass());
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001105 const art::dex::TypeList* current_interfaces = current_class->GetInterfaceTypeList();
Alex Light460d1b42017-01-10 15:37:17 +00001106 if (current_interfaces == nullptr || current_interfaces->Size() != interfaces->Size()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001107 // TODO Support this for kStructural.
Alex Light460d1b42017-01-10 15:37:17 +00001108 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Interfaces added or removed");
1109 return false;
1110 }
1111 // The order of interfaces is (barely) meaningful so we error if it changes.
1112 const art::DexFile& orig_dex_file = current_class->GetDexFile();
1113 for (uint32_t i = 0; i < interfaces->Size(); i++) {
1114 if (strcmp(
1115 dex_file_->StringByTypeIdx(interfaces->GetTypeItem(i).type_idx_),
1116 orig_dex_file.StringByTypeIdx(current_interfaces->GetTypeItem(i).type_idx_)) != 0) {
1117 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED),
1118 "Interfaces changed or re-ordered");
1119 return false;
1120 }
1121 }
1122 }
Alex Light460d1b42017-01-10 15:37:17 +00001123 return true;
1124}
1125
Alex Light0e692732017-01-10 15:00:05 -08001126bool Redefiner::ClassRedefinition::CheckRedefinable() {
Alex Lighte4a88632017-01-10 07:41:24 -08001127 std::string err;
Alex Light0e692732017-01-10 15:00:05 -08001128 art::StackHandleScope<1> hs(driver_->self_);
Alex Light460d1b42017-01-10 15:37:17 +00001129
Alex Lighte4a88632017-01-10 07:41:24 -08001130 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass()));
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001131 jvmtiError res;
Alex Lightd55b8442019-10-15 15:46:07 -07001132 if (driver_->type_ == RedefinitionType::kStructural && this->IsStructuralRedefinition()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001133 res = Redefiner::GetClassRedefinitionError<RedefinitionType::kStructural>(h_klass, &err);
Alex Light986914b2019-11-19 01:12:25 +00001134 if (res == OK && HasVirtualMembers() && h_klass->IsFinalizable()) {
1135 res = ERR(INTERNAL);
1136 err = "Cannot redefine finalizable objects at this time.";
1137 }
Alex Lightd55b8442019-10-15 15:46:07 -07001138 } else {
1139 res = Redefiner::GetClassRedefinitionError<RedefinitionType::kNormal>(h_klass, &err);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001140 }
Alex Lighte4a88632017-01-10 07:41:24 -08001141 if (res != OK) {
1142 RecordFailure(res, err);
1143 return false;
1144 } else {
1145 return true;
1146 }
Alex Light460d1b42017-01-10 15:37:17 +00001147}
1148
Alex Light0e692732017-01-10 15:00:05 -08001149bool Redefiner::ClassRedefinition::CheckRedefinitionIsValid() {
Alex Lightd55b8442019-10-15 15:46:07 -07001150 return CheckClass() && CheckFields() && CheckMethods() && CheckRedefinable();
Alex Light460d1b42017-01-10 15:37:17 +00001151}
1152
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001153class RedefinitionDataIter;
1154
Alex Light0e692732017-01-10 15:00:05 -08001155// A wrapper that lets us hold onto the arbitrary sized data needed for redefinitions in a
1156// reasonably sane way. This adds no fields to the normal ObjectArray. By doing this we can avoid
1157// having to deal with the fact that we need to hold an arbitrary number of references live.
1158class RedefinitionDataHolder {
1159 public:
1160 enum DataSlot : int32_t {
1161 kSlotSourceClassLoader = 0,
1162 kSlotJavaDexFile = 1,
1163 kSlotNewDexFileCookie = 2,
1164 kSlotNewDexCache = 3,
1165 kSlotMirrorClass = 4,
Alex Lighta7e38d82017-01-19 14:57:28 -08001166 kSlotOrigDexFile = 5,
Alex Light1e3926a2017-04-07 10:38:06 -07001167 kSlotOldObsoleteMethods = 6,
1168 kSlotOldDexCaches = 7,
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001169 kSlotNewClassObject = 8,
Alex Light986914b2019-11-19 01:12:25 +00001170 kSlotOldInstanceObjects = 9,
1171 kSlotNewInstanceObjects = 10,
Alex Light270db1c2019-12-03 12:20:01 +00001172 kSlotOldClasses = 11,
1173 kSlotNewClasses = 12,
Alex Light0e692732017-01-10 15:00:05 -08001174
1175 // Must be last one.
Alex Light270db1c2019-12-03 12:20:01 +00001176 kNumSlots = 13,
Alex Light0e692732017-01-10 15:00:05 -08001177 };
1178
1179 // This needs to have a HandleScope passed in that is capable of creating a new Handle without
1180 // overflowing. Only one handle will be created. This object has a lifetime identical to that of
1181 // the passed in handle-scope.
1182 RedefinitionDataHolder(art::StackHandleScope<1>* hs,
1183 art::Runtime* runtime,
1184 art::Thread* self,
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001185 std::vector<Redefiner::ClassRedefinition>* redefinitions)
1186 REQUIRES_SHARED(art::Locks::mutator_lock_) :
Vladimir Markob4eb1b12018-05-24 11:09:38 +01001187 arr_(hs->NewHandle(art::mirror::ObjectArray<art::mirror::Object>::Alloc(
1188 self,
1189 art::GetClassRoot<art::mirror::ObjectArray<art::mirror::Object>>(runtime->GetClassLinker()),
1190 redefinitions->size() * kNumSlots))),
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001191 redefinitions_(redefinitions) {}
Alex Light0e692732017-01-10 15:00:05 -08001192
1193 bool IsNull() const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1194 return arr_.IsNull();
1195 }
1196
Vladimir Markod93e3742018-07-18 10:58:13 +01001197 art::ObjPtr<art::mirror::ClassLoader> GetSourceClassLoader(jint klass_index) const
Alex Light0e692732017-01-10 15:00:05 -08001198 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Vladimir Markod93e3742018-07-18 10:58:13 +01001199 return art::ObjPtr<art::mirror::ClassLoader>::DownCast(
1200 GetSlot(klass_index, kSlotSourceClassLoader));
Alex Light0e692732017-01-10 15:00:05 -08001201 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001202 art::ObjPtr<art::mirror::Object> GetJavaDexFile(jint klass_index) const
Alex Light8c889d22017-02-06 13:58:27 -08001203 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light0e692732017-01-10 15:00:05 -08001204 return GetSlot(klass_index, kSlotJavaDexFile);
1205 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001206 art::ObjPtr<art::mirror::LongArray> GetNewDexFileCookie(jint klass_index) const
Alex Light0e692732017-01-10 15:00:05 -08001207 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Vladimir Markod93e3742018-07-18 10:58:13 +01001208 return art::ObjPtr<art::mirror::LongArray>::DownCast(
1209 GetSlot(klass_index, kSlotNewDexFileCookie));
Alex Light0e692732017-01-10 15:00:05 -08001210 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001211 art::ObjPtr<art::mirror::DexCache> GetNewDexCache(jint klass_index) const
Alex Light0e692732017-01-10 15:00:05 -08001212 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Vladimir Markod93e3742018-07-18 10:58:13 +01001213 return art::ObjPtr<art::mirror::DexCache>::DownCast(GetSlot(klass_index, kSlotNewDexCache));
Alex Light0e692732017-01-10 15:00:05 -08001214 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001215 art::ObjPtr<art::mirror::Class> GetMirrorClass(jint klass_index) const
Alex Light8c889d22017-02-06 13:58:27 -08001216 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Vladimir Markod93e3742018-07-18 10:58:13 +01001217 return art::ObjPtr<art::mirror::Class>::DownCast(GetSlot(klass_index, kSlotMirrorClass));
Alex Light0e692732017-01-10 15:00:05 -08001218 }
1219
Vladimir Markod93e3742018-07-18 10:58:13 +01001220 art::ObjPtr<art::mirror::Object> GetOriginalDexFile(jint klass_index) const
Alex Lighta7e38d82017-01-19 14:57:28 -08001221 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Vladimir Markod93e3742018-07-18 10:58:13 +01001222 return art::ObjPtr<art::mirror::Object>::DownCast(GetSlot(klass_index, kSlotOrigDexFile));
Alex Lighta7e38d82017-01-19 14:57:28 -08001223 }
1224
Vladimir Markod93e3742018-07-18 10:58:13 +01001225 art::ObjPtr<art::mirror::PointerArray> GetOldObsoleteMethods(jint klass_index) const
Alex Light1e3926a2017-04-07 10:38:06 -07001226 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Vladimir Markod93e3742018-07-18 10:58:13 +01001227 return art::ObjPtr<art::mirror::PointerArray>::DownCast(
Alex Light1e3926a2017-04-07 10:38:06 -07001228 GetSlot(klass_index, kSlotOldObsoleteMethods));
1229 }
1230
Vladimir Markod93e3742018-07-18 10:58:13 +01001231 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> GetOldDexCaches(
1232 jint klass_index) const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1233 return art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>>::DownCast(
Alex Light1e3926a2017-04-07 10:38:06 -07001234 GetSlot(klass_index, kSlotOldDexCaches));
1235 }
1236
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001237 art::ObjPtr<art::mirror::Class> GetNewClassObject(jint klass_index) const
1238 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1239 return art::ObjPtr<art::mirror::Class>::DownCast(GetSlot(klass_index, kSlotNewClassObject));
1240 }
1241
Alex Light986914b2019-11-19 01:12:25 +00001242 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> GetOldInstanceObjects(
1243 jint klass_index) const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1244 return art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>>::DownCast(
1245 GetSlot(klass_index, kSlotOldInstanceObjects));
1246 }
1247
1248 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> GetNewInstanceObjects(
1249 jint klass_index) const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1250 return art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>>::DownCast(
1251 GetSlot(klass_index, kSlotNewInstanceObjects));
1252 }
Alex Light270db1c2019-12-03 12:20:01 +00001253 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> GetOldClasses(jint klass_index) const
1254 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1255 return art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>>::DownCast(
1256 GetSlot(klass_index, kSlotOldClasses));
1257 }
1258 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> GetNewClasses(jint klass_index) const
1259 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1260 return art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>>::DownCast(
1261 GetSlot(klass_index, kSlotNewClasses));
1262 }
Alex Light986914b2019-11-19 01:12:25 +00001263
Vladimir Markod93e3742018-07-18 10:58:13 +01001264 void SetSourceClassLoader(jint klass_index, art::ObjPtr<art::mirror::ClassLoader> loader)
Alex Light0e692732017-01-10 15:00:05 -08001265 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1266 SetSlot(klass_index, kSlotSourceClassLoader, loader);
1267 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001268 void SetJavaDexFile(jint klass_index, art::ObjPtr<art::mirror::Object> dexfile)
Alex Light0e692732017-01-10 15:00:05 -08001269 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1270 SetSlot(klass_index, kSlotJavaDexFile, dexfile);
1271 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001272 void SetNewDexFileCookie(jint klass_index, art::ObjPtr<art::mirror::LongArray> cookie)
Alex Light0e692732017-01-10 15:00:05 -08001273 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1274 SetSlot(klass_index, kSlotNewDexFileCookie, cookie);
1275 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001276 void SetNewDexCache(jint klass_index, art::ObjPtr<art::mirror::DexCache> cache)
Alex Light0e692732017-01-10 15:00:05 -08001277 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1278 SetSlot(klass_index, kSlotNewDexCache, cache);
1279 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001280 void SetMirrorClass(jint klass_index, art::ObjPtr<art::mirror::Class> klass)
Alex Light0e692732017-01-10 15:00:05 -08001281 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1282 SetSlot(klass_index, kSlotMirrorClass, klass);
1283 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001284 void SetOriginalDexFile(jint klass_index, art::ObjPtr<art::mirror::Object> bytes)
Alex Lighta7e38d82017-01-19 14:57:28 -08001285 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1286 SetSlot(klass_index, kSlotOrigDexFile, bytes);
1287 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001288 void SetOldObsoleteMethods(jint klass_index, art::ObjPtr<art::mirror::PointerArray> methods)
Alex Light1e3926a2017-04-07 10:38:06 -07001289 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1290 SetSlot(klass_index, kSlotOldObsoleteMethods, methods);
1291 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001292 void SetOldDexCaches(jint klass_index,
1293 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> caches)
Alex Light1e3926a2017-04-07 10:38:06 -07001294 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1295 SetSlot(klass_index, kSlotOldDexCaches, caches);
1296 }
Alex Light0e692732017-01-10 15:00:05 -08001297
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001298 void SetNewClassObject(jint klass_index, art::ObjPtr<art::mirror::Class> klass)
1299 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1300 SetSlot(klass_index, kSlotNewClassObject, klass);
1301 }
1302
Alex Light986914b2019-11-19 01:12:25 +00001303 void SetOldInstanceObjects(jint klass_index,
1304 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)
1305 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1306 SetSlot(klass_index, kSlotOldInstanceObjects, objs);
1307 }
1308 void SetNewInstanceObjects(jint klass_index,
1309 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)
1310 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1311 SetSlot(klass_index, kSlotNewInstanceObjects, objs);
1312 }
Alex Light270db1c2019-12-03 12:20:01 +00001313 void SetOldClasses(jint klass_index,
1314 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)
1315 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1316 SetSlot(klass_index, kSlotOldClasses, klasses);
1317 }
1318 void SetNewClasses(jint klass_index,
1319 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)
1320 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1321 SetSlot(klass_index, kSlotNewClasses, klasses);
1322 }
Alex Light8c889d22017-02-06 13:58:27 -08001323 int32_t Length() const REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light0e692732017-01-10 15:00:05 -08001324 return arr_->GetLength() / kNumSlots;
1325 }
1326
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001327 std::vector<Redefiner::ClassRedefinition>* GetRedefinitions()
1328 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1329 return redefinitions_;
1330 }
1331
1332 bool operator==(const RedefinitionDataHolder& other) const
1333 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1334 return arr_.Get() == other.arr_.Get();
1335 }
1336
1337 bool operator!=(const RedefinitionDataHolder& other) const
1338 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1339 return !(*this == other);
1340 }
1341
1342 RedefinitionDataIter begin() REQUIRES_SHARED(art::Locks::mutator_lock_);
1343 RedefinitionDataIter end() REQUIRES_SHARED(art::Locks::mutator_lock_);
1344
Alex Light0e692732017-01-10 15:00:05 -08001345 private:
Alex Light8c889d22017-02-06 13:58:27 -08001346 mutable art::Handle<art::mirror::ObjectArray<art::mirror::Object>> arr_;
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001347 std::vector<Redefiner::ClassRedefinition>* redefinitions_;
Alex Light0e692732017-01-10 15:00:05 -08001348
Vladimir Markod93e3742018-07-18 10:58:13 +01001349 art::ObjPtr<art::mirror::Object> GetSlot(jint klass_index, DataSlot slot) const
1350 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light0e692732017-01-10 15:00:05 -08001351 DCHECK_LT(klass_index, Length());
1352 return arr_->Get((kNumSlots * klass_index) + slot);
1353 }
1354
1355 void SetSlot(jint klass_index,
1356 DataSlot slot,
1357 art::ObjPtr<art::mirror::Object> obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1358 DCHECK(!art::Runtime::Current()->IsActiveTransaction());
1359 DCHECK_LT(klass_index, Length());
1360 arr_->Set<false>((kNumSlots * klass_index) + slot, obj);
1361 }
1362
1363 DISALLOW_COPY_AND_ASSIGN(RedefinitionDataHolder);
1364};
1365
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001366class RedefinitionDataIter {
1367 public:
1368 RedefinitionDataIter(int32_t idx, RedefinitionDataHolder& holder) : idx_(idx), holder_(holder) {}
1369
1370 RedefinitionDataIter(const RedefinitionDataIter&) = default;
1371 RedefinitionDataIter(RedefinitionDataIter&&) = default;
1372 RedefinitionDataIter& operator=(const RedefinitionDataIter&) = default;
1373 RedefinitionDataIter& operator=(RedefinitionDataIter&&) = default;
1374
1375 bool operator==(const RedefinitionDataIter& other) const
1376 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1377 return idx_ == other.idx_ && holder_ == other.holder_;
1378 }
1379
1380 bool operator!=(const RedefinitionDataIter& other) const
1381 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1382 return !(*this == other);
1383 }
1384
1385 RedefinitionDataIter operator++() { // Value after modification.
1386 idx_++;
1387 return *this;
1388 }
1389
1390 RedefinitionDataIter operator++(int) {
1391 RedefinitionDataIter temp = *this;
1392 idx_++;
1393 return temp;
1394 }
1395
1396 RedefinitionDataIter operator+(ssize_t delta) const {
1397 RedefinitionDataIter temp = *this;
1398 temp += delta;
1399 return temp;
1400 }
1401
1402 RedefinitionDataIter& operator+=(ssize_t delta) {
1403 idx_ += delta;
1404 return *this;
1405 }
1406
Alex Light986914b2019-11-19 01:12:25 +00001407 // Compat for STL iterators.
1408 RedefinitionDataIter& operator*() {
1409 return *this;
1410 }
1411
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001412 Redefiner::ClassRedefinition& GetRedefinition() REQUIRES_SHARED(art::Locks::mutator_lock_) {
1413 return (*holder_.GetRedefinitions())[idx_];
1414 }
1415
1416 RedefinitionDataHolder& GetHolder() {
1417 return holder_;
1418 }
1419
Vladimir Markod93e3742018-07-18 10:58:13 +01001420 art::ObjPtr<art::mirror::ClassLoader> GetSourceClassLoader() const
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001421 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1422 return holder_.GetSourceClassLoader(idx_);
1423 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001424 art::ObjPtr<art::mirror::Object> GetJavaDexFile() const
1425 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001426 return holder_.GetJavaDexFile(idx_);
1427 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001428 art::ObjPtr<art::mirror::LongArray> GetNewDexFileCookie() const
1429 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001430 return holder_.GetNewDexFileCookie(idx_);
1431 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001432 art::ObjPtr<art::mirror::DexCache> GetNewDexCache() const
1433 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001434 return holder_.GetNewDexCache(idx_);
1435 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001436 art::ObjPtr<art::mirror::Class> GetMirrorClass() const
1437 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001438 return holder_.GetMirrorClass(idx_);
1439 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001440 art::ObjPtr<art::mirror::Object> GetOriginalDexFile() const
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001441 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light2f814aa2017-03-24 15:21:34 +00001442 return holder_.GetOriginalDexFile(idx_);
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001443 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001444 art::ObjPtr<art::mirror::PointerArray> GetOldObsoleteMethods() const
Alex Light1e3926a2017-04-07 10:38:06 -07001445 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1446 return holder_.GetOldObsoleteMethods(idx_);
1447 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001448 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> GetOldDexCaches() const
Alex Light1e3926a2017-04-07 10:38:06 -07001449 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1450 return holder_.GetOldDexCaches(idx_);
1451 }
1452
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001453 art::ObjPtr<art::mirror::Class> GetNewClassObject() const
1454 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1455 return holder_.GetNewClassObject(idx_);
1456 }
1457
Alex Light986914b2019-11-19 01:12:25 +00001458 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> GetOldInstanceObjects() const
1459 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1460 return holder_.GetOldInstanceObjects(idx_);
1461 }
1462 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> GetNewInstanceObjects() const
1463 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1464 return holder_.GetNewInstanceObjects(idx_);
1465 }
Alex Light270db1c2019-12-03 12:20:01 +00001466 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> GetOldClasses() const
1467 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1468 return holder_.GetOldClasses(idx_);
1469 }
1470 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> GetNewClasses() const
1471 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1472 return holder_.GetNewClasses(idx_);
1473 }
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001474 int32_t GetIndex() const {
1475 return idx_;
1476 }
1477
1478 void SetSourceClassLoader(art::mirror::ClassLoader* loader)
1479 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1480 holder_.SetSourceClassLoader(idx_, loader);
1481 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001482 void SetJavaDexFile(art::ObjPtr<art::mirror::Object> dexfile)
1483 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001484 holder_.SetJavaDexFile(idx_, dexfile);
1485 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001486 void SetNewDexFileCookie(art::ObjPtr<art::mirror::LongArray> cookie)
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001487 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1488 holder_.SetNewDexFileCookie(idx_, cookie);
1489 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001490 void SetNewDexCache(art::ObjPtr<art::mirror::DexCache> cache)
1491 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001492 holder_.SetNewDexCache(idx_, cache);
1493 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001494 void SetMirrorClass(art::ObjPtr<art::mirror::Class> klass)
1495 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001496 holder_.SetMirrorClass(idx_, klass);
1497 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001498 void SetOriginalDexFile(art::ObjPtr<art::mirror::Object> bytes)
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001499 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light2f814aa2017-03-24 15:21:34 +00001500 holder_.SetOriginalDexFile(idx_, bytes);
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001501 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001502 void SetOldObsoleteMethods(art::ObjPtr<art::mirror::PointerArray> methods)
Alex Light1e3926a2017-04-07 10:38:06 -07001503 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1504 holder_.SetOldObsoleteMethods(idx_, methods);
1505 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001506 void SetOldDexCaches(art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> caches)
Alex Light1e3926a2017-04-07 10:38:06 -07001507 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1508 holder_.SetOldDexCaches(idx_, caches);
1509 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001510 void SetNewClassObject(art::ObjPtr<art::mirror::Class> klass)
1511 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1512 holder_.SetNewClassObject(idx_, klass);
1513 }
Alex Light986914b2019-11-19 01:12:25 +00001514 void SetOldInstanceObjects(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)
1515 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1516 holder_.SetOldInstanceObjects(idx_, objs);
1517 }
1518 void SetNewInstanceObjects(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)
1519 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1520 holder_.SetNewInstanceObjects(idx_, objs);
1521 }
Alex Light270db1c2019-12-03 12:20:01 +00001522 void SetOldClasses(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)
1523 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1524 holder_.SetOldClasses(idx_, klasses);
1525 }
1526 void SetNewClasses(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)
1527 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1528 holder_.SetNewClasses(idx_, klasses);
1529 }
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001530
1531 private:
1532 int32_t idx_;
1533 RedefinitionDataHolder& holder_;
1534};
1535
1536RedefinitionDataIter RedefinitionDataHolder::begin() {
1537 return RedefinitionDataIter(0, *this);
1538}
1539
1540RedefinitionDataIter RedefinitionDataHolder::end() {
1541 return RedefinitionDataIter(Length(), *this);
1542}
1543
1544bool Redefiner::ClassRedefinition::CheckVerification(const RedefinitionDataIter& iter) {
Alex Light8c889d22017-02-06 13:58:27 -08001545 DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
1546 art::StackHandleScope<2> hs(driver_->self_);
1547 std::string error;
1548 // TODO Make verification log level lower
Andreas Gampe6d7abbd2017-04-24 13:19:09 -07001549 art::verifier::FailureKind failure =
Andreas Gampea43ba3d2019-03-13 15:49:20 -07001550 art::verifier::ClassVerifier::VerifyClass(driver_->self_,
1551 dex_file_.get(),
1552 hs.NewHandle(iter.GetNewDexCache()),
1553 hs.NewHandle(GetClassLoader()),
1554 /*class_def=*/ dex_file_->GetClassDef(0),
1555 /*callbacks=*/ nullptr,
1556 /*allow_soft_failures=*/ true,
1557 /*log_level=*/
1558 art::verifier::HardFailLogMode::kLogWarning,
1559 art::Runtime::Current()->GetTargetSdkVersion(),
1560 &error);
Alex Light53330612017-10-04 15:29:53 -07001561 switch (failure) {
1562 case art::verifier::FailureKind::kNoFailure:
Alex Lightb1eebde2019-10-22 16:30:47 +00001563 // TODO It is possible that by doing redefinition previous NO_COMPILE verification failures
1564 // were fixed. It would be nice to reflect this in the new implementations.
1565 return true;
Alex Light53330612017-10-04 15:29:53 -07001566 case art::verifier::FailureKind::kSoftFailure:
Alex Lightb1eebde2019-10-22 16:30:47 +00001567 // Soft failures might require interpreter on some methods. It won't prevent redefinition but
1568 // it does mean we need to run the verifier again and potentially update method flags after
1569 // performing the swap.
1570 needs_reverify_ = true;
Alex Light53330612017-10-04 15:29:53 -07001571 return true;
1572 case art::verifier::FailureKind::kHardFailure: {
1573 RecordFailure(ERR(FAILS_VERIFICATION), "Failed to verify class. Error was: " + error);
1574 return false;
1575 }
Alex Light8c889d22017-02-06 13:58:27 -08001576 }
Alex Light8c889d22017-02-06 13:58:27 -08001577}
1578
Alex Light1babae02017-02-01 15:35:34 -08001579// Looks through the previously allocated cookies to see if we need to update them with another new
1580// dexfile. This is so that even if multiple classes with the same classloader are redefined at
1581// once they are all added to the classloader.
1582bool Redefiner::ClassRedefinition::AllocateAndRememberNewDexFileCookie(
Alex Light1babae02017-02-01 15:35:34 -08001583 art::Handle<art::mirror::ClassLoader> source_class_loader,
1584 art::Handle<art::mirror::Object> dex_file_obj,
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001585 /*out*/RedefinitionDataIter* cur_data) {
Alex Light1babae02017-02-01 15:35:34 -08001586 art::StackHandleScope<2> hs(driver_->self_);
1587 art::MutableHandle<art::mirror::LongArray> old_cookie(
1588 hs.NewHandle<art::mirror::LongArray>(nullptr));
1589 bool has_older_cookie = false;
1590 // See if we already have a cookie that a previous redefinition got from the same classloader.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001591 for (auto old_data = cur_data->GetHolder().begin(); old_data != *cur_data; ++old_data) {
1592 if (old_data.GetSourceClassLoader() == source_class_loader.Get()) {
Alex Light1babae02017-02-01 15:35:34 -08001593 // Since every instance of this classloader should have the same cookie associated with it we
1594 // can stop looking here.
1595 has_older_cookie = true;
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001596 old_cookie.Assign(old_data.GetNewDexFileCookie());
Alex Light1babae02017-02-01 15:35:34 -08001597 break;
1598 }
1599 }
1600 if (old_cookie.IsNull()) {
1601 // No older cookie. Get it directly from the dex_file_obj
1602 // We should not have seen this classloader elsewhere.
1603 CHECK(!has_older_cookie);
1604 old_cookie.Assign(ClassLoaderHelper::GetDexFileCookie(dex_file_obj));
1605 }
1606 // Use the old cookie to generate the new one with the new DexFile* added in.
1607 art::Handle<art::mirror::LongArray>
1608 new_cookie(hs.NewHandle(ClassLoaderHelper::AllocateNewDexFileCookie(driver_->self_,
1609 old_cookie,
1610 dex_file_.get())));
1611 // Make sure the allocation worked.
1612 if (new_cookie.IsNull()) {
1613 return false;
1614 }
1615
1616 // Save the cookie.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001617 cur_data->SetNewDexFileCookie(new_cookie.Get());
Alex Light1babae02017-02-01 15:35:34 -08001618 // If there are other copies of this same classloader we need to make sure that we all have the
1619 // same cookie.
1620 if (has_older_cookie) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001621 for (auto old_data = cur_data->GetHolder().begin(); old_data != *cur_data; ++old_data) {
Alex Light1babae02017-02-01 15:35:34 -08001622 // We will let the GC take care of the cookie we allocated for this one.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001623 if (old_data.GetSourceClassLoader() == source_class_loader.Get()) {
1624 old_data.SetNewDexFileCookie(new_cookie.Get());
Alex Light1babae02017-02-01 15:35:34 -08001625 }
1626 }
1627 }
1628
1629 return true;
1630}
1631
Alex Light986914b2019-11-19 01:12:25 +00001632bool Redefiner::ClassRedefinition::CollectAndCreateNewInstances(
1633 /*out*/ RedefinitionDataIter* cur_data) {
1634 if (!IsStructuralRedefinition()) {
1635 return true;
1636 }
1637 art::VariableSizedHandleScope hs(driver_->self_);
1638 art::Handle<art::mirror::Class> old_klass(hs.NewHandle(cur_data->GetMirrorClass()));
1639 std::vector<art::Handle<art::mirror::Object>> old_instances;
Alex Light270db1c2019-12-03 12:20:01 +00001640 std::vector<art::Handle<art::mirror::Class>> old_types;
Alex Light986914b2019-11-19 01:12:25 +00001641 art::gc::Heap* heap = driver_->runtime_->GetHeap();
Alex Light270db1c2019-12-03 12:20:01 +00001642 auto is_subtype = [&](art::mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1643 // We've already waited for class defines to be finished and paused them. All classes should be
1644 // either resolved or error. We don't need to do anything with error classes, since they cannot
1645 // be accessed in any observable way.
1646 return obj->IsClass() && obj->AsClass()->IsResolved() &&
1647 old_klass->IsAssignableFrom(obj->AsClass());
1648 };
Alex Light986914b2019-11-19 01:12:25 +00001649 auto is_instance = [&](art::mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light270db1c2019-12-03 12:20:01 +00001650 return obj->InstanceOf(old_klass.Get());
Alex Light986914b2019-11-19 01:12:25 +00001651 };
1652 heap->VisitObjects([&](art::mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1653 if (is_instance(obj)) {
Alex Light986914b2019-11-19 01:12:25 +00001654 old_instances.push_back(hs.NewHandle(obj));
Alex Light270db1c2019-12-03 12:20:01 +00001655 } else if (is_subtype(obj)) {
1656 old_types.push_back(hs.NewHandle(obj->AsClass()));
Alex Light986914b2019-11-19 01:12:25 +00001657 }
1658 });
1659 VLOG(plugin) << "Collected " << old_instances.size() << " instances to recreate!";
Alex Light270db1c2019-12-03 12:20:01 +00001660 VLOG(plugin) << "Found " << old_types.size() << " types that are/are subtypes of "
1661 << old_klass->PrettyClass();
1662
1663 art::Handle<art::mirror::Class> cls_array_class(
1664 hs.NewHandle(art::GetClassRoot<art::mirror::ObjectArray<art::mirror::Class>>(
1665 driver_->runtime_->GetClassLinker())));
1666 art::Handle<art::mirror::ObjectArray<art::mirror::Class>> old_classes_arr(
1667 hs.NewHandle(art::mirror::ObjectArray<art::mirror::Class>::Alloc(
1668 driver_->self_, cls_array_class.Get(), old_types.size())));
1669 if (old_classes_arr.IsNull()) {
1670 driver_->self_->AssertPendingOOMException();
1671 driver_->self_->ClearException();
1672 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate old_classes arrays!");
1673 return false;
1674 }
1675 // Sort the old_types topologically.
1676 {
1677 art::ScopedAssertNoThreadSuspension sants("Sort classes");
1678 auto count_distance =
1679 [&](art::ObjPtr<art::mirror::Class> c) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1680 uint32_t res = 0;
1681 while (c != old_klass.Get()) {
1682 DCHECK_NE(c, art::GetClassRoot<art::mirror::Object>());
1683 res++;
1684 c = c->GetSuperClass();
1685 }
1686 return res;
1687 };
1688 auto compare_handles = [&](auto l, auto r) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1689 return count_distance(l.Get()) < count_distance(r.Get());
1690 };
1691 // Sort them by the distance to the base-class. This ensures that any class occurs before any of
1692 // its subtypes.
1693 std::sort(old_types.begin(), old_types.end(), compare_handles);
1694 }
1695 for (uint32_t i = 0; i < old_types.size(); ++i) {
1696 old_classes_arr->Set(i, old_types[i].Get());
1697 }
1698 cur_data->SetOldClasses(old_classes_arr.Get());
1699 art::Handle<art::mirror::ObjectArray<art::mirror::Class>> new_classes_arr(
1700 hs.NewHandle(art::mirror::ObjectArray<art::mirror::Class>::Alloc(
1701 driver_->self_, cls_array_class.Get(), old_types.size())));
1702 if (new_classes_arr.IsNull()) {
1703 driver_->self_->AssertPendingOOMException();
1704 driver_->self_->ClearException();
1705 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate new_classes arrays!");
1706 return false;
1707 }
1708 art::MutableHandle<art::mirror::DexCache> dch(hs.NewHandle<art::mirror::DexCache>(nullptr));
1709 art::MutableHandle<art::mirror::Class> superclass(hs.NewHandle<art::mirror::Class>(nullptr));
1710 for (size_t i = 0; i < old_types.size(); i++) {
1711 art::Handle<art::mirror::Class>& old_class = old_types[i];
1712 if (old_class.Get() == cur_data->GetMirrorClass()) {
1713 CHECK_EQ(i, 0u) << "original class not at index 0. Bad sort!";
1714 new_classes_arr->Set(i, cur_data->GetNewClassObject());
1715 continue;
1716 } else {
1717 auto old_super = std::find_if(old_types.begin(),
1718 old_types.begin() + i,
1719 [&](art::Handle<art::mirror::Class>& v)
1720 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1721 return v.Get() == old_class->GetSuperClass();
1722 });
1723 // Only the GetMirrorClass should not be in this list.
1724 CHECK(old_super != old_types.begin() + i)
1725 << "from first " << i << " could not find super of " << old_class->PrettyClass()
1726 << " expected to find " << old_class->GetSuperClass()->PrettyClass();
1727 superclass.Assign(new_classes_arr->Get(std::distance(old_types.begin(), old_super)));
1728 dch.Assign(old_class->GetDexCache());
1729 art::ObjPtr<art::mirror::Class> new_class(
1730 AllocateNewClassObject(old_class, superclass, dch, old_class->GetDexClassDefIndex()));
1731 if (new_class == nullptr) {
1732 return false;
1733 }
1734 new_classes_arr->Set(i, new_class);
1735 }
1736 }
1737 cur_data->SetNewClasses(new_classes_arr.Get());
Alex Light986914b2019-11-19 01:12:25 +00001738
1739 art::Handle<art::mirror::Class> obj_array_class(
1740 hs.NewHandle(art::GetClassRoot<art::mirror::ObjectArray<art::mirror::Object>>(
1741 driver_->runtime_->GetClassLinker())));
1742 art::Handle<art::mirror::ObjectArray<art::mirror::Object>> old_instances_arr(
1743 hs.NewHandle(art::mirror::ObjectArray<art::mirror::Object>::Alloc(
1744 driver_->self_, obj_array_class.Get(), old_instances.size())));
1745 if (old_instances_arr.IsNull()) {
1746 driver_->self_->AssertPendingOOMException();
1747 driver_->self_->ClearException();
1748 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate old_instance arrays!");
1749 return false;
1750 }
1751 for (uint32_t i = 0; i < old_instances.size(); ++i) {
1752 old_instances_arr->Set(i, old_instances[i].Get());
1753 }
1754 cur_data->SetOldInstanceObjects(old_instances_arr.Get());
1755
1756 art::Handle<art::mirror::ObjectArray<art::mirror::Object>> new_instances_arr(
1757 hs.NewHandle(art::mirror::ObjectArray<art::mirror::Object>::Alloc(
1758 driver_->self_, obj_array_class.Get(), old_instances.size())));
1759 if (new_instances_arr.IsNull()) {
1760 driver_->self_->AssertPendingOOMException();
1761 driver_->self_->ClearException();
1762 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate new_instance arrays!");
1763 return false;
1764 }
Alex Light270db1c2019-12-03 12:20:01 +00001765 for (auto pair : art::ZipCount(art::IterationRange(old_instances.begin(), old_instances.end()))) {
1766 art::Handle<art::mirror::Object> hinstance(pair.first);
1767 int32_t i = pair.second;
1768 auto iterator = art::ZipLeft(old_classes_arr.Iterate<art::mirror::Class>(),
1769 new_classes_arr.Iterate<art::mirror::Class>());
1770 auto [_, new_type] =
1771 *(std::find_if(iterator.begin(),
1772 iterator.end(),
1773 [&](auto class_pair) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1774 return class_pair.first == hinstance->GetClass();
1775 }));
1776 art::ObjPtr<art::mirror::Object> new_instance(new_type->AllocObject(driver_->self_));
Alex Light986914b2019-11-19 01:12:25 +00001777 if (new_instance.IsNull()) {
1778 driver_->self_->AssertPendingOOMException();
1779 driver_->self_->ClearException();
1780 std::string msg(
1781 StringPrintf("Could not allocate instance %d of %zu", i, old_instances.size()));
1782 RecordFailure(ERR(OUT_OF_MEMORY), msg);
1783 return false;
1784 }
1785 new_instances_arr->Set(i, new_instance);
1786 }
1787 cur_data->SetNewInstanceObjects(new_instances_arr.Get());
1788 return true;
1789}
1790
Alex Lighta7e38d82017-01-19 14:57:28 -08001791bool Redefiner::ClassRedefinition::FinishRemainingAllocations(
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001792 /*out*/RedefinitionDataIter* cur_data) {
Alex Light7916f202017-01-27 09:00:15 -08001793 art::ScopedObjectAccessUnchecked soa(driver_->self_);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001794 art::StackHandleScope<4> hs(driver_->self_);
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001795 cur_data->SetMirrorClass(GetMirrorClass());
Alex Lighta7e38d82017-01-19 14:57:28 -08001796 // This shouldn't allocate
1797 art::Handle<art::mirror::ClassLoader> loader(hs.NewHandle(GetClassLoader()));
Alex Light7916f202017-01-27 09:00:15 -08001798 // The bootclasspath is handled specially so it doesn't have a j.l.DexFile.
1799 if (!art::ClassLinker::IsBootClassLoader(soa, loader.Get())) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001800 cur_data->SetSourceClassLoader(loader.Get());
Alex Light7916f202017-01-27 09:00:15 -08001801 art::Handle<art::mirror::Object> dex_file_obj(hs.NewHandle(
1802 ClassLoaderHelper::FindSourceDexFileObject(driver_->self_, loader)));
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001803 cur_data->SetJavaDexFile(dex_file_obj.Get());
Andreas Gampefa4333d2017-02-14 11:10:34 -08001804 if (dex_file_obj == nullptr) {
Alex Light7916f202017-01-27 09:00:15 -08001805 RecordFailure(ERR(INTERNAL), "Unable to find dex file!");
1806 return false;
1807 }
Alex Light1babae02017-02-01 15:35:34 -08001808 // Allocate the new dex file cookie.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001809 if (!AllocateAndRememberNewDexFileCookie(loader, dex_file_obj, cur_data)) {
Alex Light7916f202017-01-27 09:00:15 -08001810 driver_->self_->AssertPendingOOMException();
1811 driver_->self_->ClearException();
1812 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate dex file array for class loader");
1813 return false;
1814 }
Alex Lighta7e38d82017-01-19 14:57:28 -08001815 }
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001816 cur_data->SetNewDexCache(CreateNewDexCache(loader));
1817 if (cur_data->GetNewDexCache() == nullptr) {
Vladimir Markocd556b02017-02-03 11:47:34 +00001818 driver_->self_->AssertPendingException();
Alex Lighta7e38d82017-01-19 14:57:28 -08001819 driver_->self_->ClearException();
1820 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate DexCache");
1821 return false;
1822 }
1823
1824 // We won't always need to set this field.
Alex Light2f814aa2017-03-24 15:21:34 +00001825 cur_data->SetOriginalDexFile(AllocateOrGetOriginalDexFile());
1826 if (cur_data->GetOriginalDexFile() == nullptr) {
Alex Lighta7e38d82017-01-19 14:57:28 -08001827 driver_->self_->AssertPendingOOMException();
1828 driver_->self_->ClearException();
1829 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate array for original dex file");
1830 return false;
1831 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001832 if (added_fields_ || added_methods_) {
1833 art::Handle<art::mirror::Class> nc(hs.NewHandle(
1834 AllocateNewClassObject(hs.NewHandle(cur_data->GetNewDexCache()))));
1835 if (nc.IsNull()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001836 return false;
1837 }
1838
1839 cur_data->SetNewClassObject(nc.Get());
Alex Light24627892019-11-06 10:28:21 -08001840 // We really want to be able to resolve to the new class-object using this dex-cache for
1841 // verification work. Since we haven't put it in the class-table yet we wll just manually add it
1842 // to the dex-cache.
1843 // TODO: We should maybe do this in a better spot.
1844 cur_data->GetNewDexCache()->SetResolvedType(nc->GetDexTypeIndex(), nc.Get());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001845 }
Alex Lighta7e38d82017-01-19 14:57:28 -08001846 return true;
1847}
1848
Alex Light270db1c2019-12-03 12:20:01 +00001849uint32_t Redefiner::ClassRedefinition::GetNewClassSize(art::ClassAccessor& accessor) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001850 uint32_t num_8bit_static_fields = 0;
1851 uint32_t num_16bit_static_fields = 0;
1852 uint32_t num_32bit_static_fields = 0;
1853 uint32_t num_64bit_static_fields = 0;
1854 uint32_t num_ref_static_fields = 0;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001855 for (const art::ClassAccessor::Field& f : accessor.GetStaticFields()) {
Alex Light270db1c2019-12-03 12:20:01 +00001856 std::string_view desc(accessor.GetDexFile().GetFieldTypeDescriptor(
1857 accessor.GetDexFile().GetFieldId(f.GetIndex())));
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001858 if (desc[0] == 'L' || desc[0] == '[') {
1859 num_ref_static_fields++;
1860 } else if (desc == "Z" || desc == "B") {
1861 num_8bit_static_fields++;
1862 } else if (desc == "C" || desc == "S") {
1863 num_16bit_static_fields++;
1864 } else if (desc == "I" || desc == "F") {
1865 num_32bit_static_fields++;
1866 } else if (desc == "J" || desc == "D") {
1867 num_64bit_static_fields++;
1868 } else {
1869 LOG(FATAL) << "Unknown type descriptor! " << desc;
1870 }
1871 }
1872
Alex Light270db1c2019-12-03 12:20:01 +00001873 return art::mirror::Class::ComputeClassSize(/*has_embedded_vtable=*/ false,
1874 /*num_vtable_entries=*/ 0,
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001875 num_8bit_static_fields,
1876 num_16bit_static_fields,
1877 num_32bit_static_fields,
1878 num_64bit_static_fields,
1879 num_ref_static_fields,
1880 art::kRuntimePointerSize);
1881}
1882
1883art::ObjPtr<art::mirror::Class>
1884Redefiner::ClassRedefinition::AllocateNewClassObject(art::Handle<art::mirror::DexCache> cache) {
Alex Light270db1c2019-12-03 12:20:01 +00001885 art::StackHandleScope<2> hs(driver_->self_);
1886 art::Handle<art::mirror::Class> old_class(hs.NewHandle(GetMirrorClass()));
1887 art::Handle<art::mirror::Class> super_class(hs.NewHandle(old_class->GetSuperClass()));
1888 return AllocateNewClassObject(old_class, super_class, cache, /*dex_class_def_index*/0);
1889}
1890
1891art::ObjPtr<art::mirror::Class> Redefiner::ClassRedefinition::AllocateNewClassObject(
1892 art::Handle<art::mirror::Class> old_class,
1893 art::Handle<art::mirror::Class> super_class,
1894 art::Handle<art::mirror::DexCache> cache,
1895 uint16_t dex_class_def_index) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001896 // This is a stripped down DefineClass. We don't want to use DefineClass directly because it needs
1897 // to perform a lot of extra steps to tell the ClassTable and the jit and everything about a new
1898 // class. For now we will need to rely on our tests catching any issues caused by changes in how
1899 // class_linker sets up classes.
1900 // TODO Unify/move this into ClassLinker maybe.
Alex Light270db1c2019-12-03 12:20:01 +00001901 art::StackHandleScope<3> hs(driver_->self_);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001902 art::ClassLinker* linker = driver_->runtime_->GetClassLinker();
Alex Light270db1c2019-12-03 12:20:01 +00001903 const art::DexFile* dex_file = cache->GetDexFile();
1904 art::ClassAccessor accessor(*dex_file, dex_class_def_index);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001905 art::Handle<art::mirror::Class> new_class(hs.NewHandle(linker->AllocClass(
Alex Light270db1c2019-12-03 12:20:01 +00001906 driver_->self_, GetNewClassSize(accessor))));
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001907 if (new_class.IsNull()) {
1908 driver_->self_->AssertPendingOOMException();
Alex Light270db1c2019-12-03 12:20:01 +00001909 RecordFailure(
1910 ERR(OUT_OF_MEMORY),
1911 "Unable to allocate class object for redefinition of " + old_class->PrettyClass());
1912 driver_->self_->ClearException();
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001913 return nullptr;
1914 }
1915 new_class->SetDexCache(cache.Get());
Alex Light270db1c2019-12-03 12:20:01 +00001916 linker->SetupClass(*dex_file,
1917 dex_file->GetClassDef(dex_class_def_index),
1918 new_class,
1919 old_class->GetClassLoader());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001920
1921 // Make sure we are ready for linking. The lock isn't really needed since this isn't visible to
1922 // other threads but the linker expects it.
1923 art::ObjectLock<art::mirror::Class> lock(driver_->self_, new_class);
1924 new_class->SetClinitThreadId(driver_->self_->GetTid());
1925 // Make sure we have a valid empty iftable even if there are errors.
1926 new_class->SetIfTable(art::GetClassRoot<art::mirror::Object>(linker)->GetIfTable());
Alex Light270db1c2019-12-03 12:20:01 +00001927 linker->LoadClass(
1928 driver_->self_, *dex_file, dex_file->GetClassDef(dex_class_def_index), new_class);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001929 // NB. We know the interfaces and supers didn't change! :)
1930 art::MutableHandle<art::mirror::Class> linked_class(hs.NewHandle<art::mirror::Class>(nullptr));
1931 art::Handle<art::mirror::ObjectArray<art::mirror::Class>> proxy_ifaces(
1932 hs.NewHandle<art::mirror::ObjectArray<art::mirror::Class>>(nullptr));
1933 // No changing hierarchy so everything is loaded.
Alex Light270db1c2019-12-03 12:20:01 +00001934 new_class->SetSuperClass(super_class.Get());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001935 art::mirror::Class::SetStatus(new_class, art::ClassStatus::kLoaded, nullptr);
1936 if (!linker->LinkClass(driver_->self_, nullptr, new_class, proxy_ifaces, &linked_class)) {
Alex Light270db1c2019-12-03 12:20:01 +00001937 std::ostringstream oss;
1938 oss << "failed to link class due to "
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001939 << (driver_->self_->IsExceptionPending() ? driver_->self_->GetException()->Dump()
1940 : " unknown");
Alex Light270db1c2019-12-03 12:20:01 +00001941 RecordFailure(ERR(INTERNAL), oss.str());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001942 driver_->self_->ClearException();
1943 return nullptr;
1944 }
Alex Light270db1c2019-12-03 12:20:01 +00001945 // Everything is already resolved.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001946 art::ObjectLock<art::mirror::Class> objlock(driver_->self_, linked_class);
Alex Lightfb119572019-09-18 15:04:53 -07001947 // Mark the class as initialized.
Alex Light270db1c2019-12-03 12:20:01 +00001948 CHECK(old_class->IsResolved())
1949 << "Attempting to redefine an unresolved class " << old_class->PrettyClass()
Alex Lightfb119572019-09-18 15:04:53 -07001950 << " status=" << old_class->GetStatus();
Alex Light270db1c2019-12-03 12:20:01 +00001951 CHECK(linked_class->IsResolved());
1952 if (old_class->WasVerificationAttempted()) {
1953 // Match verification-attempted flag
1954 linked_class->SetVerificationAttempted();
1955 }
1956 if (old_class->ShouldSkipHiddenApiChecks()) {
1957 // Match skip hiddenapi flag
1958 linked_class->SetSkipHiddenApiChecks();
1959 }
1960 if (old_class->IsInitialized()) {
1961 // We already verified the class earlier. No need to do it again.
1962 linker->ForceClassInitialized(driver_->self_, linked_class);
1963 } else if (old_class->GetStatus() > linked_class->GetStatus()) {
1964 // We want to match the old status.
1965 art::mirror::Class::SetStatus(linked_class, old_class->GetStatus(), driver_->self_);
1966 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001967 // Make sure we have ext-data space for method & field ids. We won't know if we need them until
1968 // it's too late to create them.
1969 // TODO We might want to remove these arrays if they're not needed.
Alex Lightbc19b752019-12-02 18:54:13 +00001970 if (!art::mirror::Class::EnsureInstanceFieldIds(linked_class) ||
1971 !art::mirror::Class::EnsureStaticFieldIds(linked_class) ||
1972 !art::mirror::Class::EnsureMethodIds(linked_class)) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001973 driver_->self_->AssertPendingOOMException();
1974 driver_->self_->ClearException();
Alex Light270db1c2019-12-03 12:20:01 +00001975 RecordFailure(
1976 ERR(OUT_OF_MEMORY),
1977 "Unable to allocate jni-id arrays for redefinition of " + old_class->PrettyClass());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001978 return nullptr;
1979 }
1980 // Finish setting up methods.
1981 linked_class->VisitMethods([&](art::ArtMethod* m) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1982 linker->SetEntryPointsToInterpreter(m);
1983 m->SetNotIntrinsic();
1984 DCHECK(m->IsCopied() || m->GetDeclaringClass() == linked_class.Get())
1985 << m->PrettyMethod()
1986 << " m->GetDeclaringClass(): " << m->GetDeclaringClass()->PrettyClass()
1987 << " != linked_class.Get(): " << linked_class->PrettyClass();
1988 }, art::kRuntimePointerSize);
1989 if (art::kIsDebugBuild) {
1990 linked_class->VisitFields([&](art::ArtField* f) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1991 DCHECK_EQ(f->GetDeclaringClass(), linked_class.Get());
1992 });
1993 }
Alex Light270db1c2019-12-03 12:20:01 +00001994 // Reset ClinitThreadId back to the thread that loaded the old class. This is needed if we are in
1995 // the middle of initializing a class.
1996 linked_class->SetClinitThreadId(old_class->GetClinitThreadId());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001997 return linked_class.Get();
1998}
1999
Alex Lighta26e3492017-06-27 17:55:37 -07002000void Redefiner::ClassRedefinition::UnregisterJvmtiBreakpoints() {
Vladimir Marko4617d582019-03-28 13:48:31 +00002001 BreakpointUtil::RemoveBreakpointsInClass(driver_->env_, GetMirrorClass().Ptr());
Alex Lighta26e3492017-06-27 17:55:37 -07002002}
2003
Alex Light5643caf2017-02-08 11:39:07 -08002004void Redefiner::ClassRedefinition::UnregisterBreakpoints() {
Alex Lighte34fe442018-02-21 17:35:55 -08002005 if (LIKELY(!art::Dbg::IsDebuggerActive())) {
2006 return;
2007 }
Alex Light5643caf2017-02-08 11:39:07 -08002008 art::JDWP::JdwpState* state = art::Dbg::GetJdwpState();
2009 if (state != nullptr) {
2010 state->UnregisterLocationEventsOnClass(GetMirrorClass());
2011 }
2012}
2013
2014void Redefiner::UnregisterAllBreakpoints() {
Alex Light5643caf2017-02-08 11:39:07 -08002015 for (Redefiner::ClassRedefinition& redef : redefinitions_) {
2016 redef.UnregisterBreakpoints();
Alex Lighte34fe442018-02-21 17:35:55 -08002017 redef.UnregisterJvmtiBreakpoints();
Alex Light5643caf2017-02-08 11:39:07 -08002018 }
2019}
2020
Alex Light0e692732017-01-10 15:00:05 -08002021bool Redefiner::CheckAllRedefinitionAreValid() {
2022 for (Redefiner::ClassRedefinition& redef : redefinitions_) {
2023 if (!redef.CheckRedefinitionIsValid()) {
2024 return false;
2025 }
2026 }
Alex Light270db1c2019-12-03 12:20:01 +00002027 if (std::any_of(
2028 redefinitions_.begin(),
2029 redefinitions_.end(),
2030 std::function<bool(ClassRedefinition&)>(&ClassRedefinition::IsStructuralRedefinition))) {
2031 return CheckClassHierarchy();
2032 }
Alex Light0e692732017-01-10 15:00:05 -08002033 return true;
2034}
2035
Alex Light270db1c2019-12-03 12:20:01 +00002036bool Redefiner::CheckClassHierarchy() {
2037 return std::all_of(
2038 redefinitions_.begin(),
2039 redefinitions_.end(),
2040 [&](ClassRedefinition& r) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2041 return std::none_of(
2042 redefinitions_.begin(),
2043 redefinitions_.end(),
2044 [&](ClassRedefinition& r2) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2045 bool related = &r2 != &r &&
2046 r2.GetMirrorClass()->IsAssignableFrom(r.GetMirrorClass()) &&
2047 r2.IsStructuralRedefinition();
2048 if (related) {
2049 std::ostringstream oss;
2050 oss << "Structurally redefining " << r2.GetMirrorClass()->PrettyClass()
2051 << " which is a superclass of " << r.GetMirrorClass()->PrettyClass()
2052 << ". This is not currently supported";
2053 r2.RecordFailure(ERR(INTERNAL), oss.str());
2054 }
2055 return related;
2056 });
2057 });
2058}
2059
Alex Light1e3926a2017-04-07 10:38:06 -07002060void Redefiner::RestoreObsoleteMethodMapsIfUnneeded(RedefinitionDataHolder& holder) {
2061 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2062 data.GetRedefinition().RestoreObsoleteMethodMapsIfUnneeded(&data);
2063 }
2064}
2065
2066bool Redefiner::EnsureAllClassAllocationsFinished(RedefinitionDataHolder& holder) {
2067 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2068 if (!data.GetRedefinition().EnsureClassAllocationsFinished(&data)) {
Alex Light0e692732017-01-10 15:00:05 -08002069 return false;
2070 }
2071 }
2072 return true;
2073}
2074
Alex Light986914b2019-11-19 01:12:25 +00002075bool Redefiner::CollectAndCreateNewInstances(RedefinitionDataHolder& holder) {
2076 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2077 // Allocate the data this redefinition requires.
2078 if (!data.GetRedefinition().CollectAndCreateNewInstances(&data)) {
2079 return false;
2080 }
2081 }
2082 return true;
2083}
2084
Alex Light0e692732017-01-10 15:00:05 -08002085bool Redefiner::FinishAllRemainingAllocations(RedefinitionDataHolder& holder) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002086 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
Alex Light0e692732017-01-10 15:00:05 -08002087 // Allocate the data this redefinition requires.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002088 if (!data.GetRedefinition().FinishRemainingAllocations(&data)) {
Alex Light0e692732017-01-10 15:00:05 -08002089 return false;
2090 }
Alex Light0e692732017-01-10 15:00:05 -08002091 }
2092 return true;
2093}
2094
2095void Redefiner::ClassRedefinition::ReleaseDexFile() {
Andreas Gampeafaf7f82018-10-16 11:32:38 -07002096 dex_file_.release(); // NOLINT b/117926937
Alex Light0e692732017-01-10 15:00:05 -08002097}
2098
2099void Redefiner::ReleaseAllDexFiles() {
2100 for (Redefiner::ClassRedefinition& redef : redefinitions_) {
2101 redef.ReleaseDexFile();
2102 }
2103}
2104
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002105bool Redefiner::CheckAllClassesAreVerified(RedefinitionDataHolder& holder) {
2106 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2107 if (!data.GetRedefinition().CheckVerification(data)) {
Alex Light8c889d22017-02-06 13:58:27 -08002108 return false;
2109 }
Alex Light8c889d22017-02-06 13:58:27 -08002110 }
2111 return true;
2112}
2113
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002114class ScopedDisableConcurrentAndMovingGc {
2115 public:
2116 ScopedDisableConcurrentAndMovingGc(art::gc::Heap* heap, art::Thread* self)
2117 : heap_(heap), self_(self) {
2118 if (heap_->IsGcConcurrentAndMoving()) {
2119 heap_->IncrementDisableMovingGC(self_);
2120 }
2121 }
2122
2123 ~ScopedDisableConcurrentAndMovingGc() {
2124 if (heap_->IsGcConcurrentAndMoving()) {
2125 heap_->DecrementDisableMovingGC(self_);
2126 }
2127 }
2128 private:
2129 art::gc::Heap* heap_;
2130 art::Thread* self_;
2131};
2132
Alex Light270db1c2019-12-03 12:20:01 +00002133class ClassDefinitionPauser : public art::ClassLoadCallback {
2134 public:
2135 explicit ClassDefinitionPauser(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_)
2136 : self_(self),
2137 is_running_(false),
2138 barrier_(0),
2139 release_mu_("SuspendClassDefinition lock", art::kGenericBottomLock),
2140 release_barrier_(0),
2141 release_cond_("SuspendClassDefinition condvar", release_mu_),
2142 count_(0),
2143 release_(false) {
2144 art::Locks::mutator_lock_->AssertSharedHeld(self_);
2145 }
2146 ~ClassDefinitionPauser() REQUIRES_SHARED(art::Locks::mutator_lock_) {
2147 art::Locks::mutator_lock_->AssertSharedHeld(self_);
2148 if (is_running_) {
2149 uint32_t count;
2150 // Wake up everything.
2151 {
2152 art::MutexLock mu(self_, release_mu_);
2153 release_ = true;
2154 count = count_;
2155 release_cond_.Broadcast(self_);
2156 }
2157 // Wait for all threads to leave this structs code.
2158 art::ScopedThreadSuspension sts(self_, art::ThreadState::kWaiting);
2159 VLOG(plugin) << "Resuming " << count << " threads paused before class-allocation!";
2160 release_barrier_.Increment(self_, count);
2161 }
2162 }
2163 void BeginDefineClass() override REQUIRES_SHARED(art::Locks::mutator_lock_) {
2164 art::Thread* this_thread = art::Thread::Current();
2165 if (this_thread == self_) {
2166 // Allow the redefining thread to do whatever.
2167 return;
2168 }
2169 if (this_thread->GetDefineClassCount() != 0) {
2170 // We are in the middle of a recursive define-class. Don't suspend now allow it to finish.
2171 VLOG(plugin) << "Recursive DefineClass in " << *this_thread
2172 << " allowed to proceed despite class-def pause initiated by " << *self_;
2173 return;
2174 }
2175 art::ScopedThreadSuspension sts(this_thread, art::ThreadState::kSuspended);
2176 {
2177 art::MutexLock mu(this_thread, release_mu_);
2178 if (release_) {
2179 // Count already retrieved, no need to pass.
2180 return;
2181 }
2182 VLOG(plugin) << "Suspending " << *this_thread << " due to class definition. class-def pause "
2183 << "initiated by " << *self_;
2184 count_++;
2185 while (!release_) {
2186 release_cond_.Wait(this_thread);
2187 }
2188 }
2189 release_barrier_.Pass(this_thread);
2190 }
2191 void EndDefineClass() override REQUIRES_SHARED(art::Locks::mutator_lock_) {
2192 art::Thread* this_thread = art::Thread::Current();
2193 if (this_thread == self_) {
2194 // Allow the redefining thread to do whatever.
2195 return;
2196 }
2197 if (this_thread->GetDefineClassCount() == 0) {
2198 // We are done with defining classes.
2199 barrier_.Pass(this_thread);
2200 }
2201 }
2202
2203 void ClassLoad(art::Handle<art::mirror::Class> klass ATTRIBUTE_UNUSED) override {}
2204 void ClassPrepare(art::Handle<art::mirror::Class> klass1 ATTRIBUTE_UNUSED,
2205 art::Handle<art::mirror::Class> klass2 ATTRIBUTE_UNUSED) override {}
2206
2207 void SetRunning() {
2208 is_running_ = true;
2209 }
2210 void WaitFor(uint32_t t) REQUIRES(!art::Locks::mutator_lock_) {
2211 barrier_.Increment(self_, t);
2212 }
2213
2214 private:
2215 art::Thread* self_;
2216 bool is_running_;
2217 art::Barrier barrier_;
2218 art::Mutex release_mu_;
2219 art::Barrier release_barrier_;
2220 art::ConditionVariable release_cond_;
2221 uint32_t count_ GUARDED_BY(release_mu_);
2222 bool release_;
2223};
2224
2225class ScopedSuspendClassLoading {
2226 public:
2227 ScopedSuspendClassLoading(art::Thread* self, art::Runtime* runtime, RedefinitionDataHolder& h)
2228 REQUIRES_SHARED(art::Locks::mutator_lock_)
2229 : self_(self), runtime_(runtime), paused_(false), pauser_(self_) {
2230 if (std::any_of(h.begin(), h.end(), [](auto r) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2231 return r.GetRedefinition().IsStructuralRedefinition();
2232 })) {
2233 VLOG(plugin) << "Pausing Class loading for structural redefinition.";
2234 paused_ = true;
2235 {
2236 art::ScopedThreadSuspension sts(self_, art::ThreadState::kNative);
2237 uint32_t in_progress_defines = 0;
2238 {
2239 art::ScopedSuspendAll ssa(__FUNCTION__);
2240 pauser_.SetRunning();
2241 runtime_->GetRuntimeCallbacks()->AddClassLoadCallback(&pauser_);
2242 art::MutexLock mu(self_, *art::Locks::thread_list_lock_);
2243 runtime_->GetThreadList()->ForEach([&](art::Thread* t) {
2244 if (t != self_ && t->GetDefineClassCount() != 0) {
2245 in_progress_defines++;
2246 }
2247 });
2248 VLOG(plugin) << "Waiting for " << in_progress_defines << " in progress class-loads to finish";
2249 }
2250 pauser_.WaitFor(in_progress_defines);
2251 }
2252 }
2253 }
2254 ~ScopedSuspendClassLoading() {
2255 if (paused_) {
2256 art::ScopedThreadSuspension sts(self_, art::ThreadState::kNative);
2257 art::ScopedSuspendAll ssa(__FUNCTION__);
2258 runtime_->GetRuntimeCallbacks()->RemoveClassLoadCallback(&pauser_);
2259 }
2260 }
2261
2262 private:
2263 art::Thread* self_;
2264 art::Runtime* runtime_;
2265 bool paused_;
2266 ClassDefinitionPauser pauser_;
2267};
2268
Alex Light986914b2019-11-19 01:12:25 +00002269class ScopedSuspendAllocations {
2270 public:
2271 ScopedSuspendAllocations(art::Runtime* runtime, RedefinitionDataHolder& h)
2272 REQUIRES_SHARED(art::Locks::mutator_lock_)
2273 : paused_(false) {
2274 if (std::any_of(h.begin(),
2275 h.end(),
2276 [](auto r) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2277 return r.GetRedefinition().IsStructuralRedefinition();
2278 })) {
2279 VLOG(plugin) << "Pausing allocations for structural redefinition.";
2280 paused_ = true;
2281 AllocationManager::Get()->PauseAllocations(art::Thread::Current());
2282 // Collect garbage so we don't need to recreate as much.
2283 runtime->GetHeap()->CollectGarbage(/*clear_soft_references=*/false);
2284 }
2285 }
2286
2287 ~ScopedSuspendAllocations() REQUIRES_SHARED(art::Locks::mutator_lock_) {
2288 if (paused_) {
2289 AllocationManager::Get()->ResumeAllocations(art::Thread::Current());
2290 }
2291 }
2292
2293 private:
2294 bool paused_;
2295
2296 DISALLOW_COPY_AND_ASSIGN(ScopedSuspendAllocations);
2297};
2298
Alex Lighta01de592016-11-15 10:43:06 -08002299jvmtiError Redefiner::Run() {
Alex Light0e692732017-01-10 15:00:05 -08002300 art::StackHandleScope<1> hs(self_);
2301 // Allocate an array to hold onto all java temporary objects associated with this redefinition.
2302 // We will let this be collected after the end of this function.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002303 RedefinitionDataHolder holder(&hs, runtime_, self_, &redefinitions_);
Alex Light0e692732017-01-10 15:00:05 -08002304 if (holder.IsNull()) {
2305 self_->AssertPendingOOMException();
2306 self_->ClearException();
2307 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate storage for temporaries");
2308 return result_;
2309 }
2310
Alex Lighta01de592016-11-15 10:43:06 -08002311 // First we just allocate the ClassExt and its fields that we need. These can be updated
2312 // atomically without any issues (since we allocate the map arrays as empty) so we don't bother
2313 // doing a try loop. The other allocations we need to ensure that nothing has changed in the time
2314 // between allocating them and pausing all threads before we can update them so we need to do a
2315 // try loop.
Alex Light0e692732017-01-10 15:00:05 -08002316 if (!CheckAllRedefinitionAreValid() ||
Alex Light1e3926a2017-04-07 10:38:06 -07002317 !EnsureAllClassAllocationsFinished(holder) ||
Alex Light8c889d22017-02-06 13:58:27 -08002318 !FinishAllRemainingAllocations(holder) ||
2319 !CheckAllClassesAreVerified(holder)) {
Alex Lighta01de592016-11-15 10:43:06 -08002320 return result_;
2321 }
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002322
Alex Light270db1c2019-12-03 12:20:01 +00002323 ScopedSuspendClassLoading suspend_class_load(self_, runtime_, holder);
Alex Light986914b2019-11-19 01:12:25 +00002324 ScopedSuspendAllocations suspend_alloc(runtime_, holder);
2325 if (!CollectAndCreateNewInstances(holder)) {
2326 return result_;
2327 }
2328
Alex Light5643caf2017-02-08 11:39:07 -08002329 // At this point we can no longer fail without corrupting the runtime state.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002330 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
Alex Light07f06212017-06-01 14:01:43 -07002331 art::ClassLinker* cl = runtime_->GetClassLinker();
2332 cl->RegisterExistingDexCache(data.GetNewDexCache(), data.GetSourceClassLoader());
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002333 if (data.GetSourceClassLoader() == nullptr) {
Mathieu Chartier0a19e212019-11-27 14:35:24 -08002334 cl->AppendToBootClassPath(self_, &data.GetRedefinition().GetDexFile());
Alex Light7916f202017-01-27 09:00:15 -08002335 }
Alex Light7916f202017-01-27 09:00:15 -08002336 }
Alex Light5643caf2017-02-08 11:39:07 -08002337 UnregisterAllBreakpoints();
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002338
Alex Lightc2d0c962019-10-23 14:14:25 -07002339 {
2340 // Disable GC and wait for it to be done if we are a moving GC. This is fine since we are done
2341 // allocating so no deadlocks.
2342 ScopedDisableConcurrentAndMovingGc sdcamgc(runtime_->GetHeap(), self_);
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002343
Alex Lightc2d0c962019-10-23 14:14:25 -07002344 // Do transition to final suspension
2345 // TODO We might want to give this its own suspended state!
2346 // TODO This isn't right. We need to change state without any chance of suspend ideally!
2347 art::ScopedThreadSuspension sts(self_, art::ThreadState::kNative);
2348 art::ScopedSuspendAll ssa("Final installation of redefined Classes!", /*long_suspend=*/true);
2349 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2350 art::ScopedAssertNoThreadSuspension nts("Updating runtime objects for redefinition");
2351 ClassRedefinition& redef = data.GetRedefinition();
2352 if (data.GetSourceClassLoader() != nullptr) {
2353 ClassLoaderHelper::UpdateJavaDexFile(data.GetJavaDexFile(), data.GetNewDexFileCookie());
2354 }
2355 redef.UpdateClass(data);
Alex Light7916f202017-01-27 09:00:15 -08002356 }
Alex Lightc2d0c962019-10-23 14:14:25 -07002357 RestoreObsoleteMethodMapsIfUnneeded(holder);
2358 // TODO We should check for if any of the redefined methods are intrinsic methods here and, if
2359 // any are, force a full-world deoptimization before finishing redefinition. If we don't do this
2360 // then methods that have been jitted prior to the current redefinition being applied might
2361 // continue to use the old versions of the intrinsics!
2362 // TODO Do the dex_file release at a more reasonable place. This works but it muddles who really
2363 // owns the DexFile and when ownership is transferred.
2364 ReleaseAllDexFiles();
Alex Light0e692732017-01-10 15:00:05 -08002365 }
Alex Lightb1eebde2019-10-22 16:30:47 +00002366 // By now the class-linker knows about all the classes so we can safetly retry verification and
2367 // update method flags.
2368 ReverifyClasses(holder);
Alex Lighta01de592016-11-15 10:43:06 -08002369 return OK;
2370}
2371
Alex Lightb1eebde2019-10-22 16:30:47 +00002372void Redefiner::ReverifyClasses(RedefinitionDataHolder& holder) {
Alex Lightb1eebde2019-10-22 16:30:47 +00002373 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2374 data.GetRedefinition().ReverifyClass(data);
2375 }
2376}
2377
2378void Redefiner::ClassRedefinition::ReverifyClass(const RedefinitionDataIter &cur_data) {
2379 if (!needs_reverify_) {
2380 return;
2381 }
2382 VLOG(plugin) << "Reverifying " << class_sig_ << " due to soft failures";
2383 std::string error;
2384 // TODO Make verification log level lower
2385 art::verifier::FailureKind failure =
2386 art::verifier::ClassVerifier::ReverifyClass(driver_->self_,
2387 cur_data.GetMirrorClass(),
2388 /*log_level=*/
2389 art::verifier::HardFailLogMode::kLogWarning,
2390 /*api_level=*/
2391 art::Runtime::Current()->GetTargetSdkVersion(),
2392 &error);
2393 CHECK_NE(failure, art::verifier::FailureKind::kHardFailure);
2394}
2395
Alex Light0e692732017-01-10 15:00:05 -08002396void Redefiner::ClassRedefinition::UpdateMethods(art::ObjPtr<art::mirror::Class> mclass,
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002397 const art::dex::ClassDef& class_def) {
Alex Light0e692732017-01-10 15:00:05 -08002398 art::ClassLinker* linker = driver_->runtime_->GetClassLinker();
Alex Lighta01de592016-11-15 10:43:06 -08002399 art::PointerSize image_pointer_size = linker->GetImagePointerSize();
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002400 const art::dex::TypeId& declaring_class_id = dex_file_->GetTypeId(class_def.class_idx_);
Alex Lighta01de592016-11-15 10:43:06 -08002401 const art::DexFile& old_dex_file = mclass->GetDexFile();
Alex Light200b9d72016-12-15 11:34:13 -08002402 // Update methods.
Alex Light00e475c2017-07-19 16:36:23 -07002403 for (art::ArtMethod& method : mclass->GetDeclaredMethods(image_pointer_size)) {
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002404 const art::dex::StringId* new_name_id = dex_file_->FindStringId(method.GetName());
Alex Lighta01de592016-11-15 10:43:06 -08002405 art::dex::TypeIndex method_return_idx =
2406 dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(method.GetReturnTypeDescriptor()));
2407 const auto* old_type_list = method.GetParameterTypeList();
2408 std::vector<art::dex::TypeIndex> new_type_list;
2409 for (uint32_t i = 0; old_type_list != nullptr && i < old_type_list->Size(); i++) {
2410 new_type_list.push_back(
2411 dex_file_->GetIndexForTypeId(
2412 *dex_file_->FindTypeId(
2413 old_dex_file.GetTypeDescriptor(
2414 old_dex_file.GetTypeId(
2415 old_type_list->GetTypeItem(i).type_idx_)))));
2416 }
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002417 const art::dex::ProtoId* proto_id = dex_file_->FindProtoId(method_return_idx, new_type_list);
Alex Lightdba61482016-12-21 08:20:29 -08002418 CHECK(proto_id != nullptr || old_type_list == nullptr);
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002419 const art::dex::MethodId* method_id = dex_file_->FindMethodId(declaring_class_id,
2420 *new_name_id,
2421 *proto_id);
Alex Lightdba61482016-12-21 08:20:29 -08002422 CHECK(method_id != nullptr);
Alex Lighta01de592016-11-15 10:43:06 -08002423 uint32_t dex_method_idx = dex_file_->GetIndexForMethodId(*method_id);
2424 method.SetDexMethodIndex(dex_method_idx);
2425 linker->SetEntryPointsToInterpreter(&method);
Alex Light200b9d72016-12-15 11:34:13 -08002426 method.SetCodeItemOffset(dex_file_->FindCodeItemOffset(class_def, dex_method_idx));
Alex Light7532d582017-02-13 16:36:06 -08002427 // Clear all the intrinsics related flags.
Orion Hodsoncfcc9cf2017-09-29 15:07:27 +01002428 method.SetNotIntrinsic();
Alex Lighta01de592016-11-15 10:43:06 -08002429 }
Alex Light200b9d72016-12-15 11:34:13 -08002430}
2431
Alex Light0e692732017-01-10 15:00:05 -08002432void Redefiner::ClassRedefinition::UpdateFields(art::ObjPtr<art::mirror::Class> mclass) {
Alex Light200b9d72016-12-15 11:34:13 -08002433 // TODO The IFields & SFields pointers should be combined like the methods_ arrays were.
2434 for (auto fields_iter : {mclass->GetIFields(), mclass->GetSFields()}) {
2435 for (art::ArtField& field : fields_iter) {
2436 std::string declaring_class_name;
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002437 const art::dex::TypeId* new_declaring_id =
Alex Light200b9d72016-12-15 11:34:13 -08002438 dex_file_->FindTypeId(field.GetDeclaringClass()->GetDescriptor(&declaring_class_name));
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002439 const art::dex::StringId* new_name_id = dex_file_->FindStringId(field.GetName());
2440 const art::dex::TypeId* new_type_id = dex_file_->FindTypeId(field.GetTypeDescriptor());
Alex Light200b9d72016-12-15 11:34:13 -08002441 CHECK(new_name_id != nullptr && new_type_id != nullptr && new_declaring_id != nullptr);
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002442 const art::dex::FieldId* new_field_id =
Alex Light200b9d72016-12-15 11:34:13 -08002443 dex_file_->FindFieldId(*new_declaring_id, *new_name_id, *new_type_id);
2444 CHECK(new_field_id != nullptr);
2445 // We only need to update the index since the other data in the ArtField cannot be updated.
2446 field.SetDexFieldIndex(dex_file_->GetIndexForFieldId(*new_field_id));
2447 }
2448 }
Alex Light200b9d72016-12-15 11:34:13 -08002449}
2450
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002451void Redefiner::ClassRedefinition::CollectNewFieldAndMethodMappings(
2452 const RedefinitionDataIter& data,
2453 std::map<art::ArtMethod*, art::ArtMethod*>* method_map,
2454 std::map<art::ArtField*, art::ArtField*>* field_map) {
Alex Light270db1c2019-12-03 12:20:01 +00002455 for (auto [new_cls, old_cls] :
2456 art::ZipLeft(data.GetNewClasses()->Iterate(), data.GetOldClasses()->Iterate())) {
2457 for (art::ArtField& f : old_cls->GetSFields()) {
2458 (*field_map)[&f] = new_cls->FindDeclaredStaticField(f.GetName(), f.GetTypeDescriptor());
2459 }
2460 for (art::ArtField& f : old_cls->GetIFields()) {
2461 (*field_map)[&f] = new_cls->FindDeclaredInstanceField(f.GetName(), f.GetTypeDescriptor());
2462 }
2463 auto new_methods = new_cls->GetMethods(art::kRuntimePointerSize);
2464 for (art::ArtMethod& m : old_cls->GetMethods(art::kRuntimePointerSize)) {
2465 // No support for finding methods in this way since it's generally not needed. Just do it the
2466 // easy way.
2467 auto nm_iter = std::find_if(
2468 new_methods.begin(),
2469 new_methods.end(),
2470 [&](art::ArtMethod& cand) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2471 return cand.GetNameView() == m.GetNameView() && cand.GetSignature() == m.GetSignature();
2472 });
2473 CHECK(nm_iter != new_methods.end())
2474 << "Could not find redefined version of " << m.PrettyMethod();
2475 (*method_map)[&m] = &(*nm_iter);
2476 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002477 }
2478}
2479
Alex Light986914b2019-11-19 01:12:25 +00002480static void CopyField(art::ObjPtr<art::mirror::Object> target,
2481 art::ArtField* new_field,
2482 art::ObjPtr<art::mirror::Object> source,
2483 art::ArtField& old_field) REQUIRES(art::Locks::mutator_lock_) {
2484 art::Primitive::Type ftype = old_field.GetTypeAsPrimitiveType();
2485 CHECK_EQ(ftype, new_field->GetTypeAsPrimitiveType())
2486 << old_field.PrettyField() << " vs " << new_field->PrettyField();
2487 if (ftype == art::Primitive::kPrimNot) {
2488 new_field->SetObject<false>(target, old_field.GetObject(source));
2489 } else {
2490 switch (ftype) {
2491#define UPDATE_FIELD(TYPE) \
2492 case art::Primitive::kPrim##TYPE: \
2493 new_field->Set##TYPE<false>(target, old_field.Get##TYPE(source)); \
2494 break
2495 UPDATE_FIELD(Int);
2496 UPDATE_FIELD(Float);
2497 UPDATE_FIELD(Long);
2498 UPDATE_FIELD(Double);
2499 UPDATE_FIELD(Short);
2500 UPDATE_FIELD(Char);
2501 UPDATE_FIELD(Byte);
2502 UPDATE_FIELD(Boolean);
2503 case art::Primitive::kPrimNot:
2504 case art::Primitive::kPrimVoid:
2505 LOG(FATAL) << "Unexpected field with type " << ftype << " found!";
2506 UNREACHABLE();
2507#undef UPDATE_FIELD
2508 }
2509 }
2510}
2511
2512static void CopyFields(bool is_static,
2513 art::ObjPtr<art::mirror::Object> target,
2514 art::ObjPtr<art::mirror::Class> target_class,
2515 art::ObjPtr<art::mirror::Object> source,
2516 art::ObjPtr<art::mirror::Class> source_class)
2517 REQUIRES(art::Locks::mutator_lock_) {
2518 DCHECK(!source_class->IsObjectClass() && !target_class->IsObjectClass())
2519 << "Should not be overriding object class fields. Target: " << target_class->PrettyClass()
2520 << " Source: " << source_class->PrettyClass();
2521 for (art::ArtField& f : (is_static ? source_class->GetSFields() : source_class->GetIFields())) {
2522 art::ArtField* new_field =
2523 (is_static ? target_class->FindDeclaredStaticField(f.GetName(), f.GetTypeDescriptor())
2524 : target_class->FindDeclaredInstanceField(f.GetName(), f.GetTypeDescriptor()));
2525 CHECK(new_field != nullptr) << "could not find new version of " << f.PrettyField();
2526 CopyField(target, new_field, source, f);
2527 }
2528 if (!is_static && !target_class->GetSuperClass()->IsObjectClass()) {
2529 CopyFields(
2530 is_static, target, target_class->GetSuperClass(), source, source_class->GetSuperClass());
2531 }
2532}
2533
2534static void ClearField(art::ObjPtr<art::mirror::Object> target, art::ArtField& field)
2535 REQUIRES(art::Locks::mutator_lock_) {
2536 art::Primitive::Type ftype = field.GetTypeAsPrimitiveType();
2537 if (ftype == art::Primitive::kPrimNot) {
2538 field.SetObject<false>(target, nullptr);
2539 } else {
2540 switch (ftype) {
2541#define UPDATE_FIELD(TYPE) \
2542 case art::Primitive::kPrim##TYPE: \
2543 field.Set##TYPE<false>(target, 0); \
2544 break
2545 UPDATE_FIELD(Int);
2546 UPDATE_FIELD(Float);
2547 UPDATE_FIELD(Long);
2548 UPDATE_FIELD(Double);
2549 UPDATE_FIELD(Short);
2550 UPDATE_FIELD(Char);
2551 UPDATE_FIELD(Byte);
2552 UPDATE_FIELD(Boolean);
2553 case art::Primitive::kPrimNot:
2554 case art::Primitive::kPrimVoid:
2555 LOG(FATAL) << "Unexpected field with type " << ftype << " found!";
2556 UNREACHABLE();
2557#undef UPDATE_FIELD
2558 }
2559 }
2560}
2561
2562static void ClearFields(bool is_static,
2563 art::ObjPtr<art::mirror::Object> target,
2564 art::ObjPtr<art::mirror::Class> target_class)
2565 REQUIRES(art::Locks::mutator_lock_) {
2566 DCHECK(!target_class->IsObjectClass());
2567 for (art::ArtField& f : (is_static ? target_class->GetSFields() : target_class->GetIFields())) {
2568 ClearField(target, f);
2569 }
2570 if (!is_static && !target_class->GetSuperClass()->IsObjectClass()) {
2571 ClearFields(is_static, target, target_class->GetSuperClass());
2572 }
2573}
2574
2575static void CopyAndClearFields(bool is_static,
2576 art::ObjPtr<art::mirror::Object> target,
2577 art::ObjPtr<art::mirror::Class> target_class,
2578 art::ObjPtr<art::mirror::Object> source,
2579 art::ObjPtr<art::mirror::Class> source_class)
2580 REQUIRES(art::Locks::mutator_lock_) {
2581 // Copy all non-j.l.Object fields
2582 CopyFields(is_static, target, target_class, source, source_class);
2583 // Copy the lock-word.
2584 target->SetLockWord(source->GetLockWord(false), false);
2585 // Clear (reset) the old one.
2586 source->SetLockWord(art::LockWord::Default(), false);
2587 art::WriteBarrier::ForEveryFieldWrite(target);
2588
2589 // Clear the fields from the old class. We don't need it anymore.
2590 ClearFields(is_static, source, source_class);
2591 art::WriteBarrier::ForEveryFieldWrite(source);
2592}
2593
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002594void Redefiner::ClassRedefinition::UpdateClassStructurally(const RedefinitionDataIter& holder) {
2595 DCHECK(IsStructuralRedefinition());
2596 // LETS GO. We've got all new class structures so no need to do all the updating of the stacks.
2597 // Instead we need to update everything else.
2598 // Just replace the class and be done with it.
2599 art::Locks::mutator_lock_->AssertExclusiveHeld(driver_->self_);
2600 art::ScopedAssertNoThreadSuspension sants(__FUNCTION__);
2601 art::ObjPtr<art::mirror::Class> orig(holder.GetMirrorClass());
2602 art::ObjPtr<art::mirror::Class> replacement(holder.GetNewClassObject());
Alex Light270db1c2019-12-03 12:20:01 +00002603 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> new_classes(holder.GetNewClasses());
2604 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> old_classes(holder.GetOldClasses());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002605 // Collect mappings from old to new fields/methods
2606 std::map<art::ArtMethod*, art::ArtMethod*> method_map;
2607 std::map<art::ArtField*, art::ArtField*> field_map;
2608 CollectNewFieldAndMethodMappings(holder, &method_map, &field_map);
Alex Light986914b2019-11-19 01:12:25 +00002609 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> new_instances(
2610 holder.GetNewInstanceObjects());
2611 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> old_instances(
2612 holder.GetOldInstanceObjects());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002613 CHECK(!orig.IsNull());
2614 CHECK(!replacement.IsNull());
Alex Light270db1c2019-12-03 12:20:01 +00002615 // Once we do the ReplaceReferences old_classes will have the new_classes in it. We want to keep
2616 // ahold of the old classes so copy them now.
2617 std::vector<art::ObjPtr<art::mirror::Class>> old_classes_vec(old_classes->Iterate().begin(),
2618 old_classes->Iterate().end());
Alex Light986914b2019-11-19 01:12:25 +00002619 // Copy over the static fields of the class and all the instance fields.
Alex Light270db1c2019-12-03 12:20:01 +00002620 for (auto [new_class, old_class] : art::ZipLeft(new_classes->Iterate(), old_classes->Iterate())) {
2621 CHECK(!new_class.IsNull());
2622 CHECK(!old_class.IsNull());
2623 CHECK(!old_class->IsErroneous());
2624 if (old_class->GetStatus() > new_class->GetStatus()) {
2625 // Some verification/initialization step happened during interval between
2626 // creating the new class and now. Just copy the new status.
2627 new_class->SetStatusLocked(old_class->GetStatus());
2628 }
2629 CopyAndClearFields(true, new_class, new_class, old_class, old_class);
2630 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002631
Alex Light986914b2019-11-19 01:12:25 +00002632 // Copy and clear the fields of the old-instances.
Alex Light270db1c2019-12-03 12:20:01 +00002633 for (auto [new_instance, old_instance] :
2634 art::ZipLeft(new_instances->Iterate(), old_instances->Iterate())) {
Alex Light986914b2019-11-19 01:12:25 +00002635 CopyAndClearFields(/*is_static=*/false,
2636 new_instance,
2637 new_instance->GetClass(),
2638 old_instance,
2639 old_instance->GetClass());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002640 }
2641 // Mark old class obsolete.
Alex Light270db1c2019-12-03 12:20:01 +00002642 for (auto old_class : old_classes->Iterate()) {
2643 old_class->SetObsoleteObject();
2644 // Mark methods obsolete. We need to wait until later to actually clear the jit data.
2645 for (art::ArtMethod& m : old_class->GetMethods(art::kRuntimePointerSize)) {
2646 m.SetIsObsolete();
2647 if (m.IsInvokable()) {
2648 m.SetDontCompile();
2649 }
2650 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002651 }
Alex Lightc18eba32019-09-24 14:36:27 -07002652 // Update live pointers in ART code.
Alex Light24627892019-11-06 10:28:21 -08002653 auto could_change_resolution_of = [&](auto* field_or_method,
2654 const auto& info) REQUIRES(art::Locks::mutator_lock_) {
2655 constexpr bool is_method = std::is_same_v<art::ArtMethod*, decltype(field_or_method)>;
2656 static_assert(is_method || std::is_same_v<art::ArtField*, decltype(field_or_method)>,
2657 "Input is not field or method!");
2658 // Only dex-cache is used for resolution
2659 if (LIKELY(info.GetType() != art::ReflectionSourceType::kSourceDexCacheResolvedField &&
2660 info.GetType() != art::ReflectionSourceType::kSourceDexCacheResolvedMethod)) {
2661 return false;
2662 }
2663 if constexpr (is_method) {
2664 // Only direct methods are used without further indirection through a vtable/IFTable.
2665 // Constructors cannot be shadowed.
2666 if (LIKELY(!field_or_method->IsDirect() || field_or_method->IsConstructor())) {
2667 return false;
2668 }
2669 } else {
2670 // Only non-private fields can be shadowed in a manner that's visible.
2671 if (LIKELY(field_or_method->IsPrivate())) {
2672 return false;
2673 }
2674 }
2675 // We can only shadow things from our superclasses
2676 if (LIKELY(!field_or_method->GetDeclaringClass()->IsAssignableFrom(orig))) {
2677 return false;
2678 }
2679 if constexpr (is_method) {
2680 auto direct_methods = replacement->GetDirectMethods(art::kRuntimePointerSize);
2681 return std::find_if(direct_methods.begin(),
2682 direct_methods.end(),
2683 [&](art::ArtMethod& m) REQUIRES(art::Locks::mutator_lock_) {
2684 return UNLIKELY(m.HasSameNameAndSignature(field_or_method));
2685 }) != direct_methods.end();
2686 } else {
2687 auto pred = [&](art::ArtField& f) REQUIRES(art::Locks::mutator_lock_) {
2688 return std::string_view(f.GetName()) == std::string_view(field_or_method->GetName()) &&
2689 std::string_view(f.GetTypeDescriptor()) ==
2690 std::string_view(field_or_method->GetTypeDescriptor());
2691 };
2692 if (field_or_method->IsStatic()) {
2693 auto sfields = replacement->GetSFields();
2694 return std::find_if(sfields.begin(), sfields.end(), pred) != sfields.end();
2695 } else {
2696 auto ifields = replacement->GetIFields();
2697 return std::find_if(ifields.begin(), ifields.end(), pred) != ifields.end();
2698 }
2699 }
2700 };
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002701 // TODO Performing 2 stack-walks back to back isn't the greatest. We might want to try to combine
2702 // it with the one ReplaceReferences does. Doing so would be rather complicated though.
Alex Lightc18eba32019-09-24 14:36:27 -07002703 driver_->runtime_->VisitReflectiveTargets(
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002704 [&](art::ArtField* f, const auto& info) REQUIRES(art::Locks::mutator_lock_) {
Alex Light28b6efe2019-11-06 12:49:41 -08002705 DCHECK(f != nullptr) << info;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002706 auto it = field_map.find(f);
Alex Light24627892019-11-06 10:28:21 -08002707 if (it != field_map.end()) {
2708 VLOG(plugin) << "Updating " << info << " object for (field) "
2709 << it->second->PrettyField();
2710 return it->second;
2711 } else if (UNLIKELY(could_change_resolution_of(f, info))) {
2712 // Resolution might change. Just clear the resolved value.
2713 VLOG(plugin) << "Clearing resolution " << info << " for (field) " << f->PrettyField();
2714 return static_cast<art::ArtField*>(nullptr);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002715 }
Alex Light24627892019-11-06 10:28:21 -08002716 return f;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002717 },
2718 [&](art::ArtMethod* m, const auto& info) REQUIRES(art::Locks::mutator_lock_) {
Alex Light28b6efe2019-11-06 12:49:41 -08002719 DCHECK(m != nullptr) << info;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002720 auto it = method_map.find(m);
Alex Light24627892019-11-06 10:28:21 -08002721 if (it != method_map.end()) {
2722 VLOG(plugin) << "Updating " << info << " object for (method) "
2723 << it->second->PrettyMethod();
2724 return it->second;
2725 } else if (UNLIKELY(could_change_resolution_of(m, info))) {
2726 // Resolution might change. Just clear the resolved value.
2727 VLOG(plugin) << "Clearing resolution " << info << " for (method) " << m->PrettyMethod();
2728 return static_cast<art::ArtMethod*>(nullptr);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002729 }
Alex Light24627892019-11-06 10:28:21 -08002730 return m;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002731 });
2732
2733 // Force every frame of every thread to deoptimize (any frame might have eg offsets compiled in).
2734 driver_->runtime_->GetInstrumentation()->DeoptimizeAllThreadFrames();
2735
Alex Light986914b2019-11-19 01:12:25 +00002736 std::unordered_map<art::ObjPtr<art::mirror::Object>,
2737 art::ObjPtr<art::mirror::Object>,
2738 art::HashObjPtr> map;
Alex Light270db1c2019-12-03 12:20:01 +00002739 for (auto [new_class, old_class] : art::ZipLeft(new_classes->Iterate(), old_classes->Iterate())) {
2740 map.emplace(old_class, new_class);
2741 }
2742 for (auto [new_instance, old_instance] :
2743 art::ZipLeft(new_instances->Iterate(), old_instances->Iterate())) {
2744 map.emplace(old_instance, new_instance);
2745 // Bare-bones check that the mapping is correct.
2746 CHECK(new_instance->GetClass() == map[old_instance->GetClass()]->AsClass())
2747 << new_instance->GetClass()->PrettyClass() << " vs "
2748 << map[old_instance->GetClass()]->AsClass()->PrettyClass();
Alex Light986914b2019-11-19 01:12:25 +00002749 }
2750
2751 // Actually perform the general replacement. This doesn't affect ArtMethod/ArtFields. It does
2752 // affect the declaring_class field of all the obsolete objects, which is unfortunate and needs to
2753 // be undone. This replaces the mirror::Class in 'holder' as well. It's magic!
2754 HeapExtensions::ReplaceReferences(driver_->self_, map);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002755
2756 // Save the old class so that the JIT gc doesn't get confused by it being collected before the
2757 // jit code. This is also needed to keep the dex-caches of any obsolete methods live.
Alex Light270db1c2019-12-03 12:20:01 +00002758 for (auto [new_class, old_class] :
2759 art::ZipLeft(new_classes->Iterate(), art::MakeIterationRange(old_classes_vec))) {
2760 new_class->GetExtData()->SetObsoleteClass(old_class);
2761 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002762
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002763 art::jit::Jit* jit = driver_->runtime_->GetJit();
2764 if (jit != nullptr) {
2765 // Clear jit.
2766 // TODO We might want to have some way to tell the JIT not to wait the kJitSamplesBatchSize
2767 // invokes to start compiling things again.
2768 jit->GetCodeCache()->InvalidateAllCompiledCode();
2769 }
2770
2771 // Clear thread caches
2772 {
2773 // TODO We might be able to avoid doing this but given the rather unstructured nature of the
2774 // interpreter cache it's probably not worth the effort.
2775 art::MutexLock mu(driver_->self_, *art::Locks::thread_list_lock_);
2776 driver_->runtime_->GetThreadList()->ForEach(
2777 [](art::Thread* t) { t->GetInterpreterCache()->Clear(t); });
2778 }
2779
2780 if (art::kIsDebugBuild) {
2781 // Just make sure we didn't screw up any of the now obsolete methods or fields. We need their
2782 // declaring-class to still be the obolete class
2783 orig->VisitMethods([&](art::ArtMethod* method) REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light270db1c2019-12-03 12:20:01 +00002784 if (method->IsCopied()) {
2785 // Copied methods have interfaces as their declaring class.
2786 return;
2787 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002788 DCHECK_EQ(method->GetDeclaringClass(), orig) << method->GetDeclaringClass()->PrettyClass()
2789 << " vs " << orig->PrettyClass();
2790 }, art::kRuntimePointerSize);
2791 orig->VisitFields([&](art::ArtField* field) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2792 DCHECK_EQ(field->GetDeclaringClass(), orig) << field->GetDeclaringClass()->PrettyClass()
2793 << " vs " << orig->PrettyClass();
2794 });
2795 }
2796}
2797
2798// Redefines the class in place
2799void Redefiner::ClassRedefinition::UpdateClassInPlace(const RedefinitionDataIter& holder) {
2800 art::ObjPtr<art::mirror::Class> mclass(holder.GetMirrorClass());
2801 // TODO Rewrite so we don't do a stack walk for each and every class.
2802 FindAndAllocateObsoleteMethods(mclass);
2803 art::ObjPtr<art::mirror::DexCache> new_dex_cache(holder.GetNewDexCache());
2804 art::ObjPtr<art::mirror::Object> original_dex_file(holder.GetOriginalDexFile());
Alex Light6ac57502017-01-19 15:05:06 -08002805 DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002806 const art::dex::ClassDef& class_def = dex_file_->GetClassDef(0);
Vladimir Marko5122e6b2017-08-17 16:10:09 +01002807 UpdateMethods(mclass, class_def);
Alex Light007ada22017-01-10 13:33:56 -08002808 UpdateFields(mclass);
Alex Light200b9d72016-12-15 11:34:13 -08002809
David Brazdil1a658632018-12-01 17:54:26 +00002810 art::ObjPtr<art::mirror::ClassExt> ext(mclass->GetExtData());
2811 CHECK(!ext.IsNull());
2812 ext->SetOriginalDexFile(original_dex_file);
2813
2814 // If this is the first time the class is being redefined, store
2815 // the native DexFile pointer and initial ClassDef index in ClassExt.
2816 // This preserves the pointer for hiddenapi access checks which need
2817 // to read access flags from the initial DexFile.
2818 if (ext->GetPreRedefineDexFile() == nullptr) {
2819 ext->SetPreRedefineDexFile(&mclass->GetDexFile());
2820 ext->SetPreRedefineClassDefIndex(mclass->GetDexClassDefIndex());
2821 }
2822
Alex Lighta01de592016-11-15 10:43:06 -08002823 // Update the class fields.
2824 // Need to update class last since the ArtMethod gets its DexFile from the class (which is needed
2825 // to call GetReturnTypeDescriptor and GetParameterTypeList above).
2826 mclass->SetDexCache(new_dex_cache.Ptr());
Alex Light6ac57502017-01-19 15:05:06 -08002827 mclass->SetDexClassDefIndex(dex_file_->GetIndexForClassDef(class_def));
Alex Light0e692732017-01-10 15:00:05 -08002828 mclass->SetDexTypeIndex(dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(class_sig_.c_str())));
Alex Light035105f2018-03-05 17:48:48 -08002829
2830 // Notify the jit that all the methods in this class were redefined. Need to do this last since
2831 // the jit relies on the dex_file_ being correct (for native methods at least) to find the method
2832 // meta-data.
2833 art::jit::Jit* jit = driver_->runtime_->GetJit();
2834 if (jit != nullptr) {
2835 art::PointerSize image_pointer_size =
2836 driver_->runtime_->GetClassLinker()->GetImagePointerSize();
2837 auto code_cache = jit->GetCodeCache();
2838 // Non-invokable methods don't have any JIT data associated with them so we don't need to tell
2839 // the jit about them.
2840 for (art::ArtMethod& method : mclass->GetDeclaredMethods(image_pointer_size)) {
2841 if (method.IsInvokable()) {
2842 code_cache->NotifyMethodRedefined(&method);
2843 }
2844 }
2845 }
Alex Lighta01de592016-11-15 10:43:06 -08002846}
2847
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002848// Performs final updates to class for redefinition.
2849void Redefiner::ClassRedefinition::UpdateClass(const RedefinitionDataIter& holder) {
2850 if (IsStructuralRedefinition()) {
2851 UpdateClassStructurally(holder);
2852 } else {
2853 UpdateClassInPlace(holder);
2854 }
Alex Lightc2d0c962019-10-23 14:14:25 -07002855 UpdateClassCommon(holder);
2856}
2857
2858void Redefiner::ClassRedefinition::UpdateClassCommon(const RedefinitionDataIter &cur_data) {
2859 // NB This is after we've already replaced all old-refs with new-refs in the structural case.
2860 art::ObjPtr<art::mirror::Class> klass(cur_data.GetMirrorClass());
2861 DCHECK(!IsStructuralRedefinition() || klass == cur_data.GetNewClassObject());
2862 if (!needs_reverify_) {
2863 return;
2864 }
2865 // Force the most restrictive interpreter environment. We don't know what the final verification
2866 // will allow. We will clear these after retrying verification once we drop the mutator-lock.
2867 klass->VisitMethods([](art::ArtMethod* m) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2868 if (!m->IsNative() && m->IsInvokable() && !m->IsObsolete()) {
2869 m->ClearSkipAccessChecks();
2870 m->SetDontCompile();
2871 m->SetMustCountLocks();
2872 }
2873 }, art::kRuntimePointerSize);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002874}
2875
Alex Light1e3926a2017-04-07 10:38:06 -07002876// Restores the old obsolete methods maps if it turns out they weren't needed (ie there were no new
2877// obsolete methods).
2878void Redefiner::ClassRedefinition::RestoreObsoleteMethodMapsIfUnneeded(
2879 const RedefinitionDataIter* cur_data) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002880 if (IsStructuralRedefinition()) {
2881 // We didn't touch these in this case.
2882 return;
2883 }
Vladimir Markod93e3742018-07-18 10:58:13 +01002884 art::ObjPtr<art::mirror::Class> klass = GetMirrorClass();
2885 art::ObjPtr<art::mirror::ClassExt> ext = klass->GetExtData();
2886 art::ObjPtr<art::mirror::PointerArray> methods = ext->GetObsoleteMethods();
2887 art::ObjPtr<art::mirror::PointerArray> old_methods = cur_data->GetOldObsoleteMethods();
Alex Light70713df2017-04-18 13:03:31 -07002888 int32_t old_length = old_methods == nullptr ? 0 : old_methods->GetLength();
Alex Light1e3926a2017-04-07 10:38:06 -07002889 int32_t expected_length =
2890 old_length + klass->NumDirectMethods() + klass->NumDeclaredVirtualMethods();
2891 // Check to make sure we are only undoing this one.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002892 if (methods.IsNull()) {
2893 // No new obsolete methods! We can get rid of the maps.
2894 ext->SetObsoleteArrays(cur_data->GetOldObsoleteMethods(), cur_data->GetOldDexCaches());
2895 } else if (expected_length == methods->GetLength()) {
Alex Light70713df2017-04-18 13:03:31 -07002896 for (int32_t i = 0; i < expected_length; i++) {
2897 art::ArtMethod* expected = nullptr;
2898 if (i < old_length) {
2899 expected = old_methods->GetElementPtrSize<art::ArtMethod*>(i, art::kRuntimePointerSize);
2900 }
2901 if (methods->GetElementPtrSize<art::ArtMethod*>(i, art::kRuntimePointerSize) != expected) {
Alex Light1e3926a2017-04-07 10:38:06 -07002902 // We actually have some new obsolete methods. Just abort since we cannot safely shrink the
2903 // obsolete methods array.
2904 return;
2905 }
2906 }
2907 // No new obsolete methods! We can get rid of the maps.
2908 ext->SetObsoleteArrays(cur_data->GetOldObsoleteMethods(), cur_data->GetOldDexCaches());
2909 }
2910}
2911
Alex Lighta01de592016-11-15 10:43:06 -08002912// This function does all (java) allocations we need to do for the Class being redefined.
2913// TODO Change this name maybe?
Alex Light1e3926a2017-04-07 10:38:06 -07002914bool Redefiner::ClassRedefinition::EnsureClassAllocationsFinished(
2915 /*out*/RedefinitionDataIter* cur_data) {
Alex Light0e692732017-01-10 15:00:05 -08002916 art::StackHandleScope<2> hs(driver_->self_);
2917 art::Handle<art::mirror::Class> klass(hs.NewHandle(
2918 driver_->self_->DecodeJObject(klass_)->AsClass()));
Andreas Gampefa4333d2017-02-14 11:10:34 -08002919 if (klass == nullptr) {
Alex Lighta01de592016-11-15 10:43:06 -08002920 RecordFailure(ERR(INVALID_CLASS), "Unable to decode class argument!");
2921 return false;
2922 }
2923 // Allocate the classExt
Vladimir Marko3068d582019-05-28 16:39:29 +01002924 art::Handle<art::mirror::ClassExt> ext =
2925 hs.NewHandle(art::mirror::Class::EnsureExtDataPresent(klass, driver_->self_));
Andreas Gampefa4333d2017-02-14 11:10:34 -08002926 if (ext == nullptr) {
Alex Lighta01de592016-11-15 10:43:06 -08002927 // No memory. Clear exception (it's not useful) and return error.
Alex Light0e692732017-01-10 15:00:05 -08002928 driver_->self_->AssertPendingOOMException();
2929 driver_->self_->ClearException();
Alex Lighta01de592016-11-15 10:43:06 -08002930 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate ClassExt");
2931 return false;
2932 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002933 if (!IsStructuralRedefinition()) {
2934 // First save the old values of the 2 arrays that make up the obsolete methods maps. Then
2935 // allocate the 2 arrays that make up the obsolete methods map. Since the contents of the arrays
2936 // are only modified when all threads (other than the modifying one) are suspended we don't need
2937 // to worry about missing the unsyncronized writes to the array. We do synchronize when setting
2938 // it however, since that can happen at any time.
2939 cur_data->SetOldObsoleteMethods(ext->GetObsoleteMethods());
2940 cur_data->SetOldDexCaches(ext->GetObsoleteDexCaches());
2941 if (!art::mirror::ClassExt::ExtendObsoleteArrays(
2942 ext, driver_->self_, klass->GetDeclaredMethodsSlice(art::kRuntimePointerSize).size())) {
2943 // OOM. Clear exception and return error.
2944 driver_->self_->AssertPendingOOMException();
2945 driver_->self_->ClearException();
2946 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate/extend obsolete methods map");
2947 return false;
2948 }
Alex Lighta01de592016-11-15 10:43:06 -08002949 }
2950 return true;
2951}
2952
2953} // namespace openjdkjvmti